From 355953c00ae34083f8acd89eac3360707e02dfaf Mon Sep 17 00:00:00 2001 From: Paul Moore Date: Thu, 21 Sep 2017 10:27:38 -0400 Subject: api: create an API level construct as part of the supported API WORK IN PROGRESS, DO NOT SHIP XXX - manpage needed XXX - tests needed Signed-off-by: Paul Moore --- include/seccomp.h.in | 10 ++++++++++ src/api.c | 55 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/system.c | 33 ++++++++++++++++++++++++++++--- 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 @@ -274,6 +274,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 diff --git a/src/api.c b/src/api.c index 5cc04d2..8a38d00 100644 --- a/src/api.c +++ b/src/api.c @@ -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,12 +77,65 @@ 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) { return &library_version; } +/* 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) { 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 @@ -97,25 +98,51 @@ supported: return 1; } +/** + * 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); -- cgit v1.2.1