void sandboxify() { if (seccomp_init(SCMP_ACT_TRAP) < 0) ERROR("Cannot go into SECCOMPv2"); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(open), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(openat), 0); // XXXX // seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(open), 0); seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(access), 0); seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fcntl), 0); // XXXX seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fstat), 0); seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(fstat64), 0); seccomp_rule_add(SCMP_ACT_ERRNO(EPERM), SCMP_SYS(stat64), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(getdents), 0); // XXXX seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(stat), 0); // XXXX seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(dup), 0); // XXXX seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(lseek), 0); // XXXX seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(close), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(read), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(getdents64), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(write), 0); // seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(writev), 0); // XXX // seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(mprotect), 0); // XXX // seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(futex), 0); // XXX seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(mmap2), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(mmap), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(munmap), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(mremap), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(brk), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(gettimeofday), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(time), 0); seccomp_rule_add(SCMP_ACT_ALLOW, SCMP_SYS(exit_group), 0); #ifdef DEBUG_SECCOMP if (install_syscall_reporter()) ERROR("Cannot install syscall reporter"); #endif if (seccomp_load() < 0) ERROR("Cannot load SECCOMP filters"); seccomp_release(); }
static int install_syscall_filter(void) { struct sock_filter filter[] = { /* Validate architecture. */ VALIDATE_ARCHITECTURE, /* Grab the system call number. */ EXAMINE_SYSCALL, /* List allowed syscalls. */ ALLOW_SYSCALL(rt_sigreturn), #ifdef __NR_sigreturn ALLOW_SYSCALL(sigreturn), #endif ALLOW_SYSCALL(exit_group), ALLOW_SYSCALL(exit), ALLOW_SYSCALL(read), ALLOW_SYSCALL(write), /* Add more syscalls here. */ ALLOW_SYSCALL(fstat), ALLOW_SYSCALL(mmap), ALLOW_SYSCALL(rt_sigprocmask), ALLOW_SYSCALL(rt_sigaction), ALLOW_SYSCALL(nanosleep), KILL_PROCESS, }; struct sock_fprog prog = { .len = (unsigned short)(sizeof(filter)/sizeof(filter[0])), .filter = filter, }; if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl(NO_NEW_PRIVS)"); goto failed; } if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) { perror("prctl(SECCOMP)"); goto failed; } return 0; failed: if (errno == EINVAL) fprintf(stderr, "SECCOMP_FILTER is not available. :(\n"); return 1; } int main(int argc, char *argv[]) { char buf[1024]; if (install_syscall_reporter()) return 1; if (install_syscall_filter()) return 1; printf("Type stuff here: "); fflush(NULL); buf[0] = '\0'; fgets(buf, sizeof(buf), stdin); printf("You typed: %s", buf); printf("And now we fork, which should do quite the opposite ...\n"); fflush(NULL); sleep(1); fork(); printf("You should not see this because I'm dead.\n"); return 0; }