int main(int argc, char *argv[]) { int status; int *cinit_no = malloc(sizeof(int)); pid_t cpid1, cpid2; setup(); /* create pipe */ if (pipe(pipe_fd) == -1) { tst_resm(TBROK, "parent: pipe creation failed"); cleanup(); } /* container creation on PID namespace */ if (!cinit_no) { tst_resm(TBROK, "memory allocation failed."); cleanup(); } /* Create container 1 */ *cinit_no = 1; cpid1 = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, cinit_no); /* Create container 2 */ *cinit_no = 2; cpid2 = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, cinit_no); if (cpid1 < 0 || cpid2 < 0) { tst_resm(TBROK, "parent: clone() failed."); cleanup(); } /* Close unwanted descriptors */ close(pipe_fd[0]); close(pipe_fd[1]); /* Wait for containers to exit */ if (waitpid(cpid2, &status, 0) < 0) tst_resm(TWARN, "parent: waitpid(cpid2) failed."); if (WIFSIGNALED(status) && WTERMSIG(status)) tst_resm(TWARN, "parent: cinit2 is terminated by signal(%s)", strsignal(WTERMSIG(status))); if (waitpid(cpid1, &status, 0) < 0) tst_resm(TWARN, "parent: waitpid(cpid1) failed."); if (WIFSIGNALED(status) && WTERMSIG(status)) tst_resm(TWARN, "parent: cinit1 is terminated by signal(%s)", strsignal(WTERMSIG(status))); /* Cleanup and exit */ cleanup(); /* Control won't reach below */ exit(0); }
int main(int argc, char *argv[]) { pid_t cpid2; char path[BUFSIZ]; int lc; int fd; tst_parse_opts(argc, argv, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; parentuid = geteuid(); parentgid = getegid(); cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL); if (cpid1 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid1 clone failed"); cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn2, NULL); if (cpid2 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid2 clone failed"); if (setgroupstag == false) { sprintf(path, "/proc/%d/setgroups", cpid1); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); sprintf(path, "/proc/%d/setgroups", cpid2); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); } updatemap(cpid1, UID_MAP, CHILD1UID, parentuid, cleanup); updatemap(cpid2, UID_MAP, CHILD2UID, parentuid, cleanup); updatemap(cpid1, GID_MAP, CHILD1GID, parentuid, cleanup); updatemap(cpid2, GID_MAP, CHILD2GID, parentuid, cleanup); TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 1); tst_record_childstatus(cleanup, cpid1); tst_record_childstatus(cleanup, cpid2); } cleanup(); tst_exit(); }
int main(int argc, char *argv[]) { char *child_cmd; char *parent_cmd; int ret=0, childret=0; if ( argc < 3 ) { usage(argv[0]); exit(1); } child_cmd = (char *)strdup(argv[2]); parent_cmd = (char *)strdup(argv[1]); printf("1\n"); ret = ltp_clone_quick(CLONE_NEWNS|SIGCHLD, myfunc, (void *)child_cmd); if (ret != -1) { system(parent_cmd); wait(&childret); } else { fprintf(stderr, "clone failed\n"); } if (ret || !WIFEXITED(childret)){ exit(1); } exit(0); }
int create_net_namespace(char *p1, char *c1) { int pid, status = 0, ret; char *ltproot, *par; long int clone_flags = 0; if (tst_kvercmp(2, 6, 19) < 0) return 1; clone_flags |= CLONE_NEWNS; /* Enable other namespaces too optionally */ #ifdef CLONE_NEWPID clone_flags |= CLONE_NEWPID; #endif pid = ltp_clone_quick(clone_flags, child_fn, (void *)c1); if (pid == -1) { perror("Failed to do clone..."); return -1; } /* This code will be executed in parent */ ltproot = getenv("LTPROOT"); if (!ltproot) { printf("LTPROOT env variable is not set\n"); printf("Please set LTPROOT and re-run the test.. Thankyou\n"); return -1; } par = malloc(FILENAME_MAX); if (par == NULL) { printf("FAIL: error while allocating memory"); exit(1); } /* We need to pass the child pid to the parentns.sh script */ sprintf(par, "%s/testcases/bin/parentns.sh %s %" PRId32, ltproot, p1, pid); ret = system(par); status = WEXITSTATUS(ret); if (ret == -1 || status != 0) { printf("Error while running the script\n"); fflush(stdout); exit(1); } fflush(stdout); ret = waitpid(pid, &status, __WALL); status = WEXITSTATUS(status); if (ret == -1 || status != 0) { printf("Error: waitpid() returns %d, status %d\n", ret, status); } return status; }
int main(int argc, char *argv[]) { char c = 0; const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child, (void *) argv); while (waitpid(pid, NULL, __WALL) == EOF && errno == EINTR) c++; /* Dummy. */ return 0; }
int main(int argc, char *argv[]) { int status; char buf[5]; pid_t cpid; setup(); if (pipe(child_to_father) == -1 || pipe(father_to_child) == -1) { tst_brkm(TBROK | TERRNO, cleanup, "pipe failed"); } ltp_syscall(__NR_mq_unlink, mqname); /* container creation on PID namespace */ cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); if (cpid == -1) tst_brkm(TBROK | TERRNO, cleanup, "clone failed"); mqd = ltp_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777, NULL); if (mqd == -1) tst_brkm(TBROK | TERRNO, cleanup, "mq_open failed"); else tst_resm(TINFO, "successfully created posix mqueue"); if (write(father_to_child[1], buf, 1) != 1) tst_brkm(TBROK | TERRNO, cleanup, "write failed"); /* Close the appropriate end of each pipe */ close(child_to_father[1]); close(father_to_child[0]); /* Is container ready */ read(child_to_father[0], buf, 5); if (strcmp(buf, "c:ok") != 0) tst_brkm(TBROK, cleanup, "container did not respond as expected!"); rc = mq_send(mqd, MSG, strlen(MSG), MSG_PRIO); if (rc == -1) tst_brkm(TBROK | TERRNO, cleanup, "mq_send failed"); else tst_resm(TINFO, "mq_send succeeded"); /* Tell the child the message has been sent */ if (write(father_to_child[1], "f:ok", 5) != 5) tst_brkm(TBROK | TERRNO, cleanup, "write failed"); /* Wait for child to finish */ if (wait(&status) == -1) tst_resm(TBROK | TERRNO, "wait failed"); cleanup(); tst_exit(); }
int main(int argc, char *argv[]) { int status; char buf[5]; pid_t cpid; /* Create pipes for intercommunication */ if (pipe(parent_cinit) == -1 || pipe(cinit_parent) == -1) { tst_brkm(TBROK | TERRNO, cleanup, "pipe failed"); } cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); if (cpid == -1) { tst_brkm(TBROK | TERRNO, cleanup, "clone failed"); } /* Setup pipe read and write ends */ close(cinit_parent[1]); close(parent_cinit[0]); /* Is container ready */ read(cinit_parent[0], buf, 5); if (strcmp(buf, "c:go") != 0) { tst_brkm(TBROK, cleanup, "parent: container did not respond!"); } /* Enqueue SIGUSR1 in pending signal queue of container */ if (kill(cpid, SIGUSR1) == -1) { tst_brkm(TBROK | TERRNO, cleanup, "kill() failed"); } tst_resm(TINFO, "parent: signalled SIGUSR1 to container"); if (write(parent_cinit[1], "p:go", 5) != 5) { tst_brkm(TBROK | TERRNO, cleanup, "write failed"); } /* collect exit status of child */ if (wait(&status) == -1) { tst_brkm(TBROK | TERRNO, cleanup, "wait failed"); } if (WIFSIGNALED(status)) { if (WTERMSIG(status) == SIGUSR1) tst_resm(TFAIL, "user function was not called inside cinit"); else tst_resm(TBROK, "cinit was terminated by %d", WTERMSIG(status)); } /* Cleanup and exit */ close(parent_cinit[1]); close(cinit_parent[0]); cleanup(); tst_exit(); }
int main(int argc, char *argv[]) { int status; pid_t pid, cpid; char buf[5]; setup(); pid = getpid(); tst_resm(TINFO, "parent: PID is %d", pid); /* Create pipe for intercommunication */ if (pipe(pipefd) == -1) { tst_resm(TBROK, "parent: pipe() failed. aborting!"); cleanup(); } cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); if (cpid < 0) { tst_resm(TBROK, "parent: clone() failed(%s).", strerror(errno)); cleanup(); } /* Close write end of pipe */ close(pipefd[1]); /* Check if container is ready */ read(pipefd[0], buf, 5); if (strcmp(buf, "c:go") != 0) { tst_resm(TBROK, "parent: container did not respond!"); cleanup(); } /* Send SIGUSR1 to container init */ if (kill(cpid, SIGUSR1) == -1) { tst_resm(TBROK, "parent: kill() failed(%s).", strerror(errno)); cleanup(); } if (waitpid(cpid, &status, 0) < 0) tst_resm(TWARN, "parent: waitpid() failed(%s).", strerror(errno)); if (WIFSIGNALED(status) && WTERMSIG(status)) tst_resm(TBROK, "child is terminated by signal(%s)", strsignal(WTERMSIG(status))); /* Cleanup and exit */ close(pipefd[0]); cleanup(); /* Control won't reach below */ exit(0); }
int main(int argc, char *argv[]) { int status; int lc; int childpid; int parentuid; int parentgid; char path[BUFSIZ]; char content[BUFSIZ]; int fd; tst_parse_opts(argc, argv, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; childpid = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL); if (childpid < 0) tst_brkm(TFAIL | TERRNO, cleanup, "clone failed"); parentuid = geteuid(); parentgid = getegid(); sprintf(path, "/proc/%d/uid_map", childpid); sprintf(content, "100 %d 1", parentuid); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, content, strlen(content)); SAFE_CLOSE(cleanup, fd); sprintf(path, "/proc/%d/gid_map", childpid); sprintf(content, "100 %d 1", parentgid); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, content, strlen(content)); SAFE_CLOSE(cleanup, fd); TST_SAFE_CHECKPOINT_WAKE(cleanup, 0); if (waitpid(childpid, &status, 0) < 0) tst_brkm(TBROK | TERRNO, cleanup, "waitpid failed"); if (WIFSIGNALED(status)) { tst_resm(TFAIL, "child was killed with signal = %d", WTERMSIG(status)); } else if (WIFEXITED(status) && WEXITSTATUS(status) != 0) tst_resm(TFAIL, "child exited abnormally"); else tst_resm(TPASS, "the uid and the gid are right inside " "the container"); } cleanup(); tst_exit(); }
int main() { int pid; if (tst_kvercmp(2,6,19) < 0) return 1; pid = ltp_clone_quick(CLONE_NEWIPC, dummy, NULL); if (pid == -1) return 3; return 0; }
int main() { int pid; if (tst_kvercmp(2, 6, 19) < 0) return 1; pid = ltp_clone_quick(CLONE_NEWUTS, dummy, NULL); if (pid == -1) { perror("ltp_clone_quick"); return 3; } return 0; }
int do_clone_tests(unsigned long clone_flags, int (*fn1) (void *arg), void *arg1, int (*fn2) (void *arg), void *arg2) { int ret; ret = ltp_clone_quick(clone_flags | SIGCHLD, fn1, arg1); if (ret == -1) { return -1; } if (fn2) ret = fn2(arg2); else ret = 0; return ret; }
int main() { int pid; mqd_t mqd; if (tst_kvercmp(2, 6, 30) < 0) return 1; mq_unlink("/checkmqnsenabled"); mqd = mq_open("/checkmqnsenabled", O_RDWR | O_CREAT | O_EXCL, 0777, NULL); if (mqd == -1) { perror("mq_open"); return 3; } mq_close(mqd); mq_unlink("/checkmqnsenabled"); pid = ltp_clone_quick(CLONE_NEWIPC, dummy, NULL); if (pid == -1) return 5; return 0; }
int main(int argc, char **argv) { int pid, rc, status, cloneflags; security_context_t context_s; context_t context; if (argc != 4) { fprintf(stderr, "usage: %s cloneflags newdomain program\n", argv[0]); exit(-1); } cloneflags = strtol(argv[1], NULL, 0); if (!cloneflags) { fprintf(stderr, "invalid clone flags %s\n", argv[1]); exit(-1); } rc = getcon(&context_s); if (rc < 0) { fprintf(stderr, "%s: unable to get my context\n", argv[0]); exit(-1); } context = context_new(context_s); if (!context) { fprintf(stderr, "%s: unable to create context structure\n", argv[0]); exit(-1); } if (context_type_set(context, argv[2])) { fprintf(stderr, "%s: unable to set new type\n", argv[0]); exit(-1); } freecon(context_s); context_s = context_str(context); if (!context_s) { fprintf(stderr, "%s: unable to obtain new context string\n", argv[0]); exit(-1); } rc = setexeccon(context_s); if (rc < 0) { fprintf(stderr, "%s: unable to set exec context to %s\n", argv[0], context_s); exit(-1); } pid = ltp_clone_quick(cloneflags | SIGCHLD, clone_fn, argv); if (pid < 0) { perror("clone"); exit(-1); } pid = wait(&status); if (pid < 0) { perror("wait"); exit(-1); } if (WIFEXITED(status)) { fprintf(stderr, "Child exited with status %d.\n", WEXITSTATUS(status)); exit(WEXITSTATUS(status)); } if (WIFSTOPPED(status)) { fprintf(stderr, "Child stopped by signal %d.\n", WSTOPSIG(status)); fprintf(stderr, "..This shouldn't happen.\n"); fprintf(stderr, "..Killing the child.\n"); rc = kill(pid,SIGKILL); if (rc < 0) { perror("kill"); exit(-1); } exit(-1); } if (WIFSIGNALED(status)) { fprintf(stderr, "Child terminated by signal %d.\n", WTERMSIG(status)); fprintf(stderr, "..This is consistent with a share permission denial, check the audit message.\n"); exit(1); } fprintf(stderr, "Unexpected exit status 0x%x\n", status); exit(-1); }
int main(int argc, char *argv[]) { pid_t cpid; mqd_t mqd; struct sigevent notif; struct sigaction sa; int status; struct notify_info info; setup(); if (pipe(father_to_child) == -1) { tst_resm(TBROK, "parent: pipe() failed. aborting!"); cleanup_mqueue(TBROK, NO_STEP, 0); } ltp_syscall(__NR_mq_unlink, mqname); mqd = ltp_syscall(__NR_mq_open, mqname, O_RDWR | O_CREAT | O_EXCL, 0777, NULL); if (mqd == (mqd_t) - 1) { tst_resm(TBROK, "parent: mq_open() failed (%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_0, 0); } tst_resm(TINFO, "parent: successfully created posix mqueue"); /* container creation on PID namespace */ cpid = ltp_clone_quick(CLONE_NEWPID | SIGCHLD, child_fn, NULL); if (cpid < 0) { tst_resm(TBROK, "parent: clone() failed(%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_1, mqd); } tst_resm(TINFO, "parent: successfully created child (pid = %d)", cpid); /* Register for notification on message arrival */ notif.sigev_notify = SIGEV_SIGNAL; notif.sigev_signo = SIGUSR1; info.mqd = mqd; info.pid = cpid; notif.sigev_value.sival_ptr = &info; if (ltp_syscall(__NR_mq_notify, mqd, ¬if) == (mqd_t) -1) { tst_resm(TBROK, "parent: mq_notify() failed (%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_1, mqd); } tst_resm(TINFO, "parent: successfully registered for notification"); /* Define handler for SIGUSR1 */ sa.sa_flags = SA_SIGINFO; sigemptyset(&sa.sa_mask); sa.sa_sigaction = father_signal_handler; if (sigaction(SIGUSR1, &sa, NULL) == -1) { tst_resm(TBROK, "parent: sigaction() failed(%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_2, mqd); } tst_resm(TINFO, "parent: successfully registered handler for SIGUSR1"); /* Close the appropriate end of pipe */ close(father_to_child[0]); /* Tell the child a message can be sent */ if (write(father_to_child[1], "f:ok", 5) != 5) { tst_resm(TBROK, "parent: pipe is broken(%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_2, mqd); } sleep(3); /* Wait for child to finish */ if (wait(&status) == -1) { tst_resm(TBROK, "parent: wait() failed(%s)", strerror(errno)); cleanup_mqueue(TBROK, F_STEP_1, mqd); } cleanup_mqueue(result, F_STEP_3, mqd); tst_exit(); }
int main(int argc, char *argv[]) { pid_t cpid2; char path[BUFSIZ]; int lc; int fd; int ret; tst_parse_opts(argc, argv, NULL, NULL); setup(); for (lc = 0; TEST_LOOPING(lc); lc++) { tst_count = 0; parentuid = geteuid(); parentgid = getegid(); cpid1 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn1, NULL); if (cpid1 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid1 clone failed"); cpid2 = ltp_clone_quick(CLONE_NEWUSER | SIGCHLD, (void *)child_fn2, NULL); if (cpid2 < 0) tst_brkm(TBROK | TERRNO, cleanup, "cpid2 clone failed"); if (access("/proc/self/setgroups", F_OK) == 0) { sprintf(path, "/proc/%d/setgroups", cpid1); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); /* If the setgroups file has the value "deny", * then the setgroups(2) system call can't * subsequently be reenabled (by writing "allow" to * the file) in this user namespace. (Attempts to * do so will fail with the error EPERM.) */ /* test that setgroups can't be re-enabled */ fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); ret = write(fd, "allow", 5); if (ret != -1) { tst_brkm(TBROK | TERRNO, cleanup, "write action should fail"); } else if (errno != EPERM) { tst_brkm(TBROK | TERRNO, cleanup, "unexpected error: \n"); } SAFE_CLOSE(cleanup, fd); tst_resm(TPASS, "setgroups can't be re-enabled"); sprintf(path, "/proc/%d/setgroups", cpid2); fd = SAFE_OPEN(cleanup, path, O_WRONLY, 0644); SAFE_WRITE(cleanup, 1, fd, "deny", 4); SAFE_CLOSE(cleanup, fd); } updatemap(cpid1, UID_MAP, CHILD1UID, parentuid, cleanup); updatemap(cpid2, UID_MAP, CHILD2UID, parentuid, cleanup); updatemap(cpid1, GID_MAP, CHILD1GID, parentgid, cleanup); updatemap(cpid2, GID_MAP, CHILD2GID, parentgid, cleanup); TST_SAFE_CHECKPOINT_WAKE_AND_WAIT(cleanup, 1); tst_record_childstatus(cleanup, cpid1); tst_record_childstatus(cleanup, cpid2); } cleanup(); tst_exit(); }
int main(int argc, char *argv[]) { char c = 0; tomoyo_test_init(); /* Test mount(). */ { set_profile(3, "file::mount"); show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 1); if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else if (errno == ENODEV) printf("OK: No such device.\n"); else printf("BUG: %s\n", strerror(errno)); set_profile(1, "file::mount"); show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 0); if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF && errno == ENOMEM) printf("OK: Out of memory.\n"); else if (errno == ENODEV) printf("OK: No such device.\n"); else printf("BUG: %s\n", strerror(errno)); set_profile(3, "file::mount"); show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 0); if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF && errno == ENOMEM) printf("OK: Out of memory.\n"); else if (errno == ENODEV) printf("OK: No such device.\n"); else printf("BUG: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_mount dev\\011name / " "fs\\011name 0\n"); show_prompt("mount('dev\\011name', '/', 'fs\\011name') ", 1); if (mount("dev\tname", "/", "fs\tname", 0, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else if (errno == ENODEV) printf("OK: No such device.\n"); else printf("BUG: %s\n", strerror(errno)); set_profile(1, "file::mount"); show_prompt("mount(NULL, '/', 'tmpfs') ", 0); if (mount(NULL, "/", "tmpfs", 0, NULL)) printf("BUG: %s\n", strerror(errno)); else printf("OK: Success\n"); set_profile(3, "file::mount"); show_prompt("mount(NULL, '/', 'tmpfs') ", 0); if (mount(NULL, "/", "tmpfs", 0, NULL)) printf("BUG: %s\n", strerror(errno)); else printf("OK: Success\n"); show_prompt("mount('anydev', '/', 'tmpfs') ", 0); if (mount("anydev", "/", "tmpfs", 0, NULL)) printf("BUG: %s\n", strerror(errno)); else printf("OK: Success\n"); fprintf(domain_fp, "delete allow_mount <NULL> / tmpfs 0\n"); fprintf(domain_fp, "allow_mount anydev / tmpfs 0\n"); show_prompt("mount(NULL, '/', 'tmpfs') ", 0); if (mount(NULL, "/", "tmpfs", 0, NULL)) printf("BUG: %s\n", strerror(errno)); else printf("OK: Success\n"); fprintf(domain_fp, "delete allow_mount anydev / tmpfs 0\n"); set_profile(2, "file::mount"); show_prompt("mount(NULL, NULL, 'tmpfs') ", 1); if (mount(NULL, NULL, "tmpfs", 0, NULL)) printf("OK: %s\n", strerror(errno)); else printf("BUG: Did not fail.\n"); show_prompt("mount(NULL, NULL, NULL) ", 1); if (mount(NULL, NULL, NULL, 0, NULL)) printf("OK: %s\n", strerror(errno)); else printf("BUG: Did not fail.\n"); show_prompt("mount('/', NULL, NULL) ", 1); if (mount("/", NULL, NULL, 0, NULL)) printf("OK: %s\n", strerror(errno)); else printf("BUG: Did not fail.\n"); show_prompt("mount('/', NULL, 'tmpfs') ", 1); if (mount("/", NULL, "tmpfs", 0, NULL)) printf("OK: %s\n", strerror(errno)); else printf("BUG: Did not fail.\n"); show_prompt("mount('/', '/', 'nonexistentfs') ", 1); if (mount("/", "/", "nonexistentfs", 0, NULL)) printf("OK: %s\n", strerror(errno)); else printf("BUG: Did not fail.\n"); set_profile(0, "file::mount"); } mkdir("/tmp/mount/", 0755); mkdir("/tmp/mount_bind/", 0755); mkdir("/tmp/mount_move/", 0755); /* Test mount(). */ { static char buf[4096]; char *dev_ram_path = canonicalize_file_name("/dev/ram0"); if (!dev_ram_path) dev_ram_path = canonicalize_file_name("/dev/ram"); if (!dev_ram_path) { dev_ram_path = "/dev/ram0"; mknod(dev_ram_path, S_IFBLK, MKDEV(1, 0)); } memset(buf, 0, sizeof(buf)); { struct stat sbuf; FILE *fp = NULL; snprintf(buf, sizeof(buf) - 1, "zcat - > %s", dev_ram_path); if (lstat(dev_ram_path, &sbuf) == 0 && S_ISBLK(sbuf.st_mode) && MAJOR(sbuf.st_rdev) == 1) fp = popen(buf, "w"); if (fp) { if (fwrite(compressed_ext2_image_sample, 1, sizeof(compressed_ext2_image_sample), fp) != sizeof(compressed_ext2_image_sample)) err(1, "fwrite"); pclose(fp); } else fprintf(stderr, "Can't write to %s .\n", dev_ram_path); } set_profile(3, "file::mount"); /* Test standard case */ show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for " "'/tmp/mount/'", 1); if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); /* Test device_name with pattern */ snprintf(buf, sizeof(buf) - 1, "mount('%s', '/tmp/mount/', " "'ext2') for '%s\\*'", dev_ram_path, dev_ram_path); show_prompt(buf, 1); if (mount(dev_ram_path, "/tmp/mount/", "ext2", MS_RDONLY, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); /* Test dir_name with pattern */ show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for " "'/tmp/\\?\\?\\?\\?\\?/'", 1); if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); /* Test standard case */ fprintf(domain_fp, "allow_mount none /tmp/mount/ tmpfs 0\n"); show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for " "'/tmp/mount/'", 0); if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_mount none /tmp/mount/ tmpfs 0\n"); /* Test device_name with pattern */ fprintf(domain_fp, "allow_mount %s\\* /tmp/mount/ ext2 1\n", dev_ram_path); snprintf(buf, sizeof(buf) - 1, "mount('%s', '/tmp/mount/', " "'ext2') for '%s\\*'", dev_ram_path, dev_ram_path); show_prompt(buf, 0); if (mount(dev_ram_path, "/tmp/mount/", "ext2", MS_RDONLY, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_mount %s\\* " "/tmp/mount/ ext2 1\n", dev_ram_path); /* Test dir_name with pattern */ fprintf(domain_fp, "allow_mount none /tmp/\\?\\?\\?\\?\\?/ tmpfs 0\n"); show_prompt("mount('none', '/tmp/mount/', 'tmpfs') for " "'/tmp/\\?\\?\\?\\?\\?/'", 0); if (mount("none", "/tmp/mount/", "tmpfs", 0, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_mount none " "/tmp/\\?\\?\\?\\?\\?/ tmpfs 0\n"); set_profile(0, "file::mount"); while (umount("/tmp/mount/") == 0) c++; /* Dummy. */ } /* Test mount(). */ { mount2("none", "/tmp/mount/", "tmpfs"); set_profile(3, "file::mount"); /* Test remount case */ show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 1); if (mount("none", "/tmp/mount/", "tmpfs", MS_REMOUNT, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 1); if (mount(NULL, "/tmp/mount/", NULL, MS_REMOUNT, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); fprintf(domain_fp, "allow_mount something /tmp/mount/ " "--remount 0\n"); show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 0); if (mount(NULL, "/tmp/mount/", NULL, MS_REMOUNT, NULL)) printf("BUG: %s\n", strerror(errno)); else printf("OK: Success.\n"); fprintf(domain_fp, "delete allow_mount something /tmp/mount/ " "--remount 0\n"); /* Test bind case */ show_prompt("mount('/tmp/mount/', '/tmp/mount_bind/', " "MS_BIND)", 1); if (mount("/tmp/mount/", "/tmp/mount_bind/", NULL, MS_BIND, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); /* Test move case */ show_prompt("mount('/tmp/mount/', '/tmp/mount_move/', " "MS_MOVE)", 1); if (mount("/tmp/mount/", "/tmp/mount_move/", NULL, MS_MOVE, NULL) == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); /* Test remount case */ fprintf(domain_fp, "allow_mount any /tmp/mount/ --remount 0\n"); show_prompt("mount('/tmp/mount/', MS_REMOUNT)", 0); if (mount("none", "/tmp/mount/", "tmpfs", MS_REMOUNT, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_mount any /tmp/mount/ " "--remount 0\n"); /* Test bind case */ fprintf(domain_fp, "allow_mount /tmp/mount/ /tmp/mount_bind/ --bind 0\n"); show_prompt("mount('/tmp/mount/', '/tmp/mount_bind', MS_BIND)", 0); if (mount("/tmp/mount/", "/tmp/mount_bind/", NULL, MS_BIND, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); set_profile(0, "file::mount"); umount("/tmp/mount_bind/"); fprintf(domain_fp, "delete allow_mount /tmp/mount/ " "/tmp/mount_bind/ --bind 0\n"); /* Test move case */ set_profile(3, "file::mount"); fprintf(domain_fp, "allow_unmount /tmp/mount/\n"); fprintf(domain_fp, "allow_mount /tmp/mount/ /tmp/mount_move/ " "--move 0\n"); show_prompt("mount('/tmp/mount/', '/tmp/mount_move/', " "MS_MOVE)", 0); if (mount("/tmp/mount/", "/tmp/mount_move/", NULL, MS_MOVE, NULL) == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); set_profile(0, "file::mount"); umount("/tmp/mount_move/"); fprintf(domain_fp, "delete allow_unmount /tmp/mount/\n"); fprintf(domain_fp, "delete allow_mount /tmp/mount/ " "/tmp/mount_move/ --move 0\n"); while (umount("/tmp/mount/") == 0) c++; /* Dummy. */ } /* Test umount(). */ { /* Test standard case */ fprintf(domain_fp, "allow_unmount /tmp/mount/\n"); set_profile(0, "file::umount"); mount2("none", "/tmp/mount/", "tmpfs"); set_profile(3, "file::umount"); show_prompt("umount('/tmp/mount/') for '/tmp/mount/'", 0); if (umount("/tmp/mount/") == 0) printf("OK\n"); else printf("BUG: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_unmount /tmp/mount/\n"); set_profile(0, "file::umount"); mount2("none", "/tmp/mount/", "tmpfs"); set_profile(3, "file::umount"); show_prompt("umount('/tmp/mount/') for '/tmp/mount/'", 1); if (umount("/tmp/mount/") == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("FAILED: %s\n", strerror(errno)); /* Test pattern */ fprintf(domain_fp, "allow_unmount /tmp/\\?\\?\\?\\?\\?/\n"); set_profile(0, "file::umount"); mount2("none", "/tmp/mount/", "tmpfs"); set_profile(3, "file::umount"); show_prompt("umount('/tmp/mount/') for " "'/tmp/\\?\\?\\?\\?\\?/'", 1); if (umount("/tmp/mount/") == 0) printf("OK\n"); else printf("BUG: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_unmount /tmp/\\?\\?\\?\\?\\?/\n"); set_profile(0, "file::umount"); while (umount("/tmp/mount/") == 0) c++; /* Dummy. */ } /* Test chroot(). */ { set_profile(3, "file::chroot"); /* Test standard case */ fprintf(domain_fp, "allow_chroot /tmp/mount/\n"); show_prompt("chroot('/tmp/mount/') for '/tmp/mount/'", 0); fflush(stdout); if (fork() == 0) { if (chroot("/tmp/mount/") == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fflush(stdout); _exit(0); } wait(NULL); fprintf(domain_fp, "delete allow_chroot /tmp/mount/\n"); show_prompt("chroot('/tmp/mount/') for '/tmp/mount/'", 1); fflush(stdout); if (fork() == 0) { if (chroot("/tmp/mount/") == EOF && errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); fflush(stdout); _exit(0); } wait(NULL); /* Test pattern */ fprintf(domain_fp, "allow_chroot /tmp/\\?\\?\\?\\?\\?/\n"); show_prompt("chroot('/tmp/mount/') for " "'/tmp/\\?\\?\\?\\?\\?/'", 0); fflush(stdout); if (fork() == 0) { if (chroot("/tmp/mount/") == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fflush(stdout); _exit(0); } wait(NULL); fprintf(domain_fp, "delete allow_chroot /tmp/\\?\\?\\?\\?\\?/\n"); set_profile(0, "file::chroot"); } /* Test pivot_root(). */ { int error; static char stack[8192]; set_profile(3, "file::pivot_root"); fprintf(domain_fp, "allow_pivot_root %s %s\n", pivot_root_dir, proc_policy_dir); snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir, proc_policy_dir); show_prompt(stack, 0); { const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child, NULL); while (waitpid(pid, &error, __WALL) == EOF && errno == EINTR) c++; /* Dummy. */ } errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1; if (errno == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); fprintf(domain_fp, "delete allow_pivot_root %s %s\n", pivot_root_dir, proc_policy_dir); snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir, proc_policy_dir); show_prompt(stack, 1); { const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child, NULL); while (waitpid(pid, &error, __WALL) == EOF && errno == EINTR) c++; /* Dummy. */ } errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1; if (errno == EPERM) printf("OK: Permission denied.\n"); else printf("BUG: %s\n", strerror(errno)); set_profile(2, "file::pivot_root"); snprintf(stack, 8191, "pivot_root('%s', '%s')", pivot_root_dir, proc_policy_dir); show_prompt(stack, 0); { const pid_t pid = ltp_clone_quick(CLONE_NEWNS, child, NULL); while (waitpid(pid, &error, __WALL) == EOF && errno == EINTR) c++; /* Dummy. */ } errno = WIFEXITED(error) ? WEXITSTATUS(error) : -1; if (errno == 0) printf("OK\n"); else printf("FAILED: %s\n", strerror(errno)); set_profile(0, "file::pivot_root"); } rmdir("/tmp/mount_move/"); rmdir("/tmp/mount_bind/"); rmdir("/tmp/mount/"); clear_status(); return 0; }