diff options
author | Mathias Krause <minipli@grsecurity.net> | 2024-01-23 11:12:20 +0100 |
---|---|---|
committer | Mike Gilbert <floppym@gentoo.org> | 2024-07-22 17:05:57 -0400 |
commit | a9440d0bf71c665aea026a7c06603bca2c80ae75 (patch) | |
tree | 33acb69158a104dd70da032fb1f658ab50b393c4 /seccomp-bpf.c | |
parent | make-seccomp-filters.sh: split cflags/ldflags for libseccomp (diff) | |
download | pax-utils-a9440d0bf71c665aea026a7c06603bca2c80ae75.tar.gz pax-utils-a9440d0bf71c665aea026a7c06603bca2c80ae75.tar.bz2 pax-utils-a9440d0bf71c665aea026a7c06603bca2c80ae75.zip |
seccomp: make socket() fail with -ENOSYS
At least Debian's glibc tries to make use of nscd by default leading to
the getpwuid() / getpwnam() calls in pspax trying to open up a local
connection to /var/run/nscd/socket. Neither socket() nor connect() are
allowed by the seccomp policy, leading to unavoidable killing of the
process:
$ pspax
USER PID PAX MAPS ETYPE NAME CAPS ATTR
Bad system call (core dumped)
$ strace pspax |& tail -3
newfstatat(4, "stat", {st_mode=S_IFREG|0444, st_size=0, ...}, AT_SYMLINK_NOFOLLOW) = 0
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = 41
+++ killed by SIGSYS (core dumped) +++
Fix this by making socket() fail with -ENOSYS instead:
$ strace -e trace=socket ./build/pspax >/dev/null
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = -1 ENOSYS (Function not implemented)
socket(AF_UNIX, SOCK_STREAM|SOCK_CLOEXEC|SOCK_NONBLOCK, 0) = -1 ENOSYS (Function not implemented)
+++ exited with 0 +++
Signed-off-by: Mathias Krause <minipli@grsecurity.net>
Signed-off-by: Mike Gilbert <floppym@gentoo.org>
Diffstat (limited to 'seccomp-bpf.c')
-rw-r--r-- | seccomp-bpf.c | 16 |
1 files changed, 11 insertions, 5 deletions
diff --git a/seccomp-bpf.c b/seccomp-bpf.c index b56e9e4..5d34f33 100644 --- a/seccomp-bpf.c +++ b/seccomp-bpf.c @@ -10,6 +10,7 @@ const char argv0[] = "seccomp-bpf"; #include <err.h> +#include <errno.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> @@ -49,7 +50,7 @@ static const struct { }; /* Simple helper to add all of the syscalls in an array. */ -static int gen_seccomp_rules_add(scmp_filter_ctx ctx, const int syscalls[], size_t num) +static int gen_seccomp_rules_add(scmp_filter_ctx ctx, const int syscalls[], size_t num, uint32_t action) { static uint8_t prio; size_t i; @@ -58,14 +59,14 @@ static int gen_seccomp_rules_add(scmp_filter_ctx ctx, const int syscalls[], size warn("seccomp_syscall_priority failed"); return -1; } - if (seccomp_rule_add(ctx, SCMP_ACT_ALLOW, syscalls[i], 0) < 0) { + if (seccomp_rule_add(ctx, action, syscalls[i], 0) < 0) { warn("seccomp_rule_add failed"); return -1; } } return 0; } -#define gen_seccomp_rules_add(ctx, syscalls) gen_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls)) +#define gen_seccomp_rules_add(ctx, syscalls, action) gen_seccomp_rules_add(ctx, syscalls, ARRAY_SIZE(syscalls), action) static void gen_seccomp_dump(scmp_filter_ctx ctx, const char *name) { @@ -209,6 +210,9 @@ int main(void) SCMP_SYS(waitid), SCMP_SYS(waitpid), }; + static const int soft_error_syscalls[] = { + SCMP_SYS(socket), + }; /* TODO: Handle debug and KILL vs TRAP. */ @@ -241,11 +245,13 @@ int main(void) printf("/* %s */\n", gen_seccomp_arches[i].name); printf("#define SECCOMP_BPF_AVAILABLE\n"); - if (gen_seccomp_rules_add(ctx, base_syscalls) < 0) + if (gen_seccomp_rules_add(ctx, base_syscalls, SCMP_ACT_ALLOW) < 0) + err(1, "seccomp_rules_add failed"); + if (gen_seccomp_rules_add(ctx, soft_error_syscalls, SCMP_ACT_ERRNO(ENOSYS)) < 0) err(1, "seccomp_rules_add failed"); gen_seccomp_dump(ctx, "base"); - if (gen_seccomp_rules_add(ctx, fork_syscalls) < 0) + if (gen_seccomp_rules_add(ctx, fork_syscalls, SCMP_ACT_ALLOW) < 0) err(1, "seccomp_rules_add failed"); gen_seccomp_dump(ctx, "fork"); |