aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMathias Krause <minipli@grsecurity.net>2024-01-23 11:12:20 +0100
committerMike Gilbert <floppym@gentoo.org>2024-07-22 17:05:57 -0400
commita9440d0bf71c665aea026a7c06603bca2c80ae75 (patch)
tree33acb69158a104dd70da032fb1f658ab50b393c4 /seccomp-bpf.c
parentmake-seccomp-filters.sh: split cflags/ldflags for libseccomp (diff)
downloadpax-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.c16
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");