summaryrefslogtreecommitdiff
path: root/src/system.c
diff options
context:
space:
mode:
authorTyler Hicks <tyhicks@canonical.com>2017-10-18 06:16:47 +0000
committerPaul Moore <paul@paul-moore.com>2017-11-01 12:47:46 -0400
commit8a8576c9e0cf463d2d624686a4e57058ae30e91a (patch)
tree7fa411fcc3aec8a0eb92a473c42ce0a36b2991a3 /src/system.c
parent4f16fe2082863cf317512b24e9a88da373b1894b (diff)
downloadlibseccomp-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.c30
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;
}