[PATCH RFC 6/9] filter_seccomp: list of seccomp-filter generation strategies

Paul Chaignon paul.chaignon at gmail.com
Fri Aug 23 09:44:02 UTC 2019


Iterate over a list of BPF program generators, to select the shortest
program.  This commit doesn't introduce new generation strategies.

filter_seccomp.c (filter_generator_t): New typedef.
(linear_filter_generator): New prototype.
(filter_generators, filters): New variables.
(seccomp_filter): Removed.
(init_sock_filter): Renamed to linear_filter_generator, signal overflow
via function argument instead of erroring out.
(check_seccomp_filter): Find the shortest program generated by all
generation strategies, error in case of overflow in all generated
programs.

Signed-off-by: Paul Chaignon <paul.chaignon at gmail.com>
---
 filter_seccomp.c | 41 ++++++++++++++++++++++++++++++-----------
 1 file changed, 30 insertions(+), 11 deletions(-)

diff --git a/filter_seccomp.c b/filter_seccomp.c
index 25cba5bd..826d3bc3 100644
--- a/filter_seccomp.c
+++ b/filter_seccomp.c
@@ -52,6 +52,14 @@ static const struct audit_arch_t audit_arch_vec[SUPPORTED_PERSONALITIES] = {
 #endif
 };
 
+typedef unsigned short (*filter_generator_t)(struct sock_filter *,
+					     bool *overflow);
+static unsigned short linear_filter_generator(struct sock_filter *,
+					      bool *overflow);
+static filter_generator_t filter_generators[] = {
+	linear_filter_generator,
+};
+
 bool seccomp_filtering = false;
 bool seccomp_before_sysentry;
 
@@ -59,11 +67,8 @@ bool seccomp_before_sysentry;
  * Keep some margin in seccomp_filter as programs larger than allowed may
  * be constructed before we discard them.
  */
-struct sock_filter seccomp_filter[2 * BPF_MAXINSNS];
-struct sock_fprog bpf_prog = {
-	.len = 0,
-	.filter = seccomp_filter,
-};
+struct sock_filter filters[ARRAY_SIZE(filter_generators)][2 * BPF_MAXINSNS];
+struct sock_fprog bpf_prog;
 
 static void
 check_seccomp_order_do_child(void)
@@ -197,7 +202,7 @@ bpf_syscalls_cmp(struct sock_filter *filter,
 }
 
 static unsigned short
-init_sock_filter(struct sock_filter *filter)
+linear_filter_generator(struct sock_filter *filter, bool *overflow)
 {
 	/*
 	 * Generated program looks like:
@@ -299,9 +304,7 @@ init_sock_filter(struct sock_filter *filter)
 		 * is such a case.
 		 */
 		if (pos - start > UCHAR_MAX) {
-			debug_msg("seccomp-filter disabled due to "
-				  "possibility of overflow");
-			seccomp_filtering = false;
+			*overflow = true;
 			return pos;
 		}
 
@@ -349,13 +352,29 @@ check_seccomp_filter(void)
 	rc = prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, NULL, 0, 0);
 	seccomp_filtering = rc >= 0 || errno != EINVAL;
 	if (seccomp_filtering) {
-		bpf_prog.len = init_sock_filter(seccomp_filter);
-		if (bpf_prog.len > BPF_MAXINSNS) {
+		unsigned short len, min_len = USHRT_MAX;
+		unsigned int min_index = 0;
+		for (unsigned int i = 0; i < ARRAY_SIZE(filter_generators);
+		     ++i) {
+			bool overflow = false;
+			len = filter_generators[i](filters[i], &overflow);
+			if (len < min_len && !overflow) {
+				min_len = len;
+				min_index = i;
+			}
+		}
+		if (min_len == USHRT_MAX) {
+			debug_msg("seccomp-filter disabled due to jump offset "
+				  "overflow");
+			seccomp_filtering = false;
+		} else if (min_len > BPF_MAXINSNS) {
 			debug_msg("seccomp-filter disabled due to BPF program "
 				  "being oversized (%u > %d)", bpf_prog.len,
 				  BPF_MAXINSNS);
 			seccomp_filtering = false;
 		}
+		bpf_prog.len = min_len;
+		bpf_prog.filter = filters[min_index];
 	}
 	if (seccomp_filtering && check_seccomp_order() < 0)
 		seccomp_filtering = false;
-- 
2.17.1



More information about the Strace-devel mailing list