]> git.proxmox.com Git - mirror_libseccomp.git/commitdiff
system: runtime check if a filter flag is supported by the kernel
authorTyler Hicks <tyhicks@canonical.com>
Wed, 18 Oct 2017 06:16:47 +0000 (06:16 +0000)
committerPaul Moore <paul@paul-moore.com>
Wed, 1 Nov 2017 16:47:46 +0000 (12:47 -0400)
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>
src/system.c

index f54d00ec0f5d56c2c64242902f6f328504a64e58..4ff641b548e287ee64949728f19c0a052233a58f 100644 (file)
@@ -111,6 +111,27 @@ void sys_set_seccomp_syscall(bool enable)
        _support_seccomp_syscall = (enable ? 1 : 0);
 }
 
+/**
+ * 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;
        }