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 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; }
int main(int argc, char **argv) { task_waiter_t t; pid_t pid; test_init(argc, argv); mkdir(dirname, 0755); if (mount("zdtm", dirname, "tmpfs", 0, NULL)) { pr_perror("mount"); return 1; } if (chdir(dirname)) { pr_perror("chdir"); return 1; } mkdir("1", 0755); mkdir("2", 0755); if (mount("1", "1", NULL, MS_BIND, NULL)) { pr_perror("mount"); return 1; } if (mount(NULL, "1", NULL, MS_PRIVATE, NULL)) { pr_perror("mount"); return 1; } if (mount("zdtm", "2", "tmpfs", 0, NULL)) { pr_perror("mount"); return 1; } mkdir("1/a", 0755); mkdir("2/a", 0755); if (mount("1/a", "1/a", NULL, MS_BIND, NULL)) { pr_perror("mount"); return 1; } if (mount(NULL, "1/a", NULL, MS_SHARED, NULL)) { pr_perror("mount"); return 1; } if (mount("1/a", "2/a", NULL, MS_BIND, NULL)) { pr_perror("mount"); return 1; } mkdir("1/a/c", 0755); if (mount("zdtm", "1/a/c", "tmpfs", 0, NULL)) { pr_perror("mount"); return 1; } if (mount("2", "1", NULL, MS_MOVE, NULL)) { pr_perror("mount"); return 1; } task_waiter_init(&t); pid = fork(); if (pid < 0) return -1; if (pid == 0) { if (unshare(CLONE_NEWNS)) return 1; task_waiter_complete_current(&t); test_waitsig(); return 0; } task_waiter_wait4(&t, pid); test_daemon(); test_waitsig(); kill(pid, SIGTERM); wait(NULL); pass(); return 0; }
int main(int argc, char **argv) { pthread_t diff_cred_thread; cap_t newcaps; int maingroup; int mainuser; int ret; test_init(argc, argv); task_waiter_init(&t); if (getuid() != 0) { fail("Test is expected to be run with root privileges\n"); exit(1); } test_msg("Acquiring CAP_SETGID and CAP_SETUID...\n"); 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); } ret = prctl(PR_SET_KEEPCAPS, 1, 0, 0, 0); if (ret) { pr_perror("Unable to set KEEPCAPS\n"); exit(1); } test_msg("Main thread runs as UID: %d; GID: %d\n", getuid(), getgid()); gid = 99; uid = 99; maingroup = 8; mainuser = 12; test_msg("Creating thread with different UID/GID\n"); ret = pthread_create(&diff_cred_thread, NULL, &chg_uid_gid, NULL); task_waiter_wait4(&t, 1); test_msg("Relinquishing root privileges\n"); ret = syscall(SYS_setresgid, maingroup, maingroup, maingroup); if (ret >= 0) { ret = syscall(SYS_setresuid, mainuser, mainuser, mainuser); } else if (ret < 0) { pr_perror("Failed to drop privileges\n"); exit(1); } test_msg("Now main thread runs as UID: %d; GID: %d\n", getuid(), getgid()); if (gid == getgid() || uid == getuid()) { pr_perror("Thread credentials match\n"); exit(1); } test_msg("Main thread is waiting for signal\n"); test_daemon(); test_waitsig(); if (gid == getgid() || uid == getuid()) { pr_perror("Thread credentials match after restore\n"); exit(1); } pthread_mutex_lock(&mutex); done = 1; pthread_cond_signal(&cond); pthread_mutex_unlock(&mutex); pthread_join(diff_cred_thread, NULL); test_msg("Threads joined\n"); pass(); return 0; }
int main(int argc, char **argv) { char buf[BUF_SIZE]; int fd, fd_s; struct aiocb aiocb; int status; pid_t pid; int ret, res; const struct aiocb *aioary[1]; task_waiter_t child_waiter; test_init(argc, argv); task_waiter_init(&child_waiter); if ((fd_s = tcp_init_server(AF_INET, &port)) < 0) { pr_err("initializing server failed\n"); return 1; } pid = test_fork(); if (pid < 0) { pr_perror("fork failed"); return 1; } if (pid == 0) { /* * Chiled is client of TCP connection */ close(fd_s); fd = tcp_init_client(AF_INET, "127.0.0.1", port); if (fd < 0) return 1; memset(&aiocb, 0, sizeof(struct aiocb)); aiocb.aio_fildes = fd; aiocb.aio_buf = buf; aiocb.aio_nbytes = BUF_SIZE; ret = aio_read(&aiocb); if (ret < 0) { pr_perror("aio_read failed"); return 1; } task_waiter_complete_current(&child_waiter); /* Wait for request completion */ aioary[0] = &aiocb; ret = aio_error(&aiocb); #ifdef DEBUG test_msg("."); #endif res = 0; again: if (aio_suspend(aioary, 1, NULL) < 0 && errno != EINTR) { pr_perror("aio_suspend failed"); res = 1; } ret = aio_error(&aiocb); if (!res && ret == EINPROGRESS) { #ifdef DEBUG test_msg("restart aio_suspend\n"); #endif goto again; } if (ret != 0) { pr_err("Error at aio_error(): %s\n", strerror(ret)); res = 1; } if (aio_return(&aiocb) != BUF_SIZE) { pr_perror("Error at aio_return()"); res = 1; } close(fd); return res; } /* * parent is server of TCP connection */ fd = tcp_accept_server(fd_s); close(fd_s); if (fd < 0) { pr_err("can't accept client connection\n"); goto error; } task_waiter_wait4(&child_waiter, pid); test_daemon(); test_waitsig(); if (write(fd, buf, BUF_SIZE) < BUF_SIZE) { pr_perror("can't write"); goto error; } close(fd); if (wait(&status) < 0) { pr_perror("wait failed"); goto error; } if (WIFEXITED(status) && WEXITSTATUS(status) != 0) { pr_err("child failed with exit code %d\n", WEXITSTATUS(status)); return 1; } pass(); return 0; error: kill(pid, SIGKILL); wait(&status); return -1; }
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) { int fdm, fds, status; task_waiter_t t; char *slavename; pid_t pid; test_init(argc, argv); task_waiter_init(&t); fdm = open("/dev/ptmx", O_RDWR); if (fdm == -1) { pr_perror("Can't open a master pseudoterminal"); return 1; } grantpt(fdm); unlockpt(fdm); slavename = ptsname(fdm); pid = test_fork(); if (pid < 0) { pr_perror("fork() failed"); return 1; } if (pid == 0) { close(fdm); signal(SIGHUP, sighup_handler); if (setsid() == -1) return 1; /* set up a controlling terminal */ fds = open(slavename, O_RDWR); if (fds == -1) { pr_perror("Can't open a slave pseudoterminal %s", slavename); return 1; } if (ioctl(fdm, TIOCSCTTY, 1) < 0) { pr_perror("Can't setup a controlling terminal"); return 1; } close(fds); task_waiter_complete_current(&t); test_waitsig(); if (sighup) return 0; return 1; } task_waiter_wait4(&t, pid); test_daemon(); test_waitsig(); close(fdm); if (kill(pid, SIGTERM) == -1) { pr_perror("kill failed"); return 1; } pid = waitpid(pid, &status, 0); if (pid < 0) return 1; if (WIFEXITED(status)) { if (WEXITSTATUS(status)) { fail("The child returned %d", WEXITSTATUS(status)); return 1; } } else { test_msg("The child has been killed by %d\n", 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; }