Skip to content

Commit

Permalink
Merge 778e199 into a6cc633
Browse files Browse the repository at this point in the history
  • Loading branch information
drakenclimber committed Feb 23, 2018
2 parents a6cc633 + 778e199 commit 92c44d2
Show file tree
Hide file tree
Showing 27 changed files with 439 additions and 21 deletions.
4 changes: 4 additions & 0 deletions doc/man/man3/seccomp_init.3
Expand Up @@ -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
Expand Down
4 changes: 4 additions & 0 deletions doc/man/man3/seccomp_rule_add.3
Expand Up @@ -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.
Expand Down
11 changes: 10 additions & 1 deletion include/seccomp.h.in
Expand Up @@ -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
*/
Expand Down Expand Up @@ -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);
Expand Down
10 changes: 10 additions & 0 deletions src/api.c
Expand Up @@ -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;
Expand Down
8 changes: 6 additions & 2 deletions src/gen_pfc.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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:
Expand Down
1 change: 1 addition & 0 deletions src/python/libseccomp.pxd
Expand Up @@ -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
Expand Down
10 changes: 7 additions & 3 deletions src/python/seccomp.pyx
Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down
16 changes: 15 additions & 1 deletion src/system.c
Expand Up @@ -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
Expand Down Expand Up @@ -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;
Expand Down Expand Up @@ -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);
}

/**
Expand Down
12 changes: 11 additions & 1 deletion src/system.h
Expand Up @@ -37,6 +37,13 @@ struct db_filter_col;
/* system header file */
#include <linux/seccomp.h>

/* 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 */
Expand All @@ -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

Expand Down
2 changes: 2 additions & 0 deletions tests/.gitignore
Expand Up @@ -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
6 changes: 5 additions & 1 deletion tests/06-sim-actions.c
Expand Up @@ -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;

Expand Down Expand Up @@ -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;
Expand Down
3 changes: 2 additions & 1 deletion tests/06-sim-actions.py
Expand Up @@ -30,14 +30,15 @@
from seccomp import *

def test(args):
set_api(3)
set_api(4)

f = SyscallFilter(KILL)
f.add_rule(ALLOW, "read")
f.add_rule(LOG, "rt_sigreturn")
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()
Expand Down
3 changes: 2 additions & 1 deletion tests/06-sim-actions.tests
Expand Up @@ -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
Expand Down
7 changes: 7 additions & 0 deletions tests/38-basic-pfc_coverage.c
Expand Up @@ -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;
Expand Down Expand Up @@ -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;

Expand Down
6 changes: 6 additions & 0 deletions tests/38-basic-pfc_coverage.pfc
Expand Up @@ -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);
Expand Down Expand Up @@ -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);
Expand Down
69 changes: 69 additions & 0 deletions 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 <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 = util_filter_output(&opts, ctx);
if (rc)
goto out;

out:
seccomp_release(ctx);
return (rc < 0 ? -rc : rc);
}

0 comments on commit 92c44d2

Please sign in to comment.