diff --git a/man/systemd.exec.xml b/man/systemd.exec.xml index 8079b4b210..bb38ea2467 100644 --- a/man/systemd.exec.xml +++ b/man/systemd.exec.xml @@ -1508,40 +1508,29 @@ RestrictAddressFamilies= - Restricts the set of socket address families - accessible to the processes of this unit. Takes a - space-separated list of address family names to whitelist, - such as - AF_UNIX, - AF_INET or - AF_INET6. When - prefixed with ~ the listed address - families will be applied as blacklist, otherwise as whitelist. - Note that this restricts access to the - socket2 - system call only. Sockets passed into the process by other - means (for example, by using socket activation with socket - units, see - systemd.socket5) - are unaffected. Also, sockets created with - socketpair() (which creates connected - AF_UNIX sockets only) are unaffected. Note that this option - has no effect on 32-bit x86 and is ignored (but works - correctly on x86-64). If running in user mode, or in system - mode, but without the CAP_SYS_ADMIN - capability (e.g. setting User=nobody), - NoNewPrivileges=yes is implied. By - default, no restriction applies, all address families are - accessible to processes. If assigned the empty string, any - previous list changes are undone. + Restricts the set of socket address families accessible to the processes of this unit. Takes a + space-separated list of address family names to whitelist, such as AF_UNIX, + AF_INET or AF_INET6. When prefixed with ~ the + listed address families will be applied as blacklist, otherwise as whitelist. Note that this restricts access + to the socket2 system call + only. Sockets passed into the process by other means (for example, by using socket activation with socket + units, see systemd.socket5) + are unaffected. Also, sockets created with socketpair() (which creates connected AF_UNIX + sockets only) are unaffected. Note that this option has no effect on 32-bit x86, s390, s390x, mips, mips-le, + ppc, ppc-le, pcc64, ppc64-le and is ignored (but works correctly on other architectures, including x86-64). If + running in user mode, or in system mode, but without the CAP_SYS_ADMIN capability + (e.g. setting User=nobody), NoNewPrivileges=yes is implied. By default, + no restrictions apply, all address families are accessible to processes. If assigned the empty string, any + previous address familiy restriction changes are undone. This setting does not affect commands prefixed with + +. - Use this option to limit exposure of processes to remote - systems, in particular via exotic network protocols. Note that - in most cases, the local AF_UNIX address - family should be included in the configured whitelist as it is - frequently used for local communication, including for + Use this option to limit exposure of processes to remote access, in particular via exotic and sensitive + network protocols, such as AF_PACKET. Note that in most cases, the local + AF_UNIX address family should be included in the configured whitelist as it is frequently + used for local communication, including for syslog2 - logging. This does not affect commands prefixed with +. + logging. diff --git a/src/shared/seccomp-util.c b/src/shared/seccomp-util.c index bd9c0aac60..609e0619af 100644 --- a/src/shared/seccomp-util.c +++ b/src/shared/seccomp-util.c @@ -873,6 +873,8 @@ int seccomp_protect_sysctl(void) { } int seccomp_restrict_address_families(Set *address_families, bool whitelist) { + +#if !SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN uint32_t arch; int r; @@ -1001,6 +1003,7 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist) { if (r < 0) log_debug_errno(r, "Failed to install socket family rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch)); } +#endif return 0; } diff --git a/src/shared/seccomp-util.h b/src/shared/seccomp-util.h index 4438e87fa6..2563fcd38a 100644 --- a/src/shared/seccomp-util.h +++ b/src/shared/seccomp-util.h @@ -76,6 +76,14 @@ int seccomp_restrict_address_families(Set *address_families, bool whitelist); int seccomp_restrict_realtime(void); int seccomp_memory_deny_write_execute(void); +#if defined(__i386__) || defined(__s390x__) || defined(__s390__) || defined(__powerpc64__) || defined(__powerpc__) || defined (__mips__) +/* On these archs, socket() is implemented via the socketcall() syscall multiplexer, and we can't restrict it hence via + * seccomp */ +#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 1 +#else +#define SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN 0 +#endif + extern const uint32_t seccomp_local_archs[]; #define SECCOMP_FOREACH_LOCAL_ARCH(arch) \ diff --git a/src/test/test-seccomp.c b/src/test/test-seccomp.c index 6f15879c45..54e7947c2f 100644 --- a/src/test/test-seccomp.c +++ b/src/test/test-seccomp.c @@ -283,8 +283,14 @@ static void test_restrict_address_families(void) { assert_se(fd >= 0); safe_close(fd); +#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + assert_se(fd >= 0); + safe_close(fd); +#else assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0); assert_se(errno == EAFNOSUPPORT); +#endif fd = socket(AF_NETLINK, SOCK_DGRAM, 0); assert_se(fd >= 0); @@ -300,11 +306,21 @@ static void test_restrict_address_families(void) { assert_se(fd >= 0); safe_close(fd); +#if SECCOMP_RESTRICT_ADDRESS_FAMILIES_BROKEN + fd = socket(AF_UNIX, SOCK_DGRAM, 0); + assert_se(fd >= 0); + safe_close(fd); + + fd = socket(AF_NETLINK, SOCK_DGRAM, 0); + assert_se(fd >= 0); + safe_close(fd); +#else assert_se(socket(AF_UNIX, SOCK_DGRAM, 0) < 0); assert_se(errno == EAFNOSUPPORT); assert_se(socket(AF_NETLINK, SOCK_DGRAM, 0) < 0); assert_se(errno == EAFNOSUPPORT); +#endif _exit(EXIT_SUCCESS); }