Skip to content

Commit

Permalink
seccomp: make socket() fail with -ENOSYS
Browse files Browse the repository at this point in the history
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>
  • Loading branch information
minipli-oss authored and floppym committed Jul 22, 2024
1 parent b16cce4 commit a9440d0
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 43 deletions.
16 changes: 11 additions & 5 deletions seccomp-bpf.c
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
const char argv0[] = "seccomp-bpf";

#include <err.h>
#include <errno.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
Expand Down Expand Up @@ -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;
Expand All @@ -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)
{
Expand Down Expand Up @@ -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. */

Expand Down Expand Up @@ -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");

Expand Down
Loading

0 comments on commit a9440d0

Please sign in to comment.