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; }
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; }
void task_waiter_complete_current(task_waiter_t *t) { return task_waiter_complete(t, (int)sys_gettid()); }
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; }
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; }
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; }
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; }
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; }