#include #include #include #include #include #include #include #include #include static int install_filter(int syscall_nr, int f_errno) { struct sock_filter filter[] = { /* [0] Load architecture from 'seccomp_data' buffer into accumulator. */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, arch))), /* [1] Load system call number from 'seccomp_data' buffer into accumulator. */ BPF_STMT(BPF_LD | BPF_W | BPF_ABS, (offsetof(struct seccomp_data, nr))), /* [2] Jump forward 1 instruction if system call number does not match 'syscall_nr'. */ BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, syscall_nr, 0, 1), /* [3] Matching system call: don't execute the system call, and return 'f_errno' in 'errno'. */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (f_errno & SECCOMP_RET_DATA)), /* [4] Destination of system call number mismatch: allow other system calls. */ BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), }; struct sock_fprog prog = { .len = sizeof(filter) / sizeof(*filter), .filter = filter, }; if (syscall(SYS_seccomp, SECCOMP_SET_MODE_FILTER, 0, &prog)) { perror("seccomp"); return 1; } return 0; } int main(int argc, char *argv[]) { if (argc < 4) { fprintf(stderr, "Usage: " "%s []\n" "\n", argv[0]); exit(EXIT_FAILURE); } if (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) { perror("prctl"); exit(EXIT_FAILURE); } if (install_filter(strtol(argv[1], NULL, 0), strtol(argv[2], NULL, 0))) exit(EXIT_FAILURE); execv(argv[3], &argv[3]); perror("execv"); exit(EXIT_FAILURE); }