From 4c3a917617260956faeb4eceb606c316f6bea407 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Sat, 30 Sep 2017 14:08:26 +0200 Subject: [PATCH 1/4] seccomp: include prlimit64 and ugetrlimit in @default Also, move prlimit64() out of @resources. prlimit64() may be used both for getting and setting resource limits, and is implicitly called by glibc at various places, on some archs, the same was as getrlimit(). SImilar, igetrlimit() is an arch-specific replacement for getrlimit(), and hence should be whitelisted at the same place as getrlimit() and prlimit64(). Also see: https://lists.freedesktop.org/archives/systemd-devel/2017-September/039543.html --- src/nspawn/nspawn-seccomp.c | 1 - src/shared/seccomp-util.c | 3 ++- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/nspawn/nspawn-seccomp.c b/src/nspawn/nspawn-seccomp.c index 196766dc98..92d8103ad5 100644 --- a/src/nspawn/nspawn-seccomp.c +++ b/src/nspawn/nspawn-seccomp.c @@ -136,7 +136,6 @@ static int seccomp_add_default_syscall_filter( { 0, "syncfs" }, { 0, "sysinfo" }, { 0, "tee" }, - { 0, "ugetrlimit" }, { 0, "umask" }, { 0, "uname" }, { 0, "userfaultfd" }, diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 41e0070b12..6a4d30bac1 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -306,6 +306,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "membarrier\0" "nanosleep\0" "pause\0" + "prlimit64\0" "restart_syscall\0" "rt_sigreturn\0" "sched_yield\0" @@ -314,6 +315,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "set_tid_address\0" "sigreturn\0" "time\0" + "ugetrlimit\0" }, [SYSCALL_FILTER_SET_BASIC_IO] = { .name = "@basic-io", @@ -693,7 +695,6 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = { "migrate_pages\0" "move_pages\0" "nice\0" - "prlimit64\0" "sched_setaffinity\0" "sched_setattr\0" "sched_setparam\0" From ff217dc3afe95504e48aeb8d8ad7fb7f53ce9cb1 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Oct 2017 11:23:07 +0200 Subject: [PATCH 2/4] seccomp: react gracefully if we can't translate a syscall name When a libseccomp implementation doesn't know a syscall yet, that's no reason for us to fail completely. Instead, debug log, and proceed. This hopefully fixes the preadv2/pwritev2 issues pointed out here: https://github.com/systemd/systemd/pull/6952#issuecomment-334302923 --- src/shared/seccomp-util.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 6a4d30bac1..64ea86a677 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -807,8 +807,8 @@ int seccomp_add_syscall_filter_item(scmp_filter_ctx *seccomp, const char *name, id = seccomp_syscall_resolve_name(name); if (id == __NR_SCMP_ERROR) { - log_debug("System call %s is not known!", name); - return -EINVAL; /* Not known at all? Then that's a real error */ + log_debug("System call %s is not known, ignoring.", name); + return 0; } r = seccomp_rule_add_exact(seccomp, action, id, 0); @@ -1501,7 +1501,6 @@ int seccomp_filter_set_add(Set *filter, bool add, const SyscallFilterSet *set) { if (!more) return -ENXIO; - r = seccomp_filter_set_add(filter, add, more); if (r < 0) return r; @@ -1509,8 +1508,10 @@ int seccomp_filter_set_add(Set *filter, bool add, const SyscallFilterSet *set) { int id; id = seccomp_syscall_resolve_name(i); - if (id == __NR_SCMP_ERROR) - return -ENXIO; + if (id == __NR_SCMP_ERROR) { + log_debug("Couldn't resolve system call, ignoring: %s", i); + continue; + } if (add) { r = set_put(filter, INT_TO_PTR(id + 1)); From 1c6af69b2d25af90e210bc21cc378fb4a6c96316 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Oct 2017 11:24:51 +0200 Subject: [PATCH 3/4] seccomp: always handle seccomp_load() failing the same way Unfortunately libseccomp doesn't return (nor document) clean error codes, hence until then only check for specific error codes that we propagate, but ignore (but debug log) all others. Do this at one more place, we are already doing that at all others. --- src/shared/seccomp-util.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index 64ea86a677..a3728ff7b2 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1187,7 +1187,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { if (r < 0) break; } - if (r < 0) { log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); continue; @@ -1212,7 +1211,6 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { if (r < 0) break; } - if (r < 0) { log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); continue; @@ -1453,7 +1451,13 @@ int seccomp_restrict_archs(Set *archs) { if (r < 0) return r; - return seccomp_load(seccomp); + r = seccomp_load(seccomp); + if (IN_SET(r, -EPERM, -EACCES)) + return r; + if (r < 0) + log_debug_errno(r, "Failed to restrict system call architectures, skipping: %m"); + + return 0; } int parse_syscall_archs(char **l, Set **archs) { From 448ac526a3fc95c4b4bfa24fe25ea95a88127c49 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 5 Oct 2017 11:26:09 +0200 Subject: [PATCH 4/4] seccomp: ignore (and debug log) errors by all invocations of seccomp_rule_add_exact() System calls might exist on some archs but not on others, or might be multiplexed but not on others. Ignore such errors when putting together a filter at this location like we already do it on all others. --- src/shared/seccomp-util.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index a3728ff7b2..73dc571b6b 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -1549,8 +1549,10 @@ int seccomp_lock_personality(unsigned long personality) { SCMP_SYS(personality), 1, SCMP_A0(SCMP_CMP_NE, personality)); - if (r < 0) - return r; + if (r < 0) { + log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); + continue; + } r = seccomp_load(seccomp); if (IN_SET(r, -EPERM, -EACCES))