summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Moore <paul@paul-moore.com>2022-10-31 13:21:33 -0600
committerTom Hromatka <tom.hromatka@oracle.com>2022-10-31 13:21:47 -0600
commit96989965042a515a3cbcb50e9b98243b9b7d4c37 (patch)
tree98fe9472c53c05575d4841b1bc6df61d3e35b368
parente797591bdd6834272e2db292400f608ed9bd7fab (diff)
downloadlibseccomp-96989965042a515a3cbcb50e9b98243b9b7d4c37.tar.gz
api: add the SCMP_FLTATR_CTL_WAITKILL filter attribute
The SCMP_FLTATR_CTL_WAITKILL attribute requests that the SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV flag be passed to the seccomp(2) system call when possible, which is currently only when the SECCOMP_FILTER_FLAG_NEW_LISTENER flag is also set. Signed-off-by: Paul Moore <paul@paul-moore.com> Signed-off-by: Tom Hromatka <tom.hromatka@oracle.com>
-rw-r--r--doc/man/man3/seccomp_api_get.35
-rw-r--r--doc/man/man3/seccomp_attr_set.38
-rw-r--r--include/seccomp.h.in2
-rw-r--r--src/api.c29
-rw-r--r--src/db.c7
-rw-r--r--src/db.h2
-rw-r--r--src/python/libseccomp.pxd1
-rw-r--r--src/python/seccomp.pyx2
-rw-r--r--src/system.c12
-rw-r--r--src/system.h3
-rw-r--r--tests/13-basic-attrs.c11
-rwxr-xr-xtests/13-basic-attrs.py3
-rw-r--r--tests/39-basic-api_level.c9
-rwxr-xr-xtests/39-basic-api_level.py7
14 files changed, 97 insertions, 4 deletions
diff --git a/doc/man/man3/seccomp_api_get.3 b/doc/man/man3/seccomp_api_get.3
index ea2ea75..549cce1 100644
--- a/doc/man/man3/seccomp_api_get.3
+++ b/doc/man/man3/seccomp_api_get.3
@@ -1,4 +1,4 @@
-.TH "seccomp_api_get" 3 "6 November 2020" "paul@paul-moore.com" "libseccomp Documentation"
+.TH "seccomp_api_get" 3 "22 September 2022" "paul@paul-moore.com" "libseccomp Documentation"
.\" //////////////////////////////////////////////////////////////////////////
.SH NAME
.\" //////////////////////////////////////////////////////////////////////////
@@ -60,6 +60,9 @@ The SCMP_ACT_NOTIFY action and the notify APIs are supported.
.TP
.B 6
The simultaneous use of SCMP_FLTATR_CTL_TSYNC and the notify APIs are supported.
+.TP
+.B 7
+The SCMP_FLTATR_CTL_WAITKILL 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 4341abc..571010e 100644
--- a/doc/man/man3/seccomp_attr_set.3
+++ b/doc/man/man3/seccomp_attr_set.3
@@ -1,4 +1,4 @@
-.TH "seccomp_attr_set" 3 "06 June 2020" "paul@paul-moore.com" "libseccomp Documentation"
+.TH "seccomp_attr_set" 3 "21 September 2022" "paul@paul-moore.com" "libseccomp Documentation"
.\" //////////////////////////////////////////////////////////////////////////
.SH NAME
.\" //////////////////////////////////////////////////////////////////////////
@@ -132,6 +132,12 @@ A flag to specify if libseccomp should pass system error codes back to the
caller instead of the default -ECANCELED. Defaults to off
.RI ( value
== 0).
+.TP
+.B SCMP_FLTATR_CTL_WAITKILL
+A flag to specify if libseccomp should request wait killable semantics when
+possible. Defaults to off
+.RI ( value
+== 0).
.\" //////////////////////////////////////////////////////////////////////////
.SH RETURN VALUE
.\" //////////////////////////////////////////////////////////////////////////
diff --git a/include/seccomp.h.in b/include/seccomp.h.in
index 6f4929b..dfbb267 100644
--- a/include/seccomp.h.in
+++ b/include/seccomp.h.in
@@ -78,6 +78,7 @@ enum scmp_filter_attr {
* number
*/
SCMP_FLTATR_API_SYSRAWRC = 9, /**< return the system return codes */
+ SCMP_FLTATR_CTL_WAITKILL = 10, /**< request wait killable semantics */
_SCMP_FLTATR_MAX,
};
@@ -424,6 +425,7 @@ const struct scmp_version *seccomp_version(void);
* 4 : support for the SCMP_FLTATR_CTL_SSB filter attribute
* 5 : support for the SCMP_ACT_NOTIFY action and notify APIs
* 6 : support the simultaneous use of SCMP_FLTATR_CTL_TSYNC and notify APIs
+ * 7 : support for the SCMP_FLTATR_CTL_WAITKILL filter attribute
*
*/
unsigned int seccomp_api_get(void);
diff --git a/src/api.c b/src/api.c
index 9c2f64a..b85e3b8 100644
--- a/src/api.c
+++ b/src/api.c
@@ -191,6 +191,10 @@ static unsigned int _seccomp_api_update(void)
sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH) == 1)
level = 6;
+ if (level == 6 &&
+ sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV) == 1)
+ level = 7;
+
/* update the stored api level and return */
seccomp_api_level = level;
return seccomp_api_level;
@@ -223,6 +227,8 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
break;
case 2:
sys_set_seccomp_syscall(true);
@@ -234,6 +240,8 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
break;
case 3:
sys_set_seccomp_syscall(true);
@@ -245,6 +253,8 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
break;
case 4:
sys_set_seccomp_syscall(true);
@@ -256,6 +266,8 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, false);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, false);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
break;
case 5:
sys_set_seccomp_syscall(true);
@@ -267,6 +279,8 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, false);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
break;
case 6:
sys_set_seccomp_syscall(true);
@@ -278,6 +292,21 @@ API int seccomp_api_set(unsigned int level)
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ false);
+ break;
+ case 7:
+ 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);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_NEW_LISTENER, true);
+ sys_set_seccomp_action(SCMP_ACT_NOTIFY, true);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC_ESRCH, true);
+ sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV,
+ true);
break;
default:
return _rc_filter(-EINVAL);
diff --git a/src/db.c b/src/db.c
index 6d81874..02d462e 100644
--- a/src/db.c
+++ b/src/db.c
@@ -1072,6 +1072,7 @@ int db_col_reset(struct db_filter_col *col, uint32_t def_action)
col->attr.spec_allow = 0;
col->attr.optimize = 1;
col->attr.api_sysrawrc = 0;
+ col->attr.wait_killable_recv = 0;
/* set the state */
col->state = _DB_STA_VALID;
@@ -1331,6 +1332,9 @@ int db_col_attr_get(const struct db_filter_col *col,
case SCMP_FLTATR_API_SYSRAWRC:
*value = col->attr.api_sysrawrc;
break;
+ case SCMP_FLTATR_CTL_WAITKILL:
+ *value = col->attr.wait_killable_recv;
+ break;
default:
rc = -EINVAL;
break;
@@ -1444,6 +1448,9 @@ int db_col_attr_set(struct db_filter_col *col,
case SCMP_FLTATR_API_SYSRAWRC:
col->attr.api_sysrawrc = (value ? 1 : 0);
break;
+ case SCMP_FLTATR_CTL_WAITKILL:
+ col->attr.wait_killable_recv = (value ? 1 : 0);
+ break;
default:
rc = -EINVAL;
break;
diff --git a/src/db.h b/src/db.h
index 9a41427..906a857 100644
--- a/src/db.h
+++ b/src/db.h
@@ -124,6 +124,8 @@ struct db_filter_attr {
uint32_t optimize;
/* return the raw system return codes */
uint32_t api_sysrawrc;
+ /* request SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV */
+ uint32_t wait_killable_recv;
};
struct db_filter {
diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd
index 9589cfe..55f8207 100644
--- a/src/python/libseccomp.pxd
+++ b/src/python/libseccomp.pxd
@@ -63,6 +63,7 @@ cdef extern from "seccomp.h":
SCMP_FLTATR_CTL_SSB
SCMP_FLTATR_CTL_OPTIMIZE
SCMP_FLTATR_API_SYSRAWRC
+ SCMP_FLTATR_CTL_WAITKILL
cdef enum scmp_compare:
SCMP_CMP_NE
diff --git a/src/python/seccomp.pyx b/src/python/seccomp.pyx
index 1f58517..5657577 100644
--- a/src/python/seccomp.pyx
+++ b/src/python/seccomp.pyx
@@ -325,6 +325,7 @@ cdef class Attr:
1: rules weighted by priority and complexity (DEFAULT)
2: binary tree sorted by syscall number
API_SYSRAWRC - return the raw syscall codes
+ CTL_WAITKILL - request wait killable semantics
"""
ACT_DEFAULT = libseccomp.SCMP_FLTATR_ACT_DEFAULT
ACT_BADARCH = libseccomp.SCMP_FLTATR_ACT_BADARCH
@@ -335,6 +336,7 @@ cdef class Attr:
CTL_SSB = libseccomp.SCMP_FLTATR_CTL_SSB
CTL_OPTIMIZE = libseccomp.SCMP_FLTATR_CTL_OPTIMIZE
API_SYSRAWRC = libseccomp.SCMP_FLTATR_API_SYSRAWRC
+ CTL_WAITKILL = libseccomp.SCMP_FLTATR_CTL_WAITKILL
cdef class Arg:
""" Python object representing a SyscallFilter syscall argument.
diff --git a/src/system.c b/src/system.c
index 94e0405..3d10e21 100644
--- a/src/system.c
+++ b/src/system.c
@@ -58,6 +58,7 @@ struct task_state {
int sup_flag_new_listener;
int sup_user_notif;
int sup_flag_tsync_esrch;
+ int sup_flag_wait_kill;
};
static struct task_state state = {
.nr_seccomp = -1,
@@ -73,6 +74,7 @@ static struct task_state state = {
.sup_flag_new_listener = -1,
.sup_user_notif = -1,
.sup_flag_tsync_esrch = -1,
+ .sup_flag_wait_kill = -1,
};
/**
@@ -307,6 +309,10 @@ int sys_chk_seccomp_flag(int flag)
if (state.sup_flag_tsync_esrch < 0)
state.sup_flag_tsync_esrch = _sys_chk_flag_kernel(flag);
return state.sup_flag_tsync_esrch;
+ case SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV:
+ if (state.sup_flag_wait_kill < 0)
+ state.sup_flag_wait_kill = _sys_chk_flag_kernel(flag);
+ return state.sup_flag_wait_kill;
}
return -EOPNOTSUPP;
@@ -339,6 +345,9 @@ void sys_set_seccomp_flag(int flag, bool enable)
case SECCOMP_FILTER_FLAG_TSYNC_ESRCH:
state.sup_flag_tsync_esrch = (enable ? 1 : 0);
break;
+ case SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV:
+ state.sup_flag_wait_kill = (enable ? 1 : 0);
+ break;
}
}
@@ -394,6 +403,9 @@ int sys_filter_load(struct db_filter_col *col, bool rawrc)
flgs |= SECCOMP_FILTER_FLAG_TSYNC;
} else if (listener_req)
flgs |= SECCOMP_FILTER_FLAG_NEW_LISTENER;
+ if ((flgs & SECCOMP_FILTER_FLAG_NEW_LISTENER) &&
+ col->attr.wait_killable_recv)
+ flgs |= SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV;
if (col->attr.log_enable)
flgs |= SECCOMP_FILTER_FLAG_LOG;
if (col->attr.spec_allow)
diff --git a/src/system.h b/src/system.h
index 804e9aa..7918c1f 100644
--- a/src/system.h
+++ b/src/system.h
@@ -138,6 +138,9 @@ typedef struct sock_filter bpf_instr_raw;
#ifndef SECCOMP_FILTER_FLAG_TSYNC_ESRCH
#define SECCOMP_FILTER_FLAG_TSYNC_ESRCH (1UL << 4)
#endif
+#ifndef SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV
+#define SECCOMP_FILTER_FLAG_WAIT_KILLABLE_RECV (1UL << 5)
+#endif
#ifndef SECCOMP_RET_LOG
#define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
diff --git a/tests/13-basic-attrs.c b/tests/13-basic-attrs.c
index e3c5881..fee83b4 100644
--- a/tests/13-basic-attrs.c
+++ b/tests/13-basic-attrs.c
@@ -142,6 +142,17 @@ int main(int argc, char *argv[])
goto out;
}
+ rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_WAITKILL, 1);
+ if (rc != 0)
+ goto out;
+ rc = seccomp_attr_get(ctx, SCMP_FLTATR_CTL_WAITKILL, &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 48c25a0..abf4b68 100755
--- a/tests/13-basic-attrs.py
+++ b/tests/13-basic-attrs.py
@@ -61,6 +61,9 @@ def test():
f.set_attr(Attr.API_SYSRAWRC, 1)
if f.get_attr(Attr.API_SYSRAWRC) != 1:
raise RuntimeError("Failed getting Attr.API_SYSRAWRC")
+ f.set_attr(Attr.CTL_WAITKILL, 1)
+ if f.get_attr(Attr.CTL_WAITKILL) != 1:
+ raise RuntimeError("Failed getting Attr.CTL_WAITKILL")
test()
diff --git a/tests/39-basic-api_level.c b/tests/39-basic-api_level.c
index 6c31be1..d3fb54b 100644
--- a/tests/39-basic-api_level.c
+++ b/tests/39-basic-api_level.c
@@ -75,13 +75,20 @@ int main(int argc, char *argv[])
if (api != 6)
return -13;
+ rc = seccomp_api_set(7);
+ if (rc != 0)
+ return -14;
+ api = seccomp_api_get();
+ if (api != 7)
+ return -15;
+
/* Attempt to set a high, invalid API level */
rc = seccomp_api_set(1024);
if (rc != -EINVAL)
return -1001;
/* Ensure that the previously set API level didn't change */
api = seccomp_api_get();
- if (api != 6)
+ if (api != 7)
return -1002;
return 0;
diff --git a/tests/39-basic-api_level.py b/tests/39-basic-api_level.py
index 352568e..93f3d7b 100755
--- a/tests/39-basic-api_level.py
+++ b/tests/39-basic-api_level.py
@@ -65,6 +65,11 @@ def test():
if api != 6:
raise RuntimeError("Failed getting API level 6")
+ set_api(7)
+ api = get_api()
+ if api != 7:
+ raise RuntimeError("Failed getting API level 7")
+
# Attempt to set a high, invalid API level
try:
set_api(1024)
@@ -74,7 +79,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 != 6:
+ if api != 7:
raise RuntimeError("Failed getting old API level after setting an invalid API level")
test()