Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions doc/man/man3/seccomp_api_get.3
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,9 @@ The SCMP_FLTATR_CTL_TSYNC filter attribute is supported and libseccomp uses
the
.BR seccomp(2)
syscall to load the seccomp filter into the kernel.
.TP
.B 3
The SCMP_FLTATR_CTL_LOG filter attribute and the SCMP_ACT_LOG action are supported.
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
Expand Down
8 changes: 8 additions & 0 deletions doc/man/man3/seccomp_attr_set.3
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,14 @@ specific syscall invocations, see
for more information. Defaults to off (
.I value
== 0).
.TP
.B SCMP_FLTATR_CTL_LOG
A flag to specify if the kernel should log all filter actions taken except for
the
.BR SCMP_ACT_ALLOW
action. Defaults to off (
.I value
== 0).
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
Expand Down
5 changes: 5 additions & 0 deletions doc/man/man3/seccomp_init.3
Original file line number Diff line number Diff line change
Expand Up @@ -79,6 +79,11 @@ can be retrieved using the
.B PTRACE_GETEVENTMSG
option.
.TP
.B SCMP_ACT_LOG
The seccomp filter will have no effect on the thread calling the syscall if it
does not match any of the configured seccomp filter rules but the syscall will
be logged.
.TP
.B SCMP_ACT_ALLOW
The seccomp filter will have no effect on the thread calling the syscall if it
does not match any of the configured seccomp filter rules.
Expand Down
4 changes: 4 additions & 0 deletions doc/man/man3/seccomp_rule_add.3
Original file line number Diff line number Diff line change
Expand Up @@ -133,6 +133,10 @@ can be retrieved using the
.B PTRACE_GETEVENTMSG
option.
.TP
.B SCMP_ACT_LOG
The seccomp filter will have no effect on the thread calling the syscall if it
matches the filter rule but the syscall will be logged.
.TP
.B SCMP_ACT_ALLOW
The seccomp filter will have no effect on the thread calling the syscall if it
matches the filter rule.
Expand Down
7 changes: 7 additions & 0 deletions include/seccomp.h.in
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ enum scmp_filter_attr {
SCMP_FLTATR_CTL_NNP = 3, /**< set NO_NEW_PRIVS on filter load */
SCMP_FLTATR_CTL_TSYNC = 4, /**< sync threads on filter load */
SCMP_FLTATR_API_TSKIP = 5, /**< allow rules with a -1 syscall */
SCMP_FLTATR_CTL_LOG = 6, /**< log not-allowed actions */
_SCMP_FLTATR_MAX,
};

Expand Down Expand Up @@ -256,6 +257,10 @@ struct scmp_arg_cmp {
* Notify a tracing process with the specified value
*/
#define SCMP_ACT_TRACE(x) (0x7ff00000U | ((x) & 0x0000ffffU))
/**
* Allow the syscall to be executed after the action has been logged
*/
#define SCMP_ACT_LOG 0x7ffc0000U
/**
* Allow the syscall to be executed
*/
Expand Down Expand Up @@ -290,6 +295,8 @@ const struct scmp_version *seccomp_version(void);
* 1 : base level
* 2 : support for the SCMP_FLTATR_CTL_TSYNC filter attribute
* 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
*
*/
const unsigned int seccomp_api_get(void);
Expand Down
16 changes: 16 additions & 0 deletions src/api.c
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,12 @@ static unsigned int _seccomp_api_update(void)
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC) == 1)
level = 2;

/* level 3 */
if (level == 2 &&
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG) == 1 &&
sys_chk_seccomp_action(SCMP_ACT_LOG) == 1)
level = 3;

/* update the stored api level and return */
seccomp_api_level = level;
return seccomp_api_level;
Expand All @@ -127,10 +133,20 @@ API int seccomp_api_set(unsigned int level)
case 1:
sys_set_seccomp_syscall(false);
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);
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);
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);
break;
default:
return -EINVAL;
Expand Down
26 changes: 15 additions & 11 deletions src/db.c
Original file line number Diff line number Diff line change
Expand Up @@ -660,18 +660,8 @@ void db_col_release(struct db_filter_col *col)
*/
int db_action_valid(uint32_t action)
{
if (action == SCMP_ACT_KILL)
if (sys_chk_seccomp_action(action) == 1)
return 0;
else if (action == SCMP_ACT_TRAP)
return 0;
else if ((action == SCMP_ACT_ERRNO(action & 0x0000ffff)) &&
((action & 0x0000ffff) < MAX_ERRNO))
return 0;
else if (action == SCMP_ACT_TRACE(action & 0x0000ffff))
return 0;
else if (action == SCMP_ACT_ALLOW)
return 0;

return -EINVAL;
}

Expand Down Expand Up @@ -792,6 +782,9 @@ int db_col_attr_get(const struct db_filter_col *col,
case SCMP_FLTATR_API_TSKIP:
*value = col->attr.api_tskip;
break;
case SCMP_FLTATR_CTL_LOG:
*value = col->attr.log_enable;
break;
default:
rc = -EEXIST;
break;
Expand Down Expand Up @@ -842,6 +835,17 @@ int db_col_attr_set(struct db_filter_col *col,
case SCMP_FLTATR_API_TSKIP:
col->attr.api_tskip = (value ? 1 : 0);
break;
case SCMP_FLTATR_CTL_LOG:
rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_LOG);
if (rc == 1) {
/* supported */
rc = 0;
col->attr.log_enable = (value ? 1 : 0);
} else if (rc == 0) {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Another make check-syntax question, does it allow these curly braces?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it does.

/* unsupported */
rc = -EOPNOTSUPP;
}
break;
default:
rc = -EEXIST;
break;
Expand Down
2 changes: 2 additions & 0 deletions src/db.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,8 @@ struct db_filter_attr {
uint32_t tsync_enable;
/* allow rules with a -1 syscall value */
uint32_t api_tskip;
/* SECCOMP_FILTER_FLAG_LOG related attributes */
uint32_t log_enable;
};

struct db_filter {
Expand Down
3 changes: 3 additions & 0 deletions src/gen_pfc.c
Original file line number Diff line number Diff line change
Expand Up @@ -130,6 +130,9 @@ static void _pfc_action(FILE *fds, uint32_t action)
case SCMP_ACT_TRACE(0):
fprintf(fds, "action TRACE(%u);\n", (action & 0x0000ffff));
break;
case SCMP_ACT_LOG:
fprintf(fds, "action LOG;\n");
break;
case SCMP_ACT_ALLOW:
fprintf(fds, "action ALLOW;\n");
break;
Expand Down
2 changes: 2 additions & 0 deletions src/python/libseccomp.pxd
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ cdef extern from "seccomp.h":
SCMP_FLTATR_CTL_NNP
SCMP_FLTATR_CTL_TSYNC
SCMP_FLTATR_API_TSKIP
SCMP_FLTATR_CTL_LOG

cdef enum scmp_compare:
SCMP_CMP_NE
Expand All @@ -70,6 +71,7 @@ cdef extern from "seccomp.h":
cdef enum:
SCMP_ACT_KILL
SCMP_ACT_TRAP
SCMP_ACT_LOG
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes and I will be submitting a PR against libseccomp-golang once the dust settles on this PR.

SCMP_ACT_ALLOW
unsigned int SCMP_ACT_ERRNO(int errno)
unsigned int SCMP_ACT_TRACE(int value)
Expand Down
7 changes: 5 additions & 2 deletions src/python/seccomp.pyx
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ by application developers.

Filter action values:
KILL - kill the process
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
ERRNO(x) - syscall will return (x)
Expand Down Expand Up @@ -95,6 +96,7 @@ def c_str(string):

KILL = libseccomp.SCMP_ACT_KILL
TRAP = libseccomp.SCMP_ACT_TRAP
LOG = libseccomp.SCMP_ACT_LOG
ALLOW = libseccomp.SCMP_ACT_ALLOW
def ERRNO(int errno):
"""The action ERRNO(x) means that the syscall will return (x).
Expand Down Expand Up @@ -303,6 +305,7 @@ cdef class Attr:
CTL_NNP = libseccomp.SCMP_FLTATR_CTL_NNP
CTL_TSYNC = libseccomp.SCMP_FLTATR_CTL_TSYNC
API_TSKIP = libseccomp.SCMP_FLTATR_API_TSKIP
CTL_LOG = libseccomp.SCMP_FLTATR_CTL_LOG

cdef class Arg:
""" Python object representing a SyscallFilter syscall argument.
Expand Down Expand Up @@ -542,7 +545,7 @@ cdef class SyscallFilter:
""" Add a new rule to filter.

Arguments:
action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW
action - the rule action: KILL, TRAP, ERRNO(), TRACE(), LOG, or ALLOW
syscall - the syscall name or number
args - variable number of Arg objects

Expand Down Expand Up @@ -624,7 +627,7 @@ cdef class SyscallFilter:
""" Add a new rule to filter.

Arguments:
action - the rule action: KILL, TRAP, ERRNO(), TRACE(), or ALLOW
action - the rule action: KILL, TRAP, ERRNO(), TRACE(), LOG, or ALLOW
syscall - the syscall name or number
args - variable number of Arg objects

Expand Down
95 changes: 88 additions & 7 deletions src/system.c
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,8 @@
static int _nr_seccomp = -1;
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;

/**
* Check to see if the seccomp() syscall is supported
Expand Down Expand Up @@ -111,6 +113,78 @@ void sys_set_seccomp_syscall(bool enable)
_support_seccomp_syscall = (enable ? 1 : 0);
}

/**
* Check to see if a seccomp action is supported
* @param action the seccomp action
*
* This function checks to see if a seccomp action is supported by the system.
* Return one if the action is supported, zero otherwise.
*
*/
int sys_chk_seccomp_action(uint32_t action)
{
if (action == SCMP_ACT_KILL) {
return 1;
} else if (action == SCMP_ACT_TRAP) {
return 1;
} else if ((action == SCMP_ACT_ERRNO(action & 0x0000ffff)) &&
((action & 0x0000ffff) < MAX_ERRNO)) {
return 1;
} else if (action == SCMP_ACT_TRACE(action & 0x0000ffff)) {
return 1;
} else if (action == SCMP_ACT_LOG) {
if (_support_seccomp_action_log < 0) {
if (sys_chk_seccomp_syscall() == 1 &&
syscall(_nr_seccomp, SECCOMP_GET_ACTION_AVAIL, 0,
&action) == 0)
_support_seccomp_action_log = 1;
else
_support_seccomp_action_log = 0;
}

return _support_seccomp_action_log;
} else if (action == SCMP_ACT_ALLOW) {
return 1;
}

return 0;
}

/**
* Force a seccomp action support setting
* @param action the seccomp action
* @param enable the intended support state
*
* This function overrides the current seccomp action support setting; this
* is very much a "use at your own risk" function.
*/
void sys_set_seccomp_action(uint32_t action, bool enable)
{
if (action == SCMP_ACT_LOG)
_support_seccomp_action_log = (enable ? 1 : 0);
}

/**
* Check to see if a seccomp() flag is supported by the kernel
* @param flag the seccomp() flag
*
* This function checks to see if a seccomp() flag is supported by the kernel.
* Return one if the flag is supported, zero otherwise.
*
*/
static int _sys_chk_seccomp_flag_kernel(int flag)
{
/* this is an invalid seccomp(2) call because the last argument
* is NULL, but depending on the errno value of EFAULT we can
* guess if the filter flag is supported or not */
if (sys_chk_seccomp_syscall() == 1 &&
syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flag, NULL) == -1 &&
errno == EFAULT)
return 1;

return 0;
}

/**
* Check to see if a seccomp() flag is supported
* @param flag the seccomp() flag
Expand All @@ -122,15 +196,17 @@ void sys_set_seccomp_syscall(bool enable)
*/
int sys_chk_seccomp_flag(int flag)
{
int rc;

switch (flag) {
case SECCOMP_FILTER_FLAG_TSYNC:
if (_support_seccomp_flag_tsync < 0) {
rc = sys_chk_seccomp_syscall();
_support_seccomp_flag_tsync = (rc == 1 ? 1 : 0);
}
if (_support_seccomp_flag_tsync < 0)
_support_seccomp_flag_tsync = _sys_chk_seccomp_flag_kernel(flag);

return _support_seccomp_flag_tsync;
case SECCOMP_FILTER_FLAG_LOG:
if (_support_seccomp_flag_log < 0)
_support_seccomp_flag_log = _sys_chk_seccomp_flag_kernel(flag);

return _support_seccomp_flag_log;
}

return -EOPNOTSUPP;
Expand All @@ -151,6 +227,9 @@ void sys_set_seccomp_flag(int flag, bool enable)
case SECCOMP_FILTER_FLAG_TSYNC:
_support_seccomp_flag_tsync = (enable ? 1 : 0);
break;
case SECCOMP_FILTER_FLAG_LOG:
_support_seccomp_flag_log = (enable ? 1 : 0);
break;
}
}

Expand Down Expand Up @@ -184,7 +263,9 @@ int sys_filter_load(const struct db_filter_col *col)
if (sys_chk_seccomp_syscall() == 1) {
int flgs = 0;
if (col->attr.tsync_enable)
flgs = SECCOMP_FILTER_FLAG_TSYNC;
flgs |= SECCOMP_FILTER_FLAG_TSYNC;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would just merge this patch into the other patch, there really is no reason for this to be a standalone commit.

if (col->attr.log_enable)
flgs |= SECCOMP_FILTER_FLAG_LOG;
rc = syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flgs, prgm);
if (rc > 0 && col->attr.tsync_enable)
/* always return -ESRCH if we fail to sync threads */
Expand Down
13 changes: 13 additions & 0 deletions src/system.h
Original file line number Diff line number Diff line change
Expand Up @@ -102,15 +102,28 @@ typedef struct sock_filter bpf_instr_raw;
#ifndef SECCOMP_SET_MODE_FILTER
#define SECCOMP_SET_MODE_FILTER 1
#endif
#ifndef SECCOMP_GET_ACTION_AVAIL
#define SECCOMP_GET_ACTION_AVAIL 2
#endif

/* flags for the seccomp() syscall */
#ifndef SECCOMP_FILTER_FLAG_TSYNC
#define SECCOMP_FILTER_FLAG_TSYNC 1
#endif
#ifndef SECCOMP_FILTER_FLAG_LOG
#define SECCOMP_FILTER_FLAG_LOG 2
#endif

#ifndef SECCOMP_RET_LOG
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
#endif

int sys_chk_seccomp_syscall(void);
void sys_set_seccomp_syscall(bool enable);

int sys_chk_seccomp_action(uint32_t action);
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm also wondering if we need a sys_set_seccomp_action(...) function.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We do need one. It gets added in the all: add support for new log action patch.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ah ha, found it later in the patchset. It probably should be included here, but not the end of the world.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It sounds like you're not requiring the patchset surgery needed to move sys_set_seccomp_action() up a patch in the series so I'm going to opt for leaving it where it is at rather than risk making a mistake since we seem to be close to merging this. Let me know if that's a problem.

void sys_set_seccomp_action(uint32_t action, bool enable);

int sys_chk_seccomp_flag(int flag);
void sys_set_seccomp_flag(int flag, bool enable);

Expand Down
Loading