From c12945db0b7e32f409ba3a68d18c6d6f6dd22b19 Mon Sep 17 00:00:00 2001 From: John Paul Adrian Glaubitz Date: Mon, 17 Aug 2020 13:12:14 +0200 Subject: [PATCH] arch: Add SuperH 32-bit support Initial support for seccomp for SuperH in Linux was added in 2.6.27-rc2, support for SECCOMP_FILTER was added for Linux 5.9. This adds support for SuperH in libseccomp, both for little-endian and big-endian mode. Signed-off-by: John Paul Adrian Glaubitz Acked-by: Tom Hromatka Signed-off-by: Paul Moore --- CREDITS | 1 + README.md | 2 ++ doc/man/man1/scmp_sys_resolver.1 | 2 +- include/seccomp.h.in | 6 +++++ src/Makefile.am | 1 + src/arch-sh.c | 42 +++++++++++++++++++++++++++++++ src/arch-sh.h | 23 +++++++++++++++++ src/arch-syscall-check.c | 12 ++++++++- src/arch-syscall-dump.c | 5 ++++ src/arch-syscall-validate | 35 +++++++++++++++++++++++++- src/arch.c | 15 +++++++++++ src/gen_pfc.c | 4 +++ src/syscalls.c | 1 + src/syscalls.h | 2 ++ tests/16-sim-arch_basic.c | 3 +++ tests/16-sim-arch_basic.py | 1 + tests/23-sim-arch_all_le_basic.c | 3 +++ tests/23-sim-arch_all_le_basic.py | 1 + tests/26-sim-arch_all_be_basic.c | 3 +++ tests/26-sim-arch_all_be_basic.py | 1 + tests/regression | 11 +++++--- tools/scmp_arch_detect.c | 6 +++++ tools/scmp_bpf_sim.c | 4 +++ tools/util.c | 6 +++++ 24 files changed, 183 insertions(+), 7 deletions(-) create mode 100644 src/arch-sh.c create mode 100644 src/arch-sh.h diff --git a/CREDITS b/CREDITS index 0765b1b0..d6bbc2a2 100644 --- a/CREDITS +++ b/CREDITS @@ -29,6 +29,7 @@ Jan Willeke Jay Guo Jiannan Guo Joe MacDonald +John Paul Adrian Glaubitz Jonah Petri Justin Cormack Kees Cook diff --git a/README.md b/README.md index 89e7dad5..ba02186b 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ The libseccomp library currently supports the architectures listed below: * 32-bit s390 (s390) * 64-bit s390x (s390x) * 64-bit RISC-V (riscv64) +* 32-bit SuperH big endian (sheb) +* 32-bit SuperH (sh) ## Documentation diff --git a/doc/man/man1/scmp_sys_resolver.1 b/doc/man/man1/scmp_sys_resolver.1 index a2236077..267187b9 100644 --- a/doc/man/man1/scmp_sys_resolver.1 +++ b/doc/man/man1/scmp_sys_resolver.1 @@ -36,7 +36,7 @@ The architecture to use for resolving the system call. Valid .I ARCH values are "x86", "x86_64", "x32", "arm", "aarch64", "mips", "mipsel", "mips64", "mipsel64", "mips64n32", "mipsel64n32", "parisc", "parisc64", "ppc", "ppc64", -"ppc64le", "s390" and "s390x". +"ppc64le", "s390", "s390x", "sheb" and "sh". .TP .B \-t If necessary, translate the system call name to the proper system call number, diff --git a/include/seccomp.h.in b/include/seccomp.h.in index 1e47de98..333a89cc 100644 --- a/include/seccomp.h.in +++ b/include/seccomp.h.in @@ -216,6 +216,12 @@ struct scmp_arg_cmp { #endif /* AUDIT_ARCH_RISCV64 */ #define SCMP_ARCH_RISCV64 AUDIT_ARCH_RISCV64 +/** + * The SuperH architecture tokens + */ +#define SCMP_ARCH_SHEB AUDIT_ARCH_SH +#define SCMP_ARCH_SH AUDIT_ARCH_SHEL /* Little-endian SH is more common than big */ + /** * Convert a syscall name into the associated syscall number * @param x the syscall name diff --git a/src/Makefile.am b/src/Makefile.am index 10154e14..7b59810a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -46,6 +46,7 @@ SOURCES_ALL = \ arch-riscv64.h arch-riscv64.c \ arch-s390.h arch-s390.c \ arch-s390x.h arch-s390x.c \ + arch-sh.h arch-sh.c \ syscalls.h syscalls.c syscalls.perf.c EXTRA_DIST = \ diff --git a/src/arch-sh.c b/src/arch-sh.c new file mode 100644 index 00000000..d4641ea7 --- /dev/null +++ b/src/arch-sh.c @@ -0,0 +1,42 @@ +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#include +#include +#include + +#include "arch.h" +#include "arch-sh.h" + +const struct arch_def arch_def_sheb = { + .token = SCMP_ARCH_SHEB, + .token_bpf = AUDIT_ARCH_SH, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_BIG, + .syscall_resolve_name = sh_syscall_resolve_name, + .syscall_resolve_num = sh_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; + +const struct arch_def arch_def_sh = { + .token = SCMP_ARCH_SH, + .token_bpf = AUDIT_ARCH_SHEL, + .size = ARCH_SIZE_32, + .endian = ARCH_ENDIAN_LITTLE, + .syscall_resolve_name = sh_syscall_resolve_name, + .syscall_resolve_num = sh_syscall_resolve_num, + .syscall_rewrite = NULL, + .rule_add = NULL, +}; diff --git a/src/arch-sh.h b/src/arch-sh.h new file mode 100644 index 00000000..06f107f1 --- /dev/null +++ b/src/arch-sh.h @@ -0,0 +1,23 @@ +/* + * This library is free software; you can redistribute it and/or modify it + * under the terms of version 2.1 of the GNU Lesser General Public License as + * published by the Free Software Foundation. + * + * This library is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License + * for more details. + * + * You should have received a copy of the GNU Lesser General Public License + * along with this library; if not, see . + */ + +#ifndef _ARCH_SH_H +#define _ARCH_SH_H + +#include "arch.h" + +ARCH_DECL(sheb) +ARCH_DECL(sh) + +#endif diff --git a/src/arch-syscall-check.c b/src/arch-syscall-check.c index 76969a1c..987ef551 100644 --- a/src/arch-syscall-check.c +++ b/src/arch-syscall-check.c @@ -38,6 +38,7 @@ #include "arch-ppc64.h" #include "arch-s390.h" #include "arch-s390x.h" +#include "arch-sh.h" /** * compare the syscall values @@ -77,6 +78,7 @@ int main(int argc, char *argv[]) int i_ppc64 = 0; int i_s390 = 0; int i_s390x = 0; + int i_sh = 0; char str_miss[256]; const char *sys_name; const struct arch_syscall_def *sys; @@ -115,6 +117,8 @@ int main(int argc, char *argv[]) s390_syscall_iterate(i_s390)); syscall_check(str_miss, sys_name, "s390x", s390x_syscall_iterate(i_s390x)); + syscall_check(str_miss, sys_name, "sh", + sh_syscall_iterate(i_sh)); /* output the results */ printf("%s: ", sys_name); @@ -151,12 +155,14 @@ int main(int argc, char *argv[]) i_s390 = -1; if (!s390x_syscall_iterate(++i_s390x)->name) i_s390x = -1; + if (!sh_syscall_iterate(++i_sh)->name) + i_sh = -1; } while (i_x86_64 >= 0 && i_x32 >= 0 && i_arm >= 0 && i_aarch64 >= 0 && i_mips >= 0 && i_mips64 >= 0 && i_mips64n32 >= 0 && i_parisc >= 0 && i_ppc >= 0 && i_ppc64 >= 0 && - i_s390 >= 0 && i_s390x >= 0); + i_s390 >= 0 && i_s390x >= 0 && i_sh >= 0); /* check for any leftovers */ sys = x86_syscall_iterate(i_x86 + 1); @@ -212,6 +218,10 @@ int main(int argc, char *argv[]) printf("ERROR, s390x has additional syscalls\n"); return 1; } + if (i_sh >= 0) { + printf("ERROR, sh has additional syscalls\n"); + return 1; + } /* if we made it here, all is good */ return 0; diff --git a/src/arch-syscall-dump.c b/src/arch-syscall-dump.c index 2055d342..843483b2 100644 --- a/src/arch-syscall-dump.c +++ b/src/arch-syscall-dump.c @@ -45,6 +45,7 @@ #include "arch-riscv64.h" #include "arch-s390.h" #include "arch-s390x.h" +#include "arch-sh.h" /** * Print the usage information to stderr and exit @@ -140,6 +141,10 @@ int main(int argc, char *argv[]) case SCMP_ARCH_S390X: sys = s390x_syscall_iterate(iter); break; + case SCMP_ARCH_SH: + case SCMP_ARCH_SHEB: + sys = sh_syscall_iterate(iter); + break; default: /* invalid arch */ exit_usage(argv[0]); diff --git a/src/arch-syscall-validate b/src/arch-syscall-validate index 3b69e9b2..68bebefc 100755 --- a/src/arch-syscall-validate +++ b/src/arch-syscall-validate @@ -567,6 +567,31 @@ function dump_lib_s390x() { dump_lib_arch s390x | mangle_lib_syscall s390x } +# +# Dump the sh system syscall table +# +# Arguments: +# 1 path to the kernel source +# +# Dump the architecture's syscall table to stdout. +# +function dump_sys_sh() { + cat $1/arch/sh/kernel/syscalls/syscall.tbl | \ + grep -v "^#" | \ + sed -n "/[0-9]\+[ \t]\+\(common\)/p" | \ + awk '{ print $3","$1 }' | \ + sort +} + +# +# Dump the sh library syscall table +# +# Dump the library's syscall table to stdout. +# +function dump_lib_sh() { + dump_lib_arch sh | mangle_lib_syscall sh +} + # # Dump the system syscall table # @@ -623,6 +648,9 @@ function dump_sys() { s390x) dump_sys_s390x "$2" ;; + sh) + dump_sys_sh "$2" + ;; *) echo "" return 1 @@ -687,6 +715,9 @@ function dump_lib() { s390x) dump_lib_s390x ;; + sh) + dump_lib_sh + ;; *) echo "" return 1 @@ -722,6 +753,7 @@ function gen_csv() { abi_list+=" ppc ppc64" abi_list+=" riscv64" abi_list+=" s390 s390x" + abi_list+=" sh" # get the full syscall list for abi in $abi_list; do @@ -809,7 +841,8 @@ if [[ $opt_arches == "" ]]; then mips mips64 mips64n32 \ parisc parisc64 \ ppc ppc64 \ - s390 s390x" + s390 s390x \ + sh" fi # sanity checks diff --git a/src/arch.c b/src/arch.c index 73bf710a..6ab922f3 100644 --- a/src/arch.c +++ b/src/arch.c @@ -45,6 +45,7 @@ #include "arch-riscv64.h" #include "arch-s390.h" #include "arch-s390x.h" +#include "arch-sh.h" #include "db.h" #include "system.h" @@ -98,6 +99,12 @@ const struct arch_def *arch_def_native = &arch_def_s390x; const struct arch_def *arch_def_native = &arch_def_s390; #elif __riscv && __riscv_xlen == 64 const struct arch_def *arch_def_native = &arch_def_riscv64; +#elif __sh__ +#ifdef __BIG_ENDIAN__ +const struct arch_def *arch_def_native = &arch_def_sheb; +#else +const struct arch_def *arch_def_native = &arch_def_sh; +#endif #else #error the arch code needs to know about your machine type #endif /* machine type guess */ @@ -162,6 +169,10 @@ const struct arch_def *arch_def_lookup(uint32_t token) return &arch_def_s390x; case SCMP_ARCH_RISCV64: return &arch_def_riscv64; + case SCMP_ARCH_SHEB: + return &arch_def_sheb; + case SCMP_ARCH_SH: + return &arch_def_sh; } return NULL; @@ -214,6 +225,10 @@ const struct arch_def *arch_def_lookup_name(const char *arch_name) return &arch_def_s390x; else if (strcmp(arch_name, "riscv64") == 0) return &arch_def_riscv64; + else if (strcmp(arch_name, "sheb") == 0) + return &arch_def_sheb; + else if (strcmp(arch_name, "sh") == 0) + return &arch_def_sh; return NULL; } diff --git a/src/gen_pfc.c b/src/gen_pfc.c index 405f0807..c7fb5366 100644 --- a/src/gen_pfc.c +++ b/src/gen_pfc.c @@ -89,6 +89,10 @@ static const char *_pfc_arch(const struct arch_def *arch) return "s390"; case SCMP_ARCH_RISCV64: return "riscv64"; + case SCMP_ARCH_SHEB: + return "sheb"; + case SCMP_ARCH_SH: + return "sh"; default: return "UNKNOWN"; } diff --git a/src/syscalls.c b/src/syscalls.c index 9091fa96..ddb84fa7 100644 --- a/src/syscalls.c +++ b/src/syscalls.c @@ -51,6 +51,7 @@ ARCH_DEF(ppc64) ARCH_DEF(ppc) ARCH_DEF(s390) ARCH_DEF(s390x) +ARCH_DEF(sh) ARCH_DEF(x32) ARCH_DEF(x86) ARCH_DEF(riscv64) diff --git a/src/syscalls.h b/src/syscalls.h index d638733f..4f959af3 100644 --- a/src/syscalls.h +++ b/src/syscalls.h @@ -22,6 +22,7 @@ #include "arch-ppc.h" #include "arch-s390.h" #include "arch-s390x.h" +#include "arch-sh.h" #include "arch-x32.h" #include "arch-x86_64.h" #include "arch-x86.h" @@ -51,6 +52,7 @@ struct arch_syscall_table { int riscv64; int s390; int s390x; + int sh; }; #define OFFSET_ARCH(NAME) offsetof(struct arch_syscall_table, NAME) diff --git a/tests/16-sim-arch_basic.c b/tests/16-sim-arch_basic.c index 0b141e1c..4fcbb5ca 100644 --- a/tests/16-sim-arch_basic.c +++ b/tests/16-sim-arch_basic.c @@ -93,6 +93,9 @@ int main(int argc, char *argv[]) if (rc != 0) goto out; rc = seccomp_arch_add(ctx, SCMP_ARCH_RISCV64); + if (rc != 0) + goto out; + rc = seccomp_arch_add(ctx, SCMP_ARCH_SH); if (rc != 0) goto out; diff --git a/tests/16-sim-arch_basic.py b/tests/16-sim-arch_basic.py index 846553fb..f22c9855 100755 --- a/tests/16-sim-arch_basic.py +++ b/tests/16-sim-arch_basic.py @@ -45,6 +45,7 @@ def test(args): f.add_arch(Arch("mipsel64n32")) f.add_arch(Arch("ppc64le")) f.add_arch(Arch("riscv64")) + f.add_arch(Arch("sh")) f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) diff --git a/tests/23-sim-arch_all_le_basic.c b/tests/23-sim-arch_all_le_basic.c index 32739e5b..08f030c8 100644 --- a/tests/23-sim-arch_all_le_basic.c +++ b/tests/23-sim-arch_all_le_basic.c @@ -72,6 +72,9 @@ int main(int argc, char *argv[]) if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("riscv64")); + if (rc != 0) + goto out; + rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("sh")); if (rc != 0) goto out; diff --git a/tests/23-sim-arch_all_le_basic.py b/tests/23-sim-arch_all_le_basic.py index 33eedb17..12bb243f 100755 --- a/tests/23-sim-arch_all_le_basic.py +++ b/tests/23-sim-arch_all_le_basic.py @@ -41,6 +41,7 @@ def test(args): f.add_arch(Arch("mipsel64n32")) f.add_arch(Arch("ppc64le")) f.add_arch(Arch("riscv64")) + f.add_arch(Arch("sh")) f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) diff --git a/tests/26-sim-arch_all_be_basic.c b/tests/26-sim-arch_all_be_basic.c index d31ce120..7db48eaa 100644 --- a/tests/26-sim-arch_all_be_basic.c +++ b/tests/26-sim-arch_all_be_basic.c @@ -68,6 +68,9 @@ int main(int argc, char *argv[]) if (rc != 0) goto out; rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("s390x")); + if (rc != 0) + goto out; + rc = seccomp_arch_add(ctx, seccomp_arch_resolve_name("sheb")); if (rc != 0) goto out; diff --git a/tests/26-sim-arch_all_be_basic.py b/tests/26-sim-arch_all_be_basic.py index 3a177b44..b0e5f5a2 100755 --- a/tests/26-sim-arch_all_be_basic.py +++ b/tests/26-sim-arch_all_be_basic.py @@ -39,6 +39,7 @@ def test(args): f.add_arch(Arch("ppc64")) f.add_arch(Arch("s390")) f.add_arch(Arch("s390x")) + f.add_arch(Arch("sheb")) f.add_rule(ALLOW, "read", Arg(0, EQ, sys.stdin.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stdout.fileno())) f.add_rule(ALLOW, "write", Arg(0, EQ, sys.stderr.fileno())) diff --git a/tests/regression b/tests/regression index 25043afc..53dab75a 100755 --- a/tests/regression +++ b/tests/regression @@ -26,12 +26,14 @@ GLBL_ARCH_LE_SUPPORT=" \ arm aarch64 \ mipsel mipsel64 mipsel64n32 \ ppc64le \ - riscv64" + riscv64 \ + sh" GLBL_ARCH_BE_SUPPORT=" \ mips mips64 mips64n32 \ parisc parisc64 \ ppc ppc64 \ - s390 s390x" + s390 s390x \ + sheb" GLBL_ARCH_32B_SUPPORT=" \ x86 x32 \ @@ -39,7 +41,8 @@ GLBL_ARCH_32B_SUPPORT=" \ mips mipsel mips64n32 mipsel64n32 \ parisc \ ppc \ - s390" + s390 \ + sheb sh" GLBL_ARCH_64B_SUPPORT=" \ x86_64 \ @@ -782,7 +785,7 @@ function run_test_live() { # setup the arch specific return values case "$arch" in - x86|x86_64|x32|arm|aarch64|parisc|parisc64|ppc|ppc64|ppc64le|ppc|s390|s390x|riscv64) + x86|x86_64|x32|arm|aarch64|parisc|parisc64|ppc|ppc64|ppc64le|ppc|s390|s390x|riscv64|sh|sheb) rc_kill_process=159 rc_kill=159 rc_allow=160 diff --git a/tools/scmp_arch_detect.c b/tools/scmp_arch_detect.c index b844a682..b6bd2bbd 100644 --- a/tools/scmp_arch_detect.c +++ b/tools/scmp_arch_detect.c @@ -123,6 +123,12 @@ int main(int argc, char *argv[]) case SCMP_ARCH_RISCV64: printf("riscv64\n"); break; + case SCMP_ARCH_SHEB: + printf("sheb\n"); + break; + case SCMP_ARCH_SH: + printf("sh\n"); + break; default: printf("unknown\n"); } diff --git a/tools/scmp_bpf_sim.c b/tools/scmp_bpf_sim.c index 3b581c67..04edfbc3 100644 --- a/tools/scmp_bpf_sim.c +++ b/tools/scmp_bpf_sim.c @@ -287,6 +287,10 @@ int main(int argc, char *argv[]) arch = AUDIT_ARCH_S390X; else if (strcmp(optarg, "riscv64") == 0) arch = AUDIT_ARCH_RISCV64; + else if (strcmp(optarg, "sheb") == 0) + arch = AUDIT_ARCH_SH; + else if (strcmp(optarg, "sh") == 0) + arch = AUDIT_ARCH_SHEL; else exit_fault(EINVAL); break; diff --git a/tools/util.c b/tools/util.c index 7da22f42..afea6c90 100644 --- a/tools/util.c +++ b/tools/util.c @@ -80,6 +80,12 @@ #define ARCH_NATIVE AUDIT_ARCH_S390 #elif __riscv && __riscv_xlen == 64 #define ARCH_NATIVE AUDIT_ARCH_RISCV64 +#elif __sh__ +#ifdef __BIG_ENDIAN__ +#define ARCH_NATIVE AUDIT_ARCH_SH +#else +#define ARCH_NATIVE AUDIT_ARCH_SHEL +#endif #else #error the simulator code needs to know about your machine type #endif