[PATCH RFC 1/2] filter_seccomp: use seccomp's NO_INHERIT flag when available
Paul Chaignon
paul.chaignon at gmail.com
Mon Nov 11 15:19:55 UTC 2019
When adding a new seccomp filter to a process, if the
SECCOMP_FILTER_FLAG_NO_INHERIT is given, the filter won't be inherited by
children tasks. This patch enables strace to set this flag when seccomp
filter is requested but the -f option is not given. In such a case,
--seccomp-bpf does not imply -f anymore. Support for this flag (and the
seccomp syscall) are checked on startup.
* filter_seccomp.c (seccomp_no_inherit): Declare variable.
[!seccomp] (seccomp): Define function.
[!SECCOMP_FILTER_FLAG_NO_INHERIT] (SECCOMP_FILTER_FLAG_NO_INHERIT): Define.
(check_seccomp_inheritance): New function.
(check_seccomp_filter_properties): Call check_seccomp_inheritance.
(init_seccomp_filter): Call seccomp with NO_INHERIT flag.
* filter_seccomp.h (seccomp_no_inherit): Declare variable.
* strace.c (init): Handle --seccomp-bpf without -f.
* tests/filter_seccomp-no-inherit.test: New file.
* Makefile.am (MISC_TESTS): Add it.
* tests/options-syntax.test: Remove test case for --seccomp-bpf implies -f.
* strace.1.in (--seccomp-bpf): Update documentation.
Signed-off-by: Paul Chaignon <paul.chaignon at gmail.com>
---
filter_seccomp.c | 38 +++++++++++++++++++++++++---
filter_seccomp.h | 1 +
strace.1.in | 4 ++-
strace.c | 6 ++---
tests/Makefile.am | 1 +
tests/filter_seccomp-no-inherit.test | 26 +++++++++++++++++++
tests/options-syntax.test | 2 --
7 files changed, 68 insertions(+), 10 deletions(-)
create mode 100755 tests/filter_seccomp-no-inherit.test
diff --git a/filter_seccomp.c b/filter_seccomp.c
index 73d3644e..d50bb2dd 100644
--- a/filter_seccomp.c
+++ b/filter_seccomp.c
@@ -22,11 +22,24 @@
bool seccomp_filtering;
bool seccomp_before_sysentry;
+bool seccomp_no_inherit;
#ifdef HAVE_LINUX_SECCOMP_H
# include <linux/seccomp.h>
+#ifndef seccomp
+int seccomp(unsigned int op, unsigned int flags, void *args)
+{
+ errno = 0;
+ return syscall(__NR_seccomp, op, flags, args);
+}
+#endif
+
+#ifndef SECCOMP_FILTER_FLAG_NO_INHERIT
+# define SECCOMP_FILTER_FLAG_NO_INHERIT 16
+#endif
+
/* PERSONALITY*_AUDIT_ARCH definitions depend on AUDIT_ARCH_* constants. */
# ifdef PERSONALITY0_AUDIT_ARCH
# include <linux/audit.h>
@@ -281,6 +294,17 @@ check_seccomp_order(void)
# endif /* HAVE_FORK */
}
+static void
+check_seccomp_inheritance(void)
+{
+ long ret = seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NO_INHERIT, NULL);
+ seccomp_no_inherit = errno == EFAULT && ret == -1;
+ if (!seccomp_no_inherit) {
+ error_msg("--seccomp-bpf implies -f");
+ followfork = 1;
+ }
+}
+
static bool
traced_by_seccomp(unsigned int scno, unsigned int p)
{
@@ -625,8 +649,11 @@ check_seccomp_filter_properties(void)
seccomp_filtering = false;
}
- if (seccomp_filtering)
+ if (seccomp_filtering) {
check_seccomp_order();
+ if (seccomp_no_inherit)
+ check_seccomp_inheritance();
+ }
}
static void
@@ -712,8 +739,13 @@ init_seccomp_filter(void)
if (debug_flag)
dump_seccomp_bpf();
- if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bpf_prog) < 0)
- perror_func_msg_and_die("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)");
+ if (seccomp_no_inherit) {
+ if (seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NO_INHERIT, &bpf_prog) < 0)
+ perror_func_msg_and_die("seccomp(SECCOMP_SET_MODE_FILTER, SECCOMP_FILTER_FLAG_NO_INHERIT)");
+ } else {
+ if (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &bpf_prog) < 0)
+ perror_func_msg_and_die("prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER)");
+ }
}
int
diff --git a/filter_seccomp.h b/filter_seccomp.h
index bc06c8c3..f8d241b9 100644
--- a/filter_seccomp.h
+++ b/filter_seccomp.h
@@ -13,6 +13,7 @@
extern bool seccomp_filtering;
extern bool seccomp_before_sysentry;
+extern bool seccomp_no_inherit;
extern void check_seccomp_filter(void);
extern void init_seccomp_filter(void);
diff --git a/strace.1.in b/strace.1.in
index eb872df1..89ee1b8c 100644
--- a/strace.1.in
+++ b/strace.1.in
@@ -1020,7 +1020,9 @@ to have
only when system calls that are being traced occur in the traced processes.
Implies the
.B \-f
-option.
+option on kernels that do not support the
+.B SECCOMP_FILTER_FLAG_NO_INHERIT
+flag.
An attempt to rely on seccomp-bpf to filter system calls may fail for various
reasons, e.g. there are too many system calls to filter, the seccomp API is not
available, or
diff --git a/strace.c b/strace.c
index 23bd17b9..4c8598fe 100644
--- a/strace.c
+++ b/strace.c
@@ -1833,10 +1833,8 @@ init(int argc, char *argv[])
if (nprocs && (!argc || debug_flag))
error_msg("--seccomp-bpf is not enabled for processes"
" attached with -p");
- if (!followfork) {
- error_msg("--seccomp-bpf implies -f");
- followfork = 1;
- }
+ if (!followfork)
+ seccomp_no_inherit = true;
}
if (optF) {
diff --git a/tests/Makefile.am b/tests/Makefile.am
index e0c3b60c..1ecc8881 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -329,6 +329,7 @@ MISC_TESTS = \
detach-stopped.test \
fflush.test \
filter_seccomp-perf.test \
+ filter_seccomp-no-inherit.test \
filter-unavailable.test \
filtering_fd-syntax.test \
filtering_syscall-syntax.test \
diff --git a/tests/filter_seccomp-no-inherit.test b/tests/filter_seccomp-no-inherit.test
new file mode 100755
index 00000000..5775135a
--- /dev/null
+++ b/tests/filter_seccomp-no-inherit.test
@@ -0,0 +1,26 @@
+#!/bin/sh
+#
+# Check seccomp filter with SECCOMP_FILTER_FLAG_NO_INHERIT.
+#
+# Copyright (c) 2019 Paul Chaignon <paul.chaignon at gmail.com>
+# All rights reserved.
+#
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+. "${srcdir=.}/init.sh"
+. "${srcdir=.}/filter_seccomp.sh"
+
+$STRACE --seccomp-bpf -e trace=fchdir / > /dev/null 2> "$LOG" ||:
+if grep -x "[^:]*strace: --seccomp-bpf implies -f" "$LOG" > /dev/null; then
+ skip_ 'SECCOMP_FILTER_FLAG_NO_INHERIT is not supported'
+fi
+
+cat "../filter_seccomp.in" | while read -r t prog_args; do {
+ # skip lines beginning with "#" symbol
+ [ "${t###}" = "$t" ] || continue
+
+ try_run_prog "../$t" || continue
+ run_strace $prog_args --seccomp-bpf "../$t" | grep -E "(\.(start|parent|finish)|exited with 0)" | sed -r 's/^[0-9]+\s+//' > "$EXP"
+ sed -i -r 's/ +/ /g' "$LOG"
+ match_diff "$LOG" "$EXP"
+} < /dev/null; done
diff --git a/tests/options-syntax.test b/tests/options-syntax.test
index 54083e82..6537df29 100755
--- a/tests/options-syntax.test
+++ b/tests/options-syntax.test
@@ -49,8 +49,6 @@ check_h "incorrect personality designator '42' in qualification 'getcwd at 42'" -e
check_h "incorrect personality designator '42' in qualification 'getcwd at 42'" -e trace=gettid,getcwd at 42
check_h "incorrect personality designator '42' in qualification '23 at 42'" -e trace=23 at 42,123
-check_h '--seccomp-bpf implies -f
--w must be given with (-c or -C)' --seccomp-bpf -w /
check_h '--seccomp-bpf is not enabled for processes attached with -p
-w must be given with (-c or -C)' --seccomp-bpf -f -p 1 -w
--
2.17.1
More information about the Strace-devel
mailing list