From 3385865713c1f6ed1f388a26823d0acedd859f64 Mon Sep 17 00:00:00 2001 From: Tycho Andersen Date: Tue, 5 Mar 2019 10:20:24 -0700 Subject: [PATCH] api: add support for the SPEC_ALLOW flag Signed-off-by: Tycho Andersen --- doc/man/man3/seccomp_api_get.3 | 3 +++ doc/man/man3/seccomp_attr_set.3 | 6 ++++++ include/seccomp.h.in | 2 ++ src/api.c | 12 ++++++++++++ src/db.c | 14 ++++++++++++++ src/db.h | 2 ++ src/python/libseccomp.pxd | 1 + src/system.c | 11 +++++++++++ tests/13-basic-attrs.c | 19 +++++++++++++++++-- 9 files changed, 68 insertions(+), 2 deletions(-) diff --git a/doc/man/man3/seccomp_api_get.3 b/doc/man/man3/seccomp_api_get.3 index 0def6863..ac3c2ff8 100644 --- a/doc/man/man3/seccomp_api_get.3 +++ b/doc/man/man3/seccomp_api_get.3 @@ -50,6 +50,9 @@ 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. +.TP +.B 4 +The SCMP_FLTATR_SPEC_ALLOW 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 7050d5f9..11320043 100644 --- a/doc/man/man3/seccomp_attr_set.3 +++ b/doc/man/man3/seccomp_attr_set.3 @@ -94,6 +94,12 @@ the action. Defaults to off ( .I value == 0). +.TP +.B SCMP_FLTATR_SPEC_ALLOW +A flag to disable Speculative Store Bypass mitigations for this filter. +Defaults to off ( +.I value +== 0). .\" ////////////////////////////////////////////////////////////////////////// .SH RETURN VALUE .\" ////////////////////////////////////////////////////////////////////////// diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 118d2fda..eaa56740 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -65,6 +65,7 @@ enum scmp_filter_attr { 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_SPEC_ALLOW = 7, /**< disable SSB mitigation */ _SCMP_FLTATR_MAX, }; @@ -367,6 +368,7 @@ const struct scmp_version *seccomp_version(void); * 3 : support for the SCMP_FLTATR_CTL_LOG filter attribute * support for the SCMP_ACT_LOG action * support for the SCMP_ACT_KILL_PROCESS action + * 4 : support for the SCMP_FLTATR_SPEC_ALLOW filter attrbute * */ unsigned int seccomp_api_get(void); diff --git a/src/api.c b/src/api.c index 94039a7b..34fd9c71 100644 --- a/src/api.c +++ b/src/api.c @@ -108,6 +108,10 @@ static unsigned int _seccomp_api_update(void) sys_chk_seccomp_action(SCMP_ACT_LOG) == 1) level = 3; + if (level == 3 && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW) == 1) + level = 4; + /* update the stored api level and return */ seccomp_api_level = level; return seccomp_api_level; @@ -151,6 +155,14 @@ API int seccomp_api_set(unsigned int level) sys_set_seccomp_action(SCMP_ACT_LOG, true); sys_set_seccomp_action(SCMP_ACT_KILL_PROCESS, true); 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); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW, true); + break; default: return -EINVAL; } diff --git a/src/db.c b/src/db.c index 64e0924d..064f343a 100644 --- a/src/db.c +++ b/src/db.c @@ -1280,6 +1280,9 @@ int db_col_attr_get(const struct db_filter_col *col, case SCMP_FLTATR_CTL_LOG: *value = col->attr.log_enable; break; + case SCMP_FLTATR_SPEC_ALLOW: + *value = col->attr.spec_allow; + break; default: rc = -EEXIST; break; @@ -1341,6 +1344,17 @@ int db_col_attr_set(struct db_filter_col *col, rc = -EOPNOTSUPP; } break; + case SCMP_FLTATR_SPEC_ALLOW: + rc = sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_SPEC_ALLOW); + if (rc == 1) { + /* supported */ + rc = 0; + col->attr.spec_allow = (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 8a646236..fa9c0850 100644 --- a/src/db.h +++ b/src/db.h @@ -116,6 +116,8 @@ struct db_filter_attr { uint32_t api_tskip; /* SECCOMP_FILTER_FLAG_LOG related attributes */ uint32_t log_enable; + /* SPEC_ALLOW related attributes */ + uint32_t spec_allow; }; struct db_filter { diff --git a/src/python/libseccomp.pxd b/src/python/libseccomp.pxd index 49d0be4c..1293208a 100644 --- a/src/python/libseccomp.pxd +++ b/src/python/libseccomp.pxd @@ -58,6 +58,7 @@ cdef extern from "seccomp.h": SCMP_FLTATR_CTL_TSYNC SCMP_FLTATR_API_TSKIP SCMP_FLTATR_CTL_LOG + SCMP_FLTATR_SPEC_ALLOW cdef enum scmp_compare: SCMP_CMP_NE diff --git a/src/system.c b/src/system.c index 0501b76d..f45379c1 100644 --- a/src/system.c +++ b/src/system.c @@ -44,6 +44,7 @@ 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; +static int _support_seccomp_flag_spec_allow = -1; /** * Check to see if the seccomp() syscall is supported @@ -221,6 +222,11 @@ int sys_chk_seccomp_flag(int flag) _support_seccomp_flag_log = _sys_chk_seccomp_flag_kernel(flag); return _support_seccomp_flag_log; + case SECCOMP_FILTER_FLAG_SPEC_ALLOW: + if (_support_seccomp_flag_spec_allow < 0) + _support_seccomp_flag_spec_allow = _sys_chk_seccomp_flag_kernel(flag); + + return _support_seccomp_flag_spec_allow; } return -EOPNOTSUPP; @@ -244,6 +250,9 @@ void sys_set_seccomp_flag(int flag, bool enable) case SECCOMP_FILTER_FLAG_LOG: _support_seccomp_flag_log = (enable ? 1 : 0); break; + case SECCOMP_FILTER_FLAG_SPEC_ALLOW: + _support_seccomp_flag_spec_allow = (enable ? 1 : 0); + break; } } @@ -280,6 +289,8 @@ int sys_filter_load(const struct db_filter_col *col) flgs |= SECCOMP_FILTER_FLAG_TSYNC; if (col->attr.log_enable) flgs |= SECCOMP_FILTER_FLAG_LOG; + if (col->attr.spec_allow) + flgs |= SECCOMP_FILTER_FLAG_SPEC_ALLOW; 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/tests/13-basic-attrs.c b/tests/13-basic-attrs.c index 0fe47550..6985ec9f 100644 --- a/tests/13-basic-attrs.c +++ b/tests/13-basic-attrs.c @@ -28,11 +28,11 @@ int main(int argc, char *argv[]) { - int rc; + int rc, expected; uint32_t val = (uint32_t)(-1); scmp_filter_ctx ctx = NULL; - rc = seccomp_api_set(3); + rc = seccomp_api_set(4); if (rc != 0) return EOPNOTSUPP; @@ -108,6 +108,21 @@ int main(int argc, char *argv[]) goto out; } + + expected = 1; + rc = seccomp_attr_set(ctx, SCMP_FLTATR_SPEC_ALLOW, expected); + if (rc == -EOPNOTSUPP) + expected = 0; + else if (rc != 0) + goto out; + rc = seccomp_attr_get(ctx, SCMP_FLTATR_SPEC_ALLOW, &val); + if (rc != 0) + goto out; + if (val != expected) { + rc = -1; + goto out; + } + rc = 0; out: seccomp_release(ctx);