--- /dev/null
+REVERTS
+
+From f454456e261930d94b3a1a444b6bac75c11c3cb0 Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Wed, 4 Aug 2021 11:51:12 -0400
+Subject: [PATCH] arch: consolidate all of the multiplexed syscall handling
+
+Not only does this reduce the amount of duplicated code
+significantly, it removes a lot of the "magic" numbers in the
+code, and it happened to catch some bugs too.
+
+Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+
+(imported from commit 17cbd2c253ce63e5e9e3cec867ff58efbe8b5fdc)
+
+diff --git a/src/arch-aarch64.c b/src/arch-aarch64.c
+--- a/src/arch-aarch64.c
++++ b/src/arch-aarch64.c
+@@ -31,8 +31,8 @@ const struct arch_def arch_def_aarch64 = {
+ .token_bpf = AUDIT_ARCH_AARCH64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .syscall_resolve_name_raw = aarch64_syscall_resolve_name,
+- .syscall_resolve_num_raw = aarch64_syscall_resolve_num,
++ .syscall_resolve_name = aarch64_syscall_resolve_name,
++ .syscall_resolve_num = aarch64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-arm.c b/src/arch-arm.c
+--- a/src/arch-arm.c
++++ b/src/arch-arm.c
+@@ -39,7 +39,6 @@
+
+ /**
+ * Resolve a syscall name to a number
+- * @param arch the architecture definition
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+@@ -47,13 +46,12 @@
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+-int arm_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name)
++int arm_syscall_resolve_name_munge(const char *name)
+ {
+ int sys;
+
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+- sys = arch->syscall_resolve_name_raw(name);
++ sys = arm_syscall_resolve_name(name);
+ if (sys == __NR_SCMP_ERROR || sys < 0)
+ return sys;
+
+@@ -62,7 +60,6 @@ int arm_syscall_resolve_name_munge(const struct arch_def *arch,
+
+ /**
+ * Resolve a syscall number to a name
+- * @param arch the architecture definition
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+@@ -70,12 +67,12 @@ int arm_syscall_resolve_name_munge(const struct arch_def *arch,
+ * syscall names; returns NULL on failure.
+ *
+ */
+-const char *arm_syscall_resolve_num_munge(const struct arch_def *arch, int num)
++const char *arm_syscall_resolve_num_munge(int num)
+ {
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+ if (num >= 0)
+ num &= ~__SCMP_NR_BASE;
+- return arch->syscall_resolve_num_raw(num);
++ return arm_syscall_resolve_num(num);
+ }
+
+ const struct arch_def arch_def_arm = {
+@@ -84,9 +81,7 @@ const struct arch_def arch_def_arm = {
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_LITTLE,
+ .syscall_resolve_name = arm_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = arm_syscall_resolve_name,
+ .syscall_resolve_num = arm_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = arm_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-mips.c b/src/arch-mips.c
+--- a/src/arch-mips.c
++++ b/src/arch-mips.c
+@@ -30,23 +30,535 @@
+ #include "arch.h"
+ #include "arch-mips.h"
+
++/* O32 ABI */
++#define __SCMP_NR_BASE 4000
++
+ /* mips syscall numbers */
+ #define __mips_NR_socketcall 102
+ #define __mips_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int mips_syscall_resolve_name_munge(const char *name)
++{
++
++#define _ABI_SYSCALL_RES_NAME_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return __PNR_##NAME;
++
++ _ABI_SYSCALL_RES_NAME_CHK(socket)
++ _ABI_SYSCALL_RES_NAME_CHK(bind)
++ _ABI_SYSCALL_RES_NAME_CHK(connect)
++ _ABI_SYSCALL_RES_NAME_CHK(listen)
++ _ABI_SYSCALL_RES_NAME_CHK(accept)
++ _ABI_SYSCALL_RES_NAME_CHK(getsockname)
++ _ABI_SYSCALL_RES_NAME_CHK(getpeername)
++ _ABI_SYSCALL_RES_NAME_CHK(socketpair)
++ _ABI_SYSCALL_RES_NAME_CHK(send)
++ _ABI_SYSCALL_RES_NAME_CHK(recv)
++ _ABI_SYSCALL_RES_NAME_CHK(sendto)
++ _ABI_SYSCALL_RES_NAME_CHK(recvfrom)
++ _ABI_SYSCALL_RES_NAME_CHK(shutdown)
++ _ABI_SYSCALL_RES_NAME_CHK(setsockopt)
++ _ABI_SYSCALL_RES_NAME_CHK(getsockopt)
++ _ABI_SYSCALL_RES_NAME_CHK(sendmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(recvmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(accept4)
++ _ABI_SYSCALL_RES_NAME_CHK(recvmmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(sendmmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(semop)
++ _ABI_SYSCALL_RES_NAME_CHK(semget)
++ _ABI_SYSCALL_RES_NAME_CHK(semctl)
++ _ABI_SYSCALL_RES_NAME_CHK(semtimedop)
++ _ABI_SYSCALL_RES_NAME_CHK(msgsnd)
++ _ABI_SYSCALL_RES_NAME_CHK(msgrcv)
++ _ABI_SYSCALL_RES_NAME_CHK(msgget)
++ _ABI_SYSCALL_RES_NAME_CHK(msgctl)
++ _ABI_SYSCALL_RES_NAME_CHK(shmat)
++ _ABI_SYSCALL_RES_NAME_CHK(shmdt)
++ _ABI_SYSCALL_RES_NAME_CHK(shmget)
++ _ABI_SYSCALL_RES_NAME_CHK(shmctl)
++
++ return mips_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *mips_syscall_resolve_num_munge(int num)
++{
++
++#define _ABI_SYSCALL_RES_NUM_CHK(NAME) \
++ if (num == __PNR_##NAME) return #NAME;
++
++ _ABI_SYSCALL_RES_NUM_CHK(socket)
++ _ABI_SYSCALL_RES_NUM_CHK(bind)
++ _ABI_SYSCALL_RES_NUM_CHK(connect)
++ _ABI_SYSCALL_RES_NUM_CHK(listen)
++ _ABI_SYSCALL_RES_NUM_CHK(accept)
++ _ABI_SYSCALL_RES_NUM_CHK(getsockname)
++ _ABI_SYSCALL_RES_NUM_CHK(getpeername)
++ _ABI_SYSCALL_RES_NUM_CHK(socketpair)
++ _ABI_SYSCALL_RES_NUM_CHK(send)
++ _ABI_SYSCALL_RES_NUM_CHK(recv)
++ _ABI_SYSCALL_RES_NUM_CHK(sendto)
++ _ABI_SYSCALL_RES_NUM_CHK(recvfrom)
++ _ABI_SYSCALL_RES_NUM_CHK(shutdown)
++ _ABI_SYSCALL_RES_NUM_CHK(setsockopt)
++ _ABI_SYSCALL_RES_NUM_CHK(getsockopt)
++ _ABI_SYSCALL_RES_NUM_CHK(sendmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(recvmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(accept4)
++ _ABI_SYSCALL_RES_NUM_CHK(recvmmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(sendmmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(semop)
++ _ABI_SYSCALL_RES_NUM_CHK(semget)
++ _ABI_SYSCALL_RES_NUM_CHK(semctl)
++ _ABI_SYSCALL_RES_NUM_CHK(semtimedop)
++ _ABI_SYSCALL_RES_NUM_CHK(msgsnd)
++ _ABI_SYSCALL_RES_NUM_CHK(msgrcv)
++ _ABI_SYSCALL_RES_NUM_CHK(msgget)
++ _ABI_SYSCALL_RES_NUM_CHK(msgctl)
++ _ABI_SYSCALL_RES_NUM_CHK(shmat)
++ _ABI_SYSCALL_RES_NUM_CHK(shmdt)
++ _ABI_SYSCALL_RES_NUM_CHK(shmget)
++ _ABI_SYSCALL_RES_NUM_CHK(shmctl)
++
++ return mips_syscall_resolve_num(num);
++}
++
++/**
++ * Check if a syscall is a socket syscall
++ * @param sys the syscall number
++ *
++ * Returns true if the syscall is a socket related syscall, false otherwise.
++ *
++ */
++static bool _mips_syscall_socket_test(int sys)
++{
++ const char *name;
++
++ /* multiplexed pseduo-syscalls */
++ if (sys <= -100 && sys >= -120)
++ return true;
++
++ name = mips_syscall_resolve_num(sys);
++ if (!name)
++ return false;
++
++#define _ABI_SYSCALL_SOCK_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return true;
++
++ _ABI_SYSCALL_SOCK_CHK(socket)
++ _ABI_SYSCALL_SOCK_CHK(bind)
++ _ABI_SYSCALL_SOCK_CHK(connect)
++ _ABI_SYSCALL_SOCK_CHK(listen)
++ _ABI_SYSCALL_SOCK_CHK(accept)
++ _ABI_SYSCALL_SOCK_CHK(getsockname)
++ _ABI_SYSCALL_SOCK_CHK(getpeername)
++ _ABI_SYSCALL_SOCK_CHK(socketpair)
++ _ABI_SYSCALL_SOCK_CHK(send)
++ _ABI_SYSCALL_SOCK_CHK(recv)
++ _ABI_SYSCALL_SOCK_CHK(sendto)
++ _ABI_SYSCALL_SOCK_CHK(recvfrom)
++ _ABI_SYSCALL_SOCK_CHK(shutdown)
++ _ABI_SYSCALL_SOCK_CHK(setsockopt)
++ _ABI_SYSCALL_SOCK_CHK(getsockopt)
++ _ABI_SYSCALL_SOCK_CHK(sendmsg)
++ _ABI_SYSCALL_SOCK_CHK(recvmsg)
++ _ABI_SYSCALL_SOCK_CHK(accept4)
++ _ABI_SYSCALL_SOCK_CHK(recvmmsg)
++ _ABI_SYSCALL_SOCK_CHK(sendmmsg)
++
++ return false;
++}
++
++/**
++ * Check if a syscall is an ipc syscall
++ * @param sys the syscall number
++ *
++ * Returns true if the syscall is an ipc related syscall, false otherwise.
++ *
++ */
++static bool _mips_syscall_ipc_test(int sys)
++{
++ const char *name;
++
++ /* multiplexed pseduo-syscalls */
++ if (sys <= -200 && sys >= -224)
++ return true;
++
++ name = mips_syscall_resolve_num(sys);
++ if (!name)
++ return false;
++
++#define _ABI_SYSCALL_IPC_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return true;
++
++ _ABI_SYSCALL_IPC_CHK(semop)
++ _ABI_SYSCALL_IPC_CHK(semget)
++ _ABI_SYSCALL_IPC_CHK(semctl)
++ _ABI_SYSCALL_IPC_CHK(semtimedop)
++ _ABI_SYSCALL_IPC_CHK(msgsnd)
++ _ABI_SYSCALL_IPC_CHK(msgrcv)
++ _ABI_SYSCALL_IPC_CHK(msgget)
++ _ABI_SYSCALL_IPC_CHK(msgctl)
++ _ABI_SYSCALL_IPC_CHK(shmat)
++ _ABI_SYSCALL_IPC_CHK(shmdt)
++ _ABI_SYSCALL_IPC_CHK(shmget)
++ _ABI_SYSCALL_IPC_CHK(shmctl)
++
++ return false;
++}
++
++/**
++ * Convert a multiplexed pseudo syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _mips_syscall_demux(int syscall)
++{
++ int sys = __NR_SCMP_UNDEF;
++
++#define _ABI_SYSCALL_DEMUX_CHK(NAME) \
++case __PNR_##NAME: \
++ sys = mips_syscall_resolve_name(#NAME); break;
++
++ switch (syscall) {
++ _ABI_SYSCALL_DEMUX_CHK(socket)
++ _ABI_SYSCALL_DEMUX_CHK(bind)
++ _ABI_SYSCALL_DEMUX_CHK(connect)
++ _ABI_SYSCALL_DEMUX_CHK(listen)
++ _ABI_SYSCALL_DEMUX_CHK(accept)
++ _ABI_SYSCALL_DEMUX_CHK(getsockname)
++ _ABI_SYSCALL_DEMUX_CHK(getpeername)
++ _ABI_SYSCALL_DEMUX_CHK(socketpair)
++ _ABI_SYSCALL_DEMUX_CHK(send)
++ _ABI_SYSCALL_DEMUX_CHK(recv)
++ _ABI_SYSCALL_DEMUX_CHK(sendto)
++ _ABI_SYSCALL_DEMUX_CHK(recvfrom)
++ _ABI_SYSCALL_DEMUX_CHK(shutdown)
++ _ABI_SYSCALL_DEMUX_CHK(setsockopt)
++ _ABI_SYSCALL_DEMUX_CHK(getsockopt)
++ _ABI_SYSCALL_DEMUX_CHK(sendmsg)
++ _ABI_SYSCALL_DEMUX_CHK(recvmsg)
++ _ABI_SYSCALL_DEMUX_CHK(accept4)
++ _ABI_SYSCALL_DEMUX_CHK(recvmmsg)
++ _ABI_SYSCALL_DEMUX_CHK(sendmmsg)
++ _ABI_SYSCALL_DEMUX_CHK(semop)
++ _ABI_SYSCALL_DEMUX_CHK(semget)
++ _ABI_SYSCALL_DEMUX_CHK(semctl)
++ _ABI_SYSCALL_DEMUX_CHK(semtimedop)
++ _ABI_SYSCALL_DEMUX_CHK(msgsnd)
++ _ABI_SYSCALL_DEMUX_CHK(msgrcv)
++ _ABI_SYSCALL_DEMUX_CHK(msgget)
++ _ABI_SYSCALL_DEMUX_CHK(msgctl)
++ _ABI_SYSCALL_DEMUX_CHK(shmat)
++ _ABI_SYSCALL_DEMUX_CHK(shmdt)
++ _ABI_SYSCALL_DEMUX_CHK(shmget)
++ _ABI_SYSCALL_DEMUX_CHK(shmctl)
++ }
++
++ /* this looks odd because the arch resolver returns _ERROR if it can't
++ * resolve the syscall, but we want to use _UNDEF for that, so we set
++ * 'sys' to a sentinel value of _UNDEF and if it is error here we know
++ * the resolve failed to find a match */
++ if (sys == __NR_SCMP_UNDEF)
++ sys = __NR_SCMP_ERROR;
++ else if (sys == __NR_SCMP_ERROR)
++ sys = __NR_SCMP_UNDEF;
++
++ return sys;
++}
++
++/**
++ * Convert a direct syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _mips_syscall_mux(int syscall)
++{
++ const char *sys;
++
++ sys = mips_syscall_resolve_num(syscall);
++ if (!sys)
++ return __NR_SCMP_ERROR;
++
++#define _ABI_SYSCALL_MUX_CHK(NAME) \
++ if (!strcmp(sys, #NAME)) return __PNR_##NAME;
++
++ _ABI_SYSCALL_MUX_CHK(socket)
++ _ABI_SYSCALL_MUX_CHK(bind)
++ _ABI_SYSCALL_MUX_CHK(connect)
++ _ABI_SYSCALL_MUX_CHK(listen)
++ _ABI_SYSCALL_MUX_CHK(accept)
++ _ABI_SYSCALL_MUX_CHK(getsockname)
++ _ABI_SYSCALL_MUX_CHK(getpeername)
++ _ABI_SYSCALL_MUX_CHK(socketpair)
++ _ABI_SYSCALL_MUX_CHK(send)
++ _ABI_SYSCALL_MUX_CHK(recv)
++ _ABI_SYSCALL_MUX_CHK(sendto)
++ _ABI_SYSCALL_MUX_CHK(recvfrom)
++ _ABI_SYSCALL_MUX_CHK(shutdown)
++ _ABI_SYSCALL_MUX_CHK(setsockopt)
++ _ABI_SYSCALL_MUX_CHK(getsockopt)
++ _ABI_SYSCALL_MUX_CHK(sendmsg)
++ _ABI_SYSCALL_MUX_CHK(recvmsg)
++ _ABI_SYSCALL_MUX_CHK(accept4)
++ _ABI_SYSCALL_MUX_CHK(recvmmsg)
++ _ABI_SYSCALL_MUX_CHK(sendmmsg)
++ _ABI_SYSCALL_MUX_CHK(semop)
++ _ABI_SYSCALL_MUX_CHK(semget)
++ _ABI_SYSCALL_MUX_CHK(semctl)
++ _ABI_SYSCALL_MUX_CHK(semtimedop)
++ _ABI_SYSCALL_MUX_CHK(msgsnd)
++ _ABI_SYSCALL_MUX_CHK(msgrcv)
++ _ABI_SYSCALL_MUX_CHK(msgget)
++ _ABI_SYSCALL_MUX_CHK(msgctl)
++ _ABI_SYSCALL_MUX_CHK(shmat)
++ _ABI_SYSCALL_MUX_CHK(shmdt)
++ _ABI_SYSCALL_MUX_CHK(shmget)
++ _ABI_SYSCALL_MUX_CHK(shmctl)
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int mips_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __mips_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __mips_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the mips seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the mips ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int mips_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if (_mips_syscall_socket_test(sys)) {
++ /* socket syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _mips_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _mips_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __mips_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (_mips_syscall_ipc_test(sys)) {
++ /* ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _mips_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _mips_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __mips_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_mips = {
+ .token = SCMP_ARCH_MIPS,
+ .token_bpf = AUDIT_ARCH_MIPS,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+- .sys_socketcall = __mips_NR_socketcall,
+- .sys_ipc = __mips_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = mips_syscall_resolve_name_munge,
++ .syscall_resolve_num = mips_syscall_resolve_num_munge,
++ .syscall_rewrite = mips_syscall_rewrite,
++ .rule_add = mips_rule_add,
+ };
+
+ const struct arch_def arch_def_mipsel = {
+@@ -54,12 +566,8 @@ const struct arch_def arch_def_mipsel = {
+ .token_bpf = AUDIT_ARCH_MIPSEL,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .sys_socketcall = __mips_NR_socketcall,
+- .sys_ipc = __mips_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = mips_syscall_resolve_name_munge,
++ .syscall_resolve_num = mips_syscall_resolve_num_munge,
++ .syscall_rewrite = mips_syscall_rewrite,
++ .rule_add = mips_rule_add,
+ };
+diff --git a/src/arch-mips64.c b/src/arch-mips64.c
+--- a/src/arch-mips64.c
++++ b/src/arch-mips64.c
+@@ -30,7 +30,6 @@
+
+ /**
+ * Resolve a syscall name to a number
+- * @param arch the architecture definition
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+@@ -38,13 +37,12 @@
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+-int mips64_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name)
++int mips64_syscall_resolve_name_munge(const char *name)
+ {
+ int sys;
+
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+- sys = arch->syscall_resolve_name_raw(name);
++ sys = mips64_syscall_resolve_name(name);
+ if (sys == __NR_SCMP_ERROR || sys < 0)
+ return sys;
+
+@@ -53,7 +51,6 @@ int mips64_syscall_resolve_name_munge(const struct arch_def *arch,
+
+ /**
+ * Resolve a syscall number to a name
+- * @param arch the architecture definition
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+@@ -61,13 +58,12 @@ int mips64_syscall_resolve_name_munge(const struct arch_def *arch,
+ * syscall names; returns NULL on failure.
+ *
+ */
+-const char *mips64_syscall_resolve_num_munge(const struct arch_def *arch,
+- int num)
++const char *mips64_syscall_resolve_num_munge(int num)
+ {
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+ if (num >= __SCMP_NR_BASE)
+ num -= __SCMP_NR_BASE;
+- return arch->syscall_resolve_num_raw(num);
++ return mips64_syscall_resolve_num(num);
+ }
+
+ const struct arch_def arch_def_mips64 = {
+@@ -76,9 +72,7 @@ const struct arch_def arch_def_mips64 = {
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_BIG,
+ .syscall_resolve_name = mips64_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips64_syscall_resolve_name,
+ .syscall_resolve_num = mips64_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+@@ -89,9 +83,7 @@ const struct arch_def arch_def_mipsel64 = {
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+ .syscall_resolve_name = mips64_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips64_syscall_resolve_name,
+ .syscall_resolve_num = mips64_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-mips64n32.c b/src/arch-mips64n32.c
+--- a/src/arch-mips64n32.c
++++ b/src/arch-mips64n32.c
+@@ -32,7 +32,6 @@
+
+ /**
+ * Resolve a syscall name to a number
+- * @param arch the architecture definition
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+@@ -40,8 +39,7 @@
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+-int mips64n32_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name)
++int mips64n32_syscall_resolve_name_munge(const char *name)
+ {
+ int sys;
+
+@@ -55,7 +53,6 @@ int mips64n32_syscall_resolve_name_munge(const struct arch_def *arch,
+
+ /**
+ * Resolve a syscall number to a name
+- * @param arch the architecture definition
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+@@ -63,8 +60,7 @@ int mips64n32_syscall_resolve_name_munge(const struct arch_def *arch,
+ * syscall names; returns NULL on failure.
+ *
+ */
+-const char *mips64n32_syscall_resolve_num_munge(const struct arch_def *arch,
+- int num)
++const char *mips64n32_syscall_resolve_num_munge(int num)
+ {
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+ if (num >= __SCMP_NR_BASE)
+@@ -78,9 +74,7 @@ const struct arch_def arch_def_mips64n32 = {
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+ .syscall_resolve_name = mips64n32_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips64n32_syscall_resolve_name,
+ .syscall_resolve_num = mips64n32_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips64n32_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+@@ -91,9 +85,7 @@ const struct arch_def arch_def_mipsel64n32 = {
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_LITTLE,
+ .syscall_resolve_name = mips64n32_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = mips64n32_syscall_resolve_name,
+ .syscall_resolve_num = mips64n32_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = mips64n32_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-parisc.c b/src/arch-parisc.c
+--- a/src/arch-parisc.c
++++ b/src/arch-parisc.c
+@@ -15,8 +15,8 @@ const struct arch_def arch_def_parisc = {
+ .token_bpf = AUDIT_ARCH_PARISC,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+- .syscall_resolve_name_raw = parisc_syscall_resolve_name,
+- .syscall_resolve_num_raw = parisc_syscall_resolve_num,
++ .syscall_resolve_name = parisc_syscall_resolve_name,
++ .syscall_resolve_num = parisc_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-parisc64.c b/src/arch-parisc64.c
+--- a/src/arch-parisc64.c
++++ b/src/arch-parisc64.c
+@@ -15,8 +15,8 @@ const struct arch_def arch_def_parisc64 = {
+ .token_bpf = AUDIT_ARCH_PARISC64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_BIG,
+- .syscall_resolve_name_raw = parisc64_syscall_resolve_name,
+- .syscall_resolve_num_raw = parisc64_syscall_resolve_num,
++ .syscall_resolve_name = parisc64_syscall_resolve_name,
++ .syscall_resolve_num = parisc64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-ppc.c b/src/arch-ppc.c
+--- a/src/arch-ppc.c
++++ b/src/arch-ppc.c
+@@ -34,17 +34,526 @@
+ #define __ppc_NR_socketcall 102
+ #define __ppc_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int ppc_syscall_resolve_name_munge(const char *name)
++{
++
++#define _ABI_SYSCALL_RES_NAME_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return __PNR_##NAME;
++
++ _ABI_SYSCALL_RES_NAME_CHK(socket)
++ _ABI_SYSCALL_RES_NAME_CHK(bind)
++ _ABI_SYSCALL_RES_NAME_CHK(connect)
++ _ABI_SYSCALL_RES_NAME_CHK(listen)
++ _ABI_SYSCALL_RES_NAME_CHK(accept)
++ _ABI_SYSCALL_RES_NAME_CHK(getsockname)
++ _ABI_SYSCALL_RES_NAME_CHK(getpeername)
++ _ABI_SYSCALL_RES_NAME_CHK(socketpair)
++ _ABI_SYSCALL_RES_NAME_CHK(send)
++ _ABI_SYSCALL_RES_NAME_CHK(recv)
++ _ABI_SYSCALL_RES_NAME_CHK(sendto)
++ _ABI_SYSCALL_RES_NAME_CHK(recvfrom)
++ _ABI_SYSCALL_RES_NAME_CHK(shutdown)
++ _ABI_SYSCALL_RES_NAME_CHK(setsockopt)
++ _ABI_SYSCALL_RES_NAME_CHK(getsockopt)
++ _ABI_SYSCALL_RES_NAME_CHK(sendmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(recvmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(accept4)
++ _ABI_SYSCALL_RES_NAME_CHK(recvmmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(sendmmsg)
++ _ABI_SYSCALL_RES_NAME_CHK(semop)
++ _ABI_SYSCALL_RES_NAME_CHK(semget)
++ _ABI_SYSCALL_RES_NAME_CHK(semctl)
++ _ABI_SYSCALL_RES_NAME_CHK(semtimedop)
++ _ABI_SYSCALL_RES_NAME_CHK(msgsnd)
++ _ABI_SYSCALL_RES_NAME_CHK(msgrcv)
++ _ABI_SYSCALL_RES_NAME_CHK(msgget)
++ _ABI_SYSCALL_RES_NAME_CHK(msgctl)
++ _ABI_SYSCALL_RES_NAME_CHK(shmat)
++ _ABI_SYSCALL_RES_NAME_CHK(shmdt)
++ _ABI_SYSCALL_RES_NAME_CHK(shmget)
++ _ABI_SYSCALL_RES_NAME_CHK(shmctl)
++
++ return ppc_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *ppc_syscall_resolve_num_munge(int num)
++{
++
++#define _ABI_SYSCALL_RES_NUM_CHK(NAME) \
++ if (num == __PNR_##NAME) return #NAME;
++
++ _ABI_SYSCALL_RES_NUM_CHK(socket)
++ _ABI_SYSCALL_RES_NUM_CHK(bind)
++ _ABI_SYSCALL_RES_NUM_CHK(connect)
++ _ABI_SYSCALL_RES_NUM_CHK(listen)
++ _ABI_SYSCALL_RES_NUM_CHK(accept)
++ _ABI_SYSCALL_RES_NUM_CHK(getsockname)
++ _ABI_SYSCALL_RES_NUM_CHK(getpeername)
++ _ABI_SYSCALL_RES_NUM_CHK(socketpair)
++ _ABI_SYSCALL_RES_NUM_CHK(send)
++ _ABI_SYSCALL_RES_NUM_CHK(recv)
++ _ABI_SYSCALL_RES_NUM_CHK(sendto)
++ _ABI_SYSCALL_RES_NUM_CHK(recvfrom)
++ _ABI_SYSCALL_RES_NUM_CHK(shutdown)
++ _ABI_SYSCALL_RES_NUM_CHK(setsockopt)
++ _ABI_SYSCALL_RES_NUM_CHK(getsockopt)
++ _ABI_SYSCALL_RES_NUM_CHK(sendmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(recvmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(accept4)
++ _ABI_SYSCALL_RES_NUM_CHK(recvmmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(sendmmsg)
++ _ABI_SYSCALL_RES_NUM_CHK(semop)
++ _ABI_SYSCALL_RES_NUM_CHK(semget)
++ _ABI_SYSCALL_RES_NUM_CHK(semctl)
++ _ABI_SYSCALL_RES_NUM_CHK(semtimedop)
++ _ABI_SYSCALL_RES_NUM_CHK(msgsnd)
++ _ABI_SYSCALL_RES_NUM_CHK(msgrcv)
++ _ABI_SYSCALL_RES_NUM_CHK(msgget)
++ _ABI_SYSCALL_RES_NUM_CHK(msgctl)
++ _ABI_SYSCALL_RES_NUM_CHK(shmat)
++ _ABI_SYSCALL_RES_NUM_CHK(shmdt)
++ _ABI_SYSCALL_RES_NUM_CHK(shmget)
++ _ABI_SYSCALL_RES_NUM_CHK(shmctl)
++
++ return ppc_syscall_resolve_num(num);
++}
++
++/**
++ * Check if a syscall is a socket syscall
++ * @param sys the syscall number
++ *
++ * Returns true if the syscall is a socket related syscall, false otherwise.
++ *
++ */
++static bool _ppc_syscall_socket_test(int sys)
++{
++ const char *name;
++
++ /* multiplexed pseduo-syscalls */
++ if (sys <= -100 && sys >= -120)
++ return true;
++
++ name = ppc_syscall_resolve_num(sys);
++ if (!name)
++ return false;
++
++#define _ABI_SYSCALL_SOCK_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return true;
++
++ _ABI_SYSCALL_SOCK_CHK(socket)
++ _ABI_SYSCALL_SOCK_CHK(bind)
++ _ABI_SYSCALL_SOCK_CHK(connect)
++ _ABI_SYSCALL_SOCK_CHK(listen)
++ _ABI_SYSCALL_SOCK_CHK(accept)
++ _ABI_SYSCALL_SOCK_CHK(getsockname)
++ _ABI_SYSCALL_SOCK_CHK(getpeername)
++ _ABI_SYSCALL_SOCK_CHK(socketpair)
++ _ABI_SYSCALL_SOCK_CHK(send)
++ _ABI_SYSCALL_SOCK_CHK(recv)
++ _ABI_SYSCALL_SOCK_CHK(sendto)
++ _ABI_SYSCALL_SOCK_CHK(recvfrom)
++ _ABI_SYSCALL_SOCK_CHK(shutdown)
++ _ABI_SYSCALL_SOCK_CHK(setsockopt)
++ _ABI_SYSCALL_SOCK_CHK(getsockopt)
++ _ABI_SYSCALL_SOCK_CHK(sendmsg)
++ _ABI_SYSCALL_SOCK_CHK(recvmsg)
++ _ABI_SYSCALL_SOCK_CHK(accept4)
++ _ABI_SYSCALL_SOCK_CHK(recvmmsg)
++ _ABI_SYSCALL_SOCK_CHK(sendmmsg)
++
++ return false;
++}
++
++/**
++ * Check if a syscall is an ipc syscall
++ * @param sys the syscall number
++ *
++ * Returns true if the syscall is an ipc related syscall, false otherwise.
++ *
++ */
++static bool _ppc_syscall_ipc_test(int sys)
++{
++ const char *name;
++
++ /* multiplexed pseduo-syscalls */
++ if (sys <= -200 && sys >= -224)
++ return true;
++
++ name = ppc_syscall_resolve_num(sys);
++ if (!name)
++ return false;
++
++#define _ABI_SYSCALL_IPC_CHK(NAME) \
++ if (!strcmp(name, #NAME)) return true;
++
++ _ABI_SYSCALL_IPC_CHK(semop)
++ _ABI_SYSCALL_IPC_CHK(semget)
++ _ABI_SYSCALL_IPC_CHK(semctl)
++ _ABI_SYSCALL_IPC_CHK(semtimedop)
++ _ABI_SYSCALL_IPC_CHK(msgsnd)
++ _ABI_SYSCALL_IPC_CHK(msgrcv)
++ _ABI_SYSCALL_IPC_CHK(msgget)
++ _ABI_SYSCALL_IPC_CHK(msgctl)
++ _ABI_SYSCALL_IPC_CHK(shmat)
++ _ABI_SYSCALL_IPC_CHK(shmdt)
++ _ABI_SYSCALL_IPC_CHK(shmget)
++ _ABI_SYSCALL_IPC_CHK(shmctl)
++
++ return false;
++}
++
++/**
++ * Convert a multiplexed pseudo syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _ppc_syscall_demux(int syscall)
++{
++ int sys = __NR_SCMP_UNDEF;
++
++#define _ABI_SYSCALL_DEMUX_CHK(NAME) \
++case __PNR_##NAME: \
++ sys = ppc_syscall_resolve_name(#NAME); break;
++
++ switch (syscall) {
++ _ABI_SYSCALL_DEMUX_CHK(socket)
++ _ABI_SYSCALL_DEMUX_CHK(bind)
++ _ABI_SYSCALL_DEMUX_CHK(connect)
++ _ABI_SYSCALL_DEMUX_CHK(listen)
++ _ABI_SYSCALL_DEMUX_CHK(accept)
++ _ABI_SYSCALL_DEMUX_CHK(getsockname)
++ _ABI_SYSCALL_DEMUX_CHK(getpeername)
++ _ABI_SYSCALL_DEMUX_CHK(socketpair)
++ _ABI_SYSCALL_DEMUX_CHK(send)
++ _ABI_SYSCALL_DEMUX_CHK(recv)
++ _ABI_SYSCALL_DEMUX_CHK(sendto)
++ _ABI_SYSCALL_DEMUX_CHK(recvfrom)
++ _ABI_SYSCALL_DEMUX_CHK(shutdown)
++ _ABI_SYSCALL_DEMUX_CHK(setsockopt)
++ _ABI_SYSCALL_DEMUX_CHK(getsockopt)
++ _ABI_SYSCALL_DEMUX_CHK(sendmsg)
++ _ABI_SYSCALL_DEMUX_CHK(recvmsg)
++ _ABI_SYSCALL_DEMUX_CHK(accept4)
++ _ABI_SYSCALL_DEMUX_CHK(recvmmsg)
++ _ABI_SYSCALL_DEMUX_CHK(sendmmsg)
++ _ABI_SYSCALL_DEMUX_CHK(semop)
++ _ABI_SYSCALL_DEMUX_CHK(semget)
++ _ABI_SYSCALL_DEMUX_CHK(semctl)
++ _ABI_SYSCALL_DEMUX_CHK(semtimedop)
++ _ABI_SYSCALL_DEMUX_CHK(msgsnd)
++ _ABI_SYSCALL_DEMUX_CHK(msgrcv)
++ _ABI_SYSCALL_DEMUX_CHK(msgget)
++ _ABI_SYSCALL_DEMUX_CHK(msgctl)
++ _ABI_SYSCALL_DEMUX_CHK(shmat)
++ _ABI_SYSCALL_DEMUX_CHK(shmdt)
++ _ABI_SYSCALL_DEMUX_CHK(shmget)
++ _ABI_SYSCALL_DEMUX_CHK(shmctl)
++ }
++
++ /* this looks odd because the arch resolver returns _ERROR if it can't
++ * resolve the syscall, but we want to use _UNDEF for that, so we set
++ * 'sys' to a sentinel value of _UNDEF and if it is error here we know
++ * the resolve failed to find a match */
++ if (sys == __NR_SCMP_UNDEF)
++ sys = __NR_SCMP_ERROR;
++ else if (sys == __NR_SCMP_ERROR)
++ sys = __NR_SCMP_UNDEF;
++
++ return sys;
++}
++
++/**
++ * Convert a direct syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _ppc_syscall_mux(int syscall)
++{
++ const char *sys;
++
++ sys = ppc_syscall_resolve_num(syscall);
++ if (!sys)
++ return __NR_SCMP_ERROR;
++
++#define _ABI_SYSCALL_MUX_CHK(NAME) \
++ if (!strcmp(sys, #NAME)) return __PNR_##NAME;
++
++ _ABI_SYSCALL_MUX_CHK(socket)
++ _ABI_SYSCALL_MUX_CHK(bind)
++ _ABI_SYSCALL_MUX_CHK(connect)
++ _ABI_SYSCALL_MUX_CHK(listen)
++ _ABI_SYSCALL_MUX_CHK(accept)
++ _ABI_SYSCALL_MUX_CHK(getsockname)
++ _ABI_SYSCALL_MUX_CHK(getpeername)
++ _ABI_SYSCALL_MUX_CHK(socketpair)
++ _ABI_SYSCALL_MUX_CHK(send)
++ _ABI_SYSCALL_MUX_CHK(recv)
++ _ABI_SYSCALL_MUX_CHK(sendto)
++ _ABI_SYSCALL_MUX_CHK(recvfrom)
++ _ABI_SYSCALL_MUX_CHK(shutdown)
++ _ABI_SYSCALL_MUX_CHK(setsockopt)
++ _ABI_SYSCALL_MUX_CHK(getsockopt)
++ _ABI_SYSCALL_MUX_CHK(sendmsg)
++ _ABI_SYSCALL_MUX_CHK(recvmsg)
++ _ABI_SYSCALL_MUX_CHK(accept4)
++ _ABI_SYSCALL_MUX_CHK(recvmmsg)
++ _ABI_SYSCALL_MUX_CHK(sendmmsg)
++ _ABI_SYSCALL_MUX_CHK(semop)
++ _ABI_SYSCALL_MUX_CHK(semget)
++ _ABI_SYSCALL_MUX_CHK(semctl)
++ _ABI_SYSCALL_MUX_CHK(semtimedop)
++ _ABI_SYSCALL_MUX_CHK(msgsnd)
++ _ABI_SYSCALL_MUX_CHK(msgrcv)
++ _ABI_SYSCALL_MUX_CHK(msgget)
++ _ABI_SYSCALL_MUX_CHK(msgctl)
++ _ABI_SYSCALL_MUX_CHK(shmat)
++ _ABI_SYSCALL_MUX_CHK(shmdt)
++ _ABI_SYSCALL_MUX_CHK(shmget)
++ _ABI_SYSCALL_MUX_CHK(shmctl)
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int ppc_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __ppc_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __ppc_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the ppc seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the ppc ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int ppc_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if (_ppc_syscall_socket_test(sys)) {
++ /* socket syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _ppc_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _ppc_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __ppc_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (_ppc_syscall_ipc_test(sys)) {
++ /* ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _ppc_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _ppc_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __ppc_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_ppc = {
+ .token = SCMP_ARCH_PPC,
+ .token_bpf = AUDIT_ARCH_PPC,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+- .sys_socketcall = __ppc_NR_socketcall,
+- .sys_ipc = __ppc_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = ppc_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = ppc_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = ppc_syscall_resolve_name_munge,
++ .syscall_resolve_num = ppc_syscall_resolve_num_munge,
++ .syscall_rewrite = ppc_syscall_rewrite,
++ .rule_add = ppc_rule_add,
+ };
+diff --git a/src/arch-ppc64.c b/src/arch-ppc64.c
+--- a/src/arch-ppc64.c
++++ b/src/arch-ppc64.c
+@@ -26,7 +26,6 @@
+ #include <linux/audit.h>
+
+ #include "db.h"
+-#include "syscalls.h"
+ #include "arch.h"
+ #include "arch-ppc64.h"
+
+@@ -34,19 +33,605 @@
+ #define __ppc64_NR_socketcall 102
+ #define __ppc64_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int ppc64_syscall_resolve_name_munge(const char *name)
++{
++ if (strcmp(name, "accept") == 0)
++ return __PNR_accept;
++ if (strcmp(name, "accept4") == 0)
++ return __PNR_accept4;
++ else if (strcmp(name, "bind") == 0)
++ return __PNR_bind;
++ else if (strcmp(name, "connect") == 0)
++ return __PNR_connect;
++ else if (strcmp(name, "getpeername") == 0)
++ return __PNR_getpeername;
++ else if (strcmp(name, "getsockname") == 0)
++ return __PNR_getsockname;
++ else if (strcmp(name, "getsockopt") == 0)
++ return __PNR_getsockopt;
++ else if (strcmp(name, "listen") == 0)
++ return __PNR_listen;
++ else if (strcmp(name, "msgctl") == 0)
++ return __PNR_msgctl;
++ else if (strcmp(name, "msgget") == 0)
++ return __PNR_msgget;
++ else if (strcmp(name, "msgrcv") == 0)
++ return __PNR_msgrcv;
++ else if (strcmp(name, "msgsnd") == 0)
++ return __PNR_msgsnd;
++ else if (strcmp(name, "recv") == 0)
++ return __PNR_recv;
++ else if (strcmp(name, "recvfrom") == 0)
++ return __PNR_recvfrom;
++ else if (strcmp(name, "recvmsg") == 0)
++ return __PNR_recvmsg;
++ else if (strcmp(name, "recvmmsg") == 0)
++ return __PNR_recvmmsg;
++ else if (strcmp(name, "semctl") == 0)
++ return __PNR_semctl;
++ else if (strcmp(name, "semget") == 0)
++ return __PNR_semget;
++ else if (strcmp(name, "semtimedop") == 0)
++ return __PNR_semtimedop;
++ else if (strcmp(name, "send") == 0)
++ return __PNR_send;
++ else if (strcmp(name, "sendmsg") == 0)
++ return __PNR_sendmsg;
++ else if (strcmp(name, "sendmmsg") == 0)
++ return __PNR_sendmmsg;
++ else if (strcmp(name, "sendto") == 0)
++ return __PNR_sendto;
++ else if (strcmp(name, "setsockopt") == 0)
++ return __PNR_setsockopt;
++ else if (strcmp(name, "shmat") == 0)
++ return __PNR_shmat;
++ else if (strcmp(name, "shmdt") == 0)
++ return __PNR_shmdt;
++ else if (strcmp(name, "shmget") == 0)
++ return __PNR_shmget;
++ else if (strcmp(name, "shmctl") == 0)
++ return __PNR_shmctl;
++ else if (strcmp(name, "shutdown") == 0)
++ return __PNR_shutdown;
++ else if (strcmp(name, "socket") == 0)
++ return __PNR_socket;
++ else if (strcmp(name, "socketpair") == 0)
++ return __PNR_socketpair;
++
++ return ppc64_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *ppc64_syscall_resolve_num_munge(int num)
++{
++ if (num == __PNR_accept)
++ return "accept";
++ else if (num == __PNR_accept4)
++ return "accept4";
++ else if (num == __PNR_bind)
++ return "bind";
++ else if (num == __PNR_connect)
++ return "connect";
++ else if (num == __PNR_getpeername)
++ return "getpeername";
++ else if (num == __PNR_getsockname)
++ return "getsockname";
++ else if (num == __PNR_getsockopt)
++ return "getsockopt";
++ else if (num == __PNR_listen)
++ return "listen";
++ else if (num == __PNR_msgctl)
++ return "msgctl";
++ else if (num == __PNR_msgget)
++ return "msgget";
++ else if (num == __PNR_msgrcv)
++ return "msgrcv";
++ else if (num == __PNR_msgsnd)
++ return "msgsnd";
++ else if (num == __PNR_recv)
++ return "recv";
++ else if (num == __PNR_recvfrom)
++ return "recvfrom";
++ else if (num == __PNR_recvmsg)
++ return "recvmsg";
++ else if (num == __PNR_recvmmsg)
++ return "recvmmsg";
++ else if (num == __PNR_semctl)
++ return "semctl";
++ else if (num == __PNR_semget)
++ return "semget";
++ else if (num == __PNR_semtimedop)
++ return "semtimedop";
++ else if (num == __PNR_send)
++ return "send";
++ else if (num == __PNR_sendmsg)
++ return "sendmsg";
++ else if (num == __PNR_sendmmsg)
++ return "sendmmsg";
++ else if (num == __PNR_sendto)
++ return "sendto";
++ else if (num == __PNR_setsockopt)
++ return "setsockopt";
++ else if (num == __PNR_shmat)
++ return "shmat";
++ else if (num == __PNR_shmdt)
++ return "shmdt";
++ else if (num == __PNR_shmget)
++ return "shmget";
++ else if (num == __PNR_shmctl)
++ return "shmctl";
++ else if (num == __PNR_shutdown)
++ return "shutdown";
++ else if (num == __PNR_socket)
++ return "socket";
++ else if (num == __PNR_socketpair)
++ return "socketpair";
++
++ return ppc64_syscall_resolve_num(num);
++}
++
++/**
++ * Convert a multiplexed pseudo socket syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _ppc64_syscall_demux(int syscall)
++{
++ switch (syscall) {
++ case -101:
++ /* socket */
++ return 326;
++ case -102:
++ /* bind */
++ return 327;
++ case -103:
++ /* connect */
++ return 328;
++ case -104:
++ /* listen */
++ return 329;
++ case -105:
++ /* accept */
++ return 330;
++ case -106:
++ /* getsockname */
++ return 331;
++ case -107:
++ /* getpeername */
++ return 332;
++ case -108:
++ /* socketpair */
++ return 333;
++ case -109:
++ /* send */
++ return 334;
++ case -110:
++ /* recv */
++ return 336;
++ case -111:
++ /* sendto */
++ return 335;
++ case -112:
++ /* recvfrom */
++ return 337;
++ case -113:
++ /* shutdown */
++ return 338;
++ case -114:
++ /* setsockopt */
++ return 339;
++ case -115:
++ /* getsockopt */
++ return 340;
++ case -116:
++ /* sendmsg */
++ return 341;
++ case -117:
++ /* recvmsg */
++ return 342;
++ case -118:
++ /* accept4 */
++ return 344;
++ case -119:
++ /* recvmmsg */
++ return 343;
++ case -120:
++ /* sendmmsg */
++ return 349;
++ case -201:
++ /* semop - not defined */
++ return __NR_SCMP_UNDEF;
++ case -202:
++ /* semget */
++ return 393;
++ case -203:
++ /* semctl */
++ return 394;
++ case -204:
++ /* semtimedop */
++ return 392;
++ case -211:
++ /* msgsnd */
++ return 400;
++ case -212:
++ /* msgrcv */
++ return 401;
++ case -213:
++ /* msgget */
++ return 399;
++ case -214:
++ /* msgctl */
++ return 402;
++ case -221:
++ /* shmat */
++ return 397;
++ case -222:
++ /* shmdt */
++ return 398;
++ case -223:
++ /* shmget */
++ return 395;
++ case -224:
++ /* shmctl */
++ return 396;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Convert a direct socket syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _ppc64_syscall_mux(int syscall)
++{
++ switch (syscall) {
++ case 326:
++ /* socket */
++ return -101;
++ case 327:
++ /* bind */
++ return -102;
++ case 328:
++ /* connect */
++ return -103;
++ case 329:
++ /* listen */
++ return -104;
++ case 330:
++ /* accept */
++ return -105;
++ case 331:
++ /* getsockname */
++ return -106;
++ case 332:
++ /* getpeername */
++ return -107;
++ case 333:
++ /* socketpair */
++ return -108;
++ case 334:
++ /* send */
++ return -109;
++ case 335:
++ /* sendto */
++ return -111;
++ case 336:
++ /* recv */
++ return -110;
++ case 337:
++ /* recvfrom */
++ return -112;
++ case 338:
++ /* shutdown */
++ return -113;
++ case 339:
++ /* setsockopt */
++ return -114;
++ case 340:
++ /* getsockopt */
++ return -115;
++ case 341:
++ /* sendmsg */
++ return -116;
++ case 342:
++ /* recvmsg */
++ return -117;
++ case 343:
++ /* recvmmsg */
++ return -119;
++ case 344:
++ /* accept4 */
++ return -118;
++ case 349:
++ /* sendmmsg */
++ return -120;
++ case 392:
++ /* semtimedop */
++ return -204;
++ case 393:
++ /* semget */
++ return -202;
++ case 394:
++ /* semctl */
++ return -203;
++ case 395:
++ /* shmget */
++ return -223;
++ case 396:
++ /* shmctl */
++ return -224;
++ case 397:
++ /* shmat */
++ return -221;
++ case 398:
++ /* shmdt */
++ return -222;
++ case 399:
++ /* msgget */
++ return -213;
++ case 400:
++ /* msgsnd */
++ return -211;
++ case 401:
++ /* msgrcv */
++ return -212;
++ case 402:
++ /* msgctl */
++ return -214;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int ppc64_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __ppc64_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __ppc64_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the ppc64 seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the ppc64 ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int ppc64_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if ((sys <= -100 && sys >= -120) || (sys >= 326 && sys <= 344) ||
++ (sys == 349)) {
++ /* (-100 to -120) : multiplexed socket syscalls
++ (326 to 344) : direct socket syscalls, Linux 4.3+
++ (349) : sendmmsg */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _ppc64_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _ppc64_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL) {
++ rc = -ENOMEM;
++ goto add_return;
++ }
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __ppc64_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if ((sys <= -200 && sys >= -224) || (sys >= 392 && sys <= 402)) {
++ /* (-200 to -224) : multiplexed ipc syscalls
++ (392 to 402) : direct ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _ppc64_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _ppc64_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __ppc64_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_ppc64 = {
+ .token = SCMP_ARCH_PPC64,
+ .token_bpf = AUDIT_ARCH_PPC64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_BIG,
+- .sys_socketcall = __ppc64_NR_socketcall,
+- .sys_ipc = __ppc64_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = ppc64_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = ppc64_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = ppc64_syscall_resolve_name_munge,
++ .syscall_resolve_num = ppc64_syscall_resolve_num_munge,
++ .syscall_rewrite = ppc64_syscall_rewrite,
++ .rule_add = ppc64_rule_add,
+ };
+
+ const struct arch_def arch_def_ppc64le = {
+@@ -54,12 +639,8 @@ const struct arch_def arch_def_ppc64le = {
+ .token_bpf = AUDIT_ARCH_PPC64LE,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .sys_socketcall = __ppc64_NR_socketcall,
+- .sys_ipc = __ppc64_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = ppc64_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = ppc64_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = ppc64_syscall_resolve_name_munge,
++ .syscall_resolve_num = ppc64_syscall_resolve_num_munge,
++ .syscall_rewrite = ppc64_syscall_rewrite,
++ .rule_add = ppc64_rule_add,
+ };
+diff --git a/src/arch-riscv64.c b/src/arch-riscv64.c
+--- a/src/arch-riscv64.c
++++ b/src/arch-riscv64.c
+@@ -24,8 +24,8 @@ const struct arch_def arch_def_riscv64 = {
+ .token_bpf = AUDIT_ARCH_RISCV64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .syscall_resolve_name_raw = riscv64_syscall_resolve_name,
+- .syscall_resolve_num_raw = riscv64_syscall_resolve_num,
++ .syscall_resolve_name = riscv64_syscall_resolve_name,
++ .syscall_resolve_num = riscv64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-s390.c b/src/arch-s390.c
+--- a/src/arch-s390.c
++++ b/src/arch-s390.c
+@@ -17,17 +17,593 @@
+ #define __s390_NR_socketcall 102
+ #define __s390_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int s390_syscall_resolve_name_munge(const char *name)
++{
++ if (strcmp(name, "accept") == 0)
++ return __PNR_accept;
++ if (strcmp(name, "accept4") == 0)
++ return __PNR_accept4;
++ else if (strcmp(name, "bind") == 0)
++ return __PNR_bind;
++ else if (strcmp(name, "connect") == 0)
++ return __PNR_connect;
++ else if (strcmp(name, "getpeername") == 0)
++ return __PNR_getpeername;
++ else if (strcmp(name, "getsockname") == 0)
++ return __PNR_getsockname;
++ else if (strcmp(name, "getsockopt") == 0)
++ return __PNR_getsockopt;
++ else if (strcmp(name, "listen") == 0)
++ return __PNR_listen;
++ else if (strcmp(name, "msgctl") == 0)
++ return __PNR_msgctl;
++ else if (strcmp(name, "msgget") == 0)
++ return __PNR_msgget;
++ else if (strcmp(name, "msgrcv") == 0)
++ return __PNR_msgrcv;
++ else if (strcmp(name, "msgsnd") == 0)
++ return __PNR_msgsnd;
++ else if (strcmp(name, "recv") == 0)
++ return __PNR_recv;
++ else if (strcmp(name, "recvfrom") == 0)
++ return __PNR_recvfrom;
++ else if (strcmp(name, "recvmsg") == 0)
++ return __PNR_recvmsg;
++ else if (strcmp(name, "semctl") == 0)
++ return __PNR_semctl;
++ else if (strcmp(name, "semget") == 0)
++ return __PNR_semget;
++ else if (strcmp(name, "semtimedop") == 0)
++ return __PNR_semtimedop;
++ else if (strcmp(name, "recvmmsg") == 0)
++ return __PNR_recvmmsg;
++ else if (strcmp(name, "send") == 0)
++ return __PNR_send;
++ else if (strcmp(name, "sendmsg") == 0)
++ return __PNR_sendmsg;
++ else if (strcmp(name, "sendmmsg") == 0)
++ return __PNR_sendmmsg;
++ else if (strcmp(name, "sendto") == 0)
++ return __PNR_sendto;
++ else if (strcmp(name, "setsockopt") == 0)
++ return __PNR_setsockopt;
++ else if (strcmp(name, "shmat") == 0)
++ return __PNR_shmat;
++ else if (strcmp(name, "shmdt") == 0)
++ return __PNR_shmdt;
++ else if (strcmp(name, "shmget") == 0)
++ return __PNR_shmget;
++ else if (strcmp(name, "shmctl") == 0)
++ return __PNR_shmctl;
++ else if (strcmp(name, "shutdown") == 0)
++ return __PNR_shutdown;
++ else if (strcmp(name, "socket") == 0)
++ return __PNR_socket;
++ else if (strcmp(name, "socketpair") == 0)
++ return __PNR_socketpair;
++
++ return s390_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *s390_syscall_resolve_num_munge(int num)
++{
++ if (num == __PNR_accept)
++ return "accept";
++ else if (num == __PNR_accept4)
++ return "accept4";
++ else if (num == __PNR_bind)
++ return "bind";
++ else if (num == __PNR_connect)
++ return "connect";
++ else if (num == __PNR_getpeername)
++ return "getpeername";
++ else if (num == __PNR_getsockname)
++ return "getsockname";
++ else if (num == __PNR_getsockopt)
++ return "getsockopt";
++ else if (num == __PNR_listen)
++ return "listen";
++ else if (num == __PNR_msgctl)
++ return "msgctl";
++ else if (num == __PNR_msgget)
++ return "msgget";
++ else if (num == __PNR_msgrcv)
++ return "msgrcv";
++ else if (num == __PNR_msgsnd)
++ return "msgsnd";
++ else if (num == __PNR_recv)
++ return "recv";
++ else if (num == __PNR_recvfrom)
++ return "recvfrom";
++ else if (num == __PNR_recvmsg)
++ return "recvmsg";
++ else if (num == __PNR_recvmmsg)
++ return "recvmmsg";
++ else if (num == __PNR_semctl)
++ return "semctl";
++ else if (num == __PNR_semget)
++ return "semget";
++ else if (num == __PNR_semtimedop)
++ return "semtimedop";
++ else if (num == __PNR_send)
++ return "send";
++ else if (num == __PNR_sendmsg)
++ return "sendmsg";
++ else if (num == __PNR_sendmmsg)
++ return "sendmmsg";
++ else if (num == __PNR_sendto)
++ return "sendto";
++ else if (num == __PNR_setsockopt)
++ return "setsockopt";
++ else if (num == __PNR_shmat)
++ return "shmat";
++ else if (num == __PNR_shmdt)
++ return "shmdt";
++ else if (num == __PNR_shmget)
++ return "shmget";
++ else if (num == __PNR_shmctl)
++ return "shmctl";
++ else if (num == __PNR_shutdown)
++ return "shutdown";
++ else if (num == __PNR_socket)
++ return "socket";
++ else if (num == __PNR_socketpair)
++ return "socketpair";
++
++ return s390_syscall_resolve_num(num);
++}
++
++/**
++ * Convert a multiplexed pseudo syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _s390_syscall_demux(int syscall)
++{
++ switch (syscall) {
++ case -101:
++ /* socket */
++ return 359;
++ case -102:
++ /* bind */
++ return 361;
++ case -103:
++ /* connect */
++ return 362;
++ case -104:
++ /* listen */
++ return 363;
++ case -105:
++ /* accept - not defined */
++ return __NR_SCMP_UNDEF;
++ case -106:
++ /* getsockname */
++ return 367;
++ case -107:
++ /* getpeername */
++ return 368;
++ case -108:
++ /* socketpair */
++ return 360;
++ case -109:
++ /* send - not defined */
++ return __NR_SCMP_UNDEF;
++ case -110:
++ /* recv - not defined */
++ return __NR_SCMP_UNDEF;
++ case -111:
++ /* sendto */
++ return 369;
++ case -112:
++ /* recvfrom */
++ return 371;
++ case -113:
++ /* shutdown */
++ return 373;
++ case -114:
++ /* setsockopt */
++ return 366;
++ case -115:
++ /* getsockopt */
++ return 365;
++ case -116:
++ /* sendmsg */
++ return 370;
++ case -117:
++ /* recvmsg */
++ return 372;
++ case -118:
++ /* accept4 */
++ return 364;
++ case -119:
++ /* recvmmsg */
++ return 337;
++ case -120:
++ /* sendmmsg */
++ return 345;
++ case -201:
++ /* semop - not defined */
++ return __NR_SCMP_UNDEF;
++ case -202:
++ /* semget */
++ return 393;
++ case -203:
++ /* semctl */
++ return 394;
++ case -204:
++ /* semtimedop */
++ return 392;
++ case -211:
++ /* msgsnd */
++ return 400;
++ case -212:
++ /* msgrcv */
++ return 401;
++ case -213:
++ /* msgget */
++ return 399;
++ case -214:
++ /* msgctl */
++ return 402;
++ case -221:
++ /* shmat */
++ return 397;
++ case -222:
++ /* shmdt */
++ return 398;
++ case -223:
++ /* shmget */
++ return 395;
++ case -224:
++ /* shmctl */
++ return 396;
++
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Convert a direct socket syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _s390_syscall_mux(int syscall)
++{
++ switch (syscall) {
++ case 337:
++ /* recvmmsg */
++ return -119;
++ case 345:
++ /* sendmmsg */
++ return -120;
++ case 359:
++ /* socket */
++ return -101;
++ case 360:
++ /* socketpair */
++ return -108;
++ case 361:
++ /* bind */
++ return -102;
++ case 362:
++ /* connect */
++ return -103;
++ case 363:
++ /* listen */
++ return -104;
++ case 364:
++ /* accept4 */
++ return -118;
++ case 365:
++ /* getsockopt */
++ return -115;
++ case 366:
++ /* setsockopt */
++ return -114;
++ case 367:
++ /* getsockname */
++ return -106;
++ case 368:
++ /* getpeername */
++ return -107;
++ case 369:
++ /* sendto */
++ return -111;
++ case 370:
++ /* sendmsg */
++ return -116;
++ case 371:
++ /* recvfrom */
++ return -112;
++ case 372:
++ /* recvmsg */
++ return -117;
++ case 373:
++ /* shutdown */
++ return -113;
++ case 393:
++ /* semget */
++ return -202;
++ case 394:
++ /* semctl */
++ return -203;
++ case 400:
++ /* msgsnd */
++ return -211;
++ case 401:
++ /* msgrcv */
++ return -212;
++ case 399:
++ /* msgget */
++ return -213;
++ case 402:
++ /* msgctl */
++ return -214;
++ case 397:
++ /* shmat */
++ return -221;
++ case 398:
++ /* shmdt */
++ return -222;
++ case 395:
++ /* shmget */
++ return -223;
++ case 396:
++ /* shmctl */
++ return -224;
++ case 392:
++ /* semtimedop */
++ return -204;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int s390_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __s390_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __s390_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the s390 seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the s390 ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int s390_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if ((sys <= -100 && sys >= -120) || (sys >= 359 && sys <= 373)) {
++ /* (-100 to -120) : multiplexed socket syscalls
++ (359 to 373) : direct socket syscalls, Linux 4.3+ */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _s390_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _s390_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL) {
++ rc = -ENOMEM;
++ goto add_return;
++ }
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __s390_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if ((sys <= -200 && sys >= -224) || (sys >= 393 && sys <= 402)) {
++ /* (-200 to -224) : multiplexed ipc syscalls
++ (393 to 402) : direct ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _s390_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _s390_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __s390_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_s390 = {
+ .token = SCMP_ARCH_S390,
+ .token_bpf = AUDIT_ARCH_S390,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_BIG,
+- .sys_socketcall = __s390_NR_socketcall,
+- .sys_ipc = __s390_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = s390_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = s390_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = s390_syscall_resolve_name_munge,
++ .syscall_resolve_num = s390_syscall_resolve_num_munge,
++ .syscall_rewrite = s390_syscall_rewrite,
++ .rule_add = s390_rule_add,
+ };
+diff --git a/src/arch-s390x.c b/src/arch-s390x.c
+--- a/src/arch-s390x.c
++++ b/src/arch-s390x.c
+@@ -17,17 +17,592 @@
+ #define __s390x_NR_socketcall 102
+ #define __s390x_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int s390x_syscall_resolve_name_munge(const char *name)
++{
++ if (strcmp(name, "accept") == 0)
++ return __PNR_accept;
++ if (strcmp(name, "accept4") == 0)
++ return __PNR_accept4;
++ else if (strcmp(name, "bind") == 0)
++ return __PNR_bind;
++ else if (strcmp(name, "connect") == 0)
++ return __PNR_connect;
++ else if (strcmp(name, "getpeername") == 0)
++ return __PNR_getpeername;
++ else if (strcmp(name, "getsockname") == 0)
++ return __PNR_getsockname;
++ else if (strcmp(name, "getsockopt") == 0)
++ return __PNR_getsockopt;
++ else if (strcmp(name, "listen") == 0)
++ return __PNR_listen;
++ else if (strcmp(name, "msgctl") == 0)
++ return __PNR_msgctl;
++ else if (strcmp(name, "msgget") == 0)
++ return __PNR_msgget;
++ else if (strcmp(name, "msgrcv") == 0)
++ return __PNR_msgrcv;
++ else if (strcmp(name, "msgsnd") == 0)
++ return __PNR_msgsnd;
++ else if (strcmp(name, "recv") == 0)
++ return __PNR_recv;
++ else if (strcmp(name, "recvfrom") == 0)
++ return __PNR_recvfrom;
++ else if (strcmp(name, "recvmsg") == 0)
++ return __PNR_recvmsg;
++ else if (strcmp(name, "recvmmsg") == 0)
++ return __PNR_recvmmsg;
++ else if (strcmp(name, "semctl") == 0)
++ return __PNR_semctl;
++ else if (strcmp(name, "semget") == 0)
++ return __PNR_semget;
++ else if (strcmp(name, "semtimedop") == 0)
++ return __PNR_semtimedop;
++ else if (strcmp(name, "send") == 0)
++ return __PNR_send;
++ else if (strcmp(name, "sendmsg") == 0)
++ return __PNR_sendmsg;
++ else if (strcmp(name, "sendmmsg") == 0)
++ return __PNR_sendmmsg;
++ else if (strcmp(name, "sendto") == 0)
++ return __PNR_sendto;
++ else if (strcmp(name, "setsockopt") == 0)
++ return __PNR_setsockopt;
++ else if (strcmp(name, "shmat") == 0)
++ return __PNR_shmat;
++ else if (strcmp(name, "shmdt") == 0)
++ return __PNR_shmdt;
++ else if (strcmp(name, "shmget") == 0)
++ return __PNR_shmget;
++ else if (strcmp(name, "shmctl") == 0)
++ return __PNR_shmctl;
++ else if (strcmp(name, "shutdown") == 0)
++ return __PNR_shutdown;
++ else if (strcmp(name, "socket") == 0)
++ return __PNR_socket;
++ else if (strcmp(name, "socketpair") == 0)
++ return __PNR_socketpair;
++
++ return s390x_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *s390x_syscall_resolve_num_munge(int num)
++{
++ if (num == __PNR_accept)
++ return "accept";
++ else if (num == __PNR_accept4)
++ return "accept4";
++ else if (num == __PNR_bind)
++ return "bind";
++ else if (num == __PNR_connect)
++ return "connect";
++ else if (num == __PNR_getpeername)
++ return "getpeername";
++ else if (num == __PNR_getsockname)
++ return "getsockname";
++ else if (num == __PNR_getsockopt)
++ return "getsockopt";
++ else if (num == __PNR_listen)
++ return "listen";
++ else if (num == __PNR_msgctl)
++ return "msgctl";
++ else if (num == __PNR_msgget)
++ return "msgget";
++ else if (num == __PNR_msgrcv)
++ return "msgrcv";
++ else if (num == __PNR_msgsnd)
++ return "msgsnd";
++ else if (num == __PNR_recv)
++ return "recv";
++ else if (num == __PNR_recvfrom)
++ return "recvfrom";
++ else if (num == __PNR_recvmsg)
++ return "recvmsg";
++ else if (num == __PNR_recvmmsg)
++ return "recvmmsg";
++ else if (num == __PNR_semctl)
++ return "semctl";
++ else if (num == __PNR_semget)
++ return "semget";
++ else if (num == __PNR_semtimedop)
++ return "semtimedop";
++ else if (num == __PNR_send)
++ return "send";
++ else if (num == __PNR_sendmsg)
++ return "sendmsg";
++ else if (num == __PNR_sendmmsg)
++ return "sendmmsg";
++ else if (num == __PNR_sendto)
++ return "sendto";
++ else if (num == __PNR_setsockopt)
++ return "setsockopt";
++ else if (num == __PNR_shmat)
++ return "shmat";
++ else if (num == __PNR_shmdt)
++ return "shmdt";
++ else if (num == __PNR_shmget)
++ return "shmget";
++ else if (num == __PNR_shmctl)
++ return "shmctl";
++ else if (num == __PNR_shutdown)
++ return "shutdown";
++ else if (num == __PNR_socket)
++ return "socket";
++ else if (num == __PNR_socketpair)
++ return "socketpair";
++
++ return s390x_syscall_resolve_num(num);
++}
++
++/**
++ * Convert a multiplexed pseudo socket syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _s390x_syscall_demux(int syscall)
++{
++ switch (syscall) {
++ case -101:
++ /* socket */
++ return 359;
++ case -102:
++ /* bind */
++ return 361;
++ case -103:
++ /* connect */
++ return 362;
++ case -104:
++ /* listen */
++ return 363;
++ case -105:
++ /* accept - not defined */
++ return __NR_SCMP_UNDEF;
++ case -106:
++ /* getsockname */
++ return 367;
++ case -107:
++ /* getpeername */
++ return 368;
++ case -108:
++ /* socketpair */
++ return 360;
++ case -109:
++ /* send - not defined */
++ return __NR_SCMP_UNDEF;
++ case -110:
++ /* recv - not defined */
++ return __NR_SCMP_UNDEF;
++ case -111:
++ /* sendto */
++ return 369;
++ case -112:
++ /* recvfrom */
++ return 371;
++ case -113:
++ /* shutdown */
++ return 373;
++ case -114:
++ /* setsockopt */
++ return 366;
++ case -115:
++ /* getsockopt */
++ return 365;
++ case -116:
++ /* sendmsg */
++ return 370;
++ case -117:
++ /* recvmsg */
++ return 372;
++ case -118:
++ /* accept4 */
++ return 364;
++ case -119:
++ /* recvmmsg */
++ return 337;
++ case -120:
++ /* sendmmsg */
++ return 345;
++ case -201:
++ /* semop - not defined */
++ return __NR_SCMP_UNDEF;
++ case -202:
++ /* semget */
++ return 393;
++ case -203:
++ /* semctl */
++ return 394;
++ case -204:
++ /* semtimedop */
++ return 392;
++ case -211:
++ /* msgsnd */
++ return 400;
++ case -212:
++ /* msgrcv */
++ return 401;
++ case -213:
++ /* msgget */
++ return 399;
++ case -214:
++ /* msgctl */
++ return 402;
++ case -221:
++ /* shmat */
++ return 397;
++ case -222:
++ /* shmdt */
++ return 398;
++ case -223:
++ /* shmget */
++ return 395;
++ case -224:
++ /* shmctl */
++ return 396;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Convert a direct socket syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _s390x_syscall_mux(int syscall)
++{
++ switch (syscall) {
++ case 337:
++ /* recvmmsg */
++ return -119;
++ case 345:
++ /* sendmmsg */
++ return -120;
++ case 359:
++ /* socket */
++ return -101;
++ case 360:
++ /* socketpair */
++ return -108;
++ case 361:
++ /* bind */
++ return -102;
++ case 362:
++ /* connect */
++ return -103;
++ case 363:
++ /* listen */
++ return -104;
++ case 364:
++ /* accept4 */
++ return -118;
++ case 365:
++ /* getsockopt */
++ return -115;
++ case 366:
++ /* setsockopt */
++ return -114;
++ case 367:
++ /* getsockname */
++ return -106;
++ case 368:
++ /* getpeername */
++ return -107;
++ case 369:
++ /* sendto */
++ return -111;
++ case 370:
++ /* sendmsg */
++ return -116;
++ case 371:
++ /* recvfrom */
++ return -112;
++ case 372:
++ /* recvmsg */
++ return -117;
++ case 373:
++ /* shutdown */
++ return -113;
++ case 392:
++ /* semtimedop */
++ return -204;
++ case 393:
++ /* semget */
++ return -202;
++ case 394:
++ /* semctl */
++ return -203;
++ case 400:
++ /* msgsnd */
++ return -211;
++ case 401:
++ /* msgrcv */
++ return -212;
++ case 399:
++ /* msgget */
++ return -213;
++ case 402:
++ /* msgctl */
++ return -214;
++ case 397:
++ /* shmat */
++ return -221;
++ case 398:
++ /* shmdt */
++ return -222;
++ case 395:
++ /* shmget */
++ return -223;
++ case 396:
++ /* shmctl */
++ return -224;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int s390x_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __s390x_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __s390x_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the s390x seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the s390x ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int s390x_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if ((sys <= -100 && sys >= -120) || (sys >= 359 && sys <= 373)) {
++ /* (-100 to -120) : multiplexed socket syscalls
++ (359 to 373) : direct socket syscalls, Linux 4.3+ */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _s390x_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _s390x_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL) {
++ rc = -ENOMEM;
++ goto add_return;
++ }
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __s390x_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if ((sys <= -200 && sys >= -224) || (sys >= 392 && sys <= 402)) {
++ /* (-200 to -224) : multiplexed ipc syscalls
++ (392 to 402) : direct ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _s390x_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _s390x_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __s390x_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_s390x = {
+ .token = SCMP_ARCH_S390X,
+ .token_bpf = AUDIT_ARCH_S390X,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_BIG,
+- .sys_socketcall = __s390x_NR_socketcall,
+- .sys_ipc = __s390x_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = s390x_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = s390x_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = s390x_syscall_resolve_name_munge,
++ .syscall_resolve_num = s390x_syscall_resolve_num_munge,
++ .syscall_rewrite = s390x_syscall_rewrite,
++ .rule_add = s390x_rule_add,
+ };
+diff --git a/src/arch-x32.c b/src/arch-x32.c
+--- a/src/arch-x32.c
++++ b/src/arch-x32.c
+@@ -28,7 +28,6 @@
+
+ /**
+ * Resolve a syscall name to a number
+- * @param arch the architecture definition
+ * @param name the syscall name
+ *
+ * Resolve the given syscall name to the syscall number using the syscall table.
+@@ -36,13 +35,12 @@
+ * numbers; returns __NR_SCMP_ERROR on failure.
+ *
+ */
+-int x32_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name)
++int x32_syscall_resolve_name_munge(const char *name)
+ {
+ int sys;
+
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+- sys = arch->syscall_resolve_name_raw(name);
++ sys = x32_syscall_resolve_name(name);
+ if (sys == __NR_SCMP_ERROR || sys < 0)
+ return sys;
+
+@@ -51,7 +49,6 @@ int x32_syscall_resolve_name_munge(const struct arch_def *arch,
+
+ /**
+ * Resolve a syscall number to a name
+- * @param arch the architecture definition
+ * @param num the syscall number
+ *
+ * Resolve the given syscall number to the syscall name using the syscall table.
+@@ -59,13 +56,12 @@ int x32_syscall_resolve_name_munge(const struct arch_def *arch,
+ * syscall names; returns NULL on failure.
+ *
+ */
+-const char *x32_syscall_resolve_num_munge(const struct arch_def *arch,
+- int num)
++const char *x32_syscall_resolve_num_munge(int num)
+ {
+ /* NOTE: we don't want to modify the pseudo-syscall numbers */
+ if (num >= 0)
+ num &= ~X32_SYSCALL_BIT;
+- return arch->syscall_resolve_num_raw(num);
++ return x32_syscall_resolve_num(num);
+ }
+
+ const struct arch_def arch_def_x32 = {
+@@ -75,9 +71,7 @@ const struct arch_def arch_def_x32 = {
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_LITTLE,
+ .syscall_resolve_name = x32_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = x32_syscall_resolve_name,
+ .syscall_resolve_num = x32_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = x32_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch-x86.c b/src/arch-x86.c
+--- a/src/arch-x86.c
++++ b/src/arch-x86.c
+@@ -33,17 +33,593 @@
+ #define __x86_NR_socketcall 102
+ #define __x86_NR_ipc 117
+
++/**
++ * Resolve a syscall name to a number
++ * @param name the syscall name
++ *
++ * Resolve the given syscall name to the syscall number using the syscall table.
++ * Returns the syscall number on success, including negative pseudo syscall
++ * numbers; returns __NR_SCMP_ERROR on failure.
++ *
++ */
++int x86_syscall_resolve_name_munge(const char *name)
++{
++ if (strcmp(name, "accept") == 0)
++ return __PNR_accept;
++ else if (strcmp(name, "accept4") == 0)
++ return __PNR_accept4;
++ else if (strcmp(name, "bind") == 0)
++ return __PNR_bind;
++ else if (strcmp(name, "connect") == 0)
++ return __PNR_connect;
++ else if (strcmp(name, "getpeername") == 0)
++ return __PNR_getpeername;
++ else if (strcmp(name, "getsockname") == 0)
++ return __PNR_getsockname;
++ else if (strcmp(name, "getsockopt") == 0)
++ return __PNR_getsockopt;
++ else if (strcmp(name, "listen") == 0)
++ return __PNR_listen;
++ else if (strcmp(name, "recv") == 0)
++ return __PNR_recv;
++ else if (strcmp(name, "recvfrom") == 0)
++ return __PNR_recvfrom;
++ else if (strcmp(name, "recvmsg") == 0)
++ return __PNR_recvmsg;
++ else if (strcmp(name, "recvmmsg") == 0)
++ return __PNR_recvmmsg;
++ else if (strcmp(name, "send") == 0)
++ return __PNR_send;
++ else if (strcmp(name, "sendmsg") == 0)
++ return __PNR_sendmsg;
++ else if (strcmp(name, "sendmmsg") == 0)
++ return __PNR_sendmmsg;
++ else if (strcmp(name, "sendto") == 0)
++ return __PNR_sendto;
++ else if (strcmp(name, "setsockopt") == 0)
++ return __PNR_setsockopt;
++ else if (strcmp(name, "shutdown") == 0)
++ return __PNR_shutdown;
++ else if (strcmp(name, "socket") == 0)
++ return __PNR_socket;
++ else if (strcmp(name, "socketpair") == 0)
++ return __PNR_socketpair;
++
++ if (strcmp(name, "semop") == 0)
++ return __PNR_semop;
++ else if (strcmp(name, "semget") == 0)
++ return __PNR_semget;
++ else if (strcmp(name, "semctl") == 0)
++ return __PNR_semctl;
++ else if (strcmp(name, "semtimedop") == 0)
++ return __PNR_semtimedop;
++ else if (strcmp(name, "msgsnd") == 0)
++ return __PNR_msgsnd;
++ else if (strcmp(name, "msgrcv") == 0)
++ return __PNR_msgrcv;
++ else if (strcmp(name, "msgget") == 0)
++ return __PNR_msgget;
++ else if (strcmp(name, "msgctl") == 0)
++ return __PNR_msgctl;
++ else if (strcmp(name, "shmat") == 0)
++ return __PNR_shmat;
++ else if (strcmp(name, "shmdt") == 0)
++ return __PNR_shmdt;
++ else if (strcmp(name, "shmget") == 0)
++ return __PNR_shmget;
++ else if (strcmp(name, "shmctl") == 0)
++ return __PNR_shmctl;
++
++ return x86_syscall_resolve_name(name);
++}
++
++/**
++ * Resolve a syscall number to a name
++ * @param num the syscall number
++ *
++ * Resolve the given syscall number to the syscall name using the syscall table.
++ * Returns a pointer to the syscall name string on success, including pseudo
++ * syscall names; returns NULL on failure.
++ *
++ */
++const char *x86_syscall_resolve_num_munge(int num)
++{
++ if (num == __PNR_accept)
++ return "accept";
++ else if (num == __PNR_accept4)
++ return "accept4";
++ else if (num == __PNR_bind)
++ return "bind";
++ else if (num == __PNR_connect)
++ return "connect";
++ else if (num == __PNR_getpeername)
++ return "getpeername";
++ else if (num == __PNR_getsockname)
++ return "getsockname";
++ else if (num == __PNR_getsockopt)
++ return "getsockopt";
++ else if (num == __PNR_listen)
++ return "listen";
++ else if (num == __PNR_recv)
++ return "recv";
++ else if (num == __PNR_recvfrom)
++ return "recvfrom";
++ else if (num == __PNR_recvmsg)
++ return "recvmsg";
++ else if (num == __PNR_recvmmsg)
++ return "recvmmsg";
++ else if (num == __PNR_send)
++ return "send";
++ else if (num == __PNR_sendmsg)
++ return "sendmsg";
++ else if (num == __PNR_sendmmsg)
++ return "sendmmsg";
++ else if (num == __PNR_sendto)
++ return "sendto";
++ else if (num == __PNR_setsockopt)
++ return "setsockopt";
++ else if (num == __PNR_shutdown)
++ return "shutdown";
++ else if (num == __PNR_socket)
++ return "socket";
++ else if (num == __PNR_socketpair)
++ return "socketpair";
++
++ if (num == __PNR_semop)
++ return "semop";
++ else if (num == __PNR_semget)
++ return "semget";
++ else if (num == __PNR_semctl)
++ return "semctl";
++ else if (num == __PNR_semtimedop)
++ return "semtimedop";
++ else if (num == __PNR_msgsnd)
++ return "msgsnd";
++ else if (num == __PNR_msgrcv)
++ return "msgrcv";
++ else if (num == __PNR_msgget)
++ return "msgget";
++ else if (num == __PNR_msgctl)
++ return "msgctl";
++ else if (num == __PNR_shmat)
++ return "shmat";
++ else if (num == __PNR_shmdt)
++ return "shmdt";
++ else if (num == __PNR_shmget)
++ return "shmget";
++ else if (num == __PNR_shmctl)
++ return "shmctl";
++
++ return x86_syscall_resolve_num(num);
++}
++
++/**
++ * Convert a multiplexed pseudo syscall into a direct syscall
++ * @param syscall the multiplexed pseudo syscall number
++ *
++ * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
++ * no related syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _x86_syscall_demux(int syscall)
++{
++ switch (syscall) {
++ case -101:
++ /* socket */
++ return 359;
++ case -102:
++ /* bind */
++ return 361;
++ case -103:
++ /* connect */
++ return 362;
++ case -104:
++ /* listen */
++ return 363;
++ case -105:
++ /* accept - not defined */
++ return __NR_SCMP_UNDEF;
++ case -106:
++ /* getsockname */
++ return 367;
++ case -107:
++ /* getpeername */
++ return 368;
++ case -108:
++ /* socketpair */
++ return 360;
++ case -109:
++ /* send - not defined */
++ return __NR_SCMP_UNDEF;
++ case -110:
++ /* recv - not defined */
++ return __NR_SCMP_UNDEF;
++ case -111:
++ /* sendto */
++ return 369;
++ case -112:
++ /* recvfrom */
++ return 371;
++ case -113:
++ /* shutdown */
++ return 373;
++ case -114:
++ /* setsockopt */
++ return 366;
++ case -115:
++ /* getsockopt */
++ return 365;
++ case -116:
++ /* sendmsg */
++ return 370;
++ case -117:
++ /* recvmsg */
++ return 372;
++ case -118:
++ /* accept4 */
++ return 364;
++ case -119:
++ /* recvmmsg */
++ return 337;
++ case -120:
++ /* sendmmsg */
++ return 345;
++ case -201:
++ /* semop - not defined */
++ return __NR_SCMP_UNDEF;
++ case -202:
++ /* semget */
++ return 393;
++ case -203:
++ /* semctl */
++ return 394;
++ case -204:
++ /* semtimedop - not defined */
++ return __NR_SCMP_UNDEF;
++ case -211:
++ /* msgsnd */
++ return 400;
++ case -212:
++ /* msgrcv */
++ return 401;
++ case -213:
++ /* msgget */
++ return 399;
++ case -214:
++ /* msgctl */
++ return 402;
++ case -221:
++ /* shmat */
++ return 397;
++ case -222:
++ /* shmdt */
++ return 398;
++ case -223:
++ /* shmget */
++ return 395;
++ case -224:
++ /* shmctl */
++ return 396;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Convert a direct syscall into multiplexed pseudo socket syscall
++ * @param syscall the direct syscall
++ *
++ * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
++ * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
++ *
++ */
++static int _x86_syscall_mux(int syscall)
++{
++ switch (syscall) {
++ case 337:
++ /* recvmmsg */
++ return -119;
++ case 345:
++ /* sendmmsg */
++ return -120;
++ case 359:
++ /* socket */
++ return -101;
++ case 360:
++ /* socketpair */
++ return -108;
++ case 361:
++ /* bind */
++ return -102;
++ case 362:
++ /* connect */
++ return -103;
++ case 363:
++ /* listen */
++ return -104;
++ case 364:
++ /* accept4 */
++ return -118;
++ case 365:
++ /* getsockopt */
++ return -115;
++ case 366:
++ /* setsockopt */
++ return -114;
++ case 367:
++ /* getsockname */
++ return -106;
++ case 368:
++ /* getpeername */
++ return -107;
++ case 369:
++ /* sendto */
++ return -111;
++ case 370:
++ /* sendmsg */
++ return -116;
++ case 371:
++ /* recvfrom */
++ return -112;
++ case 372:
++ /* recvmsg */
++ return -117;
++ case 373:
++ /* shutdown */
++ return -113;
++ case 393:
++ /* semget */
++ return -202;
++ case 394:
++ /* semctl */
++ return -203;
++ case 400:
++ /* msgsnd */
++ return -211;
++ case 401:
++ /* msgrcv */
++ return -212;
++ case 399:
++ /* msgget */
++ return -213;
++ case 402:
++ /* msgctl */
++ return -214;
++ case 397:
++ /* shmat */
++ return -221;
++ case 398:
++ /* shmdt */
++ return -222;
++ case 395:
++ /* shmget */
++ return -223;
++ case 396:
++ /* shmctl */
++ return -224;
++ }
++
++ return __NR_SCMP_ERROR;
++}
++
++/**
++ * Rewrite a syscall value to match the architecture
++ * @param syscall the syscall number
++ *
++ * Syscalls can vary across different architectures so this function rewrites
++ * the syscall into the correct value for the specified architecture. Returns
++ * zero on success, negative values on failure.
++ *
++ */
++int x86_syscall_rewrite(int *syscall)
++{
++ int sys = *syscall;
++
++ if (sys <= -100 && sys >= -120)
++ *syscall = __x86_NR_socketcall;
++ else if (sys <= -200 && sys >= -224)
++ *syscall = __x86_NR_ipc;
++ else if (sys < 0)
++ return -EDOM;
++
++ return 0;
++}
++
++/**
++ * add a new rule to the x86 seccomp filter
++ * @param db the seccomp filter db
++ * @param rule the filter rule
++ *
++ * This function adds a new syscall filter to the seccomp filter db, making any
++ * necessary adjustments for the x86 ABI. Returns zero on success, negative
++ * values on failure.
++ *
++ * It is important to note that in the case of failure the db may be corrupted,
++ * the caller must use the transaction mechanism if the db integrity is
++ * important.
++ *
++ */
++int x86_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
++{
++ int rc = 0;
++ unsigned int iter;
++ int sys = rule->syscall;
++ int sys_a, sys_b;
++ struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
++
++ if ((sys <= -100 && sys >= -120) || (sys >= 359 && sys <= 373)) {
++ /* (-100 to -120) : multiplexed socket syscalls
++ (359 to 373) : direct socket syscalls, Linux 4.3+ */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _x86_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _x86_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __x86_NR_socketcall;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 100;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if ((sys <= -200 && sys >= -224) || (sys >= 393 && sys <= 402)) {
++ /* (-200 to -224) : multiplexed ipc syscalls
++ (393 to 402) : direct ipc syscalls */
++
++ /* strict check for the multiplexed socket syscalls */
++ for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
++ if ((rule->args[iter].valid != 0) && (rule->strict)) {
++ rc = -EINVAL;
++ goto add_return;
++ }
++ }
++
++ /* determine both the muxed and direct syscall numbers */
++ if (sys > 0) {
++ sys_a = _x86_syscall_mux(sys);
++ if (sys_a == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ sys_b = sys;
++ } else {
++ sys_a = sys;
++ sys_b = _x86_syscall_demux(sys);
++ if (sys_b == __NR_SCMP_ERROR) {
++ rc = __NR_SCMP_ERROR;
++ goto add_return;
++ }
++ }
++
++ /* use rule_a for the multiplexed syscall and use rule_b for
++ * the direct wired syscall */
++
++ if (sys_a == __NR_SCMP_UNDEF) {
++ rule_a = NULL;
++ rule_b = rule;
++ } else if (sys_b == __NR_SCMP_UNDEF) {
++ rule_a = rule;
++ rule_b = NULL;
++ } else {
++ /* need two rules, dup the first and link together */
++ rule_a = rule;
++ rule_dup = db_rule_dup(rule_a);
++ rule_b = rule_dup;
++ if (rule_b == NULL)
++ goto add_return;
++ rule_b->prev = rule_a;
++ rule_b->next = NULL;
++ rule_a->next = rule_b;
++ }
++
++ /* multiplexed socket syscalls */
++ if (rule_a != NULL) {
++ rule_a->syscall = __x86_NR_ipc;
++ rule_a->args[0].arg = 0;
++ rule_a->args[0].op = SCMP_CMP_EQ;
++ rule_a->args[0].mask = DATUM_MAX;
++ rule_a->args[0].datum = (-sys_a) % 200;
++ rule_a->args[0].valid = 1;
++ }
++
++ /* direct wired socket syscalls */
++ if (rule_b != NULL)
++ rule_b->syscall = sys_b;
++
++ /* we should be protected by a transaction checkpoint */
++ if (rule_a != NULL) {
++ rc = db_rule_add(db, rule_a);
++ if (rc < 0)
++ goto add_return;
++ }
++ if (rule_b != NULL) {
++ rc = db_rule_add(db, rule_b);
++ if (rc < 0)
++ goto add_return;
++ }
++ } else if (sys >= 0) {
++ /* normal syscall processing */
++ rc = db_rule_add(db, rule);
++ if (rc < 0)
++ goto add_return;
++ } else if (rule->strict) {
++ rc = -EDOM;
++ goto add_return;
++ }
++
++add_return:
++ if (rule_dup != NULL)
++ free(rule_dup);
++ return rc;
++}
++
+ const struct arch_def arch_def_x86 = {
+ .token = SCMP_ARCH_X86,
+ .token_bpf = AUDIT_ARCH_I386,
+ .size = ARCH_SIZE_32,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .sys_socketcall = __x86_NR_socketcall,
+- .sys_ipc = __x86_NR_ipc,
+- .syscall_resolve_name = abi_syscall_resolve_name_munge,
+- .syscall_resolve_name_raw = x86_syscall_resolve_name,
+- .syscall_resolve_num = abi_syscall_resolve_num_munge,
+- .syscall_resolve_num_raw = x86_syscall_resolve_num,
+- .syscall_rewrite = abi_syscall_rewrite,
+- .rule_add = abi_rule_add,
++ .syscall_resolve_name = x86_syscall_resolve_name_munge,
++ .syscall_resolve_num = x86_syscall_resolve_num_munge,
++ .syscall_rewrite = x86_syscall_rewrite,
++ .rule_add = x86_rule_add,
+ };
+diff --git a/src/arch-x86_64.c b/src/arch-x86_64.c
+--- a/src/arch-x86_64.c
++++ b/src/arch-x86_64.c
+@@ -31,8 +31,8 @@ const struct arch_def arch_def_x86_64 = {
+ .token_bpf = AUDIT_ARCH_X86_64,
+ .size = ARCH_SIZE_64,
+ .endian = ARCH_ENDIAN_LITTLE,
+- .syscall_resolve_name_raw = x86_64_syscall_resolve_name,
+- .syscall_resolve_num_raw = x86_64_syscall_resolve_num,
++ .syscall_resolve_name = x86_64_syscall_resolve_name,
++ .syscall_resolve_num = x86_64_syscall_resolve_num,
+ .syscall_rewrite = NULL,
+ .rule_add = NULL,
+ };
+diff --git a/src/arch.c b/src/arch.c
+--- a/src/arch.c
++++ b/src/arch.c
+@@ -300,9 +300,7 @@ int arch_arg_offset(const struct arch_def *arch, unsigned int arg)
+ int arch_syscall_resolve_name(const struct arch_def *arch, const char *name)
+ {
+ if (arch->syscall_resolve_name)
+- return (*arch->syscall_resolve_name)(arch, name);
+- if (arch->syscall_resolve_name_raw)
+- return (*arch->syscall_resolve_name_raw)(name);
++ return (*arch->syscall_resolve_name)(name);
+
+ return __NR_SCMP_ERROR;
+ }
+@@ -320,9 +318,7 @@ int arch_syscall_resolve_name(const struct arch_def *arch, const char *name)
+ const char *arch_syscall_resolve_num(const struct arch_def *arch, int num)
+ {
+ if (arch->syscall_resolve_num)
+- return (*arch->syscall_resolve_num)(arch, num);
+- if (arch->syscall_resolve_num_raw)
+- return (*arch->syscall_resolve_num_raw)(num);
++ return (*arch->syscall_resolve_num)(num);
+
+ return NULL;
+ }
+@@ -385,7 +381,7 @@ int arch_syscall_rewrite(const struct arch_def *arch, int *syscall)
+ } else if (sys > -10000) {
+ /* rewritable syscalls */
+ if (arch->syscall_rewrite)
+- (*arch->syscall_rewrite)(arch, syscall);
++ (*arch->syscall_rewrite)(syscall);
+ }
+
+ /* syscalls not defined on this architecture */
+diff --git a/src/arch.h b/src/arch.h
+--- a/src/arch.h
++++ b/src/arch.h
+@@ -49,18 +49,10 @@ struct arch_def {
+ ARCH_ENDIAN_BIG,
+ } endian;
+
+- /* arch specific constants */
+- int sys_socketcall;
+- int sys_ipc;
+-
+ /* arch specific functions */
+- int (*syscall_resolve_name)(const struct arch_def *arch,
+- const char *name);
+- int (*syscall_resolve_name_raw)(const char *name);
+- const char *(*syscall_resolve_num)(const struct arch_def *arch,
+- int num);
+- const char *(*syscall_resolve_num_raw)(int num);
+- int (*syscall_rewrite)(const struct arch_def *arch, int *syscall);
++ int (*syscall_resolve_name)(const char *name);
++ const char *(*syscall_resolve_num)(int num);
++ int (*syscall_rewrite)(int *syscall);
+ int (*rule_add)(struct db_filter *db, struct db_api_rule_list *rule);
+ };
+
+diff --git a/src/syscalls.c b/src/syscalls.c
+--- a/src/syscalls.c
++++ b/src/syscalls.c
+@@ -1,5 +1,5 @@
+ /**
+- * Enhanced Seccomp Syscall Table Functions
++ * Enhanced Seccomp x86_64 Syscall Table
+ *
+ * Copyright (c) 2012, 2020 Red Hat <pmoore@redhat.com>
+ * Author: Paul Moore <paul@paul-moore.com>
+@@ -19,13 +19,9 @@
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this library; if not, see <http://www.gnu.org/licenses>.
+ */
+-
+-#include <stdlib.h>
+-#include <errno.h>
+-#include <string.h>
+ #include <seccomp.h>
++#include <string.h>
+
+-#include "db.h"
+ #include "arch.h"
+ #include "syscalls.h"
+
+@@ -58,524 +54,3 @@ ARCH_DEF(s390x)
+ ARCH_DEF(x32)
+ ARCH_DEF(x86)
+ ARCH_DEF(riscv64)
+-
+-/**
+- * Resolve a syscall name to a number
+- * @param arch the arch definition
+- * @param name the syscall name
+- *
+- * Resolve the given syscall name to the syscall number using the syscall table.
+- * Returns the syscall number on success, including negative pseudo syscall
+- * numbers; returns __NR_SCMP_ERROR on failure.
+- *
+- */
+-int abi_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name)
+-{
+-
+-#define _ABI_SYSCALL_RES_NAME_CHK(NAME) \
+- if (!strcmp(name, #NAME)) return __PNR_##NAME;
+-
+- _ABI_SYSCALL_RES_NAME_CHK(socket)
+- _ABI_SYSCALL_RES_NAME_CHK(bind)
+- _ABI_SYSCALL_RES_NAME_CHK(connect)
+- _ABI_SYSCALL_RES_NAME_CHK(listen)
+- _ABI_SYSCALL_RES_NAME_CHK(accept)
+- _ABI_SYSCALL_RES_NAME_CHK(getsockname)
+- _ABI_SYSCALL_RES_NAME_CHK(getpeername)
+- _ABI_SYSCALL_RES_NAME_CHK(socketpair)
+- _ABI_SYSCALL_RES_NAME_CHK(send)
+- _ABI_SYSCALL_RES_NAME_CHK(recv)
+- _ABI_SYSCALL_RES_NAME_CHK(sendto)
+- _ABI_SYSCALL_RES_NAME_CHK(recvfrom)
+- _ABI_SYSCALL_RES_NAME_CHK(shutdown)
+- _ABI_SYSCALL_RES_NAME_CHK(setsockopt)
+- _ABI_SYSCALL_RES_NAME_CHK(getsockopt)
+- _ABI_SYSCALL_RES_NAME_CHK(sendmsg)
+- _ABI_SYSCALL_RES_NAME_CHK(recvmsg)
+- _ABI_SYSCALL_RES_NAME_CHK(accept4)
+- _ABI_SYSCALL_RES_NAME_CHK(recvmmsg)
+- _ABI_SYSCALL_RES_NAME_CHK(sendmmsg)
+- _ABI_SYSCALL_RES_NAME_CHK(semop)
+- _ABI_SYSCALL_RES_NAME_CHK(semget)
+- _ABI_SYSCALL_RES_NAME_CHK(semctl)
+- _ABI_SYSCALL_RES_NAME_CHK(semtimedop)
+- _ABI_SYSCALL_RES_NAME_CHK(msgsnd)
+- _ABI_SYSCALL_RES_NAME_CHK(msgrcv)
+- _ABI_SYSCALL_RES_NAME_CHK(msgget)
+- _ABI_SYSCALL_RES_NAME_CHK(msgctl)
+- _ABI_SYSCALL_RES_NAME_CHK(shmat)
+- _ABI_SYSCALL_RES_NAME_CHK(shmdt)
+- _ABI_SYSCALL_RES_NAME_CHK(shmget)
+- _ABI_SYSCALL_RES_NAME_CHK(shmctl)
+-
+- return arch->syscall_resolve_name_raw(name);
+-}
+-
+-/**
+- * Resolve a syscall number to a name
+- * @param arch the arch definition
+- * @param num the syscall number
+- *
+- * Resolve the given syscall number to the syscall name using the syscall table.
+- * Returns a pointer to the syscall name string on success, including pseudo
+- * syscall names; returns NULL on failure.
+- *
+- */
+-const char *abi_syscall_resolve_num_munge(const struct arch_def *arch, int num)
+-{
+-
+-#define _ABI_SYSCALL_RES_NUM_CHK(NAME) \
+- if (num == __PNR_##NAME) return #NAME;
+-
+- _ABI_SYSCALL_RES_NUM_CHK(socket)
+- _ABI_SYSCALL_RES_NUM_CHK(bind)
+- _ABI_SYSCALL_RES_NUM_CHK(connect)
+- _ABI_SYSCALL_RES_NUM_CHK(listen)
+- _ABI_SYSCALL_RES_NUM_CHK(accept)
+- _ABI_SYSCALL_RES_NUM_CHK(getsockname)
+- _ABI_SYSCALL_RES_NUM_CHK(getpeername)
+- _ABI_SYSCALL_RES_NUM_CHK(socketpair)
+- _ABI_SYSCALL_RES_NUM_CHK(send)
+- _ABI_SYSCALL_RES_NUM_CHK(recv)
+- _ABI_SYSCALL_RES_NUM_CHK(sendto)
+- _ABI_SYSCALL_RES_NUM_CHK(recvfrom)
+- _ABI_SYSCALL_RES_NUM_CHK(shutdown)
+- _ABI_SYSCALL_RES_NUM_CHK(setsockopt)
+- _ABI_SYSCALL_RES_NUM_CHK(getsockopt)
+- _ABI_SYSCALL_RES_NUM_CHK(sendmsg)
+- _ABI_SYSCALL_RES_NUM_CHK(recvmsg)
+- _ABI_SYSCALL_RES_NUM_CHK(accept4)
+- _ABI_SYSCALL_RES_NUM_CHK(recvmmsg)
+- _ABI_SYSCALL_RES_NUM_CHK(sendmmsg)
+- _ABI_SYSCALL_RES_NUM_CHK(semop)
+- _ABI_SYSCALL_RES_NUM_CHK(semget)
+- _ABI_SYSCALL_RES_NUM_CHK(semctl)
+- _ABI_SYSCALL_RES_NUM_CHK(semtimedop)
+- _ABI_SYSCALL_RES_NUM_CHK(msgsnd)
+- _ABI_SYSCALL_RES_NUM_CHK(msgrcv)
+- _ABI_SYSCALL_RES_NUM_CHK(msgget)
+- _ABI_SYSCALL_RES_NUM_CHK(msgctl)
+- _ABI_SYSCALL_RES_NUM_CHK(shmat)
+- _ABI_SYSCALL_RES_NUM_CHK(shmdt)
+- _ABI_SYSCALL_RES_NUM_CHK(shmget)
+- _ABI_SYSCALL_RES_NUM_CHK(shmctl)
+-
+- return arch->syscall_resolve_num_raw(num);
+-}
+-
+-/**
+- * Check if a syscall is a socket syscall
+- * @param arch the arch definition
+- * @param sys the syscall number
+- *
+- * Returns true if the syscall is a socket related syscall, false otherwise.
+- *
+- */
+-static bool _abi_syscall_socket_test(const struct arch_def *arch, int sys)
+-{
+- const char *name;
+-
+- /* multiplexed pseduo-syscalls */
+- if (sys <= -100 && sys >= -120)
+- return true;
+-
+- name = arch->syscall_resolve_num_raw(sys);
+- if (!name)
+- return false;
+-
+-#define _ABI_SYSCALL_SOCK_CHK(NAME) \
+- if (!strcmp(name, #NAME)) return true;
+-
+- _ABI_SYSCALL_SOCK_CHK(socket)
+- _ABI_SYSCALL_SOCK_CHK(bind)
+- _ABI_SYSCALL_SOCK_CHK(connect)
+- _ABI_SYSCALL_SOCK_CHK(listen)
+- _ABI_SYSCALL_SOCK_CHK(accept)
+- _ABI_SYSCALL_SOCK_CHK(getsockname)
+- _ABI_SYSCALL_SOCK_CHK(getpeername)
+- _ABI_SYSCALL_SOCK_CHK(socketpair)
+- _ABI_SYSCALL_SOCK_CHK(send)
+- _ABI_SYSCALL_SOCK_CHK(recv)
+- _ABI_SYSCALL_SOCK_CHK(sendto)
+- _ABI_SYSCALL_SOCK_CHK(recvfrom)
+- _ABI_SYSCALL_SOCK_CHK(shutdown)
+- _ABI_SYSCALL_SOCK_CHK(setsockopt)
+- _ABI_SYSCALL_SOCK_CHK(getsockopt)
+- _ABI_SYSCALL_SOCK_CHK(sendmsg)
+- _ABI_SYSCALL_SOCK_CHK(recvmsg)
+- _ABI_SYSCALL_SOCK_CHK(accept4)
+- _ABI_SYSCALL_SOCK_CHK(recvmmsg)
+- _ABI_SYSCALL_SOCK_CHK(sendmmsg)
+-
+- return false;
+-}
+-
+-/**
+- * Check if a syscall is an ipc syscall
+- * @param arch the arch definition
+- * @param sys the syscall number
+- *
+- * Returns true if the syscall is an ipc related syscall, false otherwise.
+- *
+- */
+-static bool _abi_syscall_ipc_test(const struct arch_def *arch, int sys)
+-{
+- const char *name;
+-
+- /* multiplexed pseduo-syscalls */
+- if (sys <= -200 && sys >= -224)
+- return true;
+-
+- name = arch->syscall_resolve_num_raw(sys);
+- if (!name)
+- return false;
+-
+-#define _ABI_SYSCALL_IPC_CHK(NAME) \
+- if (!strcmp(name, #NAME)) return true;
+-
+- _ABI_SYSCALL_IPC_CHK(semop)
+- _ABI_SYSCALL_IPC_CHK(semget)
+- _ABI_SYSCALL_IPC_CHK(semctl)
+- _ABI_SYSCALL_IPC_CHK(semtimedop)
+- _ABI_SYSCALL_IPC_CHK(msgsnd)
+- _ABI_SYSCALL_IPC_CHK(msgrcv)
+- _ABI_SYSCALL_IPC_CHK(msgget)
+- _ABI_SYSCALL_IPC_CHK(msgctl)
+- _ABI_SYSCALL_IPC_CHK(shmat)
+- _ABI_SYSCALL_IPC_CHK(shmdt)
+- _ABI_SYSCALL_IPC_CHK(shmget)
+- _ABI_SYSCALL_IPC_CHK(shmctl)
+-
+- return false;
+-}
+-
+-/**
+- * Convert a multiplexed pseudo syscall into a direct syscall
+- * @param arch the arch definition
+- * @param syscall the multiplexed pseudo syscall number
+- *
+- * Return the related direct syscall number, __NR_SCMP_UNDEF is there is
+- * no related syscall, or __NR_SCMP_ERROR otherwise.
+- *
+- */
+-static int _abi_syscall_demux(const struct arch_def *arch, int syscall)
+-{
+- int sys = __NR_SCMP_UNDEF;
+-
+-#define _ABI_SYSCALL_DEMUX_CHK(NAME) \
+-case __PNR_##NAME: \
+- sys = arch->syscall_resolve_name_raw(#NAME); break;
+-
+- switch (syscall) {
+- _ABI_SYSCALL_DEMUX_CHK(socket)
+- _ABI_SYSCALL_DEMUX_CHK(bind)
+- _ABI_SYSCALL_DEMUX_CHK(connect)
+- _ABI_SYSCALL_DEMUX_CHK(listen)
+- _ABI_SYSCALL_DEMUX_CHK(accept)
+- _ABI_SYSCALL_DEMUX_CHK(getsockname)
+- _ABI_SYSCALL_DEMUX_CHK(getpeername)
+- _ABI_SYSCALL_DEMUX_CHK(socketpair)
+- _ABI_SYSCALL_DEMUX_CHK(send)
+- _ABI_SYSCALL_DEMUX_CHK(recv)
+- _ABI_SYSCALL_DEMUX_CHK(sendto)
+- _ABI_SYSCALL_DEMUX_CHK(recvfrom)
+- _ABI_SYSCALL_DEMUX_CHK(shutdown)
+- _ABI_SYSCALL_DEMUX_CHK(setsockopt)
+- _ABI_SYSCALL_DEMUX_CHK(getsockopt)
+- _ABI_SYSCALL_DEMUX_CHK(sendmsg)
+- _ABI_SYSCALL_DEMUX_CHK(recvmsg)
+- _ABI_SYSCALL_DEMUX_CHK(accept4)
+- _ABI_SYSCALL_DEMUX_CHK(recvmmsg)
+- _ABI_SYSCALL_DEMUX_CHK(sendmmsg)
+- _ABI_SYSCALL_DEMUX_CHK(semop)
+- _ABI_SYSCALL_DEMUX_CHK(semget)
+- _ABI_SYSCALL_DEMUX_CHK(semctl)
+- _ABI_SYSCALL_DEMUX_CHK(semtimedop)
+- _ABI_SYSCALL_DEMUX_CHK(msgsnd)
+- _ABI_SYSCALL_DEMUX_CHK(msgrcv)
+- _ABI_SYSCALL_DEMUX_CHK(msgget)
+- _ABI_SYSCALL_DEMUX_CHK(msgctl)
+- _ABI_SYSCALL_DEMUX_CHK(shmat)
+- _ABI_SYSCALL_DEMUX_CHK(shmdt)
+- _ABI_SYSCALL_DEMUX_CHK(shmget)
+- _ABI_SYSCALL_DEMUX_CHK(shmctl)
+- }
+-
+- /* this looks odd because the arch resolver returns _ERROR if it can't
+- * resolve the syscall, but we want to use _UNDEF for that, so we set
+- * 'sys' to a sentinel value of _UNDEF and if it is error here we know
+- * the resolve failed to find a match */
+- if (sys == __NR_SCMP_UNDEF)
+- sys = __NR_SCMP_ERROR;
+- else if (sys == __NR_SCMP_ERROR)
+- sys = __NR_SCMP_UNDEF;
+-
+- return sys;
+-}
+-
+-/**
+- * Convert a direct syscall into multiplexed pseudo socket syscall
+- * @param arch the arch definition
+- * @param syscall the direct syscall
+- *
+- * Return the related multiplexed pseduo syscall number, __NR_SCMP_UNDEF is
+- * there is no related pseudo syscall, or __NR_SCMP_ERROR otherwise.
+- *
+- */
+-static int _abi_syscall_mux(const struct arch_def *arch, int syscall)
+-{
+- const char *sys;
+-
+- sys = arch->syscall_resolve_num_raw(syscall);
+- if (!sys)
+- return __NR_SCMP_ERROR;
+-
+-#define _ABI_SYSCALL_MUX_CHK(NAME) \
+- if (!strcmp(sys, #NAME)) return __PNR_##NAME;
+-
+- _ABI_SYSCALL_MUX_CHK(socket)
+- _ABI_SYSCALL_MUX_CHK(bind)
+- _ABI_SYSCALL_MUX_CHK(connect)
+- _ABI_SYSCALL_MUX_CHK(listen)
+- _ABI_SYSCALL_MUX_CHK(accept)
+- _ABI_SYSCALL_MUX_CHK(getsockname)
+- _ABI_SYSCALL_MUX_CHK(getpeername)
+- _ABI_SYSCALL_MUX_CHK(socketpair)
+- _ABI_SYSCALL_MUX_CHK(send)
+- _ABI_SYSCALL_MUX_CHK(recv)
+- _ABI_SYSCALL_MUX_CHK(sendto)
+- _ABI_SYSCALL_MUX_CHK(recvfrom)
+- _ABI_SYSCALL_MUX_CHK(shutdown)
+- _ABI_SYSCALL_MUX_CHK(setsockopt)
+- _ABI_SYSCALL_MUX_CHK(getsockopt)
+- _ABI_SYSCALL_MUX_CHK(sendmsg)
+- _ABI_SYSCALL_MUX_CHK(recvmsg)
+- _ABI_SYSCALL_MUX_CHK(accept4)
+- _ABI_SYSCALL_MUX_CHK(recvmmsg)
+- _ABI_SYSCALL_MUX_CHK(sendmmsg)
+- _ABI_SYSCALL_MUX_CHK(semop)
+- _ABI_SYSCALL_MUX_CHK(semget)
+- _ABI_SYSCALL_MUX_CHK(semctl)
+- _ABI_SYSCALL_MUX_CHK(semtimedop)
+- _ABI_SYSCALL_MUX_CHK(msgsnd)
+- _ABI_SYSCALL_MUX_CHK(msgrcv)
+- _ABI_SYSCALL_MUX_CHK(msgget)
+- _ABI_SYSCALL_MUX_CHK(msgctl)
+- _ABI_SYSCALL_MUX_CHK(shmat)
+- _ABI_SYSCALL_MUX_CHK(shmdt)
+- _ABI_SYSCALL_MUX_CHK(shmget)
+- _ABI_SYSCALL_MUX_CHK(shmctl)
+-
+- return __NR_SCMP_ERROR;
+-}
+-
+-/**
+- * Rewrite a syscall value to match the architecture
+- * @param arch the arch definition
+- * @param syscall the syscall number
+- *
+- * Syscalls can vary across different architectures so this function rewrites
+- * the syscall into the correct value for the specified architecture. Returns
+- * zero on success, negative values on failure.
+- *
+- */
+-int abi_syscall_rewrite(const struct arch_def *arch, int *syscall)
+-{
+- int sys = *syscall;
+-
+- if (sys <= -100 && sys >= -120)
+- *syscall = arch->sys_socketcall;
+- else if (sys <= -200 && sys >= -224)
+- *syscall = arch->sys_ipc;
+- else if (sys < 0)
+- return -EDOM;
+-
+- return 0;
+-}
+-
+-/**
+- * add a new rule to the abi seccomp filter
+- * @param db the seccomp filter db
+- * @param rule the filter rule
+- *
+- * This function adds a new syscall filter to the seccomp filter db, making any
+- * necessary adjustments for the abi ABI. Returns zero on success, negative
+- * values on failure.
+- *
+- * It is important to note that in the case of failure the db may be corrupted,
+- * the caller must use the transaction mechanism if the db integrity is
+- * important.
+- *
+- */
+-int abi_rule_add(struct db_filter *db, struct db_api_rule_list *rule)
+-{
+- int rc = 0;
+- unsigned int iter;
+- int sys = rule->syscall;
+- int sys_a, sys_b;
+- struct db_api_rule_list *rule_a, *rule_b, *rule_dup = NULL;
+-
+- if (_abi_syscall_socket_test(db->arch, sys)) {
+- /* socket syscalls */
+-
+- /* strict check for the multiplexed socket syscalls */
+- for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
+- if ((rule->args[iter].valid != 0) && (rule->strict)) {
+- rc = -EINVAL;
+- goto add_return;
+- }
+- }
+-
+- /* determine both the muxed and direct syscall numbers */
+- if (sys > 0) {
+- sys_a = _abi_syscall_mux(db->arch, sys);
+- if (sys_a == __NR_SCMP_ERROR) {
+- rc = __NR_SCMP_ERROR;
+- goto add_return;
+- }
+- sys_b = sys;
+- } else {
+- sys_a = sys;
+- sys_b = _abi_syscall_demux(db->arch, sys);
+- if (sys_b == __NR_SCMP_ERROR) {
+- rc = __NR_SCMP_ERROR;
+- goto add_return;
+- }
+- }
+-
+- /* use rule_a for the multiplexed syscall and use rule_b for
+- * the direct wired syscall */
+-
+- if (sys_a == __NR_SCMP_UNDEF) {
+- rule_a = NULL;
+- rule_b = rule;
+- } else if (sys_b == __NR_SCMP_UNDEF) {
+- rule_a = rule;
+- rule_b = NULL;
+- } else {
+- /* need two rules, dup the first and link together */
+- rule_a = rule;
+- rule_dup = db_rule_dup(rule_a);
+- rule_b = rule_dup;
+- if (rule_b == NULL)
+- goto add_return;
+- rule_b->prev = rule_a;
+- rule_b->next = NULL;
+- rule_a->next = rule_b;
+- }
+-
+- /* multiplexed socket syscalls */
+- if (rule_a != NULL) {
+- rule_a->syscall = db->arch->sys_socketcall;
+- rule_a->args[0].arg = 0;
+- rule_a->args[0].op = SCMP_CMP_EQ;
+- rule_a->args[0].mask = DATUM_MAX;
+- rule_a->args[0].datum = (-sys_a) % 100;
+- rule_a->args[0].valid = 1;
+- }
+-
+- /* direct wired socket syscalls */
+- if (rule_b != NULL)
+- rule_b->syscall = sys_b;
+-
+- /* we should be protected by a transaction checkpoint */
+- if (rule_a != NULL) {
+- rc = db_rule_add(db, rule_a);
+- if (rc < 0)
+- goto add_return;
+- }
+- if (rule_b != NULL) {
+- rc = db_rule_add(db, rule_b);
+- if (rc < 0)
+- goto add_return;
+- }
+- } else if (_abi_syscall_ipc_test(db->arch, sys)) {
+- /* ipc syscalls */
+-
+- /* strict check for the multiplexed socket syscalls */
+- for (iter = 0; iter < ARG_COUNT_MAX; iter++) {
+- if ((rule->args[iter].valid != 0) && (rule->strict)) {
+- rc = -EINVAL;
+- goto add_return;
+- }
+- }
+-
+- /* determine both the muxed and direct syscall numbers */
+- if (sys > 0) {
+- sys_a = _abi_syscall_mux(db->arch, sys);
+- if (sys_a == __NR_SCMP_ERROR) {
+- rc = __NR_SCMP_ERROR;
+- goto add_return;
+- }
+- sys_b = sys;
+- } else {
+- sys_a = sys;
+- sys_b = _abi_syscall_demux(db->arch, sys);
+- if (sys_b == __NR_SCMP_ERROR) {
+- rc = __NR_SCMP_ERROR;
+- goto add_return;
+- }
+- }
+-
+- /* use rule_a for the multiplexed syscall and use rule_b for
+- * the direct wired syscall */
+-
+- if (sys_a == __NR_SCMP_UNDEF) {
+- rule_a = NULL;
+- rule_b = rule;
+- } else if (sys_b == __NR_SCMP_UNDEF) {
+- rule_a = rule;
+- rule_b = NULL;
+- } else {
+- /* need two rules, dup the first and link together */
+- rule_a = rule;
+- rule_dup = db_rule_dup(rule_a);
+- rule_b = rule_dup;
+- if (rule_b == NULL)
+- goto add_return;
+- rule_b->prev = rule_a;
+- rule_b->next = NULL;
+- rule_a->next = rule_b;
+- }
+-
+- /* multiplexed socket syscalls */
+- if (rule_a != NULL) {
+- rule_a->syscall = db->arch->sys_ipc;
+- rule_a->args[0].arg = 0;
+- rule_a->args[0].op = SCMP_CMP_EQ;
+- rule_a->args[0].mask = DATUM_MAX;
+- rule_a->args[0].datum = (-sys_a) % 200;
+- rule_a->args[0].valid = 1;
+- }
+-
+- /* direct wired socket syscalls */
+- if (rule_b != NULL)
+- rule_b->syscall = sys_b;
+-
+- /* we should be protected by a transaction checkpoint */
+- if (rule_a != NULL) {
+- rc = db_rule_add(db, rule_a);
+- if (rc < 0)
+- goto add_return;
+- }
+- if (rule_b != NULL) {
+- rc = db_rule_add(db, rule_b);
+- if (rc < 0)
+- goto add_return;
+- }
+- } else if (sys >= 0) {
+- /* normal syscall processing */
+- rc = db_rule_add(db, rule);
+- if (rc < 0)
+- goto add_return;
+- } else if (rule->strict) {
+- rc = -EDOM;
+- goto add_return;
+- }
+-
+-add_return:
+- if (rule_dup != NULL)
+- free(rule_dup);
+- return rc;
+-}
+diff --git a/src/syscalls.h b/src/syscalls.h
+--- a/src/syscalls.h
++++ b/src/syscalls.h
+@@ -59,12 +59,4 @@ int syscall_resolve_name(const char *name, int offset);
+ const char *syscall_resolve_num(int num, int offset);
+ const struct arch_syscall_def *syscall_iterate(unsigned int spot, int offset);
+
+-/* helper functions for multiplexed syscalls, e.g. socketcall(2) and ipc(2) */
+-int abi_syscall_resolve_name_munge(const struct arch_def *arch,
+- const char *name);
+-const char *abi_syscall_resolve_num_munge(const struct arch_def *arch, int num);
+-int abi_syscall_rewrite(const struct arch_def *arch, int *syscall);
+-int abi_rule_add(struct db_filter *db, struct db_api_rule_list *rule);
+-
+-
+ #endif
--- /dev/null
+REVERTS
+
+From aa0f858aa58d51c93a176c60a4c83a4a303bcffd Mon Sep 17 00:00:00 2001
+From: Paul Moore <paul@paul-moore.com>
+Date: Tue, 3 Aug 2021 14:12:50 -0400
+Subject: [PATCH] tests: various additions to improve code coverage
+
+Acked-by: Tom Hromatka <tom.hromatka@oracle.com>
+Signed-off-by: Paul Moore <paul@paul-moore.com>
+
+(imported from commit fcc601279004a7f4c2f6ebf766acb4556b0f5e65)
+---
+ tests/11-basic-basic_errors.c | 52 +++
+ tests/15-basic-resolver.c | 40 ++
+ tests/30-sim-socket_syscalls.c | 62 ++-
+ tests/33-sim-socket_syscalls_be.c | 3 +
+ tests/33-sim-socket_syscalls_be.py | 1 +
+ tests/33-sim-socket_syscalls_be.tests | 42 +-
+ tests/36-sim-ipc_syscalls.c | 3 +
+ tests/36-sim-ipc_syscalls.py | 1 +
+ tests/36-sim-ipc_syscalls.tests | 50 +--
+ tests/37-sim-ipc_syscalls_be.c | 3 +
+ tests/37-sim-ipc_syscalls_be.py | 1 +
+ tests/37-sim-ipc_syscalls_be.tests | 26 +-
+ tests/38-basic-pfc_coverage.c | 27 ++
+ tests/38-basic-pfc_coverage.pfc | 534 ++++++++++++++++++++++++++
+ tests/52-basic-load.c | 23 ++
+ 15 files changed, 804 insertions(+), 64 deletions(-)
+
+diff --git a/tests/11-basic-basic_errors.c b/tests/11-basic-basic_errors.c
+--- a/tests/11-basic-basic_errors.c
++++ b/tests/11-basic-basic_errors.c
+@@ -29,8 +29,6 @@ int main(int argc, char *argv[])
+ int rc;
+ scmp_filter_ctx ctx;
+ uint32_t attr;
+- struct seccomp_notif *req = NULL;
+- struct seccomp_notif_resp *resp = NULL;
+
+ /* seccomp_init errors */
+ ctx = seccomp_init(SCMP_ACT_ALLOW + 1);
+@@ -125,9 +123,6 @@ int main(int argc, char *argv[])
+ return -1;
+ rc = seccomp_rule_add_exact(ctx, SCMP_ACT_KILL, SCMP_SYS(socket), 1,
+ SCMP_A0(SCMP_CMP_EQ, 2));
+- if (rc != -EINVAL)
+- return -1;
+- rc = seccomp_rule_add_exact(ctx, 0xdeadbeef, SCMP_SYS(open), 0);
+ if (rc != -EINVAL)
+ return -1;
+ seccomp_release(ctx);
+@@ -185,53 +180,6 @@ int main(int argc, char *argv[])
+ rc = seccomp_attr_set(ctx, 1000, 1);
+ if (rc != -EINVAL)
+ return -1;
+- seccomp_release(ctx);
+- ctx = NULL;
+-
+- /* seccomp_merge() errors */
+- ctx = seccomp_init(SCMP_ACT_ALLOW);
+- if (ctx == NULL)
+- return -1;
+- rc = seccomp_merge(ctx, NULL);
+- if (rc == 0)
+- return -1;
+- seccomp_release(ctx);
+- ctx = NULL;
+-
+- /* seccomp notify errors */
+- ctx = seccomp_init(SCMP_ACT_ALLOW);
+- if (ctx == NULL)
+- return -1;
+- rc = seccomp_notify_alloc(NULL, NULL);
+- if (rc != 0)
+- return -1;
+- rc = seccomp_notify_alloc(&req, NULL);
+- if (rc != 0)
+- return -1;
+- rc = seccomp_notify_alloc(NULL, &resp);
+- if (rc != 0)
+- return -1;
+- seccomp_notify_free(NULL, NULL);
+- seccomp_notify_free(req, resp);
+- req = NULL;
+- resp = NULL;
+- rc = seccomp_notify_receive(-1, NULL);
+- if (rc == 0)
+- return -1;
+- rc = seccomp_notify_respond(-1, NULL);
+- if (rc == 0)
+- return -1;
+- rc = seccomp_notify_id_valid(-1, 0);
+- if (rc == 0)
+- return -1;
+- rc = seccomp_notify_fd(NULL);
+- if (rc == 0)
+- return -1;
+- rc = seccomp_notify_fd(ctx);
+- if (rc == 0)
+- return -1;
+- seccomp_release(ctx);
+- ctx = NULL;
+
+ return 0;
+ }
+diff --git a/tests/15-basic-resolver.c b/tests/15-basic-resolver.c
+--- a/tests/15-basic-resolver.c
++++ b/tests/15-basic-resolver.c
+@@ -68,7 +68,6 @@ int main(int argc, char *argv[])
+ goto fail;
+
+ while ((arch = arch_list[iter++]) != -1) {
+- int sys;
+ int nr_open;
+ int nr_read;
+ int nr_socket;
+@@ -120,45 +119,6 @@ int main(int argc, char *argv[])
+ goto fail;
+ free(name);
+ name = NULL;
+-
+- /* socket pseudo-syscalls */
+- if (seccomp_syscall_resolve_name_arch(arch, "socketcall") > 0) {
+- for (sys = -101; sys >= -120; sys--) {
+- name = seccomp_syscall_resolve_num_arch(arch,
+- sys);
+- if (name == NULL)
+- goto fail;
+- free(name);
+- name = NULL;
+- }
+- }
+- /* ipc pseudo-syscalls */
+- if (seccomp_syscall_resolve_name_arch(arch, "ipc") > 0) {
+- for (sys = -201; sys >= -204; sys--) {
+- name = seccomp_syscall_resolve_num_arch(arch,
+- sys);
+- if (name == NULL)
+- goto fail;
+- free(name);
+- name = NULL;
+- }
+- for (sys = -211; sys >= -214; sys--) {
+- name = seccomp_syscall_resolve_num_arch(arch,
+- sys);
+- if (name == NULL)
+- goto fail;
+- free(name);
+- name = NULL;
+- }
+- for (sys = -221; sys >= -224; sys--) {
+- name = seccomp_syscall_resolve_num_arch(arch,
+- sys);
+- if (name == NULL)
+- goto fail;
+- free(name);
+- name = NULL;
+- }
+- }
+ }
+
+ return 0;
+diff --git a/tests/30-sim-socket_syscalls.c b/tests/30-sim-socket_syscalls.c
+--- a/tests/30-sim-socket_syscalls.c
++++ b/tests/30-sim-socket_syscalls.c
+@@ -61,79 +61,19 @@ int main(int argc, char *argv[])
+ if (rc != 0)
+ goto out;
+
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(bind), 0);
+- if (rc != 0)
+- goto out;
+-
+ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(connect), 0);
+ if (rc != 0)
+ goto out;
+
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(listen), 0);
+- if (rc != 0)
+- goto out;
+-
+ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept), 0);
+ if (rc != 0)
+ goto out;
+
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockname), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getpeername), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(socketpair), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(send), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recv), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendto), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvfrom), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(setsockopt), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(getsockopt), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendmsg), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvmsg), 0);
+- if (rc != 0)
+- goto out;
+-
+ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(accept4), 0);
+ if (rc != 0)
+ goto out;
+
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(sendmmsg), 0);
+- if (rc != 0)
+- goto out;
+-
+- rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(recvmmsg), 0);
++ rc = seccomp_rule_add(ctx, SCMP_ACT_ALLOW, SCMP_SYS(shutdown), 0);
+ if (rc != 0)
+ goto out;
+
+diff --git a/tests/33-sim-socket_syscalls_be.c b/tests/33-sim-socket_syscalls_be.c
+--- a/tests/33-sim-socket_syscalls_be.c
++++ b/tests/33-sim-socket_syscalls_be.c
+@@ -48,9 +48,6 @@ int main(int argc, char *argv[])
+ if (rc != 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_S390X);
+- if (rc != 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC);
+ if (rc != 0)
+ goto out;
+
+diff --git a/tests/33-sim-socket_syscalls_be.py b/tests/33-sim-socket_syscalls_be.py
+--- a/tests/33-sim-socket_syscalls_be.py
++++ b/tests/33-sim-socket_syscalls_be.py
+@@ -33,7 +33,6 @@ def test(args):
+ f.remove_arch(Arch())
+ f.add_arch(Arch("s390"))
+ f.add_arch(Arch("s390x"))
+- f.add_arch(Arch("ppc"))
+ f.add_rule(ALLOW, "socket")
+ f.add_rule(ALLOW, "connect")
+ f.add_rule(ALLOW, "accept")
+diff --git a/tests/33-sim-socket_syscalls_be.tests b/tests/33-sim-socket_syscalls_be.tests
+--- a/tests/33-sim-socket_syscalls_be.tests
++++ b/tests/33-sim-socket_syscalls_be.tests
+@@ -7,23 +7,31 @@
+
+ test type: bpf-sim
+
+-# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc socketcall 1 N N N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc socketcall 3 N N N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc socketcall 5 N N N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc socketcall 13 N N N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x 359 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +ppc 326 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x 362 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +ppc 328 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x 364 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +ppc 344 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x 373 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +ppc 338 0 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc accept 5 N N N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc accept 0 1 2 N N N KILL
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc accept4 18 1 2 N N N ALLOW
+-33-sim-socket_syscalls_be +s390,+s390x,+ppc accept4 0 1 2 N N N KILL
++# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
++33-sim-socket_syscalls_be +s390 socketcall 1 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390 socketcall 3 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390 socketcall 5 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390 socketcall 13 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390 359 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390 362 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390 364 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390 373 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390 accept 5 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390 accept 0 1 2 N N N KILL
++33-sim-socket_syscalls_be +s390 accept4 18 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390 accept4 0 1 2 N N N KILL
++33-sim-socket_syscalls_be +s390x socketcall 1 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390x socketcall 3 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390x socketcall 5 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390x socketcall 13 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390x 359 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390x 362 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390x 364 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390x 373 0 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390x accept 5 N N N N N ALLOW
++33-sim-socket_syscalls_be +s390x accept 0 1 2 N N N KILL
++33-sim-socket_syscalls_be +s390x accept4 18 1 2 N N N ALLOW
++33-sim-socket_syscalls_be +s390x accept4 0 1 2 N N N KILL
+
+ test type: bpf-valgrind
+
+diff --git a/tests/36-sim-ipc_syscalls.c b/tests/36-sim-ipc_syscalls.c
+--- a/tests/36-sim-ipc_syscalls.c
++++ b/tests/36-sim-ipc_syscalls.c
+@@ -54,9 +54,6 @@ int main(int argc, char *argv[])
+ if (rc != 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC64LE);
+- if (rc != 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL);
+ if (rc != 0)
+ goto out;
+
+diff --git a/tests/36-sim-ipc_syscalls.py b/tests/36-sim-ipc_syscalls.py
+--- a/tests/36-sim-ipc_syscalls.py
++++ b/tests/36-sim-ipc_syscalls.py
+@@ -35,7 +35,6 @@ def test(args):
+ f.add_arch(Arch("x86_64"))
+ f.add_arch(Arch("x32"))
+ f.add_arch(Arch("ppc64le"))
+- f.add_arch(Arch("mipsel"))
+ f.add_rule(ALLOW, "semop")
+ f.add_rule(ALLOW, "semtimedop")
+ f.add_rule(ALLOW, "semget")
+diff --git a/tests/36-sim-ipc_syscalls.tests b/tests/36-sim-ipc_syscalls.tests
+--- a/tests/36-sim-ipc_syscalls.tests
++++ b/tests/36-sim-ipc_syscalls.tests
+@@ -7,31 +7,31 @@
+
+ test type: bpf-sim
+
+-# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 1 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 2 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 3 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 4 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 11 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 12 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 13 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 14 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 21 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 22 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 23 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86,+ppc64le,+mipsel ipc 24 N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 semop N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 semget N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 semctl N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 semtimedop N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 msgsnd N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 msgrcv N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 msgget N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 msgctl N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 shmat N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 shmdt N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 shmget N N N N N N ALLOW
+-36-sim-ipc_syscalls +x86_64 shmctl N N N N N N ALLOW
++# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
++36-sim-ipc_syscalls +x86,+ppc64le ipc 1 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 2 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 3 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 4 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 11 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 12 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 13 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 14 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 21 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 22 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 23 N N N N N ALLOW
++36-sim-ipc_syscalls +x86,+ppc64le ipc 24 N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 semop N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 semget N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 semctl N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 semtimedop N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 msgsnd N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 msgrcv N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 msgget N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 msgctl N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 shmat N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 shmdt N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 shmget N N N N N N ALLOW
++36-sim-ipc_syscalls +x86_64 shmctl N N N N N N ALLOW
+
+ test type: bpf-valgrind
+
+diff --git a/tests/37-sim-ipc_syscalls_be.c b/tests/37-sim-ipc_syscalls_be.c
+--- a/tests/37-sim-ipc_syscalls_be.c
++++ b/tests/37-sim-ipc_syscalls_be.c
+@@ -48,9 +48,6 @@ int main(int argc, char *argv[])
+ if (rc != 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_S390X);
+- if (rc != 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC);
+ if (rc != 0)
+ goto out;
+
+diff --git a/tests/37-sim-ipc_syscalls_be.py b/tests/37-sim-ipc_syscalls_be.py
+--- a/tests/37-sim-ipc_syscalls_be.py
++++ b/tests/37-sim-ipc_syscalls_be.py
+@@ -33,7 +33,6 @@ def test(args):
+ f.remove_arch(Arch())
+ f.add_arch(Arch("s390"))
+ f.add_arch(Arch("s390x"))
+- f.add_arch(Arch("ppc"))
+ f.add_rule(ALLOW, "semop")
+ f.add_rule(ALLOW, "semtimedop")
+ f.add_rule(ALLOW, "semget")
+diff --git a/tests/37-sim-ipc_syscalls_be.tests b/tests/37-sim-ipc_syscalls_be.tests
+--- a/tests/37-sim-ipc_syscalls_be.tests
++++ b/tests/37-sim-ipc_syscalls_be.tests
+@@ -7,19 +7,19 @@
+
+ test type: bpf-sim
+
+-# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 1 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 2 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 3 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 4 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 11 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 12 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 13 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 14 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 21 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 22 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 23 N N N N N ALLOW
+-37-sim-ipc_syscalls_be +s390,+s390x,+ppc ipc 24 N N N N N ALLOW
++# Testname Arch Syscall Arg0 Arg1 Arg2 Arg3 Arg4 Arg5 Result
++37-sim-ipc_syscalls_be +s390,+s390x ipc 1 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 2 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 3 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 4 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 11 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 12 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 13 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 14 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 21 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 22 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 23 N N N N N ALLOW
++37-sim-ipc_syscalls_be +s390,+s390x ipc 24 N N N N N ALLOW
+
+ test type: bpf-valgrind
+
+diff --git a/tests/38-basic-pfc_coverage.c b/tests/38-basic-pfc_coverage.c
+--- a/tests/38-basic-pfc_coverage.c
++++ b/tests/38-basic-pfc_coverage.c
+@@ -55,30 +55,6 @@ int main(int argc, char *argv[])
+ if (rc < 0)
+ goto out;
+ rc = seccomp_arch_add(ctx, SCMP_ARCH_X86);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_X32);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_ARM);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_AARCH64);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_MIPSEL64N32);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_PPC64LE);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_arch_add(ctx, SCMP_ARCH_RISCV64);
+ if (rc < 0)
+ goto out;
+
+@@ -109,9 +85,6 @@ int main(int argc, char *argv[])
+ if (rc < 0)
+ goto out;
+ rc = seccomp_rule_add(ctx, SCMP_ACT_KILL_PROCESS, SCMP_SYS(fstat), 0);
+- if (rc < 0)
+- goto out;
+- rc = seccomp_rule_add(ctx, SCMP_ACT_LOG, SCMP_SYS(exit_group), 0);
+ if (rc < 0)
+ goto out;
+
+diff --git a/tests/38-basic-pfc_coverage.pfc b/tests/38-basic-pfc_coverage.pfc
+--- a/tests/38-basic-pfc_coverage.pfc
++++ b/tests/38-basic-pfc_coverage.pfc
+@@ -3,9 +3,6 @@
+ #
+ # filter for arch x86_64 (3221225534)
+ if ($arch == 3221225534)
+- # filter for syscall "exit_group" (231) [priority: 65535]
+- if ($syscall == 231)
+- action LOG;
+ # filter for syscall "exit" (60) [priority: 65535]
+ if ($syscall == 60)
+ action TRACE(1);
+@@ -100,9 +97,6 @@ if ($arch == 3221225534)
+ action ALLOW;
+ # filter for arch x86 (1073741827)
+ if ($arch == 1073741827)
+- # filter for syscall "exit_group" (252) [priority: 65535]
+- if ($syscall == 252)
+- action LOG;
+ # filter for syscall "fstat" (108) [priority: 65535]
+ if ($syscall == 108)
+ action KILL_PROCESS;
+@@ -133,534 +127,6 @@ if ($arch == 1073741827)
+ action KILL;
+ # default action
+ action ALLOW;
+-# filter for arch x32 (3221225534)
+-if ($arch == 3221225534)
+- # filter for syscall "exit_group" (1073742055) [priority: 65535]
+- if ($syscall == 1073742055)
+- action LOG;
+- # filter for syscall "exit" (1073741884) [priority: 65535]
+- if ($syscall == 1073741884)
+- action TRACE(1);
+- # filter for syscall "fstat" (1073741829) [priority: 65535]
+- if ($syscall == 1073741829)
+- action KILL_PROCESS;
+- # filter for syscall "close" (1073741827) [priority: 65535]
+- if ($syscall == 1073741827)
+- action ERRNO(1);
+- # filter for syscall "open" (1073741826) [priority: 65535]
+- if ($syscall == 1073741826)
+- action KILL;
+- # filter for syscall "write" (1073741825) [priority: 65532]
+- if ($syscall == 1073741825)
+- if ($a0 == 0)
+- else
+- if ($a1 > 1)
+- else
+- if ($a2 >= 2)
+- else
+- action TRAP;
+- # filter for syscall "read" (1073741824) [priority: 65531]
+- if ($syscall == 1073741824)
+- if ($a0 == 0)
+- if ($a1 >= 1)
+- if ($a2 > 2)
+- if ($a3 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch arm (1073741864)
+-if ($arch == 1073741864)
+- # filter for syscall "exit_group" (248) [priority: 65535]
+- if ($syscall == 248)
+- action LOG;
+- # filter for syscall "fstat" (108) [priority: 65535]
+- if ($syscall == 108)
+- action KILL_PROCESS;
+- # filter for syscall "close" (6) [priority: 65535]
+- if ($syscall == 6)
+- action ERRNO(1);
+- # filter for syscall "open" (5) [priority: 65535]
+- if ($syscall == 5)
+- action KILL;
+- # filter for syscall "exit" (1) [priority: 65535]
+- if ($syscall == 1)
+- action TRACE(1);
+- # filter for syscall "write" (4) [priority: 65532]
+- if ($syscall == 4)
+- if ($a0 == 0)
+- else
+- if ($a1 > 1)
+- else
+- if ($a2 >= 2)
+- else
+- action TRAP;
+- # filter for syscall "read" (3) [priority: 65531]
+- if ($syscall == 3)
+- if ($a0 == 0)
+- if ($a1 >= 1)
+- if ($a2 > 2)
+- if ($a3 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch aarch64 (3221225655)
+-if ($arch == 3221225655)
+- # filter for syscall "open" (4294957130) [priority: 65535]
+- if ($syscall == 4294957130)
+- action KILL;
+- # filter for syscall "exit_group" (94) [priority: 65535]
+- if ($syscall == 94)
+- action LOG;
+- # filter for syscall "exit" (93) [priority: 65535]
+- if ($syscall == 93)
+- action TRACE(1);
+- # filter for syscall "fstat" (80) [priority: 65535]
+- if ($syscall == 80)
+- action KILL_PROCESS;
+- # filter for syscall "close" (57) [priority: 65535]
+- if ($syscall == 57)
+- action ERRNO(1);
+- # filter for syscall "write" (64) [priority: 65527]
+- if ($syscall == 64)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- # filter for syscall "read" (63) [priority: 65525]
+- if ($syscall == 63)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- if ($a1.hi32 > 0)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 >= 1)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch mipsel (1073741832)
+-if ($arch == 1073741832)
+- # filter for syscall "exit_group" (246) [priority: 65535]
+- if ($syscall == 246)
+- action LOG;
+- # filter for syscall "fstat" (108) [priority: 65535]
+- if ($syscall == 108)
+- action KILL_PROCESS;
+- # filter for syscall "close" (6) [priority: 65535]
+- if ($syscall == 6)
+- action ERRNO(1);
+- # filter for syscall "open" (5) [priority: 65535]
+- if ($syscall == 5)
+- action KILL;
+- # filter for syscall "exit" (1) [priority: 65535]
+- if ($syscall == 1)
+- action TRACE(1);
+- # filter for syscall "write" (4) [priority: 65532]
+- if ($syscall == 4)
+- if ($a0 == 0)
+- else
+- if ($a1 > 1)
+- else
+- if ($a2 >= 2)
+- else
+- action TRAP;
+- # filter for syscall "read" (3) [priority: 65531]
+- if ($syscall == 3)
+- if ($a0 == 0)
+- if ($a1 >= 1)
+- if ($a2 > 2)
+- if ($a3 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch mipsel64 (3221225480)
+-if ($arch == 3221225480)
+- # filter for syscall "exit_group" (5205) [priority: 65535]
+- if ($syscall == 5205)
+- action LOG;
+- # filter for syscall "exit" (5058) [priority: 65535]
+- if ($syscall == 5058)
+- action TRACE(1);
+- # filter for syscall "fstat" (5005) [priority: 65535]
+- if ($syscall == 5005)
+- action KILL_PROCESS;
+- # filter for syscall "close" (5003) [priority: 65535]
+- if ($syscall == 5003)
+- action ERRNO(1);
+- # filter for syscall "open" (5002) [priority: 65535]
+- if ($syscall == 5002)
+- action KILL;
+- # filter for syscall "write" (5001) [priority: 65527]
+- if ($syscall == 5001)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- # filter for syscall "read" (5000) [priority: 65525]
+- if ($syscall == 5000)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- if ($a1.hi32 > 0)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 >= 1)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch mipsel64n32 (3758096392)
+-if ($arch == 3758096392)
+- # filter for syscall "exit_group" (6205) [priority: 65535]
+- if ($syscall == 6205)
+- action LOG;
+- # filter for syscall "exit" (6058) [priority: 65535]
+- if ($syscall == 6058)
+- action TRACE(1);
+- # filter for syscall "fstat" (6005) [priority: 65535]
+- if ($syscall == 6005)
+- action KILL_PROCESS;
+- # filter for syscall "close" (6003) [priority: 65535]
+- if ($syscall == 6003)
+- action ERRNO(1);
+- # filter for syscall "open" (6002) [priority: 65535]
+- if ($syscall == 6002)
+- action KILL;
+- # filter for syscall "write" (6001) [priority: 65532]
+- if ($syscall == 6001)
+- if ($a0 == 0)
+- else
+- if ($a1 > 1)
+- else
+- if ($a2 >= 2)
+- else
+- action TRAP;
+- # filter for syscall "read" (6000) [priority: 65531]
+- if ($syscall == 6000)
+- if ($a0 == 0)
+- if ($a1 >= 1)
+- if ($a2 > 2)
+- if ($a3 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch ppc64le (3221225493)
+-if ($arch == 3221225493)
+- # filter for syscall "exit_group" (234) [priority: 65535]
+- if ($syscall == 234)
+- action LOG;
+- # filter for syscall "fstat" (108) [priority: 65535]
+- if ($syscall == 108)
+- action KILL_PROCESS;
+- # filter for syscall "close" (6) [priority: 65535]
+- if ($syscall == 6)
+- action ERRNO(1);
+- # filter for syscall "open" (5) [priority: 65535]
+- if ($syscall == 5)
+- action KILL;
+- # filter for syscall "exit" (1) [priority: 65535]
+- if ($syscall == 1)
+- action TRACE(1);
+- # filter for syscall "write" (4) [priority: 65527]
+- if ($syscall == 4)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- # filter for syscall "read" (3) [priority: 65525]
+- if ($syscall == 3)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- if ($a1.hi32 > 0)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 >= 1)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+-# filter for arch riscv64 (3221225715)
+-if ($arch == 3221225715)
+- # filter for syscall "open" (4294957130) [priority: 65535]
+- if ($syscall == 4294957130)
+- action KILL;
+- # filter for syscall "exit_group" (94) [priority: 65535]
+- if ($syscall == 94)
+- action LOG;
+- # filter for syscall "exit" (93) [priority: 65535]
+- if ($syscall == 93)
+- action TRACE(1);
+- # filter for syscall "fstat" (80) [priority: 65535]
+- if ($syscall == 80)
+- action KILL_PROCESS;
+- # filter for syscall "close" (57) [priority: 65535]
+- if ($syscall == 57)
+- action ERRNO(1);
+- # filter for syscall "write" (64) [priority: 65527]
+- if ($syscall == 64)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a1.hi32 > 0)
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 > 1)
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- else
+- if ($a2.hi32 > 0)
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 >= 2)
+- else
+- action TRAP;
+- else
+- action TRAP;
+- # filter for syscall "read" (63) [priority: 65525]
+- if ($syscall == 63)
+- if ($a0.hi32 == 0)
+- if ($a0.lo32 == 0)
+- if ($a1.hi32 > 0)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a1.hi32 == 0)
+- if ($a1.lo32 >= 1)
+- if ($a2.hi32 > 0)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- else
+- if ($a2.hi32 == 0)
+- if ($a2.lo32 > 2)
+- if ($a3.hi32 & 0x00000000 == 0)
+- if ($a3.lo32 & 0x0000000f == 3)
+- action KILL;
+- # default action
+- action ALLOW;
+ # invalid architecture action
+ action KILL;
+ #
+diff --git a/tests/52-basic-load.c b/tests/52-basic-load.c
+--- a/tests/52-basic-load.c
++++ b/tests/52-basic-load.c
+@@ -31,38 +31,15 @@ int main(int argc, char *argv[])
+ int rc;
+ struct util_options opts;
+ scmp_filter_ctx ctx = NULL;
+- unsigned int api;
+
+ rc = util_getopt(argc, argv, &opts);
+ if (rc < 0)
+ goto out;
+
+- api = seccomp_api_get();
+- if (api == 0) {
+- rc = -EFAULT;
+- goto out;
+- }
+-
+ ctx = seccomp_init(SCMP_ACT_ALLOW);
+ if (ctx == NULL)
+ return ENOMEM;
+
+- if (api >= 2) {
+- rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_TSYNC, 1);
+- if (rc != 0)
+- goto out;
+- }
+- if (api >= 3) {
+- rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_LOG, 1);
+- if (rc != 0)
+- goto out;
+- }
+- if (api >= 4) {
+- rc = seccomp_attr_set(ctx, SCMP_FLTATR_CTL_SSB, 1);
+- if (rc != 0)
+- goto out;
+- }
+-
+ rc = seccomp_load(ctx);
+
+ out: