]> granicus.if.org Git - strace/commitdiff
tests: check seccomp-assisted syscall filtering
authorChen Jingpiao <chenjingpiao@gmail.com>
Mon, 6 Aug 2018 13:58:43 +0000 (21:58 +0800)
committerDmitry V. Levin <ldv@altlinux.org>
Wed, 25 Sep 2019 01:02:03 +0000 (01:02 +0000)
Test filter_seccomp-perf checks whether seccomp-filter is actually
enabled by comparing the number of syscalls performed in a time interval
when seccomp-filter is enabled vs. disabled.  The number of syscalls
should be at least one order of magnitude higher when seccomp-filter
is enabled.

Test filter_seccomp-flag ensures the audit_arch_vec[].flag constants do
not conflict with syscall numbers.  If this test fails, then the number
of syscalls grew high enough that the code for seccomp-filter needs to
be updated.

* tests/init.sh (test_prog_set): New function.
* tests/status-none-f.c: New file.
* tests/filter_seccomp.in: Likewise.
* tests/filter_seccomp.sh: Likewise.
* tests/filter_seccomp-perf.c: Likewise.
* tests/filter_seccomp-flag.c: Likewise.
* tests/filter_seccomp-perf.test: New test.
* tests/Makefile.am (EXTRA_DIST): Add filter_seccomp.in and
filter_seccomp.sh.
(MISC_TESTS): Add filter_seccomp-perf.test.
(check_PROGRAMS): Add filter_seccomp-perf and filter_seccomp-flag.
* tests/pure_executables.list: Add status-none-f.
* tests/.gitignore: Add status-none-f, filter_seccomp-perf, and
filter_seccomp-flag.
* tests/gen_tests.in (filter_seccomp, filter_seccomp-flag): New entries.

Co-authored-by: Paul Chaignon <paul.chaignon@gmail.com>
Co-Authored-by: Dmitry V. Levin <ldv@altlinux.org>
tests/.gitignore
tests/Makefile.am
tests/filter_seccomp-flag.c [new file with mode: 0644]
tests/filter_seccomp-perf.c [new file with mode: 0644]
tests/filter_seccomp-perf.test [new file with mode: 0755]
tests/filter_seccomp.in [new file with mode: 0644]
tests/filter_seccomp.sh [new file with mode: 0755]
tests/gen_tests.in
tests/init.sh
tests/pure_executables.list
tests/status-none-f.c [new file with mode: 0644]

index f8374754c00cd298b574c43f38fbf6bb48533ab4..7ac73640c3d9315dfb3a93a1b2ac29fe183d8670 100644 (file)
@@ -93,6 +93,7 @@ fdatasync
 fflush
 file_handle
 file_ioctl
+filter_seccomp-perf
 filter-unavailable
 finit_module
 flock
@@ -523,6 +524,7 @@ sched_yield
 scm_rights
 scno.h
 seccomp-filter
+filter_seccomp-flag
 seccomp-filter-v
 seccomp-strict
 seccomp_get_action_avail
@@ -602,6 +604,7 @@ statfs64
 status-all
 status-failed
 status-none
+status-none-f
 status-none-threads
 status-successful
 status-unfinished
index 622f761c4fdd288184a154007ac05f006c57cc29..bd9f5465b148c2b3435df85b37059aec386031ac 100644 (file)
@@ -96,6 +96,8 @@ check_PROGRAMS = $(PURE_EXECUTABLES) \
        delay \
        execve-v \
        execveat-v \
+       filter_seccomp-flag \
+       filter_seccomp-perf \
        filter-unavailable \
        fork-f \
        fsync-y \
@@ -324,6 +326,7 @@ MISC_TESTS = \
        detach-sleeping.test \
        detach-stopped.test \
        fflush.test \
+       filter_seccomp-perf.test \
        filter-unavailable.test \
        filtering_fd-syntax.test \
        filtering_syscall-syntax.test \
@@ -406,6 +409,8 @@ EXTRA_DIST = \
        eventfd.expected \
        fadvise.h \
        fcntl-common.c \
+       filter_seccomp.in \
+       filter_seccomp.sh \
        filter-unavailable.expected \
        fstatat.c \
        fstatx.c \
diff --git a/tests/filter_seccomp-flag.c b/tests/filter_seccomp-flag.c
new file mode 100644 (file)
index 0000000..25d7880
--- /dev/null
@@ -0,0 +1,83 @@
+/*
+ * Check that syscall numbers do not conflict with seccomp filter flags.
+ *
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon@gmail.com>
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include "arch_defs.h"
+#include "sysent.h"
+#include "scno.h"
+#include <linux/audit.h>
+
+#ifdef __x86_64__
+# ifndef __X32_SYSCALL_BIT
+#  define __X32_SYSCALL_BIT     0x40000000
+# endif
+#endif
+
+/* Define these shorthand notations to simplify the syscallent files. */
+#include "sysent_shorthand_defs.h"
+
+const struct_sysent sysent0[] = {
+#include "syscallent.h"
+};
+
+#if SUPPORTED_PERSONALITIES > 1
+static const struct_sysent sysent1[] = {
+# include "syscallent1.h"
+};
+#endif
+
+#if SUPPORTED_PERSONALITIES > 2
+static const struct_sysent sysent2[] = {
+# include "syscallent2.h"
+};
+#endif
+
+const unsigned int nsyscall_vec[SUPPORTED_PERSONALITIES] = {
+       ARRAY_SIZE(sysent0),
+#if SUPPORTED_PERSONALITIES > 1
+       ARRAY_SIZE(sysent1),
+#endif
+#if SUPPORTED_PERSONALITIES > 2
+       ARRAY_SIZE(sysent2),
+#endif
+};
+
+struct audit_arch_t {
+       unsigned int arch;
+       unsigned int flag;
+};
+
+static const struct audit_arch_t audit_arch_vec[SUPPORTED_PERSONALITIES] = {
+#if SUPPORTED_PERSONALITIES > 1
+       PERSONALITY0_AUDIT_ARCH,
+       PERSONALITY1_AUDIT_ARCH,
+# if SUPPORTED_PERSONALITIES > 2
+       PERSONALITY2_AUDIT_ARCH,
+# endif
+#endif
+};
+
+int
+main(void)
+{
+       for (unsigned int p = 0; p < SUPPORTED_PERSONALITIES; ++p) {
+               if (!audit_arch_vec[p].flag)
+                       continue;
+               for (unsigned int nr = 1; nr < nsyscall_vec[p]; ++nr) {
+                       if (!(audit_arch_vec[p].flag & nr))
+                               continue;
+                       error_msg_and_fail("system call number %u of"
+                                          " personality %u conflicts with"
+                                          " seccomp filter flag %#x",
+                                          nr, p, audit_arch_vec[p].flag);
+               }
+       }
+       return 0;
+}
diff --git a/tests/filter_seccomp-perf.c b/tests/filter_seccomp-perf.c
new file mode 100644 (file)
index 0000000..9d5f90a
--- /dev/null
@@ -0,0 +1,39 @@
+/*
+ * Check seccomp filter performance.
+ *
+ * Copyright (c) 2019 Paul Chaignon <paul.chaignon@gmail.com>
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <signal.h>
+#include <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+
+static volatile bool stop = false;
+
+static void
+handler(int signo)
+{
+       stop = true;
+}
+
+int
+main(void)
+{
+       unsigned int i;
+       int rc = 0;
+
+       signal(SIGALRM, handler);
+       alarm(1);
+
+       for (i = 0; !stop; i++) {
+               rc |= chdir(".");
+       }
+       printf("%d\n", i);
+       return rc;
+}
diff --git a/tests/filter_seccomp-perf.test b/tests/filter_seccomp-perf.test
new file mode 100755 (executable)
index 0000000..9e6f45f
--- /dev/null
@@ -0,0 +1,27 @@
+#!/bin/sh
+#
+# Check seccomp filter performance.
+#
+# Copyright (c) 2019 Paul Chaignon <paul.chaignon@gmail.com>
+# Copyright (c) 2019 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+. "${srcdir=.}/filter_seccomp.sh"
+
+args="-f -qq -e signal=none -e trace=fchdir ../$NAME"
+num_regular="$(run_strace               $args)"
+mv "$LOG" "$LOG.regular"
+num_seccomp="$(run_strace --seccomp-bpf $args)"
+mv "$LOG" "$LOG.seccomp"
+match_diff "$LOG.regular" "$LOG.seccomp"
+
+min_ratio=8
+# With seccomp filter enabled, we should be able to complete
+# at least $min_ratio times more chdir system calls.
+ratio="$((num_seccomp / num_regular))"
+if [ "$ratio" -lt "$min_ratio" ]; then
+       fail_ "Only $ratio times more syscalls performed with seccomp filter enabled, expected at least $min_ratio times speedup"
+fi
diff --git a/tests/filter_seccomp.in b/tests/filter_seccomp.in
new file mode 100644 (file)
index 0000000..76e4d7e
--- /dev/null
@@ -0,0 +1,4 @@
+fork-f -a26 -qq -e signal=none -e trace=chdir
+vfork-f        -a26 -qq -e signal=none -e trace=chdir
+fork-f -a26 -qq -e signal=none -e trace=chdir,%memory,%ipc,%pure,%signal,%network -e status=failed
+status-none-f  -e trace=!ptrace -e status=none
diff --git a/tests/filter_seccomp.sh b/tests/filter_seccomp.sh
new file mode 100755 (executable)
index 0000000..783e951
--- /dev/null
@@ -0,0 +1,14 @@
+#!/bin/sh
+#
+# Skip the test if seccomp filter is not available.
+#
+# Copyright (c) 2019 The strace developers.
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+$STRACE --seccomp-bpf -f -e trace=fchdir / > /dev/null 2> "$LOG" ||:
+if grep -x "[^:]*strace: seccomp filter is requested but unavailable" \
+   "$LOG" > /dev/null; then
+       skip_ 'seccomp filter is unavailable'
+fi
index 9d913749b6bb8627a1603cdfa6a727c2490b89e8..fe56addd4489db91e1a075b2a0105fec662aa3bd 100644 (file)
@@ -72,6 +72,8 @@ fcntl64       -a8
 fdatasync      -a14
 file_handle    -e trace=name_to_handle_at,open_by_handle_at
 file_ioctl     +ioctl.test
+filter_seccomp . "${srcdir=.}/filter_seccomp.sh"; test_prog_set --seccomp-bpf -f
+filter_seccomp-flag    ../$NAME
 finit_module   -a25
 flock  -a19
 fork-f -a26 -qq -f -e signal=none -e trace=chdir
index 40e621889ab8b27a2bb640c424492e75131e95e2..4cd2d153555ff5eb9af700abea32680023ecea32 100644 (file)
@@ -324,6 +324,11 @@ test_trace_expr()
                < negative.list
 }
 
+test_prog_set()
+{
+       test_pure_prog_set "$@" < "$srcdir/$NAME.in"
+}
+
 check_prog cat
 check_prog rm
 
index 0a61a8eb248240a66e2b350146677acecc50b4ab..6f3650c67b9d573fe2975004c6dc242f4b258052 100755 (executable)
@@ -511,6 +511,7 @@ statfs64
 status-all
 status-failed
 status-none
+status-none-f
 status-successful
 status-unfinished
 statx
diff --git a/tests/status-none-f.c b/tests/status-none-f.c
new file mode 100644 (file)
index 0000000..33887a1
--- /dev/null
@@ -0,0 +1,19 @@
+/*
+ * Check basic seccomp filtering with large number of traced syscalls.
+ *
+ * Copyright (c) 2019 The strace developers.
+ * All rights reserved.
+ *
+ * SPDX-License-Identifier: GPL-2.0-or-later
+ */
+
+#include "tests.h"
+#include <stdio.h>
+#include <unistd.h>
+
+int
+main(void)
+{
+       printf("%-5d +++ exited with 0 +++\n", getpid());
+       return 0;
+}