1485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#ifdef HAVE_CONFIG_H 2485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin# include "config.h" 3485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#endif 4485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 5485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#include <stddef.h> 6485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#include <unistd.h> 7485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#include <stdio.h> 8485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#include <errno.h> 9485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#include <sys/syscall.h> 10485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 11485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#ifdef HAVE_PRCTL 12485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin# include <sys/prctl.h> 13485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#endif 14485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#ifdef HAVE_LINUX_SECCOMP_H 15485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin# include <linux/seccomp.h> 16485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#endif 17485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#ifdef HAVE_LINUX_FILTER_H 18485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin# include <linux/filter.h> 19485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#endif 20485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 21485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#if defined HAVE_PRCTL \ 22485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined PR_SET_NO_NEW_PRIVS \ 23485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined PR_SET_SECCOMP \ 24485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined SECCOMP_MODE_FILTER \ 25485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined SECCOMP_RET_ERRNO \ 26485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined BPF_JUMP \ 27485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin && defined BPF_STMT 28485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 29485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#define SOCK_FILTER_ALLOW_SYSCALL(nr) \ 30485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, __NR_ ## nr, 0, 1), \ 31485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW) 32485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 33485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#define SOCK_FILTER_DENY_SYSCALL(nr, err) \ 34485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, __NR_ ## nr, 0, 1), \ 35485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | (SECCOMP_RET_DATA & (err))) 36485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 37485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#define SOCK_FILTER_KILL_PROCESS \ 38485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL) 39485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 40485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#define PRINT_ALLOW_SYSCALL(nr) \ 41485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin printf("BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, %#x, 0, 0x1), " \ 42485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin "BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ALLOW), ", \ 43485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin __NR_ ## nr) 44485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 45485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#define PRINT_DENY_SYSCALL(nr, err) \ 46485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin printf("BPF_JUMP(BPF_JMP | BPF_K | BPF_JEQ, %#x, 0, 0x1), " \ 47485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin "BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_ERRNO | %#x), ", \ 48485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin __NR_ ## nr, err) 49485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 50485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levinstatic const struct sock_filter filter[] = { 51485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin /* load syscall number */ 52485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin BPF_STMT(BPF_LD | BPF_W | BPF_ABS, offsetof(struct seccomp_data, nr)), 53485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 54485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin /* allow syscalls */ 55485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_ALLOW_SYSCALL(close), 56485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_ALLOW_SYSCALL(exit), 57485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_ALLOW_SYSCALL(exit_group), 58485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 59485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin /* deny syscalls */ 60485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_DENY_SYSCALL(sync, EBUSY), 61485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_DENY_SYSCALL(setsid, EPERM), 62485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 63485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin /* kill process */ 64485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin SOCK_FILTER_KILL_PROCESS 65485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin}; 66485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 67485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levinstatic const struct sock_fprog prog = { 68485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin .len = sizeof(filter) / sizeof(filter[0]), 69485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin .filter = (struct sock_filter *) filter, 70485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin}; 71485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 72485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levinint 73485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levinmain(void) 74485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin{ 75485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin int fds[2]; 76485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 77485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin puts("prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) = 0"); 78485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 79485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin printf("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, ["); 80485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 81485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin printf("BPF_STMT(BPF_LD | BPF_W | BPF_ABS, %#x), ", 82485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin (unsigned) offsetof(struct seccomp_data, nr)); 83485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 84485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin PRINT_ALLOW_SYSCALL(close); 85485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin PRINT_ALLOW_SYSCALL(exit); 86485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin PRINT_ALLOW_SYSCALL(exit_group); 87485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 88485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin PRINT_DENY_SYSCALL(sync, EBUSY), 89485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin PRINT_DENY_SYSCALL(setsid, EPERM), 90485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 91485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin printf("BPF_STMT(BPF_RET | BPF_K, SECCOMP_RET_KILL)"); 92485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 93485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin puts("]) = 0"); 94485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin puts("+++ exited with 0 +++"); 95485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 96485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin fflush(stdout); 97485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin close(0); 98485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin close(1); 99485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 100485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin if (pipe(fds) || 101485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0) || 102485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog) || 103485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin close(0) || close(1)) 104485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin _exit(77); 105485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 106485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin _exit(0); 107485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin} 108485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 109485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#else 110485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 111485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levinint main(void) { return 77; } 112485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin 113485f8fb2500980be2cb0cde43e3582c088739a6fDmitry V. Levin#endif 114