summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorEvgeny Vereshchagin <evvers@ya.ru>2017-02-07 05:06:54 +0300
committerGitHub <noreply@github.com>2017-02-07 05:06:54 +0300
commitd52fbaa58c6b0c928d1d9a2d015edcc63acb0df6 (patch)
treea47f04c35e2b3b67bfa153e25bb09d977e74f318
parent1fb85797493dde55c9db9725970343a064e9e062 (diff)
parent142bd808a1a1a4a7dc4e75b7a9d1bda6c1530dfd (diff)
Merge pull request #5225 from poettering/seccomp-socket
make RestrictAddressFamilies= officially a NOP on i386
-rw-r--r--man/systemd.exec.xml55
-rw-r--r--src/shared/seccomp-util.c3
-rw-r--r--src/shared/seccomp-util.h8
-rw-r--r--src/test/test-seccomp.c16
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);
}