]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
seccomp: allow specifying arm64, mips, ppc (#4491)
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 1 Nov 2016 15:33:18 +0000 (11:33 -0400)
committerLennart Poettering <lennart@poettering.net>
Tue, 1 Nov 2016 15:33:18 +0000 (09:33 -0600)
"Secondary arch" table for mips is entirely speculative…

man/systemd.exec.xml
src/shared/seccomp-util.c
src/test/test-seccomp.c

index d3a19c505dacc47b9954a59f96ee9297ae9f28a0..11029ca18639edc71cb621946220b92d9e2c584b 100644 (file)
       <varlistentry>
         <term><varname>SystemCallArchitectures=</varname></term>
 
-        <listitem><para>Takes a space-separated list of architecture
-        identifiers to include in the system call filter. The known
-        architecture identifiers are <constant>x86</constant>,
-        <constant>x86-64</constant>, <constant>x32</constant>,
-        <constant>arm</constant>, <constant>s390</constant>,
-        <constant>s390x</constant> as well as the special identifier
-        <constant>native</constant>. Only system calls of the
-        specified architectures will be permitted to processes of this
-        unit. This is an effective way to disable compatibility with
-        non-native architectures for processes, for example to
-        prohibit execution of 32-bit x86 binaries on 64-bit x86-64
-        systems. The special <constant>native</constant> identifier
-        implicitly maps to the native architecture of the system (or
-        more strictly: to the architecture the system manager is
-        compiled for). 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. Note
-        that setting this option to a non-empty list implies that
-        <constant>native</constant> is included too. By default, this
-        option is set to the empty list, i.e. no architecture system
-        call filtering is applied.</para></listitem>
+        <listitem><para>Takes a space-separated list of architecture identifiers to
+        include in the system call filter. The known architecture identifiers are the same
+        as for <varname>ConditionArchitecture=</varname> described in
+        <citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry>,
+        as well as <constant>x32</constant>, <constant>mips64-n32</constant>,
+        <constant>mips64-le-n32</constant>, and the special identifier
+        <constant>native</constant>. Only system calls of the specified architectures will
+        be permitted to processes of this unit. This is an effective way to disable
+        compatibility with non-native architectures for processes, for example to prohibit
+        execution of 32-bit x86 binaries on 64-bit x86-64 systems. The special
+        <constant>native</constant> identifier implicitly maps to the native architecture
+        of the system (or more strictly: to the architecture the system manager is
+        compiled for). 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. Note that setting this option to a non-empty list implies that
+        <constant>native</constant> is included too. By default, this option is set to the
+        empty list, i.e. no architecture system call filtering is applied.
+        </para></listitem>
       </varlistentry>
 
       <varlistentry>
index 6252cd16a6090b82595a254a91477ddddbcb6341..1cbbb9d757c1f682f0357772b1e105962d7c19a7 100644 (file)
 #include "util.h"
 
 const char* seccomp_arch_to_string(uint32_t c) {
+        /* Maintain order used in <seccomp.h>.
+         *
+         * Names used here should be the same as those used for ConditionArchitecture=,
+         * except for "subarchitectures" like x32. */
 
-        if (c == SCMP_ARCH_NATIVE)
+        switch(c) {
+        case SCMP_ARCH_NATIVE:
                 return "native";
-        if (c == SCMP_ARCH_X86)
+        case SCMP_ARCH_X86:
                 return "x86";
-        if (c == SCMP_ARCH_X86_64)
+        case SCMP_ARCH_X86_64:
                 return "x86-64";
-        if (c == SCMP_ARCH_X32)
+        case SCMP_ARCH_X32:
                 return "x32";
-        if (c == SCMP_ARCH_ARM)
+        case SCMP_ARCH_ARM:
                 return "arm";
-        if (c == SCMP_ARCH_S390)
+        case SCMP_ARCH_AARCH64:
+                return "arm64";
+        case SCMP_ARCH_MIPS:
+                return "mips";
+        case SCMP_ARCH_MIPS64:
+                return "mips64";
+        case SCMP_ARCH_MIPS64N32:
+                return "mips64-n32";
+        case SCMP_ARCH_MIPSEL:
+                return "mips-le";
+        case SCMP_ARCH_MIPSEL64:
+                return "mips64-le";
+        case SCMP_ARCH_MIPSEL64N32:
+                return "mips64-le-n32";
+        case SCMP_ARCH_PPC:
+                return "ppc";
+        case SCMP_ARCH_PPC64:
+                return "ppc64";
+        case SCMP_ARCH_PPC64LE:
+                return "ppc64-le";
+        case SCMP_ARCH_S390:
                 return "s390";
-        if (c == SCMP_ARCH_S390X)
+        case SCMP_ARCH_S390X:
                 return "s390x";
-
-        return NULL;
+        default:
+                return NULL;
+        }
 }
 
 int seccomp_arch_from_string(const char *n, uint32_t *ret) {
@@ -64,6 +90,26 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) {
                 *ret = SCMP_ARCH_X32;
         else if (streq(n, "arm"))
                 *ret = SCMP_ARCH_ARM;
+        else if (streq(n, "arm64"))
+                *ret = SCMP_ARCH_AARCH64;
+        else if (streq(n, "mips"))
+                *ret = SCMP_ARCH_MIPS;
+        else if (streq(n, "mips64"))
+                *ret = SCMP_ARCH_MIPS64;
+        else if (streq(n, "mips64-n32"))
+                *ret = SCMP_ARCH_MIPS64N32;
+        else if (streq(n, "mips-le"))
+                *ret = SCMP_ARCH_MIPSEL;
+        else if (streq(n, "mips64-le"))
+                *ret = SCMP_ARCH_MIPSEL64;
+        else if (streq(n, "mips64-le-n32"))
+                *ret = SCMP_ARCH_MIPSEL64N32;
+        else if (streq(n, "ppc"))
+                *ret = SCMP_ARCH_PPC;
+        else if (streq(n, "ppc64"))
+                *ret = SCMP_ARCH_PPC64;
+        else if (streq(n, "ppc64-le"))
+                *ret = SCMP_ARCH_PPC64LE;
         else if (streq(n, "s390"))
                 *ret = SCMP_ARCH_S390;
         else if (streq(n, "s390x"))
@@ -101,41 +147,52 @@ finish:
         return r;
 }
 
-int seccomp_add_secondary_archs(scmp_filter_ctx c) {
-
-#if defined(__i386__) || defined(__x86_64__)
-        int r;
+int seccomp_add_secondary_archs(scmp_filter_ctx ctx) {
 
         /* Add in all possible secondary archs we are aware of that
          * this kernel might support. */
 
-        r = seccomp_arch_add(c, SCMP_ARCH_X86);
-        if (r < 0 && r != -EEXIST)
-                return r;
-
-        r = seccomp_arch_add(c, SCMP_ARCH_X86_64);
-        if (r < 0 && r != -EEXIST)
-                return r;
-
-        r = seccomp_arch_add(c, SCMP_ARCH_X32);
-        if (r < 0 && r != -EEXIST)
-                return r;
+        static const int seccomp_arches[] = {
+#if defined(__i386__) || defined(__x86_64__)
+                SCMP_ARCH_X86,
+                SCMP_ARCH_X86_64,
+                SCMP_ARCH_X32,
+
+#elif defined(__arm__) || defined(__aarch64__)
+                SCMP_ARCH_ARM,
+                SCMP_ARCH_AARCH64,
+
+#elif defined(__arm__) || defined(__aarch64__)
+                SCMP_ARCH_ARM,
+                SCMP_ARCH_AARCH64,
+
+#elif defined(__mips__) || defined(__mips64__)
+                SCMP_ARCH_MIPS,
+                SCMP_ARCH_MIPS64,
+                SCMP_ARCH_MIPS64N32,
+                SCMP_ARCH_MIPSEL,
+                SCMP_ARCH_MIPSEL64,
+                SCMP_ARCH_MIPSEL64N32,
+
+#elif defined(__powerpc__) || defined(__powerpc64__)
+                SCMP_ARCH_PPC,
+                SCMP_ARCH_PPC64,
+                SCMP_ARCH_PPC64LE,
 
 #elif defined(__s390__) || defined(__s390x__)
-        int r;
-
-        /* Add in all possible secondary archs we are aware of that
-         * this kernel might support. */
-
-        r = seccomp_arch_add(c, SCMP_ARCH_S390);
-        if (r < 0 && r != -EEXIST)
-                return r;
+                SCMP_ARCH_S390,
+                SCMP_ARCH_S390X,
+#endif
+        };
 
-        r = seccomp_arch_add(c, SCMP_ARCH_S390X);
-        if (r < 0 && r != -EEXIST)
-                return r;
+        unsigned i;
+        int r;
 
-#endif
+        for (i = 0; i < ELEMENTSOF(seccomp_arches); i++) {
+                r = seccomp_arch_add(ctx, seccomp_arches[i]);
+                if (r < 0 && r != -EEXIST)
+                        return r;
+        }
 
         return 0;
 }
index 0060ecdf028207918e47395af829c8b637aa56a1..43d1567288b1d38a5b1397c1c0230f4bc78d8450 100644 (file)
@@ -25,6 +25,8 @@
 #include "macro.h"
 #include "process-util.h"
 #include "seccomp-util.h"
+#include "string-util.h"
+#include "util.h"
 
 static void test_seccomp_arch_to_string(void) {
         uint32_t a, b;
@@ -38,6 +40,36 @@ static void test_seccomp_arch_to_string(void) {
         assert_se(a == b);
 }
 
+static void test_architecture_table(void) {
+        const char *n, *n2;
+
+        NULSTR_FOREACH(n,
+                       "native\0"
+                       "x86\0"
+                       "x86-64\0"
+                       "x32\0"
+                       "arm\0"
+                       "arm64\0"
+                       "mips\0"
+                       "mips64\0"
+                       "mips64-n32\0"
+                       "mips-le\0"
+                       "mips64-le\0"
+                       "mips64-le-n32\0"
+                       "ppc\0"
+                       "ppc64\0"
+                       "ppc64-le\0"
+                       "s390\0"
+                       "s390x\0") {
+                uint32_t c;
+
+                assert_se(seccomp_arch_from_string(n, &c) >= 0);
+                n2 = seccomp_arch_to_string(c);
+                log_info("seccomp-arch: %s → 0x%"PRIx32" → %s", n, c, n2);
+                assert_se(streq_ptr(n, n2));
+        }
+}
+
 static void test_syscall_filter_set_find(void) {
         assert_se(!syscall_filter_set_find(NULL));
         assert_se(!syscall_filter_set_find(""));
@@ -96,6 +128,7 @@ static void test_filter_sets(void) {
 int main(int argc, char *argv[]) {
 
         test_seccomp_arch_to_string();
+        test_architecture_table();
         test_syscall_filter_set_find();
         test_filter_sets();