void setup_seccomp() { scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); if(!ctx) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0)) exit(-1); #if (SCMP_SYS(setsockopt)) #warning System does not have sys_setsockopt, the expected way to do SO_REUSEADDR. if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 0)) exit(-1); #endif #ifdef NEEDS_SOCKETCALL #warning NEEDS_SOCKETCALL=1 has been set, I wish it was not needed on some systems. if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 0)) exit(-1); #endif if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(bind), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(listen), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigaction), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clone), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setresuid32), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setresgid32), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(alarm), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0)) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0)) exit(-1); // Allow further restrictions. if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1, SCMP_A0(SCMP_CMP_EQ, PR_SET_NO_NEW_PRIVS))) exit(-1); if(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1, SCMP_A0(SCMP_CMP_EQ, PR_SET_SECCOMP))) exit(-1); if(seccomp_load(ctx)) exit(-1); seccomp_release(ctx); }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO), SCMP_A1(SCMP_CMP_NE, 0x0), SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO), SCMP_A1(SCMP_CMP_NE, 0x0), SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 3, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO), SCMP_A1(SCMP_CMP_NE, 0x0), SCMP_A2(SCMP_CMP_LT, SSIZE_MAX)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
static int setup(struct spt *spt) { if (diskfile == NULL) return 0; /* not present */ diskfd = open(diskfile, O_RDWR); if (diskfd == -1) err(1, "Could not open disk: %s", diskfile); off_t capacity = lseek(diskfd, 0, SEEK_END); if (capacity == -1) err(1, "%s: Could not determine capacity", diskfile); if (capacity < 512) errx(1, "%s: Backing storage must be at least 1 block (512 bytes) " "in size", diskfile); spt->bi->blocki.present = 1; spt->bi->blocki.block_size = 512; spt->bi->blocki.capacity = capacity; spt->bi->blocki.hostfd = diskfd; int rc = -1; /* * When reading or writing to the file descriptor, enforce that the * operation cannot be performed beyond the (detected) capacity, otherwise, * when backed by a regular file, the guest could grow the file size * arbitrarily. * * The Solo5 API mandates that reads/writes must be equal to block_size, so * we implement the above by ensuring that (A2 == block_size) && (A3 <= * (capacity - block_size) holds. */ rc = seccomp_rule_add(spt->sc_ctx, SCMP_ACT_ALLOW, SCMP_SYS(pread64), 3, SCMP_A0(SCMP_CMP_EQ, diskfd), SCMP_A2(SCMP_CMP_EQ, spt->bi->blocki.block_size), SCMP_A3(SCMP_CMP_LE, (spt->bi->blocki.capacity - spt->bi->blocki.block_size))); if (rc != 0) errx(1, "seccomp_rule_add(pread64, fd=%d) failed: %s", diskfd, strerror(-rc)); rc = seccomp_rule_add(spt->sc_ctx, SCMP_ACT_ALLOW, SCMP_SYS(pwrite64), 3, SCMP_A0(SCMP_CMP_EQ, diskfd), SCMP_A2(SCMP_CMP_EQ, spt->bi->blocki.block_size), SCMP_A3(SCMP_CMP_LE, (spt->bi->blocki.capacity - spt->bi->blocki.block_size))); if (rc != 0) errx(1, "seccomp_rule_add(pwrite64, fd=%d) failed: %s", diskfd, strerror(-rc)); return 0; }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; /* the syscall and argument numbers are all fake to make the test * simpler */ rc = seccomp_syscall_priority(ctx, 1000, 3); if (rc != 0) goto out; rc = seccomp_syscall_priority(ctx, 1001, 2); if (rc != 0) goto out; rc = seccomp_syscall_priority(ctx, 1002, 1); if (rc != 0) goto out; rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1000, 2, SCMP_A0(SCMP_CMP_EQ, 0), SCMP_A1(SCMP_CMP_EQ, 1)); if (rc != 0) goto out; rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1001, 1, SCMP_A0(SCMP_CMP_EQ, 0)); if (rc != 0) goto out; rc = seccomp_rule_add_exact(ctx, SCMP_ACT_ALLOW, 1002, 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
int main() { printf("step 1: unrestricted\n"); // ensure none of our children will ever be granted more priv // (via setuid, capabilities, ...) prctl(PR_SET_NO_NEW_PRIVS, 1); // ensure no escape is possible via ptrace prctl(PR_SET_DUMPABLE, 0); // Init the filter scmp_filter_ctx ctx; ctx = seccomp_init(SCMP_ACT_KILL); // default action: kill // setup basic whitelist seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); // setup our rule seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(dup2), 2, SCMP_A0(SCMP_CMP_EQ, 1), SCMP_A1(SCMP_CMP_EQ, 2)); // build and load the filter seccomp_load(ctx); printf("step 2: only 'write' and dup2(1, 2) syscalls\n"); // Redirect stderr to stdout dup2(1, 2); printf("step 3: stderr redirected to stdout\n"); // Duplicate stderr to arbitrary fd dup2(2, 42); printf("step 4: !! YOU SHOULD NOT SEE ME !!\n"); // Success (well, not so in this case...) return 0; }
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 child_process(void *clone_args){ FILE *log_fp = ((struct clone_args *)clone_args)->log_fp; struct config *config = ((struct clone_args *)clone_args)->config; FILE *in_file = NULL, *out_file = NULL, *err_file = NULL; struct rlimit memory_limit, cpu_time_rlimit; gid_t group_list[] = {config->gid}; #ifndef __APPLE__ int i; int syscalls_whitelist[] = {SCMP_SYS(read), SCMP_SYS(fstat), SCMP_SYS(mmap), SCMP_SYS(mprotect), SCMP_SYS(munmap), SCMP_SYS(open), SCMP_SYS(arch_prctl), SCMP_SYS(brk), SCMP_SYS(access), SCMP_SYS(exit_group), SCMP_SYS(close)}; int syscalls_whitelist_length = sizeof(syscalls_whitelist) / sizeof(int); scmp_filter_ctx ctx = NULL; #endif // child process // On success, these system calls return 0. // On error, -1 is returned, and errno is set appropriately. if (config->max_memory != MEMORY_UNLIMITED) { memory_limit.rlim_cur = memory_limit.rlim_max = (rlim_t) (config->max_memory) * 2; if (setrlimit(RLIMIT_AS, &memory_limit) == -1) { LOG_FATAL(log_fp, "setrlimit memory failed, errno: %d", errno); ERROR(log_fp, SETRLIMIT_FAILED); } } if (config->max_cpu_time != CPU_TIME_UNLIMITED) { // cpu time if (set_timer(config->max_cpu_time / 1000, config->max_cpu_time % 1000, 1) != SUCCESS) { LOG_FATAL(log_fp, "set cpu time timer failed"); ERROR(log_fp, SETITIMER_FAILED); } // real time if (set_timer(config->max_real_time / 1000, config->max_real_time % 1000, 0) != SUCCESS) { LOG_FATAL(log_fp, "set real time timer failed"); ERROR(log_fp, SETITIMER_FAILED); } // child process can not inherit timeout rules from parent process defined by setitimer, so we use setrlimit to // control child process max running time cpu_time_rlimit.rlim_cur = cpu_time_rlimit.rlim_max = (config->max_cpu_time + 1000) / 1000; if (setrlimit(RLIMIT_CPU, &cpu_time_rlimit) == -1) { LOG_FATAL(log_fp, "setrlimit cpu time failed, errno: %d", errno); ERROR(log_fp, SETRLIMIT_FAILED); } } // read stdin from in file // On success, these system calls return the new descriptor. // On error, -1 is returned, and errno is set appropriately. if (config->in_file != NULL) { if ((in_file = fopen(config->in_file, "r")) == NULL) { LOG_FATAL(log_fp, "failed to open stdin redirect file"); ERROR(log_fp, DUP2_FAILED); } if (dup2(fileno(in_file), fileno(stdin)) == -1) { LOG_FATAL(log_fp, "dup2 stdin failed, errno: %d", errno); ERROR(log_fp, DUP2_FAILED); } } // write stdout to out file if (config->out_file != NULL) { if ((out_file = fopen(config->out_file, "w")) == NULL) { LOG_FATAL(log_fp, "failed to open stdout redirect file"); ERROR(log_fp, DUP2_FAILED); } if (dup2(fileno(out_file), fileno(stdout)) == -1) { LOG_FATAL(log_fp, "dup2 stdout failed, errno: %d", errno); ERROR(log_fp, DUP2_FAILED); } } // write stderr to err file if (config->err_file != NULL) { // if err_file and out_file are the same path, we use out_file pointer as err_file pointer, to avoid conflict if (strcmp(config->out_file, config->err_file) == 0) { err_file = out_file; } else { if ((err_file = fopen(config->err_file, "w")) == NULL) { LOG_FATAL(log_fp, "failed to open stderr redirect file"); ERROR(log_fp, DUP2_FAILED); } } if (dup2(fileno(err_file), fileno(stderr)) == -1) { LOG_FATAL(log_fp, "dup2 stdout failed, errno: %d", errno); ERROR(log_fp, DUP2_FAILED); } } if (config->gid != -1 && (setgid(config->gid) == -1 || setgroups(sizeof(group_list) / sizeof(gid_t), group_list) == -1)) { LOG_FATAL(log_fp, "setgid failed, errno: %d", errno); ERROR(log_fp, SET_GID_FAILED); } if (config->uid != -1 && setuid(config->uid) == -1) { LOG_FATAL(log_fp, "setuid failed, errno: %d", errno); ERROR(log_fp, SET_UID_FAILED); } #ifndef __APPLE__ if (config->use_sandbox != 0) { // load seccomp rules ctx = seccomp_init(SCMP_ACT_KILL); if (!ctx) { LOG_FATAL(log_fp, "init seccomp failed"); ERROR(log_fp, LOAD_SECCOMP_FAILED); } for (i = 0; i < syscalls_whitelist_length; i++) { if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls_whitelist[i], 0) != 0) { LOG_FATAL(log_fp, "load syscall white list failed"); ERROR(log_fp, LOAD_SECCOMP_FAILED); } } // add extra rule for execve if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(execve), 1, SCMP_A0(SCMP_CMP_EQ, (scmp_datum_t)(config->path))) != 0) { LOG_FATAL(log_fp, "load execve rule failed"); ERROR(log_fp, LOAD_SECCOMP_FAILED); } // only fd 0 1 2 are allowed if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_LE, 2)) != 0) { LOG_FATAL(log_fp, "load dup2 rule failed"); ERROR(log_fp, LOAD_SECCOMP_FAILED); } if (seccomp_load(ctx) != 0) { LOG_FATAL(log_fp, "seccomp load failed"); ERROR(log_fp, LOAD_SECCOMP_FAILED); } seccomp_release(ctx); } #endif execve(config->path, config->args, config->env); LOG_FATAL(log_fp, "execve failed, errno: %d", errno); ERROR(log_fp, EXCEVE_FAILED); return 1; }
void GenHash::calcGenHash() { sandbox_init(); // cannot excute execve prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0); kDebug() << "execve" << execve("ls",NULL,NULL); if (child_pid){ KParts::ReadOnlyPart * part = qobject_cast<KParts::ReadOnlyPart *>(parent()); QFile file(KFileDialog::getOpenFileName(KUrl("kfiledialog:///konqueror"), i18n("*"), part->widget(), i18n("Open File To make MD5."))); if (!file.open(QIODevice::ReadOnly)) { return; } // TODO QFile //char s[1024]; // write file content { close(pipe_fd[0]); QByteArray s = file.readAll(); char *ch = s.data(); if (write(pipe_fd[1], ch, s.size()) < 0) { perror("write"); } close(pipe_fd[1]); } //read result { close(pipe_result_fd[1]); char result[128]; if (read(pipe_result_fd[0], &result[0], 128) < 0){ perror("read"); } close(pipe_result_fd[0]); KMessageBox::information(part->widget(),i18n("Md5 : %1").arg(QString(QByteArray(result, 128)))); } }else{ scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_KILL); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 3, SCMP_A0(SCMP_CMP_EQ, (scmp_datum_t)pipe_fd[0]), SCMP_A1(SCMP_CMP_EQ, (scmp_datum_t)buff), SCMP_A2(SCMP_CMP_LE, 1024)); seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_CMP(0, SCMP_CMP_EQ, (scmp_datum_t)pipe_result_fd[1])); seccomp_load(ctx); seccomp_release(ctx); calcMD5(); } }
void drop_worker_privileges(void) { scmp_filter_ctx ctx = seccomp_init(DENY_ACTION); if (ctx == NULL) { return; } int rc = 0; rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sigreturn), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_wait), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_pwait), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(poll), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(readv), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpeername), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendmsg), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getrusage), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(ioctl), 1, SCMP_A1(SCMP_CMP_EQ, TIOCGWINSZ)); // for spawning the LRU crawler rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clone), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(set_robust_list), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(madvise), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit), 0); // stat rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockname), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0); if (settings.shutdown_command) { rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tgkill), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(tkill), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fstat), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpid), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(gettid), 0); } if (settings.relaxed_privileges) { rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(openat), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mkdir), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(access), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 0); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 0); } else { // stdout rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, 1)); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 1, SCMP_A0(SCMP_CMP_EQ, 1)); // stderr rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, 2)); rc |= seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(writev), 1, SCMP_A0(SCMP_CMP_EQ, 2)); } if (rc != 0) { goto fail; } rc = seccomp_load(ctx); if (rc < 0) { goto fail; } seccomp_release(ctx); return; fail: seccomp_release(ctx); fprintf(stderr, "Failed to set a seccomp profile on a worker thread\n"); exit(EXIT_FAILURE); }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x86")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x86_64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("x32")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("arm")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("aarch64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel64")); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("mipsel64n32")); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigreturn), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
int main(int argc, char *argv[]) { int rc; struct util_options opts; scmp_filter_ctx ctx = NULL; rc = util_getopt(argc, argv, &opts); if (rc < 0) goto out; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) return ENOMEM; rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_X32); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_ARM); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_AARCH64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32); if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC64LE); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 1, SCMP_A0(SCMP_CMP_EQ, STDIN_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDOUT_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(write), 1, SCMP_A0(SCMP_CMP_EQ, STDERR_FILENO)); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(close), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0); if (rc != 0) goto out; rc = util_filter_output(&opts, ctx); if (rc) goto out; out: seccomp_release(ctx); return (rc < 0 ? -rc : rc); }
int setup_seccomp(uint64_t cap_list_retain) { scmp_filter_ctx seccomp; int r; seccomp = seccomp_init(SCMP_ACT_ALLOW); if (!seccomp) return log_oom(); r = seccomp_add_secondary_archs(seccomp); if (r < 0) { log_error_errno(r, "Failed to add secondary archs to seccomp filter: %m"); goto finish; } r = seccomp_add_default_syscall_filter(seccomp, cap_list_retain); if (r < 0) goto finish; /* Audit is broken in containers, much of the userspace audit hookup will fail if running inside a container. We don't care and just turn off creation of audit sockets. This will make socket(AF_NETLINK, *, NETLINK_AUDIT) fail with EAFNOSUPPORT which audit userspace uses as indication that audit is disabled in the kernel. */ r = seccomp_rule_add( seccomp, SCMP_ACT_ERRNO(EAFNOSUPPORT), SCMP_SYS(socket), 2, SCMP_A0(SCMP_CMP_EQ, AF_NETLINK), SCMP_A2(SCMP_CMP_EQ, NETLINK_AUDIT)); if (r < 0) { log_error_errno(r, "Failed to add audit seccomp rule: %m"); goto finish; } r = seccomp_attr_set(seccomp, SCMP_FLTATR_CTL_NNP, 0); if (r < 0) { log_error_errno(r, "Failed to unset NO_NEW_PRIVS: %m"); goto finish; } r = seccomp_load(seccomp); if (r == -EINVAL) { log_debug_errno(r, "Kernel is probably not configured with CONFIG_SECCOMP. Disabling seccomp audit filter: %m"); r = 0; goto finish; } if (r < 0) { log_error_errno(r, "Failed to install seccomp audit filter: %m"); goto finish; } finish: seccomp_release(seccomp); return r; }
int waive(const int flags) { scmp_filter_ctx ctx; int ret = -1; ctx = seccomp_init(SCMP_ACT_ALLOW); if (NULL == ctx) goto out; if (0 != (WAIVE_SOCKET & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socketpair), 0)) goto release; } else { if (0 != (WAIVE_INET & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, AF_INET))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, AF_INET6))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socketpair), 1, SCMP_A0(SCMP_CMP_EQ, AF_INET))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socketpair), 1, SCMP_A0(SCMP_CMP_EQ, AF_INET6))) goto release; } if (0 != (WAIVE_UN & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, AF_UNIX))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socketpair), 1, SCMP_A0(SCMP_CMP_EQ, AF_UNIX))) goto release; } if (0 != (WAIVE_PACKET & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socket), 1, SCMP_A0(SCMP_CMP_EQ, AF_PACKET))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(socketpair), 1, SCMP_A0(SCMP_CMP_EQ, AF_PACKET))) goto release; } } if (0 != (WAIVE_MOUNT & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mount), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(umount), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(umount2), 0)) goto release; } if (0 != (WAIVE_OPEN & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(openat), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(creat), 0)) goto release; } if (0 != (WAIVE_EXEC & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(execve), 0)) goto release; #ifdef __NR_execveat if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(execveat), 0)) goto release; #endif if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mprotect), 1, SCMP_A2(SCMP_CMP_EQ, PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mprotect), 1, SCMP_A2(SCMP_CMP_EQ, PROT_READ | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mprotect), 1, SCMP_A2(SCMP_CMP_EQ, PROT_WRITE | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mprotect), 1, SCMP_A2(SCMP_CMP_EQ, PROT_READ | PROT_WRITE | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap), 1, SCMP_A2(SCMP_CMP_EQ, PROT_READ | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap), 1, SCMP_A2(SCMP_CMP_EQ, PROT_WRITE | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap), 1, SCMP_A2(SCMP_CMP_EQ, PROT_READ | PROT_WRITE | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap2), 1, SCMP_A2(SCMP_CMP_EQ, PROT_WRITE | PROT_EXEC))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mmap2), 1, SCMP_A2(SCMP_CMP_EQ, PROT_READ | PROT_WRITE | PROT_EXEC))) goto release; } if (0 != (WAIVE_CLONE & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(clone), 0)) goto release; } if (0 != (WAIVE_KILL & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(kill), 1, SCMP_A0(SCMP_CMP_NE, 0))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(tkill), 1, SCMP_A0(SCMP_CMP_NE, 0))) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(tgkill), 1, SCMP_A0(SCMP_CMP_NE, 0))) goto release; } if (0 != (WAIVE_PIPE & flags)) { if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pipe), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(pipe2), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mknod), 0)) goto release; if (0 != seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), SCMP_SYS(mknodat), 0)) goto release; } if (0 == seccomp_load(ctx)) ret = 0; release: seccomp_release(ctx); out: return ret; }