diff options
author | Tom Hromatka <tom.hromatka@oracle.com> | 2018-09-19 09:32:41 -0600 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2018-09-19 19:24:41 -0400 |
commit | 82cc261798966fbe1a4a9ffb40c4ab3be192e4b1 (patch) | |
tree | 9a656b2dbec52b2ff3e009cb023e72f8fbf30275 /tests | |
parent | b2f15f3d02f302b12b9d1a37d83521e6f9e08841 (diff) | |
download | libseccomp-82cc261798966fbe1a4a9ffb40c4ab3be192e4b1.tar.gz |
tests: Add tests for SECCOMP_RET_KILL_PROCESS
This addresses GitHub Issue #96 - RFE: add support for
SECCOMP_RET_KILL_PROCESS
Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'tests')
-rw-r--r-- | tests/.gitignore | 2 | ||||
-rw-r--r-- | tests/06-sim-actions.c | 4 | ||||
-rwxr-xr-x | tests/06-sim-actions.py | 1 | ||||
-rw-r--r-- | tests/06-sim-actions.tests | 3 | ||||
-rw-r--r-- | tests/38-basic-pfc_coverage.c | 7 | ||||
-rw-r--r-- | tests/38-basic-pfc_coverage.pfc | 6 | ||||
-rw-r--r-- | tests/46-sim-kill_process.c | 74 | ||||
-rwxr-xr-x | tests/46-sim-kill_process.py | 46 | ||||
-rw-r--r-- | tests/46-sim-kill_process.tests | 16 | ||||
-rw-r--r-- | tests/47-live-kill_process.c | 105 | ||||
-rwxr-xr-x | tests/47-live-kill_process.py | 68 | ||||
-rw-r--r-- | tests/47-live-kill_process.tests | 11 | ||||
-rw-r--r-- | tests/Makefile.am | 14 | ||||
-rwxr-xr-x | tests/regression | 7 | ||||
-rw-r--r-- | tests/util.c | 2 |
15 files changed, 360 insertions, 6 deletions
diff --git a/tests/.gitignore b/tests/.gitignore index 1ead61f..abe2bea 100644 --- a/tests/.gitignore +++ b/tests/.gitignore @@ -51,3 +51,5 @@ util.pyc 43-sim-a2_order 44-live-a2_order 45-sim-chain_code_coverage +46-sim-kill_process +47-live-kill_process diff --git a/tests/06-sim-actions.c b/tests/06-sim-actions.c index d81e521..10b366c 100644 --- a/tests/06-sim-actions.c +++ b/tests/06-sim-actions.c @@ -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 e3f91e9..f14d6ed 100755 --- a/tests/06-sim-actions.py +++ b/tests/06-sim-actions.py @@ -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 1402e21..40a93ae 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 c17e2ff..e680afc 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(3); + if (rc != 0) + return EOPNOTSUPP; + ctx = seccomp_init(SCMP_ACT_ALLOW); if (ctx == NULL) { rc = ENOMEM; @@ -80,6 +84,9 @@ int main(int argc, char *argv[]) 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; /* verify the prioritized, but no-rule, syscall */ rc = seccomp_syscall_priority(ctx, SCMP_SYS(poll), 255); diff --git a/tests/38-basic-pfc_coverage.pfc b/tests/38-basic-pfc_coverage.pfc index a0c31ac..a9a7019 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/46-sim-kill_process.c b/tests/46-sim-kill_process.c new file mode 100644 index 0000000..7ab0725 --- /dev/null +++ b/tests/46-sim-kill_process.c @@ -0,0 +1,74 @@ +/** + * Seccomp Library test program + * + * Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. + * Author: Tom Hromatka <tom.hromatka@oracle.com> + */ + +/* + * 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 <http://www.gnu.org/licenses>. + */ + +#include <errno.h> +#include <unistd.h> + +#include <seccomp.h> + +#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 = seccomp_rule_add(ctx, SCMP_ACT_ERRNO(6), SCMP_SYS(close), 1, + SCMP_A0(SCMP_CMP_GT, 100)); + 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/46-sim-kill_process.py b/tests/46-sim-kill_process.py new file mode 100755 index 0000000..7b425bb --- /dev/null +++ b/tests/46-sim-kill_process.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka <tom.hromatka@oracle.com> +# + +# +# 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 <http://www.gnu.org/licenses>. +# + +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") + f.add_rule_exactly(ERRNO(6), "close", Arg(0, GT, 100)) + 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/46-sim-kill_process.tests b/tests/46-sim-kill_process.tests new file mode 100644 index 0000000..f31a378 --- /dev/null +++ b/tests/46-sim-kill_process.tests @@ -0,0 +1,16 @@ +# +# libseccomp regression test automation data +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka <tom.hromatka@oracle.com> +# + +test type: bpf-sim + +# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result +46-sim-kill_process +x86_64 0 N N N N N N ALLOW +46-sim-kill_process +x86_64 1 N N N N N N ERRNO(5) +46-sim-kill_process +x86_64 2 N N N N N N KILL +46-sim-kill_process +x86_64 3 100 N N N N N KILL_PROCESS +46-sim-kill_process +x86_64 3 101 N N N N N ERRNO(6) +46-sim-kill_process +x86_64 4 N N N N N N KILL_PROCESS diff --git a/tests/47-live-kill_process.c b/tests/47-live-kill_process.c new file mode 100644 index 0000000..0311855 --- /dev/null +++ b/tests/47-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 <tom.hromatka@oracle.com> + */ + +/* + * 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 <http://www.gnu.org/licenses>. + */ + +#include <errno.h> +#include <fcntl.h> +#include <pthread.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <unistd.h> + +#include <seccomp.h> + +#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/47-live-kill_process.py b/tests/47-live-kill_process.py new file mode 100755 index 0000000..8c62ee7 --- /dev/null +++ b/tests/47-live-kill_process.py @@ -0,0 +1,68 @@ +#!/usr/bin/env python + +# +# Seccomp Library test program +# +# Copyright (c) 2018 Oracle and/or its affiliates. All rights reserved. +# Author: Tom Hromatka <tom.hromatka@oracle.com> +# + +# +# 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 <http://www.gnu.org/licenses>. +# + +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/47-live-kill_process.tests b/tests/47-live-kill_process.tests new file mode 100644 index 0000000..505349a --- /dev/null +++ b/tests/47-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 <tom.hromatka@oracle.com> +# + +test type: live + +# Testname Result +47-live-kill_process KILL_PROCESS diff --git a/tests/Makefile.am b/tests/Makefile.am index e3762ff..07e1654 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} @@ -84,7 +84,9 @@ check_PROGRAMS = \ 42-sim-adv_chains \ 43-sim-a2_order \ 44-live-a2_order \ - 45-sim-chain_code_coverage + 45-sim-chain_code_coverage \ + 46-sim-kill_process \ + 47-live-kill_process EXTRA_DIST_TESTPYTHON = \ util.py \ @@ -131,7 +133,9 @@ EXTRA_DIST_TESTPYTHON = \ 42-sim-adv_chains.py \ 43-sim-a2_order.py \ 44-live-a2_order.py \ - 45-sim-chain_code_coverage.py + 45-sim-chain_code_coverage.py \ + 46-sim-kill_process.py \ + 47-live-kill_process.py EXTRA_DIST_TESTCFGS = \ 01-sim-allow.tests \ @@ -178,7 +182,9 @@ EXTRA_DIST_TESTCFGS = \ 42-sim-adv_chains.tests \ 43-sim-a2_order.tests \ 44-live-a2_order.tests \ - 45-sim-chain_code_coverage.tests + 45-sim-chain_code_coverage.tests \ + 46-sim-kill_process.tests \ + 47-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 3c8ab51..4141399 100755 --- a/tests/regression +++ b/tests/regression @@ -729,6 +729,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 @@ -737,6 +738,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 @@ -752,7 +754,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 f079a53..a84e475 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) |