diff --git a/doc/man/man3/seccomp_init.3 b/doc/man/man3/seccomp_init.3 index d7cd383a..ad1371f1 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 86c53b19..b051577f 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 2a789d67..8e2d7f9b 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 + * 4 : support for the SCMP_ACT_KILL_PROCESS action * */ const unsigned int seccomp_api_get(void); diff --git a/src/api.c b/src/api.c index e1a5e8b1..8198fd48 100644 --- a/src/api.c +++ b/src/api.c @@ -135,18 +135,28 @@ 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, false); + break; + case 4: + 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 196635f9..68051ce6 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 a599ef2e..49d0be4c 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 159cbc18..bb5e01b5 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 af461098..0501b76d 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 b7936877..a8ff4b0d 100644 --- a/src/system.h +++ b/src/system.h @@ -37,6 +37,13 @@ struct db_filter_col; /* system header file */ #include +/* 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 + #else /* NOTE: the definitions below were taken from the Linux Kernel sources */ @@ -55,13 +62,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 diff --git a/tests/.gitignore b/tests/.gitignore index c4f2bf8e..568e9df5 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -48,3 +48,5 @@ util.pyc 40-sim-log 41-sim-syscall_priority_arch 42-sim-adv_chains +43-sim-kill_process +44-live-kill_process diff --git a/tests/06-sim-actions.c b/tests/06-sim-actions.c index d81e5211..04968a9b 100644 --- a/tests/06-sim-actions.c +++ b/tests/06-sim-actions.c @@ -36,7 +36,7 @@ int main(int argc, char *argv[]) if (rc < 0) goto out; - rc = seccomp_api_set(3); + rc = seccomp_api_set(4); if (rc != 0) return EOPNOTSUPP; @@ -64,6 +64,10 @@ int main(int argc, char *argv[]) if (rc != 0) goto out; + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL_PROCESS, SCMP_SYS(stat), 0); + if (rc != 0) + goto out; + rc = util_filter_output(&opts, ctx); if (rc) goto out; diff --git a/tests/06-sim-actions.py b/tests/06-sim-actions.py index e3f91e98..f0fe6f47 100755 --- a/tests/06-sim-actions.py +++ b/tests/06-sim-actions.py @@ -30,7 +30,7 @@ from seccomp import * def test(args): - set_api(3) + set_api(4) f = SyscallFilter(KILL) f.add_rule(ALLOW, "read") @@ -38,6 +38,7 @@ def test(args): f.add_rule(ERRNO(errno.EPERM), "write") f.add_rule(TRAP, "close") f.add_rule(TRACE(1234), "open") + f.add_rule(KILL_PROCESS, "stat") return f args = util.get_opt() diff --git a/tests/06-sim-actions.tests b/tests/06-sim-actions.tests index 1402e213..40a93aea 100644 --- a/tests/06-sim-actions.tests +++ b/tests/06-sim-actions.tests @@ -12,11 +12,12 @@ test type: bpf-sim 06-sim-actions all write 1 0x856B008 N N N N ERRNO(1) 06-sim-actions all close 4 N N N N N TRAP 06-sim-actions all,-aarch64 open 0x856B008 4 N N N N TRACE(1234) +06-sim-actions all stat N N N N N N KILL_PROCESS 06-sim-actions all rt_sigreturn N N N N N N LOG 06-sim-actions x86 0-2 N N N N N N KILL 06-sim-actions x86 7-172 N N N N N N KILL 06-sim-actions x86 174-350 N N N N N N KILL -06-sim-actions x86_64 4-14 N N N N N N KILL +06-sim-actions x86_64 5-14 N N N N N N KILL 06-sim-actions x86_64 16-350 N N N N N N KILL test type: bpf-sim-fuzz diff --git a/tests/38-basic-pfc_coverage.c b/tests/38-basic-pfc_coverage.c index a12d06c8..a53ee215 100644 --- a/tests/38-basic-pfc_coverage.c +++ b/tests/38-basic-pfc_coverage.c @@ -38,6 +38,10 @@ int main(int argc, char *argv[]) /* stdout */ fd = 1; + rc = seccomp_api_set(4); + if (rc != 0) + return EOPNOTSUPP; + ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { rc = ENOMEM; @@ -78,6 +82,9 @@ int main(int argc, char *argv[]) if (rc < 0) goto out; rc = seccomp_rule_add(ctx, SCMP_ACT_TRACE(1), SCMP_SYS(exit), 0); + if (rc < 0) + goto out; + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL_PROCESS, SCMP_SYS(fstat), 0); if (rc < 0) goto out; diff --git a/tests/38-basic-pfc_coverage.pfc b/tests/38-basic-pfc_coverage.pfc index a0c31ac1..a9a7019f 100644 --- a/tests/38-basic-pfc_coverage.pfc +++ b/tests/38-basic-pfc_coverage.pfc @@ -6,6 +6,9 @@ if ($arch == 3221225534) # filter for syscall "exit" (60) [priority: 65535] if ($syscall == 60) action TRACE(1); + # filter for syscall "fstat" (5) [priority: 65535] + if ($syscall == 5) + action KILL_PROCESS; # filter for syscall "close" (3) [priority: 65535] if ($syscall == 3) action ERRNO(1); @@ -65,6 +68,9 @@ if ($arch == 3221225534) action ALLOW; # filter for arch x86 (1073741827) if ($arch == 1073741827) + # filter for syscall "fstat" (108) [priority: 65535] + if ($syscall == 108) + action KILL_PROCESS; # filter for syscall "close" (6) [priority: 65535] if ($syscall == 6) action ERRNO(1); diff --git a/tests/43-sim-kill_process.c b/tests/43-sim-kill_process.c new file mode 100644 index 00000000..9647bcb6 --- /dev/null +++ b/tests/43-sim-kill_process.c @@ -0,0 +1,69 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include + +#include + +#include "util.h" + +int main(int argc, char *argv[]) +{ + int rc; + struct util_options opts; + scmp_filter_ctx ctx = NULL; + + rc = util_getopt(argc, argv, &opts); + if (rc < 0) + goto out; + + ctx = seccomp_init(SCMP_ACT_KILL_PROCESS); + if (ctx == NULL) + return ENOMEM; + + rc = seccomp_arch_remove(ctx, SCMP_ARCH_NATIVE); + if (rc != 0) + goto out; + rc = seccomp_arch_add(ctx, SCMP_ARCH_X86_64); + if (rc != 0) + goto out; + + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(read), 0); + if (rc != 0) + goto out; + + rc = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(5), SCMP_SYS(write), 0); + if (rc != 0) + goto out; + + rc = seccomp_rule_add(ctx, SCMP_ACT_KILL_THREAD, SCMP_SYS(open), 0); + if (rc != 0) + goto out; + + rc = util_filter_output(&opts, ctx); + if (rc) + goto out; + +out: + seccomp_release(ctx); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/43-sim-kill_process.py b/tests/43-sim-kill_process.py new file mode 100755 index 00000000..092798a2 --- /dev/null +++ b/tests/43-sim-kill_process.py @@ -0,0 +1,45 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License as +# published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# + +import argparse +import sys + +import util + +from seccomp import * + +def test(args): + f = SyscallFilter(KILL_PROCESS) + f.remove_arch(Arch()) + f.add_arch(Arch("x86_64")) + f.add_rule_exactly(ALLOW, "read") + f.add_rule_exactly(ERRNO(5), "write") + f.add_rule_exactly(KILL, "open") + return f + +args = util.get_opt() +ctx = test(args) +util.filter_output(args, ctx) + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/tests/43-sim-kill_process.tests b/tests/43-sim-kill_process.tests new file mode 100644 index 00000000..77a84fde --- /dev/null +++ b/tests/43-sim-kill_process.tests @@ -0,0 +1,17 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +test type: bpf-sim + +# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result +43-sim-kill_process +x86_64 0 N N N N N N ALLOW +43-sim-kill_process +x86_64 1 N N N N N N ERRNO(5) +43-sim-kill_process +x86_64 2 N N N N N N KILL +43-sim-kill_process +x86_64 3 N N N N N N KILL_PROCESS + +# Testname +43-sim-kill_process diff --git a/tests/44-live-kill_process.c b/tests/44-live-kill_process.c new file mode 100644 index 00000000..03118557 --- /dev/null +++ b/tests/44-live-kill_process.c @@ -0,0 +1,105 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka + */ + +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include + +#include "util.h" + + +static const unsigned int whitelist[] = { + SCMP_SYS(clone), + SCMP_SYS(exit), + SCMP_SYS(exit_group), + SCMP_SYS(futex), + SCMP_SYS(madvise), + SCMP_SYS(mmap), + SCMP_SYS(mprotect), + SCMP_SYS(munmap), + SCMP_SYS(nanosleep), + SCMP_SYS(set_robust_list), +}; + +/** + * Child thread created via pthread_create() + * + * This thread will call a disallowed syscall. It should + * cause the entire program to die (and not just this + * thread.) + */ +void *child_start(void *param) +{ + int fd, *i = (int *)param; + + *i = 1; + + /* make a disallowed syscall */ + fd = open("/dev/null", O_WRONLY | O_CREAT, S_IRUSR | S_IWUSR); + /* we should never get here. seccomp should kill the entire + * process when open() is called. + */ + if (fd < 0) + *i = fd; + + return NULL; +} + +int main(int argc, char *argv[]) +{ + int rc, i, param = 0; + scmp_filter_ctx ctx = NULL; + pthread_t child_thread; + + ctx = seccomp_init(SCMP_ACT_KILL_PROCESS); + if (ctx == NULL) + return ENOMEM; + + for (i = 0; i < sizeof(whitelist) / sizeof(whitelist[0]); i++) { + rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, whitelist[i], 0); + if (rc != 0) + goto out; + } + + rc = seccomp_load(ctx); + if (rc != 0) + goto out; + + rc = pthread_create(&child_thread, NULL, child_start, ¶m); + if (rc != 0) + goto out; + + /* sleep for a bit to ensure that the child thread has time to run */ + sleep(1); + + /* we should never get here! */ + rc = -EACCES; + goto out; + +out: + seccomp_release(ctx); + return (rc < 0 ? -rc : rc); +} diff --git a/tests/44-live-kill_process.py b/tests/44-live-kill_process.py new file mode 100755 index 00000000..30507420 --- /dev/null +++ b/tests/44-live-kill_process.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2013 Red Hat +# Author: Paul Moore +# + +# +# This library is free software; you can redistribute it and/or modify it +# under the terms of version 2.1 of the GNU Lesser General Public License as +# published by the Free Software Foundation. +# +# This library is distributed in the hope that it will be useful, but WITHOUT +# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License +# for more details. +# +# You should have received a copy of the GNU Lesser General Public License +# along with this library; if not, see . +# + +import argparse +import os +import sys +import threading +import time + +import util + +from seccomp import * + +def child_start(param): + param = 1 + + try: + fd = os.open("/dev/null", os.O_WRONLY) + except IOError as ex: + param = ex.errno + quit(ex.errno) + +def test(): + f = SyscallFilter(KILL_PROCESS) + f.add_rule(ALLOW, "clone") + f.add_rule(ALLOW, "exit") + f.add_rule(ALLOW, "exit_group") + f.add_rule(ALLOW, "futex") + f.add_rule(ALLOW, "madvise") + f.add_rule(ALLOW, "mmap") + f.add_rule(ALLOW, "mprotect") + f.add_rule(ALLOW, "munmap") + f.add_rule(ALLOW, "nanosleep") + f.add_rule(ALLOW, "set_robust_list") + f.load() + + param = 0 + threading.Thread(target = child_start, args = (param, )) + thread.start() + + time.sleep(1) + + quit(-errno.EACCES) + +test() + +# kate: syntax python; +# kate: indent-mode python; space-indent on; indent-width 4; mixedindent off; diff --git a/tests/44-live-kill_process.tests b/tests/44-live-kill_process.tests new file mode 100644 index 00000000..ccbecb94 --- /dev/null +++ b/tests/44-live-kill_process.tests @@ -0,0 +1,11 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka +# + +test type: live + +# Testname Result +44-live-kill_process KILL_PROCESS diff --git a/tests/Makefile.am b/tests/Makefile.am index 3731c462..3a1015ea 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -26,7 +26,7 @@ else DBG_STATIC = -static endif -AM_LDFLAGS = ${DBG_STATIC} +AM_LDFLAGS = ${DBG_STATIC} -lpthread LDADD = util.la ../src/libseccomp.la ${CODE_COVERAGE_LIBS} @@ -81,7 +81,9 @@ check_PROGRAMS = \ 39-basic-api_level \ 40-sim-log \ 41-sim-syscall_priority_arch \ - 42-sim-adv_chains + 42-sim-adv_chains \ + 43-sim-kill_process \ + 44-live-kill_process EXTRA_DIST_TESTPYTHON = \ util.py \ @@ -124,7 +126,9 @@ EXTRA_DIST_TESTPYTHON = \ 37-sim-ipc_syscalls_be.py \ 40-sim-log.py \ 41-sim-syscall_priority_arch.py \ - 42-sim-adv_chains.py + 42-sim-adv_chains.py \ + 43-sim-kill_process.py \ + 44-live-kill_process.py EXTRA_DIST_TESTCFGS = \ 01-sim-allow.tests \ @@ -168,7 +172,9 @@ EXTRA_DIST_TESTCFGS = \ 39-basic-api_level.tests \ 40-sim-log.tests \ 41-sim-syscall_priority_arch.tests \ - 42-sim-adv_chains.tests + 42-sim-adv_chains.tests \ + 43-sim-kill_process.tests \ + 44-live-kill_process.tests EXTRA_DIST_TESTSCRIPTS = \ 38-basic-pfc_coverage.sh 38-basic-pfc_coverage.pfc diff --git a/tests/regression b/tests/regression index 2a7a5024..164273f5 100755 --- a/tests/regression +++ b/tests/regression @@ -724,6 +724,7 @@ function run_test_live() { # setup the arch specific return values case "$arch" in x86|x86_64|x32|arm|aarch64|parisc|parisc64|ppc|ppc64|ppc64le|ppc|s390|s390x) + rc_kill_process=159 rc_kill=159 rc_allow=160 rc_trap=161 @@ -732,6 +733,7 @@ function run_test_live() { rc_log=164 ;; mips|mipsel|mips64|mips64n32|mipsel64|mipsel64n32) + rc_kill_process=140 rc_kill=140 rc_allow=160 rc_trap=161 @@ -747,7 +749,10 @@ function run_test_live() { esac # verify the results - if [[ $line_act == "KILL" && $rc -eq $rc_kill ]]; then + if [[ $line_act == "KILL_PROCESS" && $rc -eq $rc_kill_process ]]; then + print_result $1 "SUCCESS" "" + stats_success=$(($stats_success+1)) + elif [[ $line_act == "KILL" && $rc -eq $rc_kill ]]; then print_result $1 "SUCCESS" "" stats_success=$(($stats_success+1)) elif [[ $line_act == "ALLOW" && $rc -eq $rc_allow ]]; then diff --git a/tests/util.c b/tests/util.c index f079a53f..a84e475d 100644 --- a/tests/util.c +++ b/tests/util.c @@ -168,6 +168,8 @@ int util_action_parse(const char *action) if (strcasecmp(action, "KILL") == 0) return SCMP_ACT_KILL; + if (strcasecmp(action, "KILL_PROCESS") == 0) + return SCMP_ACT_KILL_PROCESS; else if (strcasecmp(action, "TRAP") == 0) return SCMP_ACT_TRAP; else if (strcasecmp(action, "ERRNO") == 0) diff --git a/tools/bpf.h b/tools/bpf.h index b8e6d818..fd204416 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 6e5282a5..27fba9ad 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 6e422c5b..73d056b1 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: