summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTom Hromatka <tom.hromatka@oracle.com>2018-09-19 09:26:25 -0600
committerPaul Moore <paul@paul-moore.com>2018-09-19 16:54:15 -0400
commitb2f15f3d02f302b12b9d1a37d83521e6f9e08841 (patch)
treee9b3e4ae6b2a9dcaf68b2877c24d9b69fc1e7122
parent6646e21ed2734dca355c5b550cb45f0379330e02 (diff)
downloadlibseccomp-b2f15f3d02f302b12b9d1a37d83521e6f9e08841.tar.gz
api: Add support for SCMP_ACT_KILL_PROCESS
This patch adds support for killing the entire process via the SCMP_ACT_KILL_PROCESS action. To maintain backward compatibility, SCMP_ACT_KILL defaults to SCMP_ACT_KILL_THREAD. Support for KILL_PROCESS was added into the Linux kernel in v4.14. This addresses GitHub Issue #96 - RFE: add support for SECCOMP_RET_KILL_PROCESS Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com> [PM: minor comment tweak in seccomp.h.in] Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--doc/man/man3/seccomp_init.34
-rw-r--r--doc/man/man3/seccomp_rule_add.34
-rw-r--r--include/seccomp.h.in11
-rw-r--r--src/api.c3
-rw-r--r--src/gen_pfc.c8
-rw-r--r--src/python/libseccomp.pxd1
-rw-r--r--src/python/seccomp.pyx10
-rw-r--r--src/system.c16
-rw-r--r--src/system.h12
-rw-r--r--tools/bpf.h5
-rw-r--r--tools/scmp_bpf_disasm.c7
-rw-r--r--tools/scmp_bpf_sim.c7
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);
diff --git a/src/api.c b/src/api.c
index 8159abe..94039a7 100644
--- a/src/api.c
+++ b/src/api.c
@@ -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: