diff options
-rw-r--r-- | include/seccomp.h.in | 10 | ||||
-rw-r--r-- | src/api.c | 55 | ||||
-rw-r--r-- | src/system.c | 33 | ||||
-rw-r--r-- | src/system.h | 3 |
4 files changed, 98 insertions, 3 deletions
diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 5843639..85b08b8 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -275,6 +275,16 @@ struct scmp_arg_cmp { const struct scmp_version *seccomp_version(void); /** + * XXX + */ +const unsigned int seccomp_api_get(void); + +/** + * XXX + */ +int seccomp_api_set(unsigned int level); + +/** * Initialize the filter state * @param def_action the default filter action * @@ -44,6 +44,8 @@ const struct scmp_version library_version = { .micro = SCMP_VER_MICRO, }; +unsigned int seccomp_api_level = 0; + /** * Validate a filter context * @param ctx the filter context @@ -75,6 +77,30 @@ static int _syscall_valid(const struct db_filter_col *col, int syscall) return 0; } +/** + * Update the API level + * + * XXX + */ +static void _seccomp_api_update(void) +{ + unsigned int level = 1; + + /* if seccomp_api_level > 0 then it's already been set, we're done */ + if (seccomp_api_level >= 1) + return; + + /* NOTE: level 1 is the base level, start checking at 2 */ + + /* level 2 */ + if (sys_chk_seccomp_syscall() && + sys_chk_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC)) + level = 2; + + /* update the stored api level */ + seccomp_api_level = level; +} + /* NOTE - function header comment in include/seccomp.h */ API const struct scmp_version *seccomp_version(void) { @@ -82,6 +108,35 @@ API const struct scmp_version *seccomp_version(void) } /* NOTE - function header comment in include/seccomp.h */ +API const unsigned int seccomp_api_get(void) +{ + /* update the api level, if needed */ + _seccomp_api_update(); + + return seccomp_api_level; +} + +/* NOTE - function header comment in include/seccomp.h */ +API int seccomp_api_set(unsigned int level) +{ + switch (level) { + case 1: + sys_set_seccomp_syscall(false); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, false); + break; + case 2: + sys_set_seccomp_syscall(true); + sys_set_seccomp_flag(SECCOMP_FILTER_FLAG_TSYNC, true); + break; + default: + return -EINVAL; + } + + seccomp_api_level = level; + return 0; +} + +/* NOTE - function header comment in include/seccomp.h */ API scmp_filter_ctx seccomp_init(uint32_t def_action) { if (db_action_valid(def_action) < 0) diff --git a/src/system.c b/src/system.c index c0a1adc..f79943a 100644 --- a/src/system.c +++ b/src/system.c @@ -40,6 +40,7 @@ static int _nr_seccomp = -1; static int _support_seccomp_syscall = -1; +static int _support_seccomp_flag_tsync = -1; /** * Check to see if the seccomp() syscall is supported @@ -98,25 +99,51 @@ supported: } /** + * XXX + */ +void sys_set_seccomp_syscall(bool enable) +{ + _support_seccomp_syscall = (enable ? 1 : 0); +} + +/** * Check to see if a seccomp() flag is supported * @param flag the seccomp() flag * * This function checks to see if a seccomp() flag is supported by the system. - * If the flag is supported one is returned, zero if unsupported, negative - * values on error. + * Return one if the syscall is supported, zero if unsupported, negative values + * on error. * */ int sys_chk_seccomp_flag(int flag) { + int rc; + switch (flag) { case SECCOMP_FILTER_FLAG_TSYNC: - return sys_chk_seccomp_syscall(); + if (_support_seccomp_flag_tsync < 0) { + rc = sys_chk_seccomp_syscall(); + _support_seccomp_flag_tsync = (rc == 1 ? 1 : 0); + } + return _support_seccomp_flag_tsync; } return -EOPNOTSUPP; } /** + * XXX + */ +void sys_set_seccomp_flag(int flag, bool enable) +{ + switch (flag) { + case SECCOMP_FILTER_FLAG_TSYNC: + _support_seccomp_flag_tsync = (enable ? 1 : 0); + break; + } +} + +/** * Loads the filter into the kernel * @param col the filter collection * diff --git a/src/system.h b/src/system.h index eea9973..0e2cd82 100644 --- a/src/system.h +++ b/src/system.h @@ -109,7 +109,10 @@ typedef struct sock_filter bpf_instr_raw; #endif int sys_chk_seccomp_syscall(void); +void sys_set_seccomp_syscall(bool enable); + int sys_chk_seccomp_flag(int flag); +void sys_set_seccomp_flag(int flag, bool enable); int sys_filter_load(const struct db_filter_col *col); |