diff options
author | Tyler Hicks <tyhicks@canonical.com> | 2017-10-18 06:16:47 +0000 |
---|---|---|
committer | Paul Moore <paul@paul-moore.com> | 2017-11-01 12:47:46 -0400 |
commit | 8a8576c9e0cf463d2d624686a4e57058ae30e91a (patch) | |
tree | 7fa411fcc3aec8a0eb92a473c42ce0a36b2991a3 /src/system.c | |
parent | 4f16fe2082863cf317512b24e9a88da373b1894b (diff) | |
download | libseccomp-8a8576c9e0cf463d2d624686a4e57058ae30e91a.tar.gz |
system: runtime check if a filter flag is supported by the kernel
As new filter flags are added to the kernel, libseccomp needs a way to
verify that a filter flag is not only valid but also supported by the
current kernel at runtime. A good way of doing that is by attempting to
enter filter mode, with the flag bit(s) in question set, and a NULL
pointer for the args parameter of seccomp(2). EFAULT indicates that the
flag is valid and EINVAL indicates that the flag is invalid. This patch
errs on the side of caution and treats any errno, besides EFAULT, as
indicating that the flag is invalid.
This check should be safe to use for the existing
SECCOMP_FILTER_FLAG_TSYNC flag so this patch enables the check for that
flag.
Signed-off-by: Tyler Hicks <tyhicks@canonical.com>
Signed-off-by: Paul Moore <paul@paul-moore.com>
Diffstat (limited to 'src/system.c')
-rw-r--r-- | src/system.c | 30 |
1 files changed, 24 insertions, 6 deletions
diff --git a/src/system.c b/src/system.c index f54d00e..4ff641b 100644 --- a/src/system.c +++ b/src/system.c @@ -112,6 +112,27 @@ void sys_set_seccomp_syscall(bool enable) } /** + * Check to see if a seccomp() flag is supported by the kernel + * @param flag the seccomp() flag + * + * This function checks to see if a seccomp() flag is supported by the kernel. + * Return one if the flag is supported, zero otherwise. + * + */ +static int _sys_chk_seccomp_flag_kernel(int flag) +{ + /* this is an invalid seccomp(2) call because the last argument + * is NULL, but depending on the errno value of EFAULT we can + * guess if the filter flag is supported or not */ + if (sys_chk_seccomp_syscall() == 1 && + syscall(_nr_seccomp, SECCOMP_SET_MODE_FILTER, flag, NULL) == -1 && + errno == EFAULT) + return 1; + + return 0; +} + +/** * Check to see if a seccomp() flag is supported * @param flag the seccomp() flag * @@ -122,14 +143,11 @@ void sys_set_seccomp_syscall(bool enable) */ int sys_chk_seccomp_flag(int flag) { - int rc; - switch (flag) { case SECCOMP_FILTER_FLAG_TSYNC: - if (_support_seccomp_flag_tsync < 0) { - rc = sys_chk_seccomp_syscall(); - _support_seccomp_flag_tsync = (rc == 1 ? 1 : 0); - } + if (_support_seccomp_flag_tsync < 0) + _support_seccomp_flag_tsync = _sys_chk_seccomp_flag_kernel(flag); + return _support_seccomp_flag_tsync; } |