riscv64 syscall stub and seccomp filter generation.
These are sufficiently intertwined that they need to be done together.
riscv64 is our first primary-only architecture, so that required some
changes. The .bp changes are to support this --- we need to only show
the python scripts the architectures they'll actually be using, rather
than showing them everything and ignoring some of the results.
riscv64 is also the first architecture that post-dates the kernel's
64-bit time work, so there's a bit of extra fiddling needed to handle
the __NR3264_ indirection in the uapi headers.
Signed-off-by: Mao Han <han_mao@linux.alibaba.com>
Signed-off-by: Xia Lifang <lifang_xia@linux.alibaba.com>
Signed-off-by: Chen Guoyin <chenguoyin.cgy@linux.alibaba.com>
Signed-off-by: Wang Chen <wangchen20@iscas.ac.cn>
Signed-off-by: Lu Xufan <luxufan@iscas.ac.cn>
Test: local builds for x86-64 and riscv64
Change-Id: I74044744e80b312088f805c44fbd667c9bfcdc69
diff --git a/libc/seccomp/seccomp_policy.cpp b/libc/seccomp/seccomp_policy.cpp
index a42816e..1ca4eec 100644
--- a/libc/seccomp/seccomp_policy.cpp
+++ b/libc/seccomp/seccomp_policy.cpp
@@ -25,13 +25,13 @@
#include <vector>
#include <android-base/logging.h>
+#include <android-base/macros.h>
#include "func_to_syscall_nrs.h"
#include "seccomp_bpfs.h"
#if defined __arm__ || defined __aarch64__
-#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_AARCH64
static const struct sock_filter* primary_app_filter = arm64_app_filter;
static const size_t primary_app_filter_size = arm64_app_filter_size;
@@ -52,9 +52,9 @@
static const long secondary_setresgid = __arm_setresgid;
static const long secondary_setresuid = __arm_setresuid;
+
#elif defined __i386__ || defined __x86_64__
-#define DUAL_ARCH
#define PRIMARY_ARCH AUDIT_ARCH_X86_64
static const struct sock_filter* primary_app_filter = x86_64_app_filter;
static const size_t primary_app_filter_size = x86_64_app_filter_size;
@@ -75,6 +75,20 @@
static const long secondary_setresgid = __x86_setresgid;
static const long secondary_setresuid = __x86_setresuid;
+
+#elif defined(__riscv)
+
+#define PRIMARY_ARCH AUDIT_ARCH_RISCV64
+static const struct sock_filter* primary_app_filter = riscv64_app_filter;
+static const size_t primary_app_filter_size = riscv64_app_filter_size;
+static const struct sock_filter* primary_app_zygote_filter = riscv64_app_zygote_filter;
+static const size_t primary_app_zygote_filter_size = riscv64_app_zygote_filter_size;
+static const struct sock_filter* primary_system_filter = riscv64_system_filter;
+static const size_t primary_system_filter_size = riscv64_system_filter_size;
+
+static const long primary_setresgid = __riscv64_setresgid;
+static const long primary_setresuid = __riscv64_setresuid;
+
#else
#error No architecture was defined!
#endif
@@ -98,7 +112,7 @@
f.push_back(BPF_STMT(BPF_LD|BPF_W|BPF_ABS, syscall_nr));
}
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
static bool SetValidateArchitectureJumpTarget(size_t offset, filter& f) {
size_t jump_length = f.size() - offset - 1;
auto u8_jump_length = (__u8) jump_length;
@@ -149,9 +163,17 @@
// that's the only system call we need to check here. A CTS test ensures the other
// calls will remain blocked.
static void ValidateSetUidGid(filter& f, uint32_t uid_gid_min, uint32_t uid_gid_max, bool primary) {
+#if defined(SECONDARY_ARCH)
+ __u32 setresuid_nr = primary ? primary_setresuid : secondary_setresuid;
+ __u32 setresgid_nr = primary ? primary_setresgid : secondary_setresgid;
+#else
+ __u32 setresuid_nr = primary_setresuid;
+ __u32 setresgid_nr = primary_setresgid;
+ UNUSED(primary);
+#endif
+
// Check setresuid(ruid, euid, sguid) fall within range
ExamineSyscall(f);
- __u32 setresuid_nr = primary ? primary_setresuid : secondary_setresuid;
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresuid_nr, 0, 12));
for (int arg = 0; arg < 3; arg++) {
ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
@@ -159,7 +181,6 @@
// Check setresgid(rgid, egid, sgid) fall within range
ExamineSyscall(f);
- __u32 setresgid_nr = primary ? primary_setresgid : secondary_setresgid;
f.push_back(BPF_JUMP(BPF_JMP|BPF_JEQ|BPF_K, setresgid_nr, 0, 12));
for (int arg = 0; arg < 3; arg++) {
ValidateSyscallArgInRange(f, arg, uid_gid_min, uid_gid_max);
@@ -184,7 +205,7 @@
bool _install_setuidgid_filter(uint32_t uid_gid_min, uint32_t uid_gid_max) {
filter f;
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
// Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
// jump that must be changed to point to the start of the 32-bit policy
// 32 bit syscalls will not hit the policy between here and the call to SetJump
@@ -195,7 +216,7 @@
ValidateSetUidGid(f, uid_gid_min, uid_gid_max, true /* primary */);
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
if (!SetValidateArchitectureJumpTarget(offset_to_secondary_filter, f)) {
return false;
}
@@ -213,32 +234,43 @@
};
bool _set_seccomp_filter(FilterType type) {
- const sock_filter *p, *s;
- size_t p_size, s_size;
filter f;
+ const sock_filter* p;
+ size_t p_size;
+#if defined(SECONDARY_ARCH)
+ const sock_filter* s;
+ size_t s_size;
+#endif
+
switch (type) {
case APP:
p = primary_app_filter;
p_size = primary_app_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_app_filter;
s_size = secondary_app_filter_size;
+#endif
break;
case APP_ZYGOTE:
p = primary_app_zygote_filter;
p_size = primary_app_zygote_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_app_zygote_filter;
s_size = secondary_app_zygote_filter_size;
+#endif
break;
case SYSTEM:
p = primary_system_filter;
p_size = primary_system_filter_size;
+#if defined(SECONDARY_ARCH)
s = secondary_system_filter;
s_size = secondary_system_filter_size;
+#endif
break;
}
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
// Note that for mixed 64/32 bit architectures, ValidateArchitecture inserts a
// jump that must be changed to point to the start of the 32-bit policy
// 32 bit syscalls will not hit the policy between here and the call to SetJump
@@ -254,7 +286,7 @@
}
Disallow(f);
-#ifdef DUAL_ARCH
+#if defined(SECONDARY_ARCH)
if (!SetValidateArchitectureJumpTarget(offset_to_secondary_filter, f)) {
return false;
}