]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/shared/seccomp-util.c
nspawn,shared: make ERRNO_IS_SECCOMP_FATAL an inline func with _NEG_ variant
[thirdparty/systemd.git] / src / shared / seccomp-util.c
index 0996ca66254a83b14324b9bde3de0ad477d2be17..66c564aea2852e025f71796eb9b044840760ba49 100644 (file)
@@ -18,6 +18,7 @@
 #include "env-util.h"
 #include "errno-list.h"
 #include "macro.h"
+#include "namespace-util.h"
 #include "nsflags.h"
 #include "nulstr-util.h"
 #include "process-util.h"
@@ -46,6 +47,8 @@ uint32_t seccomp_local_archs[] = {
                 SCMP_ARCH_AARCH64,     /* native */
 #elif defined(__arm__)
                 SCMP_ARCH_ARM,
+#elif defined(__loongarch_lp64)
+                SCMP_ARCH_LOONGARCH64,
 #elif defined(__mips__) && __BYTE_ORDER == __BIG_ENDIAN && _MIPS_SIM == _MIPS_SIM_ABI32
                 SCMP_ARCH_MIPSEL,
                 SCMP_ARCH_MIPS,        /* native */
@@ -80,6 +83,11 @@ uint32_t seccomp_local_archs[] = {
                 SCMP_ARCH_MIPSEL64,
                 SCMP_ARCH_MIPS64N32,
                 SCMP_ARCH_MIPSEL64N32, /* native */
+#elif defined(__hppa64__) && defined(SCMP_ARCH_PARISC) && defined(SCMP_ARCH_PARISC64)
+                SCMP_ARCH_PARISC,
+                SCMP_ARCH_PARISC64,    /* native */
+#elif defined(__hppa__) && defined(SCMP_ARCH_PARISC)
+                SCMP_ARCH_PARISC,
 #elif defined(__powerpc64__) && __BYTE_ORDER == __BIG_ENDIAN
                 SCMP_ARCH_PPC,
                 SCMP_ARCH_PPC64LE,
@@ -120,6 +128,10 @@ const char* seccomp_arch_to_string(uint32_t c) {
                 return "arm";
         case SCMP_ARCH_AARCH64:
                 return "arm64";
+#ifdef SCMP_ARCH_LOONGARCH64
+        case SCMP_ARCH_LOONGARCH64:
+                return "loongarch64";
+#endif
         case SCMP_ARCH_MIPS:
                 return "mips";
         case SCMP_ARCH_MIPS64:
@@ -132,6 +144,14 @@ const char* seccomp_arch_to_string(uint32_t c) {
                 return "mips64-le";
         case SCMP_ARCH_MIPSEL64N32:
                 return "mips64-le-n32";
+#ifdef SCMP_ARCH_PARISC
+        case SCMP_ARCH_PARISC:
+                return "parisc";
+#endif
+#ifdef SCMP_ARCH_PARISC64
+        case SCMP_ARCH_PARISC64:
+                return "parisc64";
+#endif
         case SCMP_ARCH_PPC:
                 return "ppc";
         case SCMP_ARCH_PPC64:
@@ -169,6 +189,10 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) {
                 *ret = SCMP_ARCH_ARM;
         else if (streq(n, "arm64"))
                 *ret = SCMP_ARCH_AARCH64;
+#ifdef SCMP_ARCH_LOONGARCH64
+        else if (streq(n, "loongarch64"))
+                *ret = SCMP_ARCH_LOONGARCH64;
+#endif
         else if (streq(n, "mips"))
                 *ret = SCMP_ARCH_MIPS;
         else if (streq(n, "mips64"))
@@ -181,6 +205,14 @@ int seccomp_arch_from_string(const char *n, uint32_t *ret) {
                 *ret = SCMP_ARCH_MIPSEL64;
         else if (streq(n, "mips64-le-n32"))
                 *ret = SCMP_ARCH_MIPSEL64N32;
+#ifdef SCMP_ARCH_PARISC
+        else if (streq(n, "parisc"))
+                *ret = SCMP_ARCH_PARISC;
+#endif
+#ifdef SCMP_ARCH_PARISC64
+        else if (streq(n, "parisc64"))
+                *ret = SCMP_ARCH_PARISC64;
+#endif
         else if (streq(n, "ppc"))
                 *ret = SCMP_ARCH_PPC;
         else if (streq(n, "ppc64"))
@@ -300,6 +332,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "exit_group\0"
                 "futex\0"
                 "futex_time64\0"
+                "futex_waitv\0"
                 "get_robust_list\0"
                 "get_thread_area\0"
                 "getegid\0"
@@ -334,6 +367,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "pause\0"
                 "prlimit64\0"
                 "restart_syscall\0"
+                "riscv_flush_icache\0"
+                "riscv_hwprobe\0"
                 "rseq\0"
                 "rt_sigreturn\0"
                 "sched_getaffinity\0"
@@ -425,9 +460,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "pidfd_getfd\0"
                 "ptrace\0"
                 "rtas\0"
-#if defined __s390__ || defined __s390x__
                 "s390_runtime_instr\0"
-#endif
                 "sys_debug_setcontext\0"
         },
         [SYSCALL_FILTER_SET_FILE_SYSTEM] = {
@@ -698,6 +731,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "open_by_handle_at\0"
                 "pivot_root\0"
                 "quotactl\0"
+                "quotactl_fd\0"
                 "setdomainname\0"
                 "setfsuid\0"
                 "setfsuid32\0"
@@ -751,10 +785,8 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "pciconfig_iobase\0"
                 "pciconfig_read\0"
                 "pciconfig_write\0"
-#if defined __s390__ || defined __s390x__
                 "s390_pci_mmio_read\0"
                 "s390_pci_mmio_write\0"
-#endif
         },
         [SYSCALL_FILTER_SET_REBOOT] = {
                 .name = "@reboot",
@@ -778,9 +810,19 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "sched_setparam\0"
                 "sched_setscheduler\0"
                 "set_mempolicy\0"
+                "set_mempolicy_home_node\0"
                 "setpriority\0"
                 "setrlimit\0"
         },
+        [SYSCALL_FILTER_SET_SANDBOX] = {
+                .name = "@sandbox",
+                .help = "Sandbox functionality",
+                .value =
+                "landlock_add_rule\0"
+                "landlock_create_ruleset\0"
+                "landlock_restrict_self\0"
+                "seccomp\0"
+        },
         [SYSCALL_FILTER_SET_SETUID] = {
                 .name = "@setuid",
                 .help = "Operations for changing user/group credentials",
@@ -858,6 +900,7 @@ const SyscallFilterSet syscall_filter_sets[_SYSCALL_FILTER_SET_MAX] = {
                 "@signal\0"
                 "@sync\0"
                 "@timer\0"
+                "arm_fadvise64_64\0"
                 "capget\0"
                 "capset\0"
                 "copy_file_range\0"
@@ -1020,7 +1063,6 @@ static int add_syscall_filter_set(
                 bool log_missing,
                 char ***added) {
 
-        const char *sys;
         int r;
 
         /* Any syscalls that are handled are added to the *added strv. It needs to be initialized. */
@@ -1049,7 +1091,7 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 r = seccomp_init_for_arch(&seccomp, arch, default_action);
                 if (r < 0)
@@ -1060,10 +1102,11 @@ int seccomp_load_syscall_filter_set(uint32_t default_action, const SyscallFilter
                         return log_debug_errno(r, "Failed to add filter set: %m");
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install filter set for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1083,7 +1126,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* filter
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 void *syscall_id, *val;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 r = seccomp_init_for_arch(&seccomp, arch, default_action);
                 if (r < 0)
@@ -1121,7 +1164,7 @@ int seccomp_load_syscall_filter_set_raw(uint32_t default_action, Hashmap* filter
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
                         log_debug_errno(r, "Failed to install system call filter for architecture %s, skipping: %m",
@@ -1150,7 +1193,6 @@ int seccomp_parse_syscall_filter(
 
         if (name[0] == '@') {
                 const SyscallFilterSet *set;
-                const char *i;
 
                 set = syscall_filter_set_find(name);
                 if (!set) {
@@ -1163,10 +1205,10 @@ int seccomp_parse_syscall_filter(
                 }
 
                 NULSTR_FOREACH(i, set->value) {
-                        /* Call ourselves again, for the group to parse. Note that we downgrade logging here (i.e. take
-                         * away the SECCOMP_PARSE_LOG flag) since any issues in the group table are our own problem,
-                         * not a problem in user configuration data and we shouldn't pretend otherwise by complaining
-                         * about them. */
+                        /* Call ourselves again, for the group to parse. Note that we downgrade logging here
+                         * (i.e. take away the SECCOMP_PARSE_LOG flag) since any issues in the group table
+                         * are our own problem, not a problem in user configuration data and we shouldn't
+                         * pretend otherwise by complaining about them. */
                         r = seccomp_parse_syscall_filter(i, errno_num, filter, flags &~ SECCOMP_PARSE_LOG, unit, filename, line);
                         if (r < 0)
                                 return r;
@@ -1184,9 +1226,9 @@ int seccomp_parse_syscall_filter(
                         return 0;
                 }
 
-                /* If we previously wanted to forbid a syscall and now we want to allow it, then remove
-                 * it from the list. The entries in allow-list with non-negative error value will be
-                 * handled with SCMP_ACT_ERRNO() instead of the default action. */
+                /* If we previously wanted to forbid a syscall and now we want to allow it, then remove it
+                 * from the list. The entries in allow-list with non-negative error value will be handled
+                 * with SCMP_ACT_ERRNO() instead of the default action. */
                 if (!FLAGS_SET(flags, SECCOMP_PARSE_INVERT) == FLAGS_SET(flags, SECCOMP_PARSE_ALLOW_LIST) ||
                     (FLAGS_SET(flags, SECCOMP_PARSE_INVERT | SECCOMP_PARSE_ALLOW_LIST) && errno_num >= 0)) {
                         r = hashmap_put(filter, INT_TO_PTR(id + 1), INT_TO_PTR(errno_num));
@@ -1225,7 +1267,7 @@ int seccomp_restrict_namespaces(unsigned long retain) {
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
                 if (r < 0)
@@ -1244,19 +1286,20 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                                 SCMP_SYS(clone3),
                                 0);
                 if (r < 0)
-                        log_debug_errno(r, "Failed to add clone3() rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add clone3() rule for architecture %s, ignoring: %m",
+                                        seccomp_arch_to_string(arch));
 
                 if ((retain & NAMESPACE_FLAGS_ALL) == 0)
-                        /* If every single kind of namespace shall be prohibited, then let's block the whole setns() syscall
-                         * altogether. */
+                        /* If every single kind of namespace shall be prohibited, then let's block the whole
+                         * setns() syscall altogether. */
                         r = seccomp_rule_add_exact(
                                         seccomp,
                                         SCMP_ACT_ERRNO(EPERM),
                                         SCMP_SYS(setns),
                                         0);
                 else
-                        /* Otherwise, block only the invocations with the appropriate flags in the loop below, but also the
-                         * special invocation with a zero flags argument, right here. */
+                        /* Otherwise, block only the invocations with the appropriate flags in the loop
+                         * below, but also the special invocation with a zero flags argument, right here. */
                         r = seccomp_rule_add_exact(
                                         seccomp,
                                         SCMP_ACT_ERRNO(EPERM),
@@ -1264,20 +1307,21 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                                         1,
                                         SCMP_A1(SCMP_CMP_EQ, 0));
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
-                for (unsigned i = 0; namespace_flag_map[i].name; i++) {
+                for (unsigned i = 0; namespace_info[i].proc_name; i++) {
                         unsigned long f;
 
-                        f = namespace_flag_map[i].flag;
+                        f = namespace_info[i].clone_flag;
                         if (FLAGS_SET(retain, f)) {
-                                log_debug("Permitting %s.", namespace_flag_map[i].name);
+                                log_debug("Permitting %s.", namespace_info[i].proc_name);
                                 continue;
                         }
 
-                        log_debug("Blocking %s.", namespace_flag_map[i].name);
+                        log_trace("Blocking %s.", namespace_info[i].proc_name);
 
                         r = seccomp_rule_add_exact(
                                         seccomp,
@@ -1286,7 +1330,8 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                                         1,
                                         SCMP_A0(SCMP_CMP_MASKED_EQ, f, f));
                         if (r < 0) {
-                                log_debug_errno(r, "Failed to add unshare() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                log_debug_errno(r, "Failed to add unshare() rule for architecture %s, skipping: %m",
+                                                seccomp_arch_to_string(arch));
                                 break;
                         }
 
@@ -1306,7 +1351,8 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                                                 1,
                                                 SCMP_A1(SCMP_CMP_MASKED_EQ, f, f));
                         if (r < 0) {
-                                log_debug_errno(r, "Failed to add clone() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                log_debug_errno(r, "Failed to add clone() rule for architecture %s, skipping: %m",
+                                                seccomp_arch_to_string(arch));
                                 break;
                         }
 
@@ -1318,7 +1364,8 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                                                 1,
                                                 SCMP_A1(SCMP_CMP_MASKED_EQ, f, f));
                                 if (r < 0) {
-                                        log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                        log_debug_errno(r, "Failed to add setns() rule for architecture %s, skipping: %m",
+                                                        seccomp_arch_to_string(arch));
                                         break;
                                 }
                         }
@@ -1327,10 +1374,11 @@ int seccomp_restrict_namespaces(unsigned long retain) {
                         continue;
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install namespace restriction rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install namespace restriction rules for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1343,10 +1391,13 @@ int seccomp_protect_sysctl(void) {
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 if (IN_SET(arch,
                            SCMP_ARCH_AARCH64,
+#ifdef SCMP_ARCH_LOONGARCH64
+                           SCMP_ARCH_LOONGARCH64,
+#endif
 #ifdef SCMP_ARCH_RISCV64
                            SCMP_ARCH_RISCV64,
 #endif
@@ -1365,15 +1416,17 @@ int seccomp_protect_sysctl(void) {
                                 SCMP_SYS(_sysctl),
                                 0);
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add _sysctl() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add _sysctl() rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install sysctl protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install sysctl protection rules for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1402,10 +1455,11 @@ int seccomp_protect_syslog(void) {
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install syslog protection rules for architecture %s, skipping %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install syslog protection rules for architecture %s, skipping %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1419,7 +1473,7 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 bool supported;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 switch (arch) {
 
@@ -1427,6 +1481,9 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                 case SCMP_ARCH_X32:
                 case SCMP_ARCH_ARM:
                 case SCMP_ARCH_AARCH64:
+#ifdef SCMP_ARCH_LOONGARCH64
+                case SCMP_ARCH_LOONGARCH64:
+#endif
                 case SCMP_ARCH_MIPSEL64N32:
                 case SCMP_ARCH_MIPS64N32:
                 case SCMP_ARCH_MIPSEL64:
@@ -1443,6 +1500,12 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                 case SCMP_ARCH_X86:
                 case SCMP_ARCH_MIPSEL:
                 case SCMP_ARCH_MIPS:
+#ifdef SCMP_ARCH_PARISC
+                case SCMP_ARCH_PARISC:
+#endif
+#ifdef SCMP_ARCH_PARISC64
+                case SCMP_ARCH_PARISC64:
+#endif
                 case SCMP_ARCH_PPC:
                 case SCMP_ARCH_PPC64:
                 case SCMP_ARCH_PPC64LE:
@@ -1492,7 +1555,8 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                                                 SCMP_SYS(socket),
                                                 0);
                                 if (r < 0) {
-                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m",
+                                                        seccomp_arch_to_string(arch));
                                         continue;
                                 }
 
@@ -1506,7 +1570,8 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                                                 1,
                                                 SCMP_A0(SCMP_CMP_LT, first));
                                 if (r < 0) {
-                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m",
+                                                        seccomp_arch_to_string(arch));
                                         continue;
                                 }
 
@@ -1518,7 +1583,8 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                                                 1,
                                                 SCMP_A0(SCMP_CMP_GT, last));
                                 if (r < 0) {
-                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m",
+                                                        seccomp_arch_to_string(arch));
                                         continue;
                                 }
 
@@ -1538,7 +1604,8 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                                                 break;
                                 }
                                 if (r < 0) {
-                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                        log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m",
+                                                        seccomp_arch_to_string(arch));
                                         continue;
                                 }
                         }
@@ -1560,22 +1627,24 @@ int seccomp_restrict_address_families(Set *address_families, bool allow_list) {
                                         break;
                         }
                         if (r < 0) {
-                                log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                log_debug_errno(r, "Failed to add socket() rule for architecture %s, skipping: %m",
+                                                seccomp_arch_to_string(arch));
                                 continue;
                         }
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install socket family rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install socket family rules for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
 }
 
-int seccomp_restrict_realtime(void) {
+int seccomp_restrict_realtime_full(int error_code) {
         static const int permitted_policies[] = {
                 SCHED_OTHER,
                 SCHED_BATCH,
@@ -1586,6 +1655,8 @@ int seccomp_restrict_realtime(void) {
         uint32_t arch;
         unsigned i;
 
+        assert(error_code > 0);
+
         /* Determine the highest policy constant we want to allow */
         for (i = 0; i < ELEMENTSOF(permitted_policies); i++)
                 if (permitted_policies[i] > max_policy)
@@ -1595,7 +1666,7 @@ int seccomp_restrict_realtime(void) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 int p;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
                 if (r < 0)
@@ -1619,12 +1690,13 @@ int seccomp_restrict_realtime(void) {
                         /* Deny this policy */
                         r = seccomp_rule_add_exact(
                                         seccomp,
-                                        SCMP_ACT_ERRNO(EPERM),
+                                        SCMP_ACT_ERRNO(error_code),
                                         SCMP_SYS(sched_setscheduler),
                                         1,
                                         SCMP_A1(SCMP_CMP_EQ, p));
                         if (r < 0) {
-                                log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                                log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m",
+                                                seccomp_arch_to_string(arch));
                                 continue;
                         }
                 }
@@ -1633,20 +1705,22 @@ int seccomp_restrict_realtime(void) {
                  * are unsigned here, hence no need no check for < 0 values. */
                 r = seccomp_rule_add_exact(
                                 seccomp,
-                                SCMP_ACT_ERRNO(EPERM),
+                                SCMP_ACT_ERRNO(error_code),
                                 SCMP_SYS(sched_setscheduler),
                                 1,
                                 SCMP_A1(SCMP_CMP_GT, max_policy));
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to install realtime protection rules for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to install realtime protection rules for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1673,7 +1747,7 @@ static int add_seccomp_syscall_filter(scmp_filter_ctx seccomp,
 }
 
 /* For known architectures, check that syscalls are indeed defined or not. */
-#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || (defined(__riscv) && __riscv_xlen == 64)
+#if defined(__x86_64__) || defined(__arm__) || defined(__aarch64__) || defined(__loongarch_lp64) || (defined(__riscv) && __riscv_xlen == 64)
 assert_cc(SCMP_SYS(shmget) > 0);
 assert_cc(SCMP_SYS(shmat) > 0);
 assert_cc(SCMP_SYS(shmdt) > 0);
@@ -1687,13 +1761,17 @@ int seccomp_memory_deny_write_execute(void) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
                 int filter_syscall = 0, block_syscall = 0, shmat_syscall = 0, r;
 
-                log_debug("Operating on architecture: %s", seccomp_arch_to_string(arch));
+                log_trace("Operating on architecture: %s", seccomp_arch_to_string(arch));
 
                 switch (arch) {
 
                 /* Note that on some architectures shmat() isn't available, and the call is multiplexed through ipc().
                  * We ignore that here, which means there's still a way to get writable/executable
-                 * memory, if an IPC key is mapped like this. That's a pity, but no total loss. */
+                 * memory, if an IPC key is mapped like this. That's a pity, but no total loss.
+                 *
+                 * Also, PARISC isn't here right now because it still needs executable memory, but work is in progress
+                 * on that front (kernel work done in 5.18).
+                 */
 
                 case SCMP_ARCH_X86:
                 case SCMP_ARCH_S390:
@@ -1718,16 +1796,19 @@ int seccomp_memory_deny_write_execute(void) {
                 case SCMP_ARCH_X86_64:
                 case SCMP_ARCH_X32:
                 case SCMP_ARCH_AARCH64:
+#ifdef SCMP_ARCH_LOONGARCH64
+                case SCMP_ARCH_LOONGARCH64:
+#endif
 #ifdef SCMP_ARCH_RISCV64
                 case SCMP_ARCH_RISCV64:
 #endif
-                        filter_syscall = SCMP_SYS(mmap); /* amd64, x32, arm64 and riscv64 have only mmap */
+                        filter_syscall = SCMP_SYS(mmap); /* amd64, x32, arm64, loongarch64 and riscv64 have only mmap */
                         shmat_syscall = SCMP_SYS(shmat);
                         break;
 
                 /* Please add more definitions here, if you port systemd to other architectures! */
 
-#if !defined(__i386__) && !defined(__x86_64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__s390__) && !defined(__s390x__) && !(defined(__riscv) && __riscv_xlen == 64)
+#if !defined(__i386__) && !defined(__x86_64__) && !defined(__hppa__) && !defined(__hppa64__) && !defined(__powerpc__) && !defined(__powerpc64__) && !defined(__arm__) && !defined(__aarch64__) && !defined(__s390__) && !defined(__s390x__) && !(defined(__riscv) && __riscv_xlen == 64) && !defined(__loongarch_lp64)
 #warning "Consider adding the right mmap() syscall definitions here!"
 #endif
                 }
@@ -1773,7 +1854,7 @@ int seccomp_memory_deny_write_execute(void) {
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
                         log_debug_errno(r, "Failed to install MemoryDenyWriteExecute= rule for architecture %s, skipping: %m",
@@ -1846,7 +1927,7 @@ int seccomp_restrict_archs(Set *archs) {
                 return r;
 
         r = seccomp_load(seccomp);
-        if (ERRNO_IS_SECCOMP_FATAL(r))
+        if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                 return r;
         if (r < 0)
                 log_debug_errno(r, "Failed to restrict system call architectures, skipping: %m");
@@ -1878,7 +1959,6 @@ int parse_syscall_archs(char **l, Set **ret_archs) {
 }
 
 int seccomp_filter_set_add(Hashmap *filter, bool add, const SyscallFilterSet *set) {
-        const char *i;
         int r;
 
         assert(set);
@@ -1937,15 +2017,17 @@ int seccomp_lock_personality(unsigned long personality) {
                                 1,
                                 SCMP_A0(SCMP_CMP_NE, personality));
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add scheduler rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to enable personality lock for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to enable personality lock for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -1968,7 +2050,8 @@ int seccomp_protect_hostname(void) {
                                 SCMP_SYS(sethostname),
                                 0);
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add sethostname() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add sethostname() rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
@@ -1978,15 +2061,17 @@ int seccomp_protect_hostname(void) {
                                 SCMP_SYS(setdomainname),
                                 0);
                 if (r < 0) {
-                        log_debug_errno(r, "Failed to add setdomainname() rule for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add setdomainname() rule for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
                         continue;
                 }
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to apply hostname restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to apply hostname restrictions for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -2151,20 +2236,23 @@ int seccomp_restrict_suid_sgid(void) {
 
                 r = seccomp_restrict_sxid(seccomp, S_ISUID);
                 if (r < 0)
-                        log_debug_errno(r, "Failed to add suid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add suid rule for architecture %s, ignoring: %m",
+                                        seccomp_arch_to_string(arch));
 
                 k = seccomp_restrict_sxid(seccomp, S_ISGID);
                 if (k < 0)
-                        log_debug_errno(r, "Failed to add sgid rule for architecture %s, ignoring: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to add sgid rule for architecture %s, ignoring: %m",
+                                        seccomp_arch_to_string(arch));
 
                 if (r < 0 && k < 0)
                         continue;
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to apply suid/sgid restrictions for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to apply suid/sgid restrictions for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;
@@ -2277,7 +2365,6 @@ int seccomp_suppress_sync(void) {
 
         SECCOMP_FOREACH_LOCAL_ARCH(arch) {
                 _cleanup_(seccomp_releasep) scmp_filter_ctx seccomp = NULL;
-                const char *c;
 
                 r = seccomp_init_for_arch(&seccomp, arch, SCMP_ACT_ALLOW);
                 if (r < 0)
@@ -2307,10 +2394,11 @@ int seccomp_suppress_sync(void) {
 #endif
 
                 r = seccomp_load(seccomp);
-                if (ERRNO_IS_SECCOMP_FATAL(r))
+                if (ERRNO_IS_NEG_SECCOMP_FATAL(r))
                         return r;
                 if (r < 0)
-                        log_debug_errno(r, "Failed to apply sync() suppression for architecture %s, skipping: %m", seccomp_arch_to_string(arch));
+                        log_debug_errno(r, "Failed to apply sync() suppression for architecture %s, skipping: %m",
+                                        seccomp_arch_to_string(arch));
         }
 
         return 0;