/** * Function responsible for setting up the setsockopt syscall for * the seccomp filter sandbox. */ static int sb_setsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; #ifdef __i386__ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 0); if (rc) return rc; #endif rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 2, SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), SCMP_CMP(2, SCMP_CMP_EQ, SO_REUSEADDR)); if (rc) return rc; #ifdef IP_TRANSPARENT rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 2, SCMP_CMP(1, SCMP_CMP_EQ, SOL_IP), SCMP_CMP(2, SCMP_CMP_EQ, IP_TRANSPARENT)); if (rc) return rc; #endif return 0; }
/** * Function responsible for setting up the open syscall for * the seccomp filter sandbox. */ static int sb_open(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc; sandbox_cfg_t *elem = NULL; // for each dynamic parameter filters for (elem = filter; elem != NULL; elem = elem->next) { smp_param_t *param = elem->param; if (param != NULL && param->prot == 1 && param->syscall == SCMP_SYS(open)) { rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(open), 1, SCMP_CMP(0, SCMP_CMP_EQ, param->value)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add open syscall, received " "libseccomp error %d", rc); return rc; } } } rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(-1), SCMP_SYS(open), 1, SCMP_CMP(1, SCMP_CMP_EQ, O_RDONLY|O_CLOEXEC)); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add open syscall, received libseccomp " "error %d", rc); return rc; } return 0; }
/** * Function responsible for setting up the fcntl64 syscall for * the seccomp filter sandbox. */ static int sb_fcntl64(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1, SCMP_CMP(1, SCMP_CMP_EQ, F_GETFL)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 2, SCMP_CMP(1, SCMP_CMP_EQ, F_SETFL), SCMP_CMP(2, SCMP_CMP_EQ, O_RDWR|O_NONBLOCK)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 1, SCMP_CMP(1, SCMP_CMP_EQ, F_GETFD)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(fcntl64), 2, SCMP_CMP(1, SCMP_CMP_EQ, F_SETFD), SCMP_CMP(2, SCMP_CMP_EQ, FD_CLOEXEC)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the futex syscall for * the seccomp filter sandbox. */ static int sb_futex(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; // can remove rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1, SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_BITSET_PRIVATE|FUTEX_CLOCK_REALTIME)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1, SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAKE_PRIVATE)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(futex), 1, SCMP_CMP(1, SCMP_CMP_EQ, FUTEX_WAIT_PRIVATE)); if (rc) return 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; 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_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(accept), 0); if (rc != 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 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 main() { char *addr; int fd,ret; char buf[20]={0}; char sc[128]={0}; scmp_filter_ctx ctx; ctx = seccomp_init(SCMP_ACT_KILL); if (!ctx) { perror("seccomp_init"); return -1; } ret = seccomp_rule_add(ctx,SCMP_ACT_ALLOW,SCMP_SYS(write),0); if(ret) { perror("add rule"); return -1; } ret = seccomp_rule_add(ctx,SCMP_ACT_ALLOW,SCMP_SYS(access),0); if(ret) { perror("add rule"); return -1; } fd = open("./.passwd",O_RDONLY); if(fd == -1) { perror("open"); return -1; } read(fd,buf,20); addr = mmap(0,4096,PROT_READ|PROT_WRITE,MAP_SHARED |MAP_ANONYMOUS,-1,0); if (addr == (char*)-1) { perror("mmap"); return -1; } memset(addr,0,4096); memcpy(addr,"MCSC",4); memcpy(addr+4,"2014",4); memcpy(&addr[8],buf,20); printf("put you shellcode here : "); fflush(stdout); ssize_t rc = read(0,sc,128); sc[rc-1]=0; seccomp_load(ctx); ((void (*)(void))sc)(); return 0; }
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 seccomp_start(void) { int rc = 0; unsigned int i = 0; scmp_filter_ctx ctx; ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) { rc = -1; goto seccomp_return; } for (i = 0; i < ARRAY_SIZE(seccomp_whitelist); i++) { rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, seccomp_whitelist[i].num, 0); if (rc < 0) { goto seccomp_return; } rc = seccomp_syscall_priority(ctx, seccomp_whitelist[i].num, seccomp_whitelist[i].priority); if (rc < 0) { goto seccomp_return; } } rc = seccomp_load(ctx); seccomp_return: seccomp_release(ctx); return rc; }
static int seccomp_add_default_syscall_filter(scmp_filter_ctx ctx, uint64_t cap_list_retain) { unsigned i; int r; static const struct { uint64_t capability; int syscall_num; } blacklist[] = { { CAP_SYS_RAWIO, SCMP_SYS(iopl) }, { CAP_SYS_RAWIO, SCMP_SYS(ioperm) }, { CAP_SYS_BOOT, SCMP_SYS(kexec_load) }, { CAP_SYS_ADMIN, SCMP_SYS(swapon) }, { CAP_SYS_ADMIN, SCMP_SYS(swapoff) }, { CAP_SYS_ADMIN, SCMP_SYS(open_by_handle_at) }, { CAP_SYS_MODULE, SCMP_SYS(init_module) }, { CAP_SYS_MODULE, SCMP_SYS(finit_module) }, { CAP_SYS_MODULE, SCMP_SYS(delete_module) }, { CAP_SYSLOG, SCMP_SYS(syslog) }, }; for (i = 0; i < ELEMENTSOF(blacklist); i++) { if (cap_list_retain & (1ULL << blacklist[i].capability)) continue; r = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(EPERM), blacklist[i].syscall_num, 0); if (r == -EFAULT) continue; /* unknown syscall */ if (r < 0) { log_error_errno(r, "Failed to block syscall: %m"); return r; } } return 0; }
/** * Function responsible for setting up the time syscall for * the seccomp filter sandbox. */ static int sb_time(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { (void) filter; return seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(time), 1, SCMP_CMP(0, SCMP_CMP_EQ, 0)); }
int main(int argc, char *argv[]) { if (argc < 6 || strcmp(argv[1], "--error") || (strcmp(argv[3], "--allow") && strcmp(argv[3], "--deny"))) { usage(argv[0]); return 1; } const int err = parse_positive(argv[2]); if (err < 0) { return 2; } const bool default_block = !strcmp(argv[3], "--allow"); if (-1 == prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl"); return 10; } uint32_t rule_action = !default_block ? SCMP_ACT_ERRNO(err) : SCMP_ACT_ALLOW; scmp_filter_ctx ctx = seccomp_init(default_block ? SCMP_ACT_ERRNO(err) : SCMP_ACT_ALLOW); int arg = 4; for (; arg < argc; ++arg) { if (!strcmp(argv[arg], "--")) { ++arg; break; } const int syscall_no = parse_positive(argv[arg]); if (syscall_no < 0) { seccomp_release(ctx); return 5; } if (seccomp_rule_add(ctx, rule_action, syscall_no, 0)) { perror("rule add"); fprintf(stderr, "not a valid syscall number for a rule: '%s'\n", argv[arg]); seccomp_release(ctx); return 20; } } if (arg == argc) { usage(argv[0]); return 3; } if (seccomp_load(ctx)) { perror("load"); seccomp_release(ctx); return 4; } seccomp_release(ctx); execvp(argv[arg], &argv[arg]); perror("execve"); return 5; }
int main(int const argc, char * const * const argv) { try { alarm(10); close(fileno(stdin)); for (int fd = fileno(stderr); fd != 1024; ++fd) close(fd); dup2(fileno(stdout), fileno(stderr)); limitResource(RLIMIT_CPU, 9, 11); limitResource(RLIMIT_AS, 512*1024*1024); limitResource(RLIMIT_DATA, 512*1024*1024); limitResource(RLIMIT_FSIZE, 10*1024*1024); limitResource(RLIMIT_LOCKS, 0); limitResource(RLIMIT_MEMLOCK, 0); limitResource(RLIMIT_NPROC, 16); if (argc < 2) e("params: program args"); if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) != 0) e("prctl"); scmp_filter_ctx const ctx = seccomp_init(SCMP_ACT_TRAP); if (!ctx) e("seccomp_init"); if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(clone), 1, SCMP_CMP(0, SCMP_CMP_MASKED_EQ, CLONE_THREAD, CLONE_THREAD)) != 0) e("seccomp_rule_add"); for (auto && p : rules) if (seccomp_rule_add(ctx, p.second, p.first, 0) != 0) e("seccomp_rule_add"); if (seccomp_load(ctx) < 0) e("seccomp_load"); execv(argv[1], argv + 1); e("execv"); } catch (std::exception const & e) { std::cerr << "exception: " << e.what() << '\n'; return 1; } }
/** * Function responsible for setting up the rt_sigprocmask syscall for * the seccomp filter sandbox. */ static int sb_rt_sigprocmask(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1, SCMP_CMP(0, SCMP_CMP_EQ, SIG_UNBLOCK)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(rt_sigprocmask), 1, SCMP_CMP(0, SCMP_CMP_EQ, SIG_SETMASK)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the fcntl64 syscall for * the seccomp filter sandbox. * * NOTE: does not NEED to be here.. currently only occurs before filter; will * keep just in case for the future. */ static int sb_mprotect(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 1, SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the flock syscall for * the seccomp filter sandbox. * * NOTE: does not need to be here, occurs before filter is applied. */ static int sb_flock(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock), 1, SCMP_CMP(1, SCMP_CMP_EQ, LOCK_EX|LOCK_NB)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(flock), 1, SCMP_CMP(1, SCMP_CMP_EQ, LOCK_UN)); if (rc) return 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; 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); }
/** * Function responsible for setting up the mmap2 syscall for * the seccomp filter sandbox. */ static int sb_mmap2(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void)filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_NONE), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS|MAP_NORESERVE)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_ANONYMOUS)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), SCMP_CMP(3, SCMP_CMP_EQ,MAP_PRIVATE|MAP_ANONYMOUS|MAP_STACK)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_DENYWRITE)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_WRITE), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_FIXED|MAP_ANONYMOUS)); if (rc) { return rc; } rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 2, SCMP_CMP(2, SCMP_CMP_EQ, PROT_READ|PROT_EXEC), SCMP_CMP(3, SCMP_CMP_EQ, MAP_PRIVATE|MAP_DENYWRITE)); if (rc) { return rc; } return 0; }
/** * Function responsible for setting up the socket syscall for * the seccomp filter sandbox. */ static int sb_socket(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; #ifdef __i386__ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 0); if (rc) return rc; #endif rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 3, SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE), SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK), SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 3, SCMP_CMP(0, SCMP_CMP_EQ, PF_INET), SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC), SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_TCP)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 3, SCMP_CMP(0, SCMP_CMP_EQ, PF_INET), SCMP_CMP(1, SCMP_CMP_EQ, SOCK_DGRAM|SOCK_CLOEXEC|SOCK_NONBLOCK), SCMP_CMP(2, SCMP_CMP_EQ, IPPROTO_IP)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socket), 3, SCMP_CMP(0, SCMP_CMP_EQ, PF_NETLINK), SCMP_CMP(1, SCMP_CMP_EQ, SOCK_RAW), SCMP_CMP(2, SCMP_CMP_EQ, 0)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the getsockopt syscall for * the seccomp filter sandbox. */ static int sb_getsockopt(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; #ifdef __i386__ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 0); if (rc) return rc; #endif rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 2, SCMP_CMP(1, SCMP_CMP_EQ, SOL_SOCKET), SCMP_CMP(2, SCMP_CMP_EQ, SO_ERROR)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the socketpair syscall for * the seccomp filter sandbox. */ static int sb_socketpair(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; #ifdef __i386__ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 0); if (rc) return rc; #endif rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 2, SCMP_CMP(0, SCMP_CMP_EQ, PF_FILE), SCMP_CMP(1, SCMP_CMP_EQ, SOCK_STREAM|SOCK_CLOEXEC)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the fcntl64 syscall for * the seccomp filter sandbox. * * NOTE: if multiple filters need to be added, the PR_SECCOMP parameter needs * to be whitelisted in this function. */ static int sb_prctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(prctl), 1, SCMP_CMP(0, SCMP_CMP_EQ, PR_SET_DUMPABLE)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the mremap syscall for * the seccomp filter sandbox. * * NOTE: so far only occurs before filter is applied. */ static int sb_mremap(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(mremap), 1, SCMP_CMP(3, SCMP_CMP_EQ, MREMAP_MAYMOVE)); if (rc) return rc; return 0; }
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; }
/** * Function responsible for setting up the accept4 syscall for * the seccomp filter sandbox. */ static int sb_accept4(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void)filter; #ifdef __i386__ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketcall), 1, SCMP_CMP(0, SCMP_CMP_EQ, 18)); if (rc) { return rc; } #endif rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 1, SCMP_CMP(3, SCMP_CMP_EQ, SOCK_CLOEXEC)); if (rc) { return rc; } return 0; }
static void setup_seccomp() { scmp_filter_ctx ctx; unsigned int i; int ret; /* Make sure the lists are in sync */ INSIST((sizeof(scmp_syscalls) / sizeof(int)) == (sizeof(scmp_syscall_names) / sizeof(const char *))); ctx = seccomp_init(SCMP_ACT_KILL); if (ctx == NULL) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_WARNING, "libseccomp activation failed"); return; } for (i = 0 ; i < sizeof(scmp_syscalls)/sizeof(*(scmp_syscalls)); i++) { ret = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, scmp_syscalls[i], 0); if (ret < 0) isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_WARNING, "libseccomp rule failed: %s", scmp_syscall_names[i]); else isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_DEBUG(9), "added libseccomp rule: %s", scmp_syscall_names[i]); } ret = seccomp_load(ctx); if (ret < 0) { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_WARNING, "libseccomp unable to load filter"); } else { isc_log_write(ns_g_lctx, NS_LOGCATEGORY_GENERAL, NS_LOGMODULE_MAIN, ISC_LOG_NOTICE, "libseccomp sandboxing active"); } /* * Release filter in ctx. Filters already loaded are not * affected. */ seccomp_release(ctx); }
static void install_seccomp_filter(const char *syscalls[]) { scmp_filter_ctx ctx = seccomp_init(SCMP_ACT_TRAP); if (!ctx) { errx(EXIT_FAILURE, "Failed to init seccomp"); } for (int i = 0; ; i++) { const char *syscall = syscalls[i]; if (!syscall) break; check(seccomp_rule_add(ctx, SCMP_ACT_ALLOW, get_syscall_nr(syscall), 0)); } check(seccomp_load(ctx)); }
/** * Function responsible for setting up the poll syscall for * the seccomp filter sandbox. */ static int sb_poll(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(poll), 2, SCMP_CMP(1, SCMP_CMP_EQ, 1), SCMP_CMP(2, SCMP_CMP_EQ, 10)); if (rc) return rc; return 0; }
/** * Function responsible for setting up the epoll_ctl syscall for * the seccomp filter sandbox. * * Note: basically allows everything but will keep for now.. */ static int sb_epoll_ctl(scmp_filter_ctx ctx, sandbox_cfg_t *filter) { int rc = 0; (void) filter; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1, SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_ADD)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1, SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_MOD)); if (rc) return rc; rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(epoll_ctl), 1, SCMP_CMP(1, SCMP_CMP_EQ, EPOLL_CTL_DEL)); if (rc) return rc; return 0; }
void poe_init_seccomp(uint32_t act) { scmp_filter_ctx ctx = seccomp_init(act); if (!ctx) ERROR("seccomp_init() failed"); for (int i = 0; i < syscall_rules_count; i++) { struct syscall_rule rule = syscall_rules[i]; if (seccomp_rule_add(ctx, rule.action, rule.syscall, 0) < 0) ERROR("seccomp_rule_add() failed"); } int rc = seccomp_load(ctx); if (rc < 0) ERROR("seccomp_load() failed: %s", strerror(-rc)); seccomp_release(ctx); }
/** * Function responsible of loading the libseccomp syscall filters which do not * have parameter filtering. */ static int add_noparam_filter(scmp_filter_ctx ctx) { unsigned i; int rc = 0; // add general filters for (i = 0; i < ARRAY_LENGTH(filter_nopar_gen); i++) { rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, filter_nopar_gen[i], 0); if (rc != 0) { log_err(LD_BUG,"(Sandbox) failed to add syscall index %d (NR=%d), " "received libseccomp error %d", i, filter_nopar_gen[i], rc); return rc; } } return 0; }