static void child(const char *root, char *cmd[]) { pid_t pid = (pid_t)syscall(SYS_getpid); assert(pid == 1); // die when parent dies NONNEGATIVE(prctl(PR_SET_PDEATHSIG, SIGKILL, 0, 0, 0)); NONNEGATIVE(sethostname(POE_HOSTNAME, strlen(POE_HOSTNAME))); NONNEGATIVE(mount(NULL, "/", NULL, MS_PRIVATE | MS_REC, NULL)); NONNEGATIVE(mount(root, root, "bind", MS_BIND | MS_REC, NULL)); NONNEGATIVE(chroot(root)); // NONNEGATIVE(mount(NULL, "/proc", "proc", MS_NOSUID | MS_NOEXEC | MS_NODEV, NULL)); // NONNEGATIVE(mount(NULL, "/dev", "devtmpfs", MS_NOSUID | MS_NOEXEC, NULL)); // NONNEGATIVE(mount(NULL, "/dev/shm", "tmpfs", MS_NOSUID | MS_NODEV, NULL)); struct passwd *pw = getpwnam(POE_USERNAME); if (!pw) ERROR("getpwnam() failed"); NONNEGATIVE(chdir("/tmp")); NONNEGATIVE(setsid()); NONNEGATIVE(initgroups(POE_USERNAME, pw->pw_gid)); NONNEGATIVE(setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid)); NONNEGATIVE(setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid)); char *env[] = { "PATH=/opt/bin:/usr/bin", "USER="******"LOGNAME=" POE_USERNAME, NULL, NULL }; NONNEGATIVE(asprintf(env + 3, "HOME=%s", pw->pw_dir)); // wait parent NONNEGATIVE(kill(pid, SIGSTOP)); NONNEGATIVE(prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)); poe_init_seccomp(SCMP_ACT_TRACE(0)); NONNEGATIVE(execvpe(cmd[0], cmd, env)); }
int main(int argc, char *argv[]) { char *filename = read_opts(argc, argv); /* set up an rnn context */ rnn_init(); rnndb = rnn_newdb(); rnn_parsefile(rnndb, "fifo/nv_objects.xml"); if (rnndb->estatus) demmt_abort(); rnn_prepdb(rnndb); domain = rnn_finddomain(rnndb, "SUBCHAN"); if (!domain) demmt_abort(); rnndb_g80_texture = rnn_newdb(); rnn_parsefile(rnndb_g80_texture, "graph/g80_texture.xml"); if (rnndb_g80_texture->estatus) demmt_abort(); rnn_parsefile(rnndb_g80_texture, "graph/gm107_texture.xml"); if (rnndb_g80_texture->estatus) demmt_abort(); rnn_prepdb(rnndb_g80_texture); rnndb_gf100_shaders = rnn_newdb(); rnn_parsefile(rnndb_gf100_shaders, "graph/gf100_shaders.xml"); if (rnndb_gf100_shaders->estatus) demmt_abort(); rnn_prepdb(rnndb_gf100_shaders); gf100_shaders_ctx = rnndec_newcontext(rnndb_gf100_shaders); gf100_shaders_ctx->colors = colors; /* doesn't matter which, just needs to exist to make it * possible to modify later. */ rnndec_varadd(gf100_shaders_ctx, "GF100_SHADER_KIND", "FP"); rnndb_nvrm_object = rnn_newdb(); rnn_parsefile(rnndb_nvrm_object, "../docs/nvrm/rnndb/nvrm_object.xml"); if (rnndb_nvrm_object->estatus) demmt_abort(); rnn_prepdb(rnndb_nvrm_object); tic_domain = rnn_finddomain(rnndb_g80_texture, "TIC"); tic2_domain = rnn_finddomain(rnndb_g80_texture, "TIC2"); tsc_domain = rnn_finddomain(rnndb_g80_texture, "TSC"); gf100_sp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_SP_HEADER"); gf100_fp_header_domain = rnn_finddomain(rnndb_gf100_shaders, "GF100_FP_HEADER"); if (!gf100_sp_header_domain || !gf100_fp_header_domain) demmt_abort(); gk104_cp_header_domain = rnn_finddomain(rnndb, "GK104_COMPUTE_LAUNCH_DESC"); if (!gk104_cp_header_domain) demmt_abort(); if (filename) { close(0); if (open_input(filename) == NULL) { perror("open"); exit(1); } free(filename); } if (pager_enabled) { int pipe_fds[2]; pid_t pid; if (pipe(pipe_fds) < 0) { perror("pipe"); demmt_abort(); } pid = fork(); if (pid < 0) { perror("fork"); demmt_abort(); } if (pid > 0) { char *less_argv[] = { "less", "-ScR", NULL }; close(pipe_fds[1]); dup2(pipe_fds[0], 0); close(pipe_fds[0]); execvp(less_argv[0], less_argv); perror("exec"); demmt_abort(); } close(pipe_fds[0]); dup2(pipe_fds[1], 1); dup2(pipe_fds[1], 2); close(pipe_fds[1]); } #ifdef LIBSECCOMP_AVAILABLE if (seccomp_level) { int rc; scmp_filter_ctx ctx; if (seccomp_level == 2) ctx = seccomp_init(SCMP_ACT_KILL); else ctx = seccomp_init(SCMP_ACT_TRACE(1234)); if (!ctx) { fprintf(stderr, "seccomp_init failed\n"); exit(1); } rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, 0)); if (rc != 0) exit(1); seccomp_syscall_priority(ctx, SCMP_SYS(read), 254); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)); if (rc != 0) exit(1); seccomp_syscall_priority(ctx, SCMP_SYS(write), 255); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 1, SCMP_A0(SCMP_CMP_EQ, 1)); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); if (rc != 0) exit(1); rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 2, SCMP_A0(SCMP_CMP_EQ, 1), SCMP_A1(SCMP_CMP_EQ, 0x5401/*TCGETS*/)); if (rc != 0) exit(1); rc = seccomp_load(ctx); if (rc != 0) { fprintf(stderr, "seccomp_load failed with error: %d\n", rc); exit(1); } seccomp_release(ctx); } #endif mmt_decode(&demmt_funcs.base, NULL); fflush(stdout); fini_macrodis(); demmt_cleanup_isas(); rnndec_freecontext(gf100_shaders_ctx); rnn_freedb(rnndb); rnn_freedb(rnndb_g80_texture); rnn_freedb(rnndb_gf100_shaders); rnn_freedb(rnndb_nvrm_object); rnn_fini(); return 0; }
int main(int argc, char **argv) { prevent_leaked_file_descriptors(); bool mount_proc = false; bool mount_dev = false; const char *username = "******"; const char *hostname = "playpen"; long timeout = 0; long memory_limit = 128; struct bind_list *binds = NULL, *binds_tail = NULL; char *devices = NULL; char *syscalls = NULL; const char *syscalls_file = NULL; const char *learn_name = NULL; static const struct option opts[] = { { "help", no_argument, 0, 'h' }, { "version", no_argument, 0, 'v' }, { "mount-proc", no_argument, 0, 'p' }, { "mount-dev", no_argument, 0, 0x100 }, { "bind", required_argument, 0, 'b' }, { "bind-rw", required_argument, 0, 'B' }, { "user", required_argument, 0, 'u' }, { "hostname", required_argument, 0, 'n' }, { "timeout", required_argument, 0, 't' }, { "memory-limit", required_argument, 0, 'm' }, { "devices", required_argument, 0, 'd' }, { "syscalls", required_argument, 0, 's' }, { "syscalls-file", required_argument, 0, 'S' }, { "learn", required_argument, 0, 'l' }, { 0, 0, 0, 0 } }; for (;;) { int opt = getopt_long(argc, argv, "hvpb:B:u:n:t:m:d:s:S:l:", opts, NULL); if (opt == -1) break; switch (opt) { case 'h': usage(stdout); case 'v': printf("%s %s\n", program_invocation_short_name, VERSION); return 0; case 'p': mount_proc = true; break; case 0x100: mount_dev = true; break; case 'b': case 'B': if (binds) { binds_tail->next = bind_list_alloc(optarg, opt == 'b'); binds_tail = binds_tail->next; } else { binds = binds_tail = bind_list_alloc(optarg, opt == 'b'); } break; case 'u': username = optarg; break; case 'n': hostname = optarg; break; case 't': timeout = strtolx_positive(optarg, "timeout"); break; case 'm': memory_limit = strtolx_positive(optarg, "memory limit"); break; case 'd': devices = optarg; break; case 's': syscalls = optarg; break; case 'S': syscalls_file = optarg; break; case 'l': learn_name = optarg; break; default: usage(stderr); } } if (argc - optind < 2) { usage(stderr); } const char *root = argv[optind]; optind++; scmp_filter_ctx ctx = seccomp_init(learn_name ? SCMP_ACT_TRACE(0) : SCMP_ACT_KILL); if (!ctx) errx(EXIT_FAILURE, "seccomp_init"); if (syscalls_file) { char name[SYSCALL_NAME_MAX]; FILE *file = fopen(syscalls_file, "r"); if (!file) err(EXIT_FAILURE, "failed to open syscalls file: %s", syscalls_file); while (fgets(name, sizeof name, file)) { char *pos; if ((pos = strchr(name, '\n'))) *pos = '\0'; check(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, get_syscall_nr(name), 0)); } fclose(file); } check(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, __NR_execve, 0)); if (syscalls) { for (char *s_ptr = syscalls, *saveptr; ; s_ptr = NULL) { const char *syscall = strtok_r(s_ptr, ",", &saveptr); if (!syscall) break; check(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, get_syscall_nr(syscall), 0)); } } int epoll_fd = epoll_create1(EPOLL_CLOEXEC); check_posix(epoll_fd, "epoll_create1"); sigset_t mask; sigemptyset(&mask); sigaddset(&mask, SIGCHLD); sigaddset(&mask, SIGHUP); sigaddset(&mask, SIGINT); sigaddset(&mask, SIGTERM); check_posix(sigprocmask(SIG_BLOCK, &mask, NULL), "sigprocmask"); int sig_fd = signalfd(-1, &mask, SFD_CLOEXEC); check_posix(sig_fd, "signalfd"); epoll_add(epoll_fd, sig_fd, EPOLLIN); int pipe_in[2]; int pipe_out[2]; int pipe_err[2]; check_posix(pipe(pipe_in), "pipe"); check_posix(pipe(pipe_out), "pipe"); set_non_blocking(pipe_out[0]); check_posix(pipe(pipe_err), "pipe"); set_non_blocking(pipe_err[0]); int rc = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, STDIN_FILENO, &(struct epoll_event){ .data.fd = STDIN_FILENO, .events = EPOLLIN });