]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
seccomp: add test-seccomp test tool
authorLennart Poettering <lennart@poettering.net>
Fri, 21 Oct 2016 19:48:10 +0000 (21:48 +0200)
committerLennart Poettering <lennart@poettering.net>
Mon, 24 Oct 2016 15:32:51 +0000 (17:32 +0200)
This validates the system call set table and many of our seccomp-util.c APIs.

Makefile.am
src/shared/seccomp-util.h
src/test/test-seccomp.c [new file with mode: 0644]

index 18a5f4a82ad9563470caf00b060c6e00ddbe5173..8ef3b42c4104dd2574e4b7590fe02a54e7b09ca3 100644 (file)
@@ -1570,6 +1570,11 @@ tests += \
        test-acl-util
 endif
 
+if HAVE_SECCOMP
+tests += \
+       test-seccomp
+endif
+
 EXTRA_DIST += \
        test/a.service \
        test/basic.target \
@@ -2038,6 +2043,12 @@ test_acl_util_SOURCES = \
 test_acl_util_LDADD = \
        libsystemd-shared.la
 
+test_seccomp_SOURCES = \
+       src/test/test-seccomp.c
+
+test_seccomp_LDADD = \
+       libsystemd-shared.la
+
 test_namespace_LDADD = \
        libcore.la
 
index 667687b14f297cdf8b769a0e89e6186d43455f07..8050fc6fbf1341408291f894f39ea209f63347ea 100644 (file)
@@ -20,6 +20,7 @@
 ***/
 
 #include <seccomp.h>
+#include <stdbool.h>
 #include <stdint.h>
 
 const char* seccomp_arch_to_string(uint32_t c);
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
new file mode 100644 (file)
index 0000000..0060ecd
--- /dev/null
@@ -0,0 +1,103 @@
+/***
+  This file is part of systemd.
+
+  Copyright 2016 Lennart Poettering
+
+  systemd is free software; you can redistribute it and/or modify it
+  under the terms of the GNU Lesser General Public License as published by
+  the Free Software Foundation; either version 2.1 of the License, or
+  (at your option) any later version.
+
+  systemd is distributed in the hope that it will be useful, but
+  WITHOUT ANY WARRANTY; without even the implied warranty of
+  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+  Lesser General Public License for more details.
+
+  You should have received a copy of the GNU Lesser General Public License
+  along with systemd; If not, see <http://www.gnu.org/licenses/>.
+***/
+
+#include <stdlib.h>
+#include <sys/eventfd.h>
+#include <unistd.h>
+
+#include "fd-util.h"
+#include "macro.h"
+#include "process-util.h"
+#include "seccomp-util.h"
+
+static void test_seccomp_arch_to_string(void) {
+        uint32_t a, b;
+        const char *name;
+
+        a = seccomp_arch_native();
+        assert_se(a > 0);
+        name = seccomp_arch_to_string(a);
+        assert_se(name);
+        assert_se(seccomp_arch_from_string(name, &b) >= 0);
+        assert_se(a == b);
+}
+
+static void test_syscall_filter_set_find(void) {
+        assert_se(!syscall_filter_set_find(NULL));
+        assert_se(!syscall_filter_set_find(""));
+        assert_se(!syscall_filter_set_find("quux"));
+        assert_se(!syscall_filter_set_find("@quux"));
+
+        assert_se(syscall_filter_set_find("@clock") == syscall_filter_sets + SYSCALL_FILTER_SET_CLOCK);
+        assert_se(syscall_filter_set_find("@default") == syscall_filter_sets + SYSCALL_FILTER_SET_DEFAULT);
+        assert_se(syscall_filter_set_find("@raw-io") == syscall_filter_sets + SYSCALL_FILTER_SET_RAW_IO);
+}
+
+static void test_filter_sets(void) {
+        unsigned i;
+        int r;
+
+        if (!is_seccomp_available())
+                return;
+
+        if (geteuid() != 0)
+                return;
+
+        for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
+                pid_t pid;
+
+                log_info("Testing %s", syscall_filter_sets[i].name);
+
+                pid = fork();
+                assert_se(pid >= 0);
+
+                if (pid == 0) { /* Child? */
+                        int fd;
+
+                        if (i == SYSCALL_FILTER_SET_DEFAULT) /* if we look at the default set, whitelist instead of blacklist */
+                                r = seccomp_load_filter_set(SCMP_ACT_ERRNO(EPERM), syscall_filter_sets + i, SCMP_ACT_ALLOW);
+                        else
+                                r = seccomp_load_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EPERM));
+                        if (r < 0)
+                                _exit(EXIT_FAILURE);
+
+                        /* Test the sycall filter with one random system call */
+                        fd = eventfd(0, EFD_NONBLOCK|EFD_CLOEXEC);
+                        if (IN_SET(i, SYSCALL_FILTER_SET_IO_EVENT, SYSCALL_FILTER_SET_DEFAULT))
+                                assert_se(fd < 0 && errno == EPERM);
+                        else {
+                                assert_se(fd >= 0);
+                                safe_close(fd);
+                        }
+
+                        _exit(EXIT_SUCCESS);
+                }
+
+                assert_se(wait_for_terminate_and_warn(syscall_filter_sets[i].name, pid, true) == EXIT_SUCCESS);
+        }
+}
+
+int main(int argc, char *argv[]) {
+
+        test_seccomp_arch_to_string();
+        test_syscall_filter_set_find();
+        test_filter_sets();
+
+        return 0;
+}