diff options
author | Evgeny Vereshchagin <evvers@ya.ru> | 2017-02-07 05:06:54 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-02-07 05:06:54 +0300 |
commit | d52fbaa58c6b0c928d1d9a2d015edcc63acb0df6 (patch) | |
tree | a47f04c35e2b3b67bfa153e25bb09d977e74f318 | |
parent | 1fb85797493dde55c9db9725970343a064e9e062 (diff) | |
parent | 142bd808a1a1a4a7dc4e75b7a9d1bda6c1530dfd (diff) |
Merge pull request #5225 from poettering/seccomp-socket
make RestrictAddressFamilies= officially a NOP on i386
-rw-r--r-- | man/systemd.exec.xml | 55 | ||||
-rw-r--r-- | src/shared/seccomp-util.c | 3 | ||||
-rw-r--r-- | src/shared/seccomp-util.h | 8 | ||||
-rw-r--r-- | src/test/test-seccomp.c | 16 |
4 files changed, 49 insertions, 33 deletions
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 @@ <varlistentry> <term><varname>RestrictAddressFamilies=</varname></term> - <listitem><para>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 - <constant>AF_UNIX</constant>, - <constant>AF_INET</constant> or - <constant>AF_INET6</constant>. When - prefixed with <constant>~</constant> the listed address - families will be applied as blacklist, otherwise as whitelist. - Note that this restricts access to the - <citerefentry project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry> - system call only. Sockets passed into the process by other - means (for example, by using socket activation with socket - units, see - <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>) - are unaffected. Also, sockets created with - <function>socketpair()</function> (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 <constant>CAP_SYS_ADMIN</constant> - capability (e.g. setting <varname>User=nobody</varname>), - <varname>NoNewPrivileges=yes</varname> 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.</para> - - <para>Use this option to limit exposure of processes to remote - systems, in particular via exotic network protocols. Note that - in most cases, the local <constant>AF_UNIX</constant> address - family should be included in the configured whitelist as it is - frequently used for local communication, including for + <listitem><para>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 <constant>AF_UNIX</constant>, + <constant>AF_INET</constant> or <constant>AF_INET6</constant>. When prefixed with <constant>~</constant> the + listed address families will be applied as blacklist, otherwise as whitelist. Note that this restricts access + to the <citerefentry + project='man-pages'><refentrytitle>socket</refentrytitle><manvolnum>2</manvolnum></citerefentry> system call + only. Sockets passed into the process by other means (for example, by using socket activation with socket + units, see <citerefentry><refentrytitle>systemd.socket</refentrytitle><manvolnum>5</manvolnum></citerefentry>) + are unaffected. Also, sockets created with <function>socketpair()</function> (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 <constant>CAP_SYS_ADMIN</constant> capability + (e.g. setting <varname>User=nobody</varname>), <varname>NoNewPrivileges=yes</varname> 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 + <literal>+</literal>.</para> + + <para>Use this option to limit exposure of processes to remote access, in particular via exotic and sensitive + network protocols, such as <constant>AF_PACKET</constant>. Note that in most cases, the local + <constant>AF_UNIX</constant> address family should be included in the configured whitelist as it is frequently + used for local communication, including for <citerefentry><refentrytitle>syslog</refentrytitle><manvolnum>2</manvolnum></citerefentry> - logging. This does not affect commands prefixed with <literal>+</literal>.</para></listitem> + logging.</para></listitem> </varlistentry> <varlistentry> 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); } |