diff options
-rw-r--r-- | doc/man/man3/seccomp_init.3 | 4 | ||||
-rw-r--r-- | doc/man/man3/seccomp_rule_add.3 | 4 | ||||
-rw-r--r-- | include/seccomp.h.in | 11 | ||||
-rw-r--r-- | src/api.c | 3 | ||||
-rw-r--r-- | src/gen_pfc.c | 8 | ||||
-rw-r--r-- | src/python/libseccomp.pxd | 1 | ||||
-rw-r--r-- | src/python/seccomp.pyx | 10 | ||||
-rw-r--r-- | src/system.c | 16 | ||||
-rw-r--r-- | src/system.h | 12 | ||||
-rw-r--r-- | tools/bpf.h | 5 | ||||
-rw-r--r-- | tools/scmp_bpf_disasm.c | 7 | ||||
-rw-r--r-- | tools/scmp_bpf_sim.c | 7 |
12 files changed, 75 insertions, 13 deletions
diff --git a/doc/man/man3/seccomp_init.3 b/doc/man/man3/seccomp_init.3 index d7cd383..ad1371f 100644 --- a/doc/man/man3/seccomp_init.3 +++ b/doc/man/man3/seccomp_init.3 @@ -52,6 +52,10 @@ The thread will be terminated by the kernel with SIGSYS when it calls a syscall that does not match any of the configured seccomp filter rules. The thread will not be able to catch the signal. .TP +.B SCMP_ACT_KILL_PROCESS +The entire process will be terminated by the kernel with SIGSYS when it calls a +syscall that does not match any of the configured seccomp filter rules. +.TP .B SCMP_ACT_TRAP The thread will be sent a SIGSYS signal when it calls a syscall that does not match any of the configured seccomp filter rules. It may catch this and change diff --git a/doc/man/man3/seccomp_rule_add.3 b/doc/man/man3/seccomp_rule_add.3 index 86c53b1..b051577 100644 --- a/doc/man/man3/seccomp_rule_add.3 +++ b/doc/man/man3/seccomp_rule_add.3 @@ -111,6 +111,10 @@ values are as follows: The thread will be killed by the kernel when it calls a syscall that matches the filter rule. .TP +.B SCMP_ACT_KILL_PROCESS +The process will be killed by the kernel when it calls a syscall that matches +the filter rule. +.TP .B SCMP_ACT_TRAP The thread will throw a SIGSYS signal when it calls a syscall that matches the filter rule. diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 03973a4..ab6a638 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -244,7 +244,15 @@ struct scmp_arg_cmp { /** * Kill the process */ -#define SCMP_ACT_KILL 0x00000000U +#define SCMP_ACT_KILL_PROCESS 0x80000000U +/** + * Kill the thread + */ +#define SCMP_ACT_KILL_THREAD 0x00000000U +/** + * Kill the thread, defined for backward compatibility + */ +#define SCMP_ACT_KILL SCMP_ACT_KILL_THREAD /** * Throw a SIGSYS signal */ @@ -297,6 +305,7 @@ const struct scmp_version *seccomp_version(void); * uses the seccomp(2) syscall instead of the prctl(2) syscall * 3 : support for the SCMP_FLTATR_CTL_LOG filter attribute * support for the SCMP_ACT_LOG action + * support for the SCMP_ACT_KILL_PROCESS action * */ unsigned int seccomp_api_get(void); @@ -135,18 +135,21 @@ API int seccomp_api_set(unsigned int level) sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, false); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false); sys_set_seccomp_action(SCMP_ACT_LOG, false); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false); break; case 2: sys_set_seccomp_syscall(true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, false); sys_set_seccomp_action(SCMP_ACT_LOG, false); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, false); break; case 3: sys_set_seccomp_syscall(true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_LOG, true); sys_set_seccomp_action(SCMP_ACT_LOG, true); + sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); break; default: return -EINVAL; diff --git a/src/gen_pfc.c b/src/gen_pfc.c index ebde3bf..75d8507 100644 --- a/src/gen_pfc.c +++ b/src/gen_pfc.c @@ -35,6 +35,7 @@ #include "db.h" #include "gen_pfc.h" #include "helper.h" +#include "system.h" struct pfc_sys_list { struct db_sys_list *sys; @@ -117,8 +118,11 @@ static void _pfc_arg(FILE *fds, */ static void _pfc_action(FILE *fds, uint32_t action) { - switch (action & 0xffff0000) { - case SCMP_ACT_KILL: + switch (action & SECCOMP_RET_ACTION_FULL) { + case SCMP_ACT_KILL_PROCESS: + fprintf(fds, "action KILL_PROCESS;\n"); + break; + case SCMP_ACT_KILL_THREAD: fprintf(fds, "action KILL;\n"); break; case SCMP_ACT_TRAP: diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index a599ef2..49d0be4 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -69,6 +69,7 @@ cdef extern from "seccomp.h": SCMP_CMP_MASKED_EQ cdef enum: + SCMP_ACT_KILL_PROCESS SCMP_ACT_KILL SCMP_ACT_TRAP SCMP_ACT_LOG diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx index c9a0dab..771b9c3 100644 --- a/src/python/seccomp.pyx +++ b/src/python/seccomp.pyx @@ -29,7 +29,8 @@ based filtering interface that should be familiar to, and easily adopted by application developers. Filter action values: - KILL - kill the process + KILL_PROCESS - kill the process + KILL - kill the thread LOG - allow the syscall to be executed after the action has been logged ALLOW - allow the syscall to execute TRAP - a SIGSYS signal will be thrown @@ -94,6 +95,7 @@ def c_str(string): else: return bytes(string, "ascii") +KILL_PROCESS = libseccomp.SCMP_ACT_KILL_PROCESS KILL = libseccomp.SCMP_ACT_KILL TRAP = libseccomp.SCMP_ACT_TRAP LOG = libseccomp.SCMP_ACT_LOG @@ -545,7 +547,8 @@ cdef class SyscallFilter: """ Add a new rule to filter. Arguments: - action - the rule action: KILL, TRAP, ERRNO(), TRACE(), LOG, or ALLOW + action - the rule action: KILL_PROCESS, KILL, TRAP, ERRNO(), TRACE(), + LOG, or ALLOW syscall - the syscall name or number args - variable number of Arg objects @@ -627,7 +630,8 @@ cdef class SyscallFilter: """ Add a new rule to filter. Arguments: - action - the rule action: KILL, TRAP, ERRNO(), TRACE(), LOG, or ALLOW + action - the rule action: KILL_PROCESS, KILL, TRAP, ERRNO(), TRACE(), + LOG, or ALLOW syscall - the syscall name or number args - variable number of Arg objects diff --git a/src/system.c b/src/system.c index af46109..0501b76 100644 --- a/src/system.c +++ b/src/system.c @@ -43,6 +43,7 @@ static int _support_seccomp_syscall = -1; static int _support_seccomp_flag_tsync = -1; static int _support_seccomp_flag_log = -1; static int _support_seccomp_action_log = -1; +static int _support_seccomp_kill_process = -1; /** * Check to see if the seccomp() syscall is supported @@ -123,7 +124,18 @@ void sys_set_seccomp_syscall(bool enable) */ int sys_chk_seccomp_action(uint32_t action) { - if (action == SCMP_ACT_KILL) { + if (action == SCMP_ACT_KILL_PROCESS) { + if (_support_seccomp_kill_process < 0) { + if (sys_chk_seccomp_syscall() == 1 && + syscall(_nr_seccomp, SECCOMP_GET_ACTION_AVAIL, 0, + &action) == 0) + _support_seccomp_kill_process = 1; + else + _support_seccomp_kill_process = 0; + } + + return _support_seccomp_kill_process; + } else if (action == SCMP_ACT_KILL_THREAD) { return 1; } else if (action == SCMP_ACT_TRAP) { return 1; @@ -162,6 +174,8 @@ void sys_set_seccomp_action(uint32_t action, bool enable) { if (action == SCMP_ACT_LOG) _support_seccomp_action_log = (enable ? 1 : 0); + else if (action == SCMP_ACT_KILL_PROCESS) + _support_seccomp_kill_process = (enable ? 1 : 0); } /** diff --git a/src/system.h b/src/system.h index b793687..a0c8ec8 100644 --- a/src/system.h +++ b/src/system.h @@ -55,13 +55,16 @@ struct db_filter_col; * The ordering ensures that a min_t() over composed return values always * selects the least permissive choice. */ -#define SECCOMP_RET_KILL 0x00000000U /* kill the task immediately */ +#define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process immediately */ +#define SECCOMP_RET_KILL_THREAD 0x00000000U /* kill the thread immediately */ +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD /* default to killing the thread */ #define SECCOMP_RET_TRAP 0x00030000U /* disallow and force a SIGSYS */ #define SECCOMP_RET_ERRNO 0x00050000U /* returns an errno */ #define SECCOMP_RET_TRACE 0x7ff00000U /* pass to a tracer or disallow */ #define SECCOMP_RET_ALLOW 0x7fff0000U /* allow */ /* Masks for the return value sections. */ +#define SECCOMP_RET_ACTION_FULL 0xffff0000U #define SECCOMP_RET_ACTION 0x7fff0000U #define SECCOMP_RET_DATA 0x0000ffffU @@ -118,6 +121,13 @@ typedef struct sock_filter bpf_instr_raw; #define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */ #endif +/* SECCOMP_RET_ACTION_FULL was added in kernel v4.14. It may not be + * defined on older kernels + */ +#ifndef SECCOMP_RET_ACTION_FULL +#define SECCOMP_RET_ACTION_FULL 0xffff0000U +#endif + int sys_chk_seccomp_syscall(void); void sys_set_seccomp_syscall(bool enable); diff --git a/tools/bpf.h b/tools/bpf.h index b8e6d81..fd20441 100644 --- a/tools/bpf.h +++ b/tools/bpf.h @@ -56,11 +56,14 @@ struct sock_filter { typedef struct sock_filter bpf_instr_raw; /* seccomp return masks */ +#define SECCOMP_RET_ACTION_FULL 0xffff0000U #define SECCOMP_RET_ACTION 0x7fff0000U #define SECCOMP_RET_DATA 0x0000ffffU /* seccomp action values */ -#define SECCOMP_RET_KILL 0x00000000U +#define SECCOMP_RET_KILL_PROCESS 0x80000000U +#define SECCOMP_RET_KILL_THREAD 0x00000000U +#define SECCOMP_RET_KILL SECCOMP_RET_KILL_THREAD #define SECCOMP_RET_TRAP 0x00030000U #define SECCOMP_RET_ERRNO 0x00050000U #define SECCOMP_RET_TRACE 0x7ff00000U diff --git a/tools/scmp_bpf_disasm.c b/tools/scmp_bpf_disasm.c index 6e5282a..27fba9a 100644 --- a/tools/scmp_bpf_disasm.c +++ b/tools/scmp_bpf_disasm.c @@ -173,11 +173,14 @@ static const char *bpf_decode_op(const bpf_instr_raw *bpf) */ static void bpf_decode_action(uint32_t k) { - uint32_t act = k & SECCOMP_RET_ACTION; + uint32_t act = k & SECCOMP_RET_ACTION_FULL; uint32_t data = k & SECCOMP_RET_DATA; switch (act) { - case SECCOMP_RET_KILL: + case SECCOMP_RET_KILL_PROCESS: + printf("KILL_PROCESS"); + break; + case SECCOMP_RET_KILL_THREAD: printf("KILL"); break; case SECCOMP_RET_TRAP: diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c index 6e422c5..73d056b 100644 --- a/tools/scmp_bpf_sim.c +++ b/tools/scmp_bpf_sim.c @@ -112,11 +112,14 @@ static void exit_error(unsigned int rc, unsigned int line) */ static void end_action(uint32_t action, unsigned int line) { - uint32_t act = action & SECCOMP_RET_ACTION; + uint32_t act = action & SECCOMP_RET_ACTION_FULL; uint32_t data = action & SECCOMP_RET_DATA; switch (act) { - case SECCOMP_RET_KILL: + case SECCOMP_RET_KILL_PROCESS: + fprintf(stdout, "KILL_PROCESS\n"); + break; + case SECCOMP_RET_KILL_THREAD: fprintf(stdout, "KILL\n"); break; case SECCOMP_RET_TRAP: |