[systemd-devel] [PATCH] execute: Fix seccomp support on x32
Jonathan Callen
abcd at gentoo.org
Tue Jul 24 19:45:22 PDT 2012
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.
Signed-off-by: Jonathan Callen <abcd at gentoo.org>
---
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 | 12 ++++++++++++
5 files changed, 18 insertions(+), 3 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 27666ea..995707f 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1028,7 +1028,7 @@ BUILT_SOURCES += \
src/core/syscall-to-name.h
src/core/syscall-list.txt: Makefile
- $(AM_V_GEN)cpp $(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 $(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_GEN)$(AWK) 'BEGIN{ print "struct syscall_name { const char* name; int id; };"; print "%null-strings"; print "%%";} { printf "%s, __NR_%s\n", $$1, $$1 }' < $< > $@
@@ -1037,7 +1037,7 @@ src/core/syscall-from-name.h: src/core/syscall-from-name.gperf Makefile
$(AM_V_GEN)$(GPERF) -L ANSI-C -t --ignore-case -N lookup_syscall -H hash_syscall_name -p -C < $< > $@
src/core/syscall-to-name.h: src/core/syscall-list.txt Makefile
- $(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 "[__NR_%s & ~SYSCALL_MASK] = \"%s\",\n", $$1, $$1 } END{print "};"}' < $< > $@
# ------------------------------------------------------------------------------
systemd_SOURCES = \
diff --git a/src/core/execute.c b/src/core/execute.c
index fc0edc6..ace1b61 100644
--- a/src/core/execute.c
+++ b/src/core/execute.c
@@ -955,7 +955,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, i | SYSCALL_MASK, 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 bbd82b9..31c82db 100644
--- a/src/core/load-fragment.c
+++ b/src/core/load-fragment.c
@@ -2003,10 +2003,12 @@ int config_parse_documentation(
}
static void syscall_set(uint32_t *p, int nr) {
+ nr &= ~SYSCALL_MASK;
p[nr >> 4] |= 1 << (nr & 31);
}
static void syscall_unset(uint32_t *p, int nr) {
+ nr &= ~SYSCALL_MASK;
p[nr >> 4] &= ~(1 << (nr & 31));
}
diff --git a/src/core/syscall-list.c b/src/core/syscall-list.c
index 05fad3e..ad0ba2b 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_MASK;
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..181e2a2 100644
--- a/src/core/syscall-list.h
+++ b/src/core/syscall-list.h
@@ -22,6 +22,18 @@
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_MASK __X32_SYSCALL_BIT
+#else
+#define SYSCALL_MASK 0
+#endif
+
const char *syscall_to_name(int id);
int syscall_from_name(const char *name);
--
1.7.8.6
More information about the systemd-devel
mailing list