void *chg_uid_gid(void *arg)
{
	cap_t newcaps;
	cap_t mycaps;
	int ret;

	test_msg("Aux thread runs as UID: %d; GID: %d\n", getuid(), getgid());

	newcaps = cap_from_text("cap_setgid,cap_setuid=+eip");
	if (!newcaps) {
		pr_perror("Failed to get capability struct\n");
		exit(1);
	}

	ret = cap_set_proc(newcaps);
	if (ret) {
		pr_perror("Failed to set capabilities for the process\n");
		exit(1);
	}

	mycaps = cap_get_proc();
	if (!mycaps) {
		pr_perror("Failed to get child thread capabilities\n");
		exit_group(2);
	}

	test_msg("Child capabilities: %s\n", cap_to_text(mycaps, NULL));
	test_msg("Changing UID/GID in child thread to %d:%d\n", uid, gid);

	ret = syscall(SYS_setresgid, gid, gid, gid);
	if (ret >= 0) {
		syscall(SYS_setresuid, uid, uid, uid);
	} else if (ret < 0) {
		pr_perror("Failed to change UID/GID\n");
		exit_group(2);
	}

	gid = getgid();
	uid = getuid();
	test_msg("Now aux thread runs as UID: %d; GID: %d\n", uid, gid);

	test_msg("Child thread is waiting for main thread's signal\n");
	task_waiter_complete(&t, 1);

	pthread_mutex_lock(&mutex);
	while (!done) {
		pthread_cond_wait(&cond, &mutex);
	}
	pthread_mutex_unlock(&mutex);

	test_msg("Child thread returns\n");
	return NULL;
}
Beispiel #2
0
int main(int argc, char *argv[])
{
	char buf[sizeof(teststr)];
	int master, slave, ret;
	char *slavename;
	task_waiter_t t;
	pid_t pid;

	test_init(argc, argv);

	master = open("/dev/ptmx", O_RDWR);
	if (master == -1) {
		err("open(%s) failed", "/dev/ptmx");
		return 1;
	}

	grantpt(master);
	unlockpt(master);

	slavename = ptsname(master);
	slave = open(slavename, O_RDWR);
	if (slave == -1) {
		err("open(%s) failed", slavename);
		return 1;
	}

	task_waiter_init(&t);

	pid = test_fork();
	if (pid == 0) {
		int new_master, ret;

		new_master = dup(master);
		if (new_master < 0) {
			err("can't dup master\n");
			exit_shot_parent(1);
		}

		task_waiter_complete_current(&t);

		ret = write(new_master, teststr, sizeof(teststr) - 1);
		if (ret != sizeof(teststr) - 1) {
			err("write(new_master) failed");
			exit_shot_parent(1);
		}

		task_waiter_wait4(&t, 1);

		close(new_master);
		exit(0);
	} else if (pid < 0) {
		err("test_fork failed: %m\n");
		exit(1);
	}

	task_waiter_wait4(&t, pid);
	close(master);

	test_daemon();
	test_waitsig();

	signal(SIGHUP, SIG_IGN);
	task_waiter_complete(&t, 1);

	ret = read(slave, buf, sizeof(teststr) - 1);
	if (ret != sizeof(teststr) - 1) {
		err("read(slave) failed");
		return 1;
	}

	if (strncmp(teststr, buf, sizeof(teststr) - 1)) {
		fail("data mismatch");
		return 1;
	}

	close(slave);

	pass();

	return 0;
}
Beispiel #3
0
void task_waiter_complete_current(task_waiter_t *t)
{
    return task_waiter_complete(t, (int)sys_gettid());
}
Beispiel #4
0
int main(int argc, char **argv)
{
	task_waiter_t lock;
	pid_t pid1, pid2, pid3, pid0 = getpid();
	int status = -1, sk;

	test_init(argc, argv);
	task_waiter_init(&lock);

	sk = create_socket(0);
	if (sk < 0)
		return 1;

	pid1 = fork();
	if (pid1 < 0) {
		pr_perror("fork");
		return -1;
	}
	if (pid1 == 0) {
		close(sk);
		unshare(CLONE_NEWNET);
		sk = create_socket(1);
		if (sk < 0)
			return 1;

		pid3 = fork();
		if (pid3 < 0) {
			pr_perror("fork");
			return 1;
		}
		if (pid3 == 0) {
			char ns[] = "/proc/0123456789/ns/net";
			int fd;

			snprintf(ns, sizeof(ns), "/proc/%d/ns/net", pid0);
			fd = open(ns, O_RDONLY);
			if (fd < 0)
				return 1;

			if (setns(fd, 0))
				return 1;
			close(fd);

			task_waiter_complete(&lock, 3);
			test_waitsig();

			if (check_socket(0, true))
				return 1;
			if (check_socket(2, false))
				return 1;
			if (check_socket(1, false))
				return 1;

			return 0;
		}
		/* This socket will be alive in the 3 process */
		close(sk);

		task_waiter_complete(&lock, 1);
		test_waitsig();

		if (check_socket(1, true))
			return 1;

		kill(pid3, SIGTERM);
		waitpid(pid3, &status, 0);
		if (status) {
			fail();
			return 1;
		}

		return 0;
	}
	pid2 = fork();
	if (pid2 < 0) {
		pr_perror("fork");
		return -1;
	}
	if (pid2 == 0) {
		unshare(CLONE_NEWNET);
		sk = create_socket(2);
		if (sk < 0)
			return 1;
		task_waiter_complete(&lock, 2);

		test_waitsig();

		if (check_socket(0, false))
			return 1;
		if (check_socket(1, false))
			return 1;
		if (check_socket(2, true))
			return 1;

		return 0;
	}
	close(sk);
	task_waiter_wait4(&lock, 1);
	task_waiter_wait4(&lock, 2);
	task_waiter_wait4(&lock, 3);

	test_daemon();
	test_waitsig();

	kill(pid1, SIGTERM);
	waitpid(pid1, &status, 0);
	if (status) {
		fail();
		return 1;
	}
	kill(pid2, SIGTERM);
	status = -1;
	waitpid(pid2, &status, 0);
	if (status) {
		fail();
		return 1;
	}
	pass();
	return 0;
}
int main(int argc, char **argv)
{
	char path[PATH_MAX];
	pid_t pid;
	int status, i;
	task_waiter_t t;

	test_init(argc, argv);

	task_waiter_init(&t);

	snprintf(path, sizeof(path), "%s/fs", dirname);
	if (mkdir(dirname, 0700)) {
		pr_perror("mkdir");
		return 1;
	}

	if (mount(NULL, "/", NULL, MS_SHARED, NULL)) {
		pr_perror("mount");
		return 1;
	}

	if (mount("zdtm_fs", dirname, "tmpfs", 0, NULL)) {
		pr_perror("mount");
		return 1;
	}

	if (mount(NULL, dirname, NULL, MS_PRIVATE, NULL)) {
		pr_perror("mount");
		return 1;
	}

	if (mkdir(path, 0700)) {
		pr_perror("mkdir");
		return 1;
	}

	if (mount("zdtm_fs", path, "tmpfs", 0, NULL)) {
		pr_perror("mount");
		return 1;
	}

	for (i = 0; i < 2; i++) {
		pid = fork();
		if (pid < 0) {
			pr_perror("fork");
			return 1;
		}
		if (pid == 0) {
			unshare(CLONE_NEWNS);

			task_waiter_complete(&t, 1);
			task_waiter_wait4(&t, 2);

			return 0;
		}
	}

	for (i = 0; i < 2; i++)
		task_waiter_wait4(&t, 1);

	test_daemon();
	test_waitsig();

	if (umount(path)) {
		pr_perror("Unable to umount %s", path);
		return 1;
	}
	if (umount(dirname)) {
		pr_perror("Unable to umount %s", dirname);
		return 1;
	}

	for (i = 0; i < 2; i++) {
		task_waiter_complete(&t, 2);

		if (waitpid(-1, &status, 0) < 0) {
			pr_perror("waitpid %d", pid);
			return 1;
		}

		if (status) {
			pr_err("%d/%d/%d/%d\n", WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status));
			return 1;
		}
	}

	pass();

	return 0;
}
Beispiel #6
0
int main(int argc, char *argv[])
{
	struct sockaddr_un addr;
	unsigned int addrlen;
	task_waiter_t lock;

	char dir[] = "/tmp/zdtm.unix.sock.XXXXXX";
	char *path;
	pid_t pid;
	int ret, sk;
	char *val;

	unsetenv("ZDTM_GROUPS");
	val = getenv("ZDTM_GID");
	if (val && (setgid(atoi(val)) == -1)) {
		fprintf(stderr, "Can't set gid: %m");
		exit(1);
	}

	val = getenv("ZDTM_UID");
	if (val && (setuid(atoi(val)) == -1)) {
		fprintf(stderr, "Can't set uid: %m");
		exit(1);
	}

	if (mkdtemp(dir) < 0) {
		pr_perror("mkdtemp(%s) failed", dir);
		return 1;
	}
	chmod(dir, 0777);
	addr.sun_family = AF_UNIX;
	snprintf(addr.sun_path, sizeof(addr.sun_path),
			"%s/%s", dir, "sock");
	path = addr.sun_path;
	addrlen = sizeof(addr.sun_family) + strlen(path);

	task_waiter_init(&lock);

	pid = fork();
	if (pid < 0) {
		pr_perror("fork() failed");
		return 1;
	} else if (pid == 0) {
		char c;
		test_ext_init(argc, argv);

		sk = socket(AF_UNIX, SOCK_DGRAM, 0);
		if (sk < 0) {
			pr_perror("Can't create socket");
			return 1;
		}
		ret = bind(sk, (struct sockaddr *) &addr, addrlen);
		if (ret < 0) {
			pr_perror("Can't bind socket to %s", path);
			return 1;
		}
		chmod(dir, 0777);
		chmod(path, 0777);
		test_msg("The external socket %s\n", path);
		task_waiter_complete(&lock, 1);
		task_waiter_fini(&lock);

		recv(sk, &c, sizeof(c), 0);

		return 0;
	}

	task_waiter_wait4(&lock, 1);
	task_waiter_fini(&lock);

	test_init(argc, argv);

	sk = socket(AF_UNIX, SOCK_DGRAM, 0);
	if (sk < 0) {
		pr_perror("Can't create socket");
		return 1;
	}

	ret = connect(sk, (struct sockaddr *) &addr, addrlen);
	if (ret < 0) {
		pr_perror("Can't connect socket");
		return 1;
	}


	test_daemon();
	test_waitsig();

	if (unlink(path)) {
		pr_perror("Unable to remove %s\n", path);
		return 1;
	}
	if (rmdir(dir)) {
		pr_perror("Unable to remove %s", dir);
		return 1;
	}

	ret = send(sk, "H", 1, 0);
	if (ret != 1) {
		pr_perror("Can't send a symbol");
		fail();
		return 1;
	}

	pass();
	return 0;
}
Beispiel #7
0
int main(int argc, char **argv)
{
	char path[PATH_MAX], bpath[PATH_MAX], spath[PATH_MAX], bspath[PATH_MAX];
	pid_t pid;
	int status;
	task_waiter_t t;

	test_init(argc, argv);

	task_waiter_init(&t);

	mount(NULL, "/", NULL, MS_SHARED, NULL);

	snprintf(path, sizeof(path), "%s/test", dirname);
	snprintf(bpath, sizeof(bpath), "%s/test.bind", dirname);
	snprintf(spath, sizeof(spath), "%s/test/sub", dirname);
	snprintf(bspath, sizeof(bspath), "%s/test.bind/sub", dirname);

	if (mkdir(dirname, 0700) ||
	    mkdir(path, 0700) ||
	    mkdir(spath, 0700) ||
	    mkdir(bpath, 0700)) {
		err("mkdir");
		return 1;
	}

	pid = fork();
	if (pid < 0) {
		err("fork");
		return 1;
	}
	if (pid == 0) {
		unshare(CLONE_NEWNS);
		if (mount(path, bpath, NULL, MS_BIND, NULL)) {
			err("mount");
			return 1;
		}

		task_waiter_complete(&t, 1);
		task_waiter_wait4(&t, 2);

		if (access(bspath, F_OK)) {
			fail("%s isn't accessiable", bspath);
			return 1;
		}


		if (umount2(bpath, MNT_DETACH)) {
			fail("umount");
			return 1;
		}

		return 0;
	}

	task_waiter_wait4(&t, 1);

	if (mount("test", spath, "tmpfs", 0, NULL)) {
		err("mount");
		return 1;
	}

	test_daemon();
	test_waitsig();

	task_waiter_complete(&t, 2);

	if (waitpid(pid, &status, 0) != pid) {
		err("waitpid %d", pid);
		return 1;
	}

	if (status) {
		err("%d/%d/%d/%d", WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status));
		return 1;
	}

	pass();

	return 0;
}
Beispiel #8
0
int main(int argc, char **argv)
{
	task_waiter_t lock;
	pid_t pid = -1;
	int status = 1;

	task_waiter_init(&lock);
	test_init(argc, argv);

	pid = fork();
	if (pid < 0) {
		pr_perror("fork");
		return 1;
	}

	if (pid == 0) {
		int fd;
		DIR *d;
		struct dirent *de;

		if (unshare(CLONE_NEWNS)) {
			pr_perror("unshare");
			return 1;
		}
		if (mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL)) {
			pr_perror("mount");
			return 1;
		}

		if (mkdir(dirname, 0600) < 0) {
			pr_perror("mkdir");
			return 1;
		}

		if (mount(dirname, dirname, NULL, MS_BIND, NULL)) {
			pr_perror("mount");
			return 1;
		}
		if (chdir(dirname))
			return 1;

		fd = open("test.ghost", O_CREAT | O_WRONLY, 0600);
		if (fd < 0) {
			pr_perror("open");
			return 1;
		}

		if (unlink("test.ghost")) {
			pr_perror("unlink");
			return 1;
		}

		task_waiter_complete(&lock, 1);
		test_waitsig();

		if (close(fd)) {
			pr_perror("close");
			return 1;
		}
		d = opendir(".");
		if (d == NULL) {
			pr_perror("opendir");
			return 1;
		}
		while ((de = readdir(d)) != NULL) {
			if (!strcmp(de->d_name, "."))
				continue;
			if (!strcmp(de->d_name, ".."))
				continue;
			pr_err("%s\n", de->d_name);
		}
		closedir(d);

		return 0;
	}

	task_waiter_wait4(&lock, 1);
	test_daemon();
	test_waitsig();


	kill(pid, SIGTERM);
	wait(&status);
	if (status) {
		fail("Test died");
		return 1;
	}
	pass();

	return 0;
}
Beispiel #9
0
int main(int argc, char **argv)
{
	char path[PATH_MAX], bpath[PATH_MAX], spath[PATH_MAX];
	pid_t pid;
	int status;
	task_waiter_t t;

	test_init(argc, argv);

	task_waiter_init(&t);

	snprintf(path, sizeof(path), "%s/test", dirname);
	snprintf(bpath, sizeof(bpath), "%s/test.bind", dirname);
	snprintf(spath, sizeof(spath), "%s/test/sub", dirname);
	if (mkdir(dirname, 0700)) {
		pr_perror("mkdir");
		return 1;
	}

	if (mount(NULL, "/", NULL, MS_SHARED, NULL)) {
		pr_perror("mount");
		return 1;
	}

#ifdef SHARED_BIND02
	/* */
	if (mount(dirname, dirname, "tmpfs", 0, NULL) ||
	    mount(NULL, dirname, NULL, MS_SHARED, NULL)) {
		pr_perror("mount");
		return 1;
	}
#endif

	if (mkdir(path, 0700) ||
	    mkdir(spath, 0700) ||
	    mkdir(bpath, 0700)) {
		pr_perror("mkdir");
		return 1;
	}

	pid = fork();
	if (pid < 0) {
		pr_perror("fork");
		return 1;
	}
	if (pid == 0) {
		if (unshare(CLONE_NEWNS)) {
			pr_perror("unshare");
			return 1;
		}
		if (mount(path, bpath, NULL, MS_BIND, NULL)) {
			pr_perror("mount");
			return 1;
		}

		task_waiter_complete(&t, 1);
		task_waiter_wait4(&t, 2);
		if (umount(spath)) {
			task_waiter_complete(&t, 2);
			fail("umount");
			return 1;
		}
		task_waiter_complete(&t, 3);
		task_waiter_wait4(&t, 4);

		return 0;
	}

	task_waiter_wait4(&t, 1);

	if (mount("test", spath, "tmpfs", 0, NULL)) {
		pr_perror("mount");
		return 1;
	}


	test_daemon();
	test_waitsig();

	task_waiter_complete(&t, 2);
	task_waiter_wait4(&t, 3);

	if (umount(bpath)) {
		task_waiter_complete(&t, 2);
		fail("umount");
		return 1;
	}

	task_waiter_complete(&t, 4);

	if (waitpid(pid, &status, 0) != pid) {
		pr_perror("waitpid %d", pid);
		return 1;
	}

	if (status) {
		pr_perror("%d/%d/%d/%d", WIFEXITED(status), WEXITSTATUS(status), WIFSIGNALED(status), WTERMSIG(status));
		return 1;
	}

	pass();

	return 0;
}