dryang / rpms / systemd

Forked from rpms/systemd a year ago
Clone
b7dd4d
From f3c6abebbe4718085fcf17ed3ab0690e379fbb7e Mon Sep 17 00:00:00 2001
b7dd4d
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
b7dd4d
Date: Wed, 19 Aug 2020 17:43:23 +0200
b7dd4d
Subject: [PATCH] shared: add @known syscall list
b7dd4d
b7dd4d
(cherry picked from commit 95aac01259db689dac7d8e5bfafb60e8c70cd734)
b7dd4d
b7dd4d
Related: #2040247
b7dd4d
---
b7dd4d
 man/systemd.exec.xml                |  4 ++++
b7dd4d
 src/shared/generate-syscall-list.py |  5 +++++
b7dd4d
 src/shared/meson.build              | 11 +++++++++++
b7dd4d
 src/shared/seccomp-util.c           |  6 ++++++
b7dd4d
 src/shared/seccomp-util.h           |  3 ++-
b7dd4d
 src/test/test-seccomp.c             | 19 ++++++++++++-------
b7dd4d
 6 files changed, 40 insertions(+), 8 deletions(-)
b7dd4d
 create mode 100755 src/shared/generate-syscall-list.py
b7dd4d
b7dd4d
diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml
b7dd4d
index dc88cf9781..b04b4ba552 100644
b7dd4d
--- a/man/systemd.exec.xml
b7dd4d
+++ b/man/systemd.exec.xml
b7dd4d
@@ -1556,6 +1556,10 @@ RestrictNamespaces=~cgroup net</programlisting>
b7dd4d
                 <entry>@timer</entry>
b7dd4d
                 <entry>System calls for scheduling operations by time (<citerefentry project='man-pages'><refentrytitle>alarm</refentrytitle><manvolnum>2</manvolnum></citerefentry>, <citerefentry project='man-pages'><refentrytitle>timer_create</refentrytitle><manvolnum>2</manvolnum></citerefentry>, …)</entry>
b7dd4d
               </row>
b7dd4d
+              <row>
b7dd4d
+                <entry>@known</entry>
b7dd4d
+                <entry>All system calls defined by the kernel. This list is defined statically in systemd based on a kernel version that was available when this systmed version was released. It will become progressively more out-of-date as the kernel is updated.</entry>
b7dd4d
+              </row>
b7dd4d
             
b7dd4d
           </tgroup>
b7dd4d
         
b7dd4d
diff --git a/src/shared/generate-syscall-list.py b/src/shared/generate-syscall-list.py
b7dd4d
new file mode 100755
b7dd4d
index 0000000000..13a6ae9241
b7dd4d
--- /dev/null
b7dd4d
+++ b/src/shared/generate-syscall-list.py
b7dd4d
@@ -0,0 +1,5 @@
b7dd4d
+#!/usr/bin/env python
b7dd4d
+import sys
b7dd4d
+
b7dd4d
+for line in open(sys.argv[1]):
b7dd4d
+    print('"{}\\0"'.format(line.strip()))
b7dd4d
diff --git a/src/shared/meson.build b/src/shared/meson.build
b7dd4d
index c9dd0a3a4e..fed08571d1 100644
b7dd4d
--- a/src/shared/meson.build
b7dd4d
+++ b/src/shared/meson.build
b7dd4d
@@ -109,6 +109,16 @@ shared_sources = files('''
b7dd4d
 test_tables_h = files('test-tables.h')
b7dd4d
 shared_sources += [test_tables_h]
b7dd4d
 
b7dd4d
+generate_syscall_list = find_program('generate-syscall-list.py')
b7dd4d
+fname = 'syscall-list.h'
b7dd4d
+syscall_list_h = custom_target(
b7dd4d
+        fname,
b7dd4d
+        input : 'syscall-names.text',
b7dd4d
+        output : fname,
b7dd4d
+        command : [generate_syscall_list,
b7dd4d
+                   '@INPUT@'],
b7dd4d
+        capture : true)
b7dd4d
+
b7dd4d
 if conf.get('HAVE_ACL') == 1
b7dd4d
         shared_sources += files('acl-util.c')
b7dd4d
 endif
b7dd4d
@@ -119,6 +129,7 @@ endif
b7dd4d
 
b7dd4d
 if conf.get('HAVE_SECCOMP') == 1
b7dd4d
         shared_sources += files('seccomp-util.c')
b7dd4d
+        shared_sources += syscall_list_h
b7dd4d
 endif
b7dd4d
 
b7dd4d
 if conf.get('HAVE_LIBIPTC') == 1
b7dd4d
diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c
b7dd4d
index c57c409433..c2b2f2da92 100644
b7dd4d
--- a/src/shared/seccomp-util.c
b7dd4d
+++ b/src/shared/seccomp-util.c
b7dd4d
@@ -855,6 +855,12 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
b7dd4d
                 "timerfd_settime\0"
b7dd4d
                 "times\0"
b7dd4d
         },
b7dd4d
+        [SYSCALL_FILTER_SET_KNOWN] = {
b7dd4d
+                .name = "@known",
b7dd4d
+                .help = "All known syscalls declared in the kernel",
b7dd4d
+                .value =
b7dd4d
+#include "syscall-list.h"
b7dd4d
+        },
b7dd4d
 };
b7dd4d
 
b7dd4d
 const SyscallFilterSet *syscall_filter_set_find(const char *name) {
b7dd4d
diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h
b7dd4d
index 602f092255..541ba1e067 100644
b7dd4d
--- a/src/shared/seccomp-util.h
b7dd4d
+++ b/src/shared/seccomp-util.h
b7dd4d
@@ -21,7 +21,7 @@ typedef struct SyscallFilterSet {
b7dd4d
 } SyscallFilterSet;
b7dd4d
 
b7dd4d
 enum {
b7dd4d
-        /* Please leave DEFAULT first, but sort the rest alphabetically */
b7dd4d
+        /* Please leave DEFAULT first and KNOWN last, but sort the rest alphabetically */
b7dd4d
         SYSCALL_FILTER_SET_DEFAULT,
b7dd4d
         SYSCALL_FILTER_SET_AIO,
b7dd4d
         SYSCALL_FILTER_SET_BASIC_IO,
b7dd4d
@@ -49,6 +49,7 @@ enum {
b7dd4d
         SYSCALL_FILTER_SET_SYNC,
b7dd4d
         SYSCALL_FILTER_SET_SYSTEM_SERVICE,
b7dd4d
         SYSCALL_FILTER_SET_TIMER,
b7dd4d
+        SYSCALL_FILTER_SET_KNOWN,
b7dd4d
         _SYSCALL_FILTER_SET_MAX
b7dd4d
 };
b7dd4d
 
b7dd4d
diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c
b7dd4d
index 6ec04c4c55..286f01b5ce 100644
b7dd4d
--- a/src/test/test-seccomp.c
b7dd4d
+++ b/src/test/test-seccomp.c
b7dd4d
@@ -106,8 +106,10 @@ static void test_filter_sets(void) {
b7dd4d
                 if (pid == 0) { /* Child? */
b7dd4d
                         int fd;
b7dd4d
 
b7dd4d
-                        /* If we look at the default set (or one that includes it), whitelist instead of blacklist */
b7dd4d
-                        if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT, SYSCALL_FILTER_SET_SYSTEM_SERVICE))
b7dd4d
+                        /* If we look at the default set (or one that includes it), allow-list instead of deny-list */
b7dd4d
+                        if (IN_SET(i, SYSCALL_FILTER_SET_DEFAULT,
b7dd4d
+                                      SYSCALL_FILTER_SET_SYSTEM_SERVICE,
b7dd4d
+                                      SYSCALL_FILTER_SET_KNOWN))
b7dd4d
                                 r = seccomp_load_syscall_filter_set(SCMP_ACT_ERRNO(EUCLEAN), syscall_filter_sets + i, SCMP_ACT_ALLOW, true);
b7dd4d
                         else
b7dd4d
                                 r = seccomp_load_syscall_filter_set(SCMP_ACT_ALLOW, syscall_filter_sets + i, SCMP_ACT_ERRNO(EUCLEAN), true);
b7dd4d
@@ -639,20 +641,23 @@ static void test_lock_personality(void) {
b7dd4d
 }
b7dd4d
 
b7dd4d
 static void test_filter_sets_ordered(void) {
b7dd4d
-        size_t i;
b7dd4d
-
b7dd4d
         /* Ensure "@default" always remains at the beginning of the list */
b7dd4d
         assert_se(SYSCALL_FILTER_SET_DEFAULT == 0);
b7dd4d
         assert_se(streq(syscall_filter_sets[0].name, "@default"));
b7dd4d
 
b7dd4d
-        for (i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
b7dd4d
+        /* Ensure "@known" always remains at the end of the list */
b7dd4d
+        assert_se(SYSCALL_FILTER_SET_KNOWN == _SYSCALL_FILTER_SET_MAX - 1);
b7dd4d
+        assert_se(streq(syscall_filter_sets[SYSCALL_FILTER_SET_KNOWN].name, "@known"));
b7dd4d
+
b7dd4d
+        for (size_t i = 0; i < _SYSCALL_FILTER_SET_MAX; i++) {
b7dd4d
                 const char *k, *p = NULL;
b7dd4d
 
b7dd4d
                 /* Make sure each group has a description */
b7dd4d
                 assert_se(!isempty(syscall_filter_sets[0].help));
b7dd4d
 
b7dd4d
-                /* Make sure the groups are ordered alphabetically, except for the first entry */
b7dd4d
-                assert_se(i < 2 || strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
b7dd4d
+                /* Make sure the groups are ordered alphabetically, except for the first and last entries */
b7dd4d
+                assert_se(i < 2 || i == _SYSCALL_FILTER_SET_MAX - 1 ||
b7dd4d
+                          strcmp(syscall_filter_sets[i-1].name, syscall_filter_sets[i].name) < 0);
b7dd4d
 
b7dd4d
                 NULSTR_FOREACH(k, syscall_filter_sets[i].value) {
b7dd4d