From 21f7373e76ff909ea6e1a87a2f3aa0d7344095eb Mon Sep 17 00:00:00 2001 From: Christian Blichmann Date: Fri, 11 Sep 2020 06:33:57 -0700 Subject: [PATCH] Initial changes to support AArch64 This is a work in progress: - Syscall tables need work - Only tested on real hardware using one of our test hosts As a drive-by, this change also enables the open source version to function on POWER. Another side-effect of this change is that the default policies no longer check for different host architectures at runtime. On x86_64, we do not need to check for PPC or AArch64 specifice and vice versa. PiperOrigin-RevId: 331137472 Change-Id: Ic6d6be5cbe61d83dbe13d5a0be036871754b2eb8 --- sandboxed_api/sandbox.cc | 2 + sandboxed_api/sandbox2/buffer_test.cc | 7 + sandboxed_api/sandbox2/config.h | 6 +- .../examples/static/static_sandbox.cc | 2 + sandboxed_api/sandbox2/mounts.cc | 4 + .../sandbox2/network_proxy/client.cc | 27 +- sandboxed_api/sandbox2/notify_test.cc | 4 + sandboxed_api/sandbox2/policy.cc | 79 ++--- sandboxed_api/sandbox2/policy_test.cc | 17 ++ sandboxed_api/sandbox2/policybuilder.cc | 7 + sandboxed_api/sandbox2/policybuilder_test.cc | 2 +- sandboxed_api/sandbox2/regs.cc | 66 +++- sandboxed_api/sandbox2/regs.h | 8 + sandboxed_api/sandbox2/stack_trace.cc | 4 + sandboxed_api/sandbox2/syscall.cc | 4 + sandboxed_api/sandbox2/syscall_defs.cc | 287 ++++++++++++++++++ sandboxed_api/sandbox2/util.cc | 5 +- sandboxed_api/sandbox2/violation.proto | 4 +- 18 files changed, 477 insertions(+), 58 deletions(-) diff --git a/sandboxed_api/sandbox.cc b/sandboxed_api/sandbox.cc index b18a1b0..8c9da3d 100644 --- a/sandboxed_api/sandbox.cc +++ b/sandboxed_api/sandbox.cc @@ -84,7 +84,9 @@ void InitDefaultPolicyBuilder(sandbox2::PolicyBuilder* builder) { __NR_kill, __NR_tgkill, __NR_tkill, +#ifdef __NR_readlink __NR_readlink, +#endif #ifdef __NR_arch_prctl // x86-64 only __NR_arch_prctl, #endif diff --git a/sandboxed_api/sandbox2/buffer_test.cc b/sandboxed_api/sandbox2/buffer_test.cc index 876be31..2b72a8b 100644 --- a/sandboxed_api/sandbox2/buffer_test.cc +++ b/sandboxed_api/sandbox2/buffer_test.cc @@ -84,11 +84,18 @@ std::unique_ptr BufferTestcasePolicy() { .AllowSyscall(__NR_lseek) .AllowSyscall(__NR_close) .BlockSyscallWithErrno(__NR_prlimit64, EPERM) +#ifdef __NR_open .BlockSyscallWithErrno(__NR_open, ENOENT) +#endif .BlockSyscallWithErrno(__NR_openat, ENOENT) +#ifdef __NR_access // On Debian, even static binaries check existence of // /etc/ld.so.nohwcap. .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif +#ifdef __NR_faccessat + .BlockSyscallWithErrno(__NR_faccessat, ENOENT) +#endif .BuildOrDie(); return s2p; diff --git a/sandboxed_api/sandbox2/config.h b/sandboxed_api/sandbox2/config.h index ba0fec5..209cd82 100644 --- a/sandboxed_api/sandbox2/config.h +++ b/sandboxed_api/sandbox2/config.h @@ -61,6 +61,8 @@ constexpr cpu::Architecture Architecture() { return cpu::kX8664; #elif defined(SAPI_PPC64_LE) return cpu::kPPC64LE; +#elif defined(SAPI_ARM64) + return cpu::kArm64; #else return cpu::kUnknown; #endif @@ -75,8 +77,8 @@ constexpr bool IsArm64() { return Architecture() == cpu::kArm64; } } // namespace host_cpu static_assert(host_cpu::Architecture() != cpu::kUnknown, - "Host CPU architecture is not supported: One of x86-64 or " - "POWER64 (little endian) is required."); + "Host CPU architecture is not supported: One of x86-64, POWER64 " + "(little endian) or AArch64 is required."); } // namespace sandbox2 diff --git a/sandboxed_api/sandbox2/examples/static/static_sandbox.cc b/sandboxed_api/sandbox2/examples/static/static_sandbox.cc index 44f794c..7290b72 100644 --- a/sandboxed_api/sandbox2/examples/static/static_sandbox.cc +++ b/sandboxed_api/sandbox2/examples/static/static_sandbox.cc @@ -52,8 +52,10 @@ std::unique_ptr GetPolicy() { // Allow the getpid() syscall. .AllowSyscall(__NR_getpid) +#ifdef __NR_access // On Debian, even static binaries check existence of /etc/ld.so.nohwcap. .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif // Examples for AddPolicyOnSyscall: .AddPolicyOnSyscall(__NR_write, diff --git a/sandboxed_api/sandbox2/mounts.cc b/sandboxed_api/sandbox2/mounts.cc index 24afdc6..4c71d52 100644 --- a/sandboxed_api/sandbox2/mounts.cc +++ b/sandboxed_api/sandbox2/mounts.cc @@ -113,6 +113,8 @@ absl::StatusOr ExistingPathInsideDir( absl::Status ValidateInterpreter(absl::string_view interpreter) { const absl::flat_hash_set allowed_interpreters = { "/lib64/ld-linux-x86-64.so.2", + "/lib64/ld64.so.2", // PPC64 + "/lib/ld-linux-aarch64.so.1", // AArch64 }; if (!allowed_interpreters.contains(interpreter)) { @@ -139,6 +141,8 @@ constexpr absl::string_view GetPlatformCPUName() { return "x86_64"; case cpu::kPPC64LE: return "ppc64"; + case cpu::kArm64: + return "aarch64"; default: return "unknown"; } diff --git a/sandboxed_api/sandbox2/network_proxy/client.cc b/sandboxed_api/sandbox2/network_proxy/client.cc index 51b1260..3dde8c1 100644 --- a/sandboxed_api/sandbox2/network_proxy/client.cc +++ b/sandboxed_api/sandbox2/network_proxy/client.cc @@ -49,10 +49,14 @@ constexpr int kRegSyscall = 0; constexpr int kRegArg0 = 3; constexpr int kRegArg1 = 4; constexpr int kRegArg2 = 5; +#elif defined(SAPI_ARM64) +constexpr int kRegResult = 0; +constexpr int kRegSyscall = 8; +constexpr int kRegArg0 = 0; +constexpr int kRegArg1 = 1; +constexpr int kRegArg2 = 2; #endif -constexpr char NetworkProxyClient::kFDName[]; - int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr, socklen_t addrlen) { absl::Status status = Connect(sockfd, addr, addrlen); @@ -154,20 +158,22 @@ void NetworkProxyHandler::InvokeOldAct(int nr, siginfo_t* info, void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info, void* void_context) { - ucontext_t* ctx = (ucontext_t*)(void_context); if (info->si_code != SYS_SECCOMP) { InvokeOldAct(nr, info, void_context); return; } - if (!ctx) return; + auto* ctx = static_cast(void_context); + if (!ctx) { + return; + } #if defined(SAPI_X86_64) auto* registers = ctx->uc_mcontext.gregs; #elif defined(SAPI_PPC64_LE) auto* registers = ctx->uc_mcontext.gp_regs; - using ppc_gpreg_t = std::decay::type; +#elif defined(SAPI_ARM64) + auto* registers = ctx->uc_mcontext.regs; #endif - int syscall = registers[kRegSyscall]; int sockfd; @@ -181,11 +187,10 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info, #if defined(SAPI_PPC64_LE) } else if (syscall == __NR_socketcall && static_cast(registers[kRegArg0]) == SYS_CONNECT) { - ppc_gpreg_t* args = reinterpret_cast(registers[kRegArg1]); - - sockfd = static_cast(args[0]); - addr = reinterpret_cast(args[1]); - addrlen = static_cast(args[2]); + auto* connect_args = reinterpret_cast(registers[kRegArg1]); + sockfd = static_cast(connect_args[0]); + addr = reinterpret_cast(connect_args[1]); + addrlen = static_cast(connect_args[2]); #endif } else { InvokeOldAct(nr, info, void_context); diff --git a/sandboxed_api/sandbox2/notify_test.cc b/sandboxed_api/sandbox2/notify_test.cc index 77fc67f..8e0bc38 100644 --- a/sandboxed_api/sandbox2/notify_test.cc +++ b/sandboxed_api/sandbox2/notify_test.cc @@ -49,8 +49,12 @@ std::unique_ptr NotifyTestcasePolicy() { .AllowWrite() .AllowSyscall(__NR_close) .AddPolicyOnSyscall(__NR_personality, {SANDBOX2_TRACE}) +#ifdef __NR_open .BlockSyscallWithErrno(__NR_open, ENOENT) +#endif +#ifdef __NR_access .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif .BlockSyscallWithErrno(__NR_openat, ENOENT) .BlockSyscallWithErrno(__NR_prlimit64, EPERM) .BuildOrDie(); diff --git a/sandboxed_api/sandbox2/policy.cc b/sandboxed_api/sandbox2/policy.cc index 4e3fe03..398fbfe 100644 --- a/sandboxed_api/sandbox2/policy.cc +++ b/sandboxed_api/sandbox2/policy.cc @@ -82,41 +82,41 @@ std::vector Policy::GetDefaultPolicy() const { bpf_labels l = {0}; std::vector policy = { - // If compiled arch is different than the runtime one, inform the Monitor. - LOAD_ARCH, - JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)), - JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)), - JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), - JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)), - TRACE(cpu::kUnknown), - LABEL(&l, past_arch_check_l), + // If compiled arch is different than the runtime one, inform the Monitor. + LOAD_ARCH, + JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)), +#if defined(SAPI_X86_64) + JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), // 32-bit sandboxee +#endif + TRACE(cpu::kUnknown), + LABEL(&l, past_arch_check_l), - // After the policy is uploaded, forkserver will execve the sandboxee. We - // need to allow this execve but not others. Since BPF does not have - // state, we need to inform the Monitor to decide, and for that we use a - // magic value in syscall args 5. Note that this value is not supposed to - // be secret, but just an optimization so that the monitor is not - // triggered on every call to execveat. - LOAD_SYSCALL_NR, - JNE32(__NR_execveat, JUMP(&l, past_execveat_l)), - ARG_32(4), - JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)), - ARG_32(5), - JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)), - SANDBOX2_TRACE, - LABEL(&l, past_execveat_l), + // After the policy is uploaded, forkserver will execve the sandboxee. We + // need to allow this execve but not others. Since BPF does not have + // state, we need to inform the Monitor to decide, and for that we use a + // magic value in syscall args 5. Note that this value is not supposed to + // be secret, but just an optimization so that the monitor is not + // triggered on every call to execveat. + LOAD_SYSCALL_NR, + JNE32(__NR_execveat, JUMP(&l, past_execveat_l)), + ARG_32(4), + JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)), + ARG_32(5), + JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)), + SANDBOX2_TRACE, + LABEL(&l, past_execveat_l), - // Forbid some syscalls because unsafe or too risky. - LOAD_SYSCALL_NR, - JEQ32(__NR_ptrace, DENY), - JEQ32(__NR_bpf, DENY), + // Forbid some syscalls because unsafe or too risky. + LOAD_SYSCALL_NR, + JEQ32(__NR_ptrace, DENY), + JEQ32(__NR_bpf, DENY), - // Disallow clone with CLONE_UNTRACED flag. - JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)), - // Regardless of arch, we only care about the lower 32-bits of the flags. - ARG_32(0), - JA32(CLONE_UNTRACED, DENY), - LABEL(&l, past_clone_untraced_l), + // Disallow clone with CLONE_UNTRACED flag. + JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)), + // Regardless of arch, we only care about the lower 32-bits of the flags. + ARG_32(0), + JA32(CLONE_UNTRACED, DENY), + LABEL(&l, past_clone_untraced_l), }; if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) { @@ -129,11 +129,16 @@ std::vector Policy::GetDefaultPolicy() const { std::vector Policy::GetTrackingPolicy() const { return { - LOAD_ARCH, - JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)), - JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), - JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)), - TRACE(cpu::kUnknown), + LOAD_ARCH, +#if defined(SAPI_X86_64) + JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)), + JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), +#elif defined(SAPI_PPC64_LE) + JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)), +#elif defined(SAPI_ARM64) + JEQ32(AUDIT_ARCH_AARCH64, TRACE(cpu::kArm64)), +#endif + TRACE(cpu::kUnknown), }; } diff --git a/sandboxed_api/sandbox2/policy_test.cc b/sandboxed_api/sandbox2/policy_test.cc index 226b450..a7cf852 100644 --- a/sandboxed_api/sandbox2/policy_test.cc +++ b/sandboxed_api/sandbox2/policy_test.cc @@ -50,9 +50,16 @@ std::unique_ptr PolicyTestcasePolicy() { .AllowSyscall(__NR_close) .AllowSyscall(__NR_getppid) .AllowTCGETS() +#ifdef __NR_open .BlockSyscallWithErrno(__NR_open, ENOENT) +#endif .BlockSyscallWithErrno(__NR_openat, ENOENT) +#ifdef __NR_access .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif +#ifdef __NR_faccessat + .BlockSyscallWithErrno(__NR_faccessat, ENOENT) +#endif .BlockSyscallWithErrno(__NR_prlimit64, EPERM) .BuildOrDie(); } @@ -162,7 +169,9 @@ std::unique_ptr MinimalTestcasePolicy() { .AllowStaticStartup() .AllowExit() .BlockSyscallWithErrno(__NR_prlimit64, EPERM) +#ifdef __NR_access .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif .BuildOrDie(); } @@ -197,8 +206,10 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) { .AllowOpen() .AllowExit() .AllowMmap() +#ifdef __NR_access // New glibc accesses /etc/ld.so.preload .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif .BlockSyscallWithErrno(__NR_prlimit64, EPERM) .AddLibrariesForBinary(path) .BuildOrDie(); @@ -223,7 +234,9 @@ TEST(MallocTest, SystemMallocWorks) { .AllowSystemMalloc() .AllowExit() .BlockSyscallWithErrno(__NR_prlimit64, EPERM) +#ifdef __NR_access .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif .BuildOrDie(); Sandbox2 s2(std::move(executor), std::move(policy)); @@ -247,7 +260,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) { auto policy = PolicyBuilder() +#ifdef __NR_open .BlockSyscallWithErrno(__NR_open, ENOENT) +#endif .BlockSyscallWithErrno(__NR_openat, ENOENT) .AllowStaticStartup() .AllowTcMalloc() @@ -258,7 +273,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) { .AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)}) .AddPolicyOnSyscall(__NR_umask, {DENY}) .BlockSyscallWithErrno(__NR_prlimit64, EPERM) +#ifdef __NR_access .BlockSyscallWithErrno(__NR_access, ENOENT) +#endif .BuildOrDie(); Sandbox2 s2(std::move(executor), std::move(policy)); diff --git a/sandboxed_api/sandbox2/policybuilder.cc b/sandboxed_api/sandbox2/policybuilder.cc index a560190..c0bfd41 100644 --- a/sandboxed_api/sandbox2/policybuilder.cc +++ b/sandboxed_api/sandbox2/policybuilder.cc @@ -520,7 +520,12 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() { }); #endif + if constexpr (host_cpu::IsArm64()) { + BlockSyscallWithErrno(__NR_readlinkat, ENOENT); + } +#ifdef __NR_readlink BlockSyscallWithErrno(__NR_readlink, ENOENT); +#endif return *this; } @@ -881,7 +886,9 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() { AllowFutexOp(FUTEX_WAIT); AllowFutexOp(FUTEX_WAIT_BITSET); AllowSyscalls({ +#ifdef __NR_dup2 __NR_dup2, +#endif __NR_recvmsg, __NR_close, __NR_gettid, diff --git a/sandboxed_api/sandbox2/policybuilder_test.cc b/sandboxed_api/sandbox2/policybuilder_test.cc index b5387d9..652a827 100644 --- a/sandboxed_api/sandbox2/policybuilder_test.cc +++ b/sandboxed_api/sandbox2/policybuilder_test.cc @@ -101,7 +101,7 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) { builder.AllowSystemMalloc(); assert_increased(); builder.AllowSyscall(__NR_munmap); assert_same(); builder.BlockSyscallWithErrno(__NR_munmap, 1); assert_same(); - builder.BlockSyscallWithErrno(__NR_open, 1); + builder.BlockSyscallWithErrno(__NR_openat, 1); assert_increased(); builder.AllowTCGETS(); assert_increased(); diff --git a/sandboxed_api/sandbox2/regs.cc b/sandboxed_api/sandbox2/regs.cc index 07f8e87..7a4c214 100644 --- a/sandboxed_api/sandbox2/regs.cc +++ b/sandboxed_api/sandbox2/regs.cc @@ -23,12 +23,18 @@ #include +#include "absl/base/macros.h" +#include "absl/status/status.h" #include "absl/strings/str_cat.h" #include "sandboxed_api/sandbox2/config.h" #include "sandboxed_api/sandbox2/util/strerror.h" namespace sandbox2 { +#ifndef NT_ARM_SYSTEM_CALL +#define NT_ARM_SYSTEM_CALL 0x404 +#endif + absl::Status Regs::Fetch() { #ifdef SAPI_X86_64 if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) { @@ -36,7 +42,7 @@ absl::Status Regs::Fetch() { ") failed: ", StrError(errno))); } #endif - if constexpr (host_cpu::IsPPC64LE()) { + if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) { iovec pt_iov = {&user_regs_, sizeof(user_regs_)}; if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) { @@ -50,6 +56,24 @@ absl::Status Regs::Fetch() { ") size returned: ", pt_iov.iov_len, " different than sizeof(user_regs_): ", sizeof(user_regs_))); } + + // On AArch64, we are not done yet. Read the syscall number. + if constexpr (host_cpu::IsArm64()) { + iovec sys_iov = {&syscall_number_, sizeof(syscall_number_)}; + + if (ptrace(PTRACE_GETREGSET, pid_, NT_ARM_SYSTEM_CALL, &sys_iov) == -1L) { + return absl::InternalError( + absl::StrCat("ptrace(PTRACE_GETREGSET, pid=", pid_, + ", NT_ARM_SYSTEM_CALL) failed: ", StrError(errno))); + } + if (sys_iov.iov_len != sizeof(syscall_number_)) { + return absl::InternalError(absl::StrCat( + "ptrace(PTRACE_GETREGSET, pid=", pid_, + ", NT_ARM_SYSTEM_CALL) size returned: ", sys_iov.iov_len, + " different than sizeof(syscall_number_): ", + sizeof(syscall_number_))); + } + } } return absl::OkStatus(); } @@ -61,7 +85,7 @@ absl::Status Regs::Store() { ") failed: ", StrError(errno))); } #endif - if constexpr (host_cpu::IsPPC64LE()) { + if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) { iovec pt_iov = {&user_regs_, sizeof(user_regs_)}; if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) { @@ -69,6 +93,17 @@ absl::Status Regs::Store() { absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_, ") failed: ", StrError(errno))); } + + // Store syscall number on AArch64. + if constexpr (host_cpu::IsArm64()) { + iovec sys_iov = {&syscall_number_, sizeof(syscall_number_)}; + + if (ptrace(PTRACE_SETREGSET, pid_, NT_ARM_SYSTEM_CALL, &sys_iov) == -1L) { + return absl::InternalError( + absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_, + ", NT_ARM_SYSTEM_CALL) failed: ", StrError(errno))); + } + } } return absl::OkStatus(); } @@ -80,6 +115,9 @@ absl::Status Regs::SkipSyscallReturnValue(uint64_t value) { #elif defined(SAPI_PPC64_LE) user_regs_.gpr[0] = -1; user_regs_.gpr[3] = value; +#elif defined(SAPI_ARM64) + user_regs_.regs[0] = -1; + syscall_number_ = value; #endif return Store(); } @@ -114,6 +152,22 @@ Syscall Regs::ToSyscall(cpu::Architecture syscall_arch) const { auto ip = user_regs_.nip; return Syscall(syscall_arch, syscall, args, pid_, sp, ip); } +#elif defined(SAPI_ARM64) + if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kArm64)) { + Syscall::Args args = { + // First argument should be orig_x0, which is not available to ptrace on + // AArch64 (see + // https://undo.io/resources/arm64-vs-arm32-whats-different-linux-programmers/), + // as it will have been overwritten. For our use case, though, using + // regs[0] is fine, as we are always called on syscall entry and never + // on exit. + user_regs_.regs[0], user_regs_.regs[1], user_regs_.regs[2], + user_regs_.regs[3], user_regs_.regs[4], user_regs_.regs[5], + }; + auto sp = user_regs_.sp; + auto ip = user_regs_.pc; + return Syscall(syscall_arch, syscall_number_, args, pid_, sp, ip); + } #endif return Syscall(pid_); } @@ -169,6 +223,14 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const { regs->set_zero1(user_regs_.zero1); regs->set_zero2(user_regs_.zero2); regs->set_zero3(user_regs_.zero3); +#elif defined(SAPI_ARM64) + RegisterAarch64* regs = values->mutable_register_aarch64(); + for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.regs); ++i) { + regs->add_regs(user_regs_.regs[i]); + } + regs->set_sp(user_regs_.sp); + regs->set_pc(user_regs_.pc); + regs->set_pstate(user_regs_.pstate); #endif } diff --git a/sandboxed_api/sandbox2/regs.h b/sandboxed_api/sandbox2/regs.h index 661c8b6..cce7022 100644 --- a/sandboxed_api/sandbox2/regs.h +++ b/sandboxed_api/sandbox2/regs.h @@ -105,6 +105,11 @@ class Regs { uint64_t zero1; uint64_t zero2; uint64_t zero3; +#elif defined(SAPI_ARM64) + uint64_t regs[31]; + uint64_t sp; + uint64_t pc; + uint64_t pstate; #else static_assert(false, "Host CPU architecture not supported, see config.h"); #endif @@ -115,6 +120,9 @@ class Regs { // Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid). PtraceRegisters user_regs_ = {}; + + // On AArch64, obtaining the syscall number needs a specific call to ptrace() + int syscall_number_ = 0; }; } // namespace sandbox2 diff --git a/sandboxed_api/sandbox2/stack_trace.cc b/sandboxed_api/sandbox2/stack_trace.cc index 7df7952..868b89e 100644 --- a/sandboxed_api/sandbox2/stack_trace.cc +++ b/sandboxed_api/sandbox2/stack_trace.cc @@ -31,6 +31,7 @@ #include "absl/strings/strip.h" #include "libcap/include/sys/capability.h" #include "sandboxed_api/sandbox2/comms.h" +#include "sandboxed_api/sandbox2/config.h" #include "sandboxed_api/sandbox2/executor.h" #include "sandboxed_api/sandbox2/ipc.h" #include "sandboxed_api/sandbox2/limits.h" @@ -270,6 +271,9 @@ bool StackTracePeer::LaunchLibunwindSandbox(const Regs* regs, } std::vector GetStackTrace(const Regs* regs, const Mounts& mounts) { + if constexpr (host_cpu::IsArm64()) { + return {"[Stack traces unavailable]"}; + } if (absl::GetFlag(FLAGS_sandbox_disable_all_stack_traces)) { return {"[Stacktraces disabled]"}; } diff --git a/sandboxed_api/sandbox2/syscall.cc b/sandboxed_api/sandbox2/syscall.cc index 7e06717..980320a 100644 --- a/sandboxed_api/sandbox2/syscall.cc +++ b/sandboxed_api/sandbox2/syscall.cc @@ -42,6 +42,8 @@ std::string Syscall::GetArchDescription(cpu::Architecture arch) { return "[X86-32]"; case cpu::kPPC64LE: return "[PPC-64]"; + case cpu::kArm64: + return "[Arm-64]"; default: LOG(ERROR) << "Unknown CPU architecture: " << arch; return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch); @@ -54,6 +56,8 @@ uint32_t Syscall::GetHostAuditArch() { return AUDIT_ARCH_X86_64; case cpu::kPPC64LE: return AUDIT_ARCH_PPC64LE; + case cpu::kArm64: + return AUDIT_ARCH_AARCH64; default: // The static_assert() in config.h should prevent us from ever getting // here. diff --git a/sandboxed_api/sandbox2/syscall_defs.cc b/sandboxed_api/sandbox2/syscall_defs.cc index 410d054..b79f6c7 100644 --- a/sandboxed_api/sandbox2/syscall_defs.cc +++ b/sandboxed_api/sandbox2/syscall_defs.cc @@ -1216,6 +1216,291 @@ constexpr SyscallTable::Entry kSyscallDataPPC64LE[] = { MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381 }; +// TODO(cblichmann): Confirm the entries in this list. +// https://github.com/torvalds/linux/blob/v5.8/include/uapi/asm-generic/unistd.h +constexpr SyscallTable::Entry kSyscallDataArm64[] = { + MakeEntry("io_setup", UnknownArguments()), // 0 + MakeEntry("io_destroy", UnknownArguments()), // 1 + MakeEntry("io_submit", UnknownArguments()), // 2 + MakeEntry("io_cancel", UnknownArguments()), // 3 + MakeEntry("io_getevents", UnknownArguments()), // 4 + MakeEntry("setxattr", kPath, kString, kGen, kInt, kHex, kGen), // 5 + MakeEntry("lsetxattr", kPath, kString, kGen, kInt, kHex, kGen), // 6 + MakeEntry("fsetxattr", UnknownArguments()), // 7 + MakeEntry("getxattr", kPath, kString, kGen, kInt, kGen, kGen), // 8 + MakeEntry("lgetxattr", kPath, kString, kGen, kInt, kGen, kGen), // 9 + MakeEntry("fgetxattr", UnknownArguments()), // 10 + MakeEntry("listxattr", kPath, kGen, kInt, kGen, kGen, kGen), // 11 + MakeEntry("llistxattr", kPath, kGen, kInt, kGen, kGen, kGen), // 12 + MakeEntry("flistxattr", UnknownArguments()), // 13 + MakeEntry("removexattr", kPath, kString, kGen, kGen, kGen, kGen), // 14 + MakeEntry("lremovexattr", UnknownArguments()), // 15 + MakeEntry("fremovexattr", UnknownArguments()), // 16 + MakeEntry("getcwd", UnknownArguments()), // 17 + MakeEntry("lookup_dcookie", UnknownArguments()), // 18 + MakeEntry("eventfd2", UnknownArguments()), // 19 + MakeEntry("epoll_create1", UnknownArguments()), // 20 + MakeEntry("epoll_ctl", UnknownArguments()), // 21 + MakeEntry("epoll_pwait", UnknownArguments()), // 22 + MakeEntry("dup", UnknownArguments()), // 23 + MakeEntry("dup3", UnknownArguments()), // 24 + MakeEntry("fcntl", UnknownArguments()), // 25 + MakeEntry("inotify_init1", UnknownArguments()), // 26 + MakeEntry("inotify_add_watch", UnknownArguments()), // 27 + MakeEntry("inotify_rm_watch", UnknownArguments()), // 28 + MakeEntry("ioctl", UnknownArguments()), // 29 + MakeEntry("ioprio_set", UnknownArguments()), // 30 + MakeEntry("ioprio_get", UnknownArguments()), // 31 + MakeEntry("flock", UnknownArguments()), // 32 + MakeEntry("mknodat", kGen, kPath, kGen, kGen, kGen, kGen), // 33 + MakeEntry("mkdirat", kGen, kPath, kGen, kGen, kGen, kGen), // 34 + MakeEntry("unlinkat", kGen, kPath, kGen, kGen, kGen, kGen), // 35 + MakeEntry("symlinkat", kPath, kGen, kPath, kGen, kGen, kGen), // 36 + MakeEntry("linkat", kGen, kPath, kGen, kPath, kGen, kGen), // 37 + MakeEntry("renameat", kGen, kPath, kGen, kPath, kGen, kGen), // 38 + MakeEntry("umount2", kPath, kHex, kGen, kGen, kGen, kGen), // 39 + MakeEntry("mount", kPath, kPath, kString, kHex, kGen, kGen), // 40 + MakeEntry("pivot_root", kPath, kPath, kGen, kGen, kGen, kGen), // 41 + MakeEntry("nfsservctl", UnknownArguments()), // 42 + MakeEntry("statfs", kPath, kGen, kGen, kGen, kGen, kGen), // 43 + MakeEntry("fstatfs", UnknownArguments()), // 44 + MakeEntry("truncate", kPath, kInt, kGen, kGen, kGen, kGen), // 45 + MakeEntry("ftruncate", UnknownArguments()), // 46 + MakeEntry("fallocate", UnknownArguments()), // 47 + MakeEntry("faccessat", kGen, kPath, kGen, kGen, kGen, kGen), // 48 + MakeEntry("chdir", kPath, kGen, kGen, kGen, kGen, kGen), // 49 + MakeEntry("fchdir", UnknownArguments()), // 50 + MakeEntry("chroot", kPath, kGen, kGen, kGen, kGen, kGen), // 51 + MakeEntry("fchmod", UnknownArguments()), // 52 + MakeEntry("fchmodat", kGen, kPath, kGen, kGen, kGen, kGen), // 53 + MakeEntry("fchownat", kGen, kPath, kGen, kGen, kGen, kGen), // 54 + MakeEntry("fchown", UnknownArguments()), // 55 + MakeEntry("openat", kGen, kPath, kOct, kHex, kGen, kGen), // 56 + MakeEntry("close", kInt, kGen, kGen, kGen, kGen, kGen), // 57 + MakeEntry("vhangup", UnknownArguments()), // 58 + MakeEntry("pipe2", UnknownArguments()), // 59 + MakeEntry("quotactl", kInt, kPath, kInt, kGen, kGen, kGen), // 60 + MakeEntry("getdents64", UnknownArguments()), // 61 + MakeEntry("lseek", UnknownArguments()), // 62 + MakeEntry("read", kInt, kHex, kInt, kGen, kGen, kGen), // 63 + MakeEntry("write", kInt, kHex, kInt, kGen, kGen, kGen), // 64 + MakeEntry("readv", UnknownArguments()), // 65 + MakeEntry("writev", UnknownArguments()), // 66 + MakeEntry("pread64", UnknownArguments()), // 67 + MakeEntry("pwrite64", UnknownArguments()), // 68 + MakeEntry("preadv", UnknownArguments()), // 69 + MakeEntry("pwritev", UnknownArguments()), // 70 + MakeEntry("sendfile", UnknownArguments()), // 71 + MakeEntry("pselect6", UnknownArguments()), // 72 + MakeEntry("ppoll", UnknownArguments()), // 73 + MakeEntry("signalfd4", UnknownArguments()), // 74 + MakeEntry("vmsplice", UnknownArguments()), // 75 + MakeEntry("splice", UnknownArguments()), // 76 + MakeEntry("tee", UnknownArguments()), // 77 + MakeEntry("readlinkat", kGen, kPath, kGen, kGen, kGen, kGen), // 78 + MakeEntry("newfstatat", kGen, kPath, kGen, kGen, kGen, kGen), // 79 + MakeEntry("fstat", kInt, kHex, kGen, kGen, kGen, kGen), // 80 + MakeEntry("sync", UnknownArguments()), // 81 + MakeEntry("fsync", UnknownArguments()), // 82 + MakeEntry("fdatasync", UnknownArguments()), // 83 + MakeEntry("sync_file_range", UnknownArguments()), // 84 + MakeEntry("timerfd_create", UnknownArguments()), // 85 + MakeEntry("timerfd_settime", UnknownArguments()), // 86 + MakeEntry("timerfd_gettime", UnknownArguments()), // 87 + MakeEntry("utimensat", UnknownArguments()), // 88 + MakeEntry("acct", kPath, kGen, kGen, kGen, kGen, kGen), // 89 + MakeEntry("capget", UnknownArguments()), // 90 + MakeEntry("capset", UnknownArguments()), // 91 + MakeEntry("personality", UnknownArguments()), // 92 + MakeEntry("exit", kInt, kGen, kGen, kGen, kGen, kGen), // 93 + MakeEntry("exit_group", kInt, kGen, kGen, kGen, kGen, kGen), // 94 + MakeEntry("waitid", UnknownArguments()), // 95 + MakeEntry("set_tid_address", kHex, kGen, kGen, kGen, kGen, kGen), // 96 + MakeEntry("unshare", UnknownArguments()), // 97 + MakeEntry("futex", UnknownArguments()), // 98 + MakeEntry("set_robust_list", UnknownArguments()), // 99 + MakeEntry("get_robust_list", UnknownArguments()), // 100 + MakeEntry("nanosleep", kHex, kHex, kGen, kGen, kGen, kGen), // 101 + MakeEntry("getitimer", UnknownArguments()), // 102 + MakeEntry("setitimer", UnknownArguments()), // 103 + MakeEntry("kexec_load", UnknownArguments()), // 104 + MakeEntry("init_module", UnknownArguments()), // 105 + MakeEntry("delete_module", UnknownArguments()), // 106 + MakeEntry("timer_create", UnknownArguments()), // 107 + MakeEntry("timer_gettime", UnknownArguments()), // 108 + MakeEntry("timer_getoverrun", UnknownArguments()), // 109 + MakeEntry("timer_settime", UnknownArguments()), // 110 + MakeEntry("timer_delete", UnknownArguments()), // 111 + MakeEntry("clock_settime", UnknownArguments()), // 112 + MakeEntry("clock_gettime", UnknownArguments()), // 113 + MakeEntry("clock_getres", UnknownArguments()), // 114 + MakeEntry("clock_nanosleep", UnknownArguments()), // 115 + MakeEntry("syslog", UnknownArguments()), // 116 + MakeEntry("ptrace", UnknownArguments()), // 117 + MakeEntry("sched_setparam", UnknownArguments()), // 118 + MakeEntry("sched_setscheduler", UnknownArguments()), // 119 + MakeEntry("sched_getscheduler", UnknownArguments()), // 120 + MakeEntry("sched_getparam", UnknownArguments()), // 121 + MakeEntry("sched_setaffinity", UnknownArguments()), // 122 + MakeEntry("sched_getaffinity", UnknownArguments()), // 123 + MakeEntry("sched_yield", UnknownArguments()), // 124 + MakeEntry("sched_get_priority_max", UnknownArguments()), // 125 + MakeEntry("sched_get_priority_min", UnknownArguments()), // 126 + MakeEntry("sched_rr_get_interval", UnknownArguments()), // 127 + MakeEntry("restart_syscall", UnknownArguments()), // 128 + MakeEntry("kill", kInt, kSignal, kGen, kGen, kGen, kGen), // 129 + MakeEntry("tkill", kInt, kSignal, kGen, kGen, kGen, kGen), // 130 + MakeEntry("tgkill", kInt, kInt, kSignal, kGen, kGen, kGen), // 131 + MakeEntry("sigaltstack", UnknownArguments()), // 132 + MakeEntry("rt_sigsuspend", UnknownArguments()), // 133 + MakeEntry("rt_sigaction", kSignal, kHex, kHex, kInt, kGen, kGen), // 134 + MakeEntry("rt_sigprocmask", UnknownArguments()), // 135 + MakeEntry("rt_sigpending", UnknownArguments()), // 136 + MakeEntry("rt_sigtimedwait", UnknownArguments()), // 137 + MakeEntry("rt_sigqueueinfo", UnknownArguments()), // 138 + MakeEntry("rt_sigreturn", UnknownArguments()), // 139 + MakeEntry("setpriority", UnknownArguments()), // 140 + MakeEntry("getpriority", UnknownArguments()), // 141 + MakeEntry("reboot", UnknownArguments()), // 142 + MakeEntry("setregid", UnknownArguments()), // 143 + MakeEntry("setgid", UnknownArguments()), // 144 + MakeEntry("setreuid", UnknownArguments()), // 145 + MakeEntry("setuid", UnknownArguments()), // 146 + MakeEntry("setresuid", UnknownArguments()), // 147 + MakeEntry("getresuid", UnknownArguments()), // 148 + MakeEntry("setresgid", UnknownArguments()), // 149 + MakeEntry("getresgid", UnknownArguments()), // 150 + MakeEntry("setfsuid", UnknownArguments()), // 151 + MakeEntry("setfsgid", UnknownArguments()), // 152 + MakeEntry("times", UnknownArguments()), // 153 + MakeEntry("setpgid", UnknownArguments()), // 154 + MakeEntry("getpgid", UnknownArguments()), // 155 + MakeEntry("getsid", UnknownArguments()), // 156 + MakeEntry("setsid", UnknownArguments()), // 157 + MakeEntry("getgroups", UnknownArguments()), // 158 + MakeEntry("setgroups", UnknownArguments()), // 159 + MakeEntry("uname", UnknownArguments()), // 160 + MakeEntry("sethostname", UnknownArguments()), // 161 + MakeEntry("setdomainname", UnknownArguments()), // 162 + MakeEntry("getrlimit", UnknownArguments()), // 163 + MakeEntry("setrlimit", UnknownArguments()), // 164 + MakeEntry("getrusage", UnknownArguments()), // 165 + MakeEntry("umask", kHex, kGen, kGen, kGen, kGen, kGen), // 166 + MakeEntry("prctl", kInt, kHex, kHex, kHex, kHex, kGen), // 167 + MakeEntry("getcpu", kHex, kHex, kHex, kGen, kGen, kGen), // 168 + MakeEntry("gettimeofday", kHex, kHex, kGen, kGen, kGen, kGen), // 169 + MakeEntry("settimeofday", kHex, kHex, kGen, kGen, kGen, kGen), // 170 + MakeEntry("adjtimex", UnknownArguments()), // 171 + MakeEntry("getpid", UnknownArguments()), // 172 + MakeEntry("getppid", UnknownArguments()), // 173 + MakeEntry("getuid", UnknownArguments()), // 174 + MakeEntry("geteuid", UnknownArguments()), // 175 + MakeEntry("getgid", UnknownArguments()), // 176 + MakeEntry("getegid", UnknownArguments()), // 177 + MakeEntry("gettid", UnknownArguments()), // 178 + MakeEntry("sysinfo", UnknownArguments()), // 179 + MakeEntry("mq_open", UnknownArguments()), // 180 + MakeEntry("mq_unlink", UnknownArguments()), // 181 + MakeEntry("mq_timedsend", UnknownArguments()), // 182 + MakeEntry("mq_timedreceive", UnknownArguments()), // 183 + MakeEntry("mq_notify", UnknownArguments()), // 184 + MakeEntry("mq_getsetattr", UnknownArguments()), // 185 + MakeEntry("msgget", UnknownArguments()), // 186 + MakeEntry("msgctl", UnknownArguments()), // 187 + MakeEntry("msgrcv", UnknownArguments()), // 188 + MakeEntry("msgsnd", UnknownArguments()), // 189 + MakeEntry("semget", UnknownArguments()), // 190 + MakeEntry("semctl", UnknownArguments()), // 191 + MakeEntry("semtimedop", UnknownArguments()), // 192 + MakeEntry("semop", UnknownArguments()), // 193 + MakeEntry("shmget", UnknownArguments()), // 194 + MakeEntry("shmctl", UnknownArguments()), // 195 + MakeEntry("shmat", UnknownArguments()), // 196 + MakeEntry("shmdt", UnknownArguments()), // 197 + MakeEntry("socket", kAddressFamily, kInt, kInt, kGen, kGen, kGen), // 198 + MakeEntry("socketpair", UnknownArguments()), // 199 + MakeEntry("bind", UnknownArguments()), // 200 + MakeEntry("listen", UnknownArguments()), // 201 + MakeEntry("accept", UnknownArguments()), // 202 + MakeEntry("connect", kInt, kSockaddr, kInt, kGen, kGen, kGen), // 203 + MakeEntry("getsockname", UnknownArguments()), // 204 + MakeEntry("getpeername", UnknownArguments()), // 205 + MakeEntry("sendto", kInt, kGen, kInt, kHex, kSockaddr, kInt), // 206 + MakeEntry("recvfrom", UnknownArguments()), // 207 + MakeEntry("setsockopt", UnknownArguments()), // 208 + MakeEntry("getsockopt", UnknownArguments()), // 209 + MakeEntry("shutdown", UnknownArguments()), // 210 + MakeEntry("sendmsg", kInt, kSockmsghdr, kHex, kGen, kGen, kGen), // 211 + MakeEntry("recvmsg", UnknownArguments()), // 212 + MakeEntry("readahead", UnknownArguments()), // 213 + MakeEntry("brk", kHex, kGen, kGen, kGen, kGen, kGen), // 214 + MakeEntry("munmap", kHex, kHex, kGen, kGen, kGen, kGen), // 215 + MakeEntry("mremap", UnknownArguments()), // 216 + MakeEntry("add_key", UnknownArguments()), // 217 + MakeEntry("request_key", UnknownArguments()), // 218 + MakeEntry("keyctl", UnknownArguments()), // 219 + MakeEntry("clone", kCloneFlag, kHex, kHex, kHex, kHex, kGen), // 220 + MakeEntry("execve", kPath, kHex, kHex, kGen, kGen, kGen), // 221 + MakeEntry("mmap", kHex, kInt, kHex, kHex, kInt, kInt), // 222 + MakeEntry("fadvise64", UnknownArguments()), // 223 + MakeEntry("swapon", kPath, kHex, kGen, kGen, kGen, kGen), // 224 + MakeEntry("swapoff", kPath, kGen, kGen, kGen, kGen, kGen), // 225 + MakeEntry("mprotect", kHex, kHex, kHex, kGen, kGen, kGen), // 226 + MakeEntry("msync", UnknownArguments()), // 227 + MakeEntry("mlock", UnknownArguments()), // 228 + MakeEntry("munlock", UnknownArguments()), // 229 + MakeEntry("mlockall", UnknownArguments()), // 230 + MakeEntry("munlockall", UnknownArguments()), // 231 + MakeEntry("mincore", UnknownArguments()), // 232 + MakeEntry("madvise", UnknownArguments()), // 233 + MakeEntry("remap_file_pages", UnknownArguments()), // 234 + MakeEntry("mbind", UnknownArguments()), // 235 + MakeEntry("get_mempolicy", UnknownArguments()), // 236 + MakeEntry("set_mempolicy", UnknownArguments()), // 237 + MakeEntry("migrate_pages", UnknownArguments()), // 238 + MakeEntry("move_pages", UnknownArguments()), // 239 + MakeEntry("rt_tgsigqueueinfo", UnknownArguments()), // 240 + MakeEntry("perf_event_open", UnknownArguments()), // 241 + MakeEntry("accept4", UnknownArguments()), // 242 + MakeEntry("recvmmsg", kInt, kHex, kHex, kHex, kGen, kGen), // 243 + SYSCALLS_UNUSED("UNUSED244"), // 244 + SYSCALLS_UNUSED("UNUSED245"), // 245 + SYSCALLS_UNUSED("UNUSED246"), // 246 + SYSCALLS_UNUSED("UNUSED247"), // 247 + SYSCALLS_UNUSED("UNUSED248"), // 248 + SYSCALLS_UNUSED("UNUSED249"), // 249 + SYSCALLS_UNUSED("UNUSED250"), // 250 + SYSCALLS_UNUSED("UNUSED251"), // 251 + SYSCALLS_UNUSED("UNUSED252"), // 252 + SYSCALLS_UNUSED("UNUSED253"), // 253 + SYSCALLS_UNUSED("UNUSED254"), // 254 + SYSCALLS_UNUSED("UNUSED255"), // 255 + SYSCALLS_UNUSED("UNUSED256"), // 256 + SYSCALLS_UNUSED("UNUSED257"), // 257 + SYSCALLS_UNUSED("UNUSED258"), // 258 + SYSCALLS_UNUSED("UNUSED259"), // 259 + MakeEntry("wait4", kInt, kHex, kHex, kHex, kGen, kGen), // 260 + MakeEntry("prlimit64", kInt, kInt, kHex, kHex, kGen, kGen), // 261 + MakeEntry("fanotify_init", kHex, kHex, kInt, kGen, kGen, kGen), // 262 + MakeEntry("fanotify_mark", kInt, kHex, kInt, kPath, kGen, kGen), // 263 + MakeEntry("name_to_handle_at", kInt, kGen, kHex, kHex, kHex, kGen), // 264 + MakeEntry("open_by_handle_at", kInt, kHex, kHex, kGen, kGen, kGen), // 265 + MakeEntry("clock_adjtime", kInt, kHex, kGen, kGen, kGen, kGen), // 266 + MakeEntry("syncfs", kInt, kGen, kGen, kGen, kGen, kGen), // 267 + MakeEntry("setns", kInt, kHex, kGen, kGen, kGen, kGen), // 268 + MakeEntry("sendmmsg", kInt, kHex, kInt, kHex, kGen, kGen), // 269 + MakeEntry("process_vm_readv", kInt, kHex, kInt, kHex, kInt, kInt), // 270 + MakeEntry("process_vm_writev", kInt, kHex, kInt, kHex, kInt, kInt), // 271 + MakeEntry("kcmp", kInt, kInt, kInt, kHex, kHex, kGen), // 272 + MakeEntry("finit_module", kInt, kPath, kHex, kGen, kGen, kGen), // 273 + MakeEntry("sched_setattr", UnknownArguments()), // 274 + MakeEntry("sched_getattr", UnknownArguments()), // 275 + MakeEntry("renameat2", kGen, kPath, kGen, kPath, kGen, kGen), // 276 + MakeEntry("seccomp", UnknownArguments()), // 277 + MakeEntry("getrandom", UnknownArguments()), // 278 + MakeEntry("memfd_create", UnknownArguments()), // 279 +}; + #undef SYSCALLS_UNUSED00_99 #undef SYSCALLS_UNUSED50_99 #undef SYSCALLS_UNUSED00_49 @@ -1230,6 +1515,8 @@ SyscallTable SyscallTable::get(cpu::Architecture arch) { return SyscallTable(kSyscallDataX8632); case cpu::kPPC64LE: return SyscallTable(kSyscallDataPPC64LE); + case cpu::kArm64: + return SyscallTable(kSyscallDataArm64); default: return SyscallTable(); } diff --git a/sandboxed_api/sandbox2/util.cc b/sandboxed_api/sandbox2/util.cc index 3e97abc..c3d90ba 100644 --- a/sandboxed_api/sandbox2/util.cc +++ b/sandboxed_api/sandbox2/util.cc @@ -126,8 +126,9 @@ ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS ABSL_ATTRIBUTE_NOINLINE pid_t CloneAndJump(int flags, jmp_buf* env_ptr) { uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED; - static_assert(host_cpu::IsX8664() || host_cpu::IsPPC64LE(), - "Host CPU architecture not supported, see config.h"); + static_assert( + host_cpu::IsX8664() || host_cpu::IsPPC64LE() || host_cpu::IsArm64(), + "Host CPU architecture not supported, see config.h"); // Stack grows down. void* stack = stack_buf + sizeof(stack_buf); int r; diff --git a/sandboxed_api/sandbox2/violation.proto b/sandboxed_api/sandbox2/violation.proto index 57a3b3d..235cf6a 100644 --- a/sandboxed_api/sandbox2/violation.proto +++ b/sandboxed_api/sandbox2/violation.proto @@ -25,7 +25,6 @@ enum PBViolationType { SYSCALL_ARCHITECTURE_MISMATCH = 3; } -// X86_64 not allowed (naming convention...) message RegisterX8664 { uint64 r15 = 1; uint64 r14 = 2; @@ -77,7 +76,6 @@ message RegisterPowerpc64 { uint64 zero3 = 17; } -// Deprecated. message RegisterAarch64 { repeated uint64 regs = 1; uint64 sp = 2; @@ -90,7 +88,7 @@ message RegisterValues { oneof register_values { RegisterX8664 register_x86_64 = 2; RegisterPowerpc64 register_powerpc64 = 3; - RegisterAarch64 register_aarch64 = 4; // Deprecated. + RegisterAarch64 register_aarch64 = 4; } }