summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2017-10-18 06:16:52 +0000
committerPaul Moore <paul@paul-moore.com>2017-11-01 12:48:14 -0400
commitd0e11951f6484db5d8e98591ddc0c0157b333d85 (patch)
tree0402519270e14ee916dfa31503505bc49037bdd7
parent8a8576c9e0cf463d2d624686a4e57058ae30e91a (diff)
downloadlibseccomp-d0e11951f6484db5d8e98591ddc0c0157b333d85.tar.gz
all: add support for new log filter flag
Extend libseccomp to support SECCOMP_FILTER_FLAG_LOG, which is intended to cause log events for all actions taken by a filter except for SCMP_ACT_ALLOW actions. This is done via a new filter attribute called SCMP_FLTATR_CTL_LOG that is off by default. Signed-off-by: Tyler Hicks <tyhicks@canonical.com> Signed-off-by: Paul Moore <paul@paul-moore.com>
-rw-r--r--doc/man/man3/seccomp_api_get.33
-rw-r--r--doc/man/man3/seccomp_attr_set.38
-rw-r--r--include/seccomp.h.in2
-rw-r--r--src/api.c12
-rw-r--r--src/db.c14
-rw-r--r--src/db.h2
-rw-r--r--src/python/libseccomp.pxd1
-rw-r--r--src/python/seccomp.pyx1
-rw-r--r--src/system.c13
-rw-r--r--src/system.h3
-rw-r--r--tests/13-basic-attrs.c15
-rwxr-xr-xtests/13-basic-attrs.py5
-rw-r--r--tests/39-basic-api_level.c13
-rwxr-xr-xtests/39-basic-api_level.py7
14 files changed, 94 insertions, 5 deletions
diff --git a/doc/man/man3/seccomp_api_get.3 b/doc/man/man3/seccomp_api_get.3
index a209dcc..b6c0453 100644
--- a/doc/man/man3/seccomp_api_get.3
+++ b/doc/man/man3/seccomp_api_get.3
@@ -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 is supported.
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
diff --git a/doc/man/man3/seccomp_attr_set.3 b/doc/man/man3/seccomp_attr_set.3
index 091d6d1..7050d5f 100644
--- a/doc/man/man3/seccomp_attr_set.3
+++ b/doc/man/man3/seccomp_attr_set.3
@@ -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
.\" //////////////////////////////////////////////////////////////////////////
diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 350a840..014a2d7 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -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,
};
@@ -290,6 +291,7 @@ 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
*
*/
const unsigned int seccomp_api_get(void);
diff --git a/src/api.c b/src/api.c
index 8d01738..3c65031 100644
--- a/src/api.c
+++ b/src/api.c
@@ -102,6 +102,11 @@ 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)
+ level = 3;
+
/* update the stored api level and return */
seccomp_api_level = level;
return seccomp_api_level;
@@ -127,10 +132,17 @@ 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);
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);
+ 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);
break;
default:
return -EINVAL;
diff --git a/src/db.c b/src/db.c
index 3ea8d64..e194089 100644
--- a/src/db.c
+++ b/src/db.c
@@ -792,6 +792,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;
@@ -842,6 +845,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) {
+ /* unsupported */
+ rc = -EOPNOTSUPP;
+ }
+ break;
default:
rc = -EEXIST;
break;
diff --git a/src/db.h b/src/db.h
index c4ad549..b82491a 100644
--- a/src/db.h
+++ b/src/db.h
@@ -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 {
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index b851d25..4cc83fd 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -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
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 27e374f..dbf0e0a 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -303,6 +303,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.
diff --git a/src/system.c b/src/system.c
index 4ff641b..f84cab6 100644
--- a/src/system.c
+++ b/src/system.c
@@ -41,6 +41,7 @@
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;
/**
* Check to see if the seccomp() syscall is supported
@@ -149,6 +150,11 @@ int sys_chk_seccomp_flag(int flag)
_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;
@@ -169,6 +175,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;
}
}
@@ -202,7 +211,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;
+ 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 */
diff --git a/src/system.h b/src/system.h
index 0e2cd82..edddf14 100644
--- a/src/system.h
+++ b/src/system.h
@@ -107,6 +107,9 @@ typedef struct sock_filter bpf_instr_raw;
#ifndef SECCOMP_FILTER_FLAG_TSYNC
#define SECCOMP_FILTER_FLAG_TSYNC 1
#endif
+#ifndef SECCOMP_FILTER_FLAG_LOG
+#define SECCOMP_FILTER_FLAG_LOG 2
+#endif
int sys_chk_seccomp_syscall(void);
void sys_set_seccomp_syscall(bool enable);
diff --git a/tests/13-basic-attrs.c b/tests/13-basic-attrs.c
index bbb6765..0fe4755 100644
--- a/tests/13-basic-attrs.c
+++ b/tests/13-basic-attrs.c
@@ -32,6 +32,10 @@ int main(int argc, char *argv[])
uint32_t val = (uint32_t)(-1);
scmp_filter_ctx ctx = NULL;
+ rc = seccomp_api_set(3);
+ if (rc != 0)
+ return EOPNOTSUPP;
+
ctx = seccomp_init(SCMP_ACT_ALLOW);
if (ctx == NULL)
return ENOMEM;
@@ -93,6 +97,17 @@ int main(int argc, char *argv[])
goto out;
}
+ rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_LOG, 1);
+ if (rc != 0)
+ goto out;
+ rc = seccomp_attr_get(ctx, SCMP_FLTATR_CTL_LOG, &val);
+ if (rc != 0)
+ goto out;
+ if (val != 1) {
+ rc = -1;
+ goto out;
+ }
+
rc = 0;
out:
seccomp_release(ctx);
diff --git a/tests/13-basic-attrs.py b/tests/13-basic-attrs.py
index 8133942..49759ee 100755
--- a/tests/13-basic-attrs.py
+++ b/tests/13-basic-attrs.py
@@ -29,6 +29,8 @@ import util
from seccomp import *
def test():
+ set_api(3)
+
f = SyscallFilter(ALLOW)
if f.get_attr(Attr.ACT_DEFAULT) != ALLOW:
raise RuntimeError("Failed getting Attr.ACT_DEFAULT")
@@ -47,6 +49,9 @@ def test():
f.set_attr(Attr.API_TSKIP, 0)
if f.get_attr(Attr.API_TSKIP) != 0:
raise RuntimeError("Failed getting Attr.API_TSKIP")
+ f.set_attr(Attr.CTL_LOG, 1)
+ if f.get_attr(Attr.CTL_LOG) != 1:
+ raise RuntimeError("Failed getting Attr.CTL_LOG")
test()
diff --git a/tests/39-basic-api_level.c b/tests/39-basic-api_level.c
index 18c082a..9ce3b41 100644
--- a/tests/39-basic-api_level.c
+++ b/tests/39-basic-api_level.c
@@ -47,14 +47,21 @@ int main(int argc, char *argv[])
if (api != 2)
return -5;
+ rc = seccomp_api_set(3);
+ if (rc != 0)
+ return -6;
+ api = seccomp_api_get();
+ if (api != 3)
+ return -7;
+
/* Attempt to set a high, invalid API level */
rc = seccomp_api_set(1024);
if (rc != -EINVAL)
- return -6;
+ return -8;
/* Ensure that the previously set API level didn't change */
api = seccomp_api_get();
- if (api != 2)
- return -7;
+ if (api != 3)
+ return -9;
return 0;
}
diff --git a/tests/39-basic-api_level.py b/tests/39-basic-api_level.py
index 49d23f2..9c40c33 100755
--- a/tests/39-basic-api_level.py
+++ b/tests/39-basic-api_level.py
@@ -45,6 +45,11 @@ def test():
if api != 2:
raise RuntimeError("Failed getting API level 2")
+ set_api(3)
+ api = get_api()
+ if api != 3:
+ raise RuntimeError("Failed getting API level 3")
+
# Attempt to set a high, invalid API level
try:
set_api(1024)
@@ -54,7 +59,7 @@ def test():
raise RuntimeError("Missing failure when setting invalid API level")
# Ensure that the previously set API level didn't change
api = get_api()
- if api != 2:
+ if api != 3:
raise RuntimeError("Failed getting old API level after setting an invalid API level")
test()