mirror of
https://github.com/Dasharo/systemd.git
synced 2026-03-06 15:02:31 -08:00
seccomp: allow specifying arm64, mips, ppc (#4491)
"Secondary arch" table for mips is entirely speculative…
This commit is contained in:
committed by
Lennart Poettering
parent
67ae43665e
commit
aa34055ffb
@@ -1396,28 +1396,25 @@
|
||||
<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>
|
||||
|
||||
@@ -29,23 +29,49 @@
|
||||
#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;
|
||||
static const int seccomp_arches[] = {
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
SCMP_ARCH_X86,
|
||||
SCMP_ARCH_X86_64,
|
||||
SCMP_ARCH_X32,
|
||||
|
||||
r = seccomp_arch_add(c, SCMP_ARCH_X86_64);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
#elif defined(__arm__) || defined(__aarch64__)
|
||||
SCMP_ARCH_ARM,
|
||||
SCMP_ARCH_AARCH64,
|
||||
|
||||
r = seccomp_arch_add(c, SCMP_ARCH_X32);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return r;
|
||||
#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__)
|
||||
SCMP_ARCH_S390,
|
||||
SCMP_ARCH_S390X,
|
||||
#endif
|
||||
};
|
||||
|
||||
unsigned i;
|
||||
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;
|
||||
|
||||
r = seccomp_arch_add(c, SCMP_ARCH_S390X);
|
||||
if (r < 0 && r != -EEXIST)
|
||||
return 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;
|
||||
}
|
||||
|
||||
@@ -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();
|
||||
|
||||
|
||||
Reference in New Issue
Block a user