From 702434cd5a14f3cc60579ccd3fc4d79d9698dc8c Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Wed, 21 Sep 2022 22:16:47 -0400 Subject: [PATCH] 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 --- doc/man/man3/seccomp_attr_set.3 | 8 +++++++- include/seccomp.h.in | 1 + src/db.c | 7 +++++++ src/db.h | 2 ++ src/python/libseccomp.pxd | 1 + src/python/seccomp.pyx | 2 ++ src/system.c | 12 ++++++++++++ src/system.h | 3 +++ tests/13-basic-attrs.c | 11 +++++++++++ tests/13-basic-attrs.py | 3 +++ 10 files changed, 49 insertions(+), 1 deletion(-) diff --git a/doc/man/man3/seccomp_attr_set.3 b/doc/man/man3/seccomp_attr_set.3 index 4341abc9..571010ee 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 6f4929b9..02c72677 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, }; diff --git a/src/db.c b/src/db.c index 6d818749..02d462ef 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 9a414270..906a857c 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 9589cfea..55f8207d 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 1f58517b..5657577f 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 94e0405d..3d10e21d 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 804e9aae..7918c1f5 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 e3c5881d..fee83b4b 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 48c25a06..abf4b68c 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()