[systemd-commits] Makefile.am src/core

Zbigniew Jędrzejewski-Szmek zbyszek at kemper.freedesktop.org
Sat Jan 19 09:07:57 PST 2013


 Makefile.am              |    4 ++--
 src/core/execute.c       |    2 +-
 src/core/load-fragment.c |    2 ++
 src/core/syscall-list.c  |    1 +
 src/core/syscall-list.h  |   14 ++++++++++++++
 5 files changed, 20 insertions(+), 3 deletions(-)

New commits:
commit 843fc7f7f26a6507fe896a79ed1b474c35c4300f
Author: Jonathan Callen <abcd at gentoo.org>
Date:   Tue Jul 24 22:45:22 2012 -0400

    execute: Fix seccomp support on x32
    
    In the x32 ABI, syscall numbers start at 0x40000000.  Mask that bit on
    x32 for lookups in the syscall_names array and syscall_filter and ensure
    that syscall.h is parsed correctly.
    
    [zj: added SYSCALL_TO_INDEX, INDEX_TO_SYSCALL macros.]

diff --git a/Makefile.am b/Makefile.am
index ba93db0..2631748 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1099,7 +1099,7 @@ BUILT_SOURCES += \
 
 src/core/syscall-list.txt: Makefile
 	$(AM_V_at)$(MKDIR_P) $(dir $@)
-	$(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+\(?.*[0-9]+.*\)?/ { sub(/__NR_/, "", $$2); print $$2; }' > $@
+	$(AM_V_GEN)$(CPP) $(CFLAGS) $(AM_CPPFLAGS) $(CPPFLAGS) -dM -include sys/syscall.h - < /dev/null | $(AWK) '/^#define[ \t]+__NR_[^ ]+[ \t]+[0-9(]/ { sub(/__NR_/, "", $$2); print $$2; }' > $@
 
 src/core/syscall-from-name.gperf: src/core/syscall-list.txt Makefile
 	$(AM_V_at)$(MKDIR_P) $(dir $@)
@@ -1111,7 +1111,7 @@ src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile
 
 src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile
 	$(AM_V_at)$(MKDIR_P) $(dir $@)
-	$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[__NR_%s] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
+	$(AM_V_GEN)$(AWK) 'BEGIN{ print "const char* const syscall_names[] = { "} { printf "[SYSCALL_TO_INDEX(__NR_%s)] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
 
 # ------------------------------------------------------------------------------
 systemd_SOURCES = \
diff --git a/src/core/execute.c b/src/core/execute.c
index 65a10af..1413c91 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -957,7 +957,7 @@ static int apply_seccomp(uint32_t *syscall_filter) {
         for (i = 0, n = 0; i < syscall_max(); i++)
                 if (syscall_filter[i >> 4] & (1 << (i & 31))) {
                         struct sock_filter item[] = {
-                                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, i, 0, 1),
+                                BPF_JUMP(BPF_JMP+BPF_JEQ+BPF_K, INDEX_TO_SYSCALL(i), 0, 1),
                                 BPF_STMT(BPF_RET+BPF_K, SECCOMP_RET_ALLOW)
                         };
 
diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c
index f82ddd5..8436d4f 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2120,10 +2120,12 @@ int config_parse_documentation(
 }
 
 static void syscall_set(uint32_t *p, int nr) {
+        nr = SYSCALL_TO_INDEX(nr);
         p[nr >> 4] |= 1 << (nr & 31);
 }
 
 static void syscall_unset(uint32_t *p, int nr) {
+        nr = SYSCALL_TO_INDEX(nr);
         p[nr >> 4] &= ~(1 << (nr & 31));
 }
 
diff --git a/src/core/syscall-list.c b/src/core/syscall-list.c
index 05fad3e..b608e85 100644
--- a/src/core/syscall-list.c
+++ b/src/core/syscall-list.c
@@ -32,6 +32,7 @@ const struct syscall_name *lookup_syscall(register const char *str, register uns
 #include "syscall-from-name.h"
 
 const char *syscall_to_name(int id) {
+        id = SYSCALL_TO_INDEX(id);
         if (id < 0 || id >= (int) ELEMENTSOF(syscall_names))
                 return NULL;
 
diff --git a/src/core/syscall-list.h b/src/core/syscall-list.h
index 0fc6859..503838b 100644
--- a/src/core/syscall-list.h
+++ b/src/core/syscall-list.h
@@ -22,6 +22,20 @@
   along with systemd; If not, see <http://www.gnu.org/licenses/>.
 ***/
 
+#if defined __x86_64__ && defined __ILP32__
+/* The x32 ABI defines all of its syscalls with bit 30 set, which causes
+   issues when attempting to use syscalls as simple indicies into an array.
+   Instead, use the syscall id & ~SYSCALL_MASK as the index, and | the
+   internal id with the syscall mask as needed.
+*/
+#include <asm/unistd.h>
+#define SYSCALL_TO_INDEX(x) ((x) & ~__X32_SYSCALL_BIT)
+#define INDEX_TO_SYSCALL(x) ((x) | __X32_SYSCALL_BIT)
+#else
+#define SYSCALL_TO_INDEX(x) (x)
+#define INDEX_TO_SYSCALL(x) (x)
+#endif
+
 const char *syscall_to_name(int id);
 int syscall_from_name(const char *name);
 



More information about the systemd-commits mailing list