mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
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
This commit is contained in:
parent
c19949eb7b
commit
21f7373e76
|
@ -84,7 +84,9 @@ void InitDefaultPolicyBuilder(sandbox2::PolicyBuilder* builder) {
|
||||||
__NR_kill,
|
__NR_kill,
|
||||||
__NR_tgkill,
|
__NR_tgkill,
|
||||||
__NR_tkill,
|
__NR_tkill,
|
||||||
|
#ifdef __NR_readlink
|
||||||
__NR_readlink,
|
__NR_readlink,
|
||||||
|
#endif
|
||||||
#ifdef __NR_arch_prctl // x86-64 only
|
#ifdef __NR_arch_prctl // x86-64 only
|
||||||
__NR_arch_prctl,
|
__NR_arch_prctl,
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -84,11 +84,18 @@ std::unique_ptr<Policy> BufferTestcasePolicy() {
|
||||||
.AllowSyscall(__NR_lseek)
|
.AllowSyscall(__NR_lseek)
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
|
#ifdef __NR_access
|
||||||
// On Debian, even static binaries check existence of
|
// On Debian, even static binaries check existence of
|
||||||
// /etc/ld.so.nohwcap.
|
// /etc/ld.so.nohwcap.
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_faccessat
|
||||||
|
.BlockSyscallWithErrno(__NR_faccessat, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
return s2p;
|
return s2p;
|
||||||
|
|
|
@ -61,6 +61,8 @@ constexpr cpu::Architecture Architecture() {
|
||||||
return cpu::kX8664;
|
return cpu::kX8664;
|
||||||
#elif defined(SAPI_PPC64_LE)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
return cpu::kPPC64LE;
|
return cpu::kPPC64LE;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
return cpu::kArm64;
|
||||||
#else
|
#else
|
||||||
return cpu::kUnknown;
|
return cpu::kUnknown;
|
||||||
#endif
|
#endif
|
||||||
|
@ -75,8 +77,8 @@ constexpr bool IsArm64() { return Architecture() == cpu::kArm64; }
|
||||||
} // namespace host_cpu
|
} // namespace host_cpu
|
||||||
|
|
||||||
static_assert(host_cpu::Architecture() != cpu::kUnknown,
|
static_assert(host_cpu::Architecture() != cpu::kUnknown,
|
||||||
"Host CPU architecture is not supported: One of x86-64 or "
|
"Host CPU architecture is not supported: One of x86-64, POWER64 "
|
||||||
"POWER64 (little endian) is required.");
|
"(little endian) or AArch64 is required.");
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
||||||
|
|
|
@ -52,8 +52,10 @@ std::unique_ptr<sandbox2::Policy> GetPolicy() {
|
||||||
// Allow the getpid() syscall.
|
// Allow the getpid() syscall.
|
||||||
.AllowSyscall(__NR_getpid)
|
.AllowSyscall(__NR_getpid)
|
||||||
|
|
||||||
|
#ifdef __NR_access
|
||||||
// On Debian, even static binaries check existence of /etc/ld.so.nohwcap.
|
// On Debian, even static binaries check existence of /etc/ld.so.nohwcap.
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
|
||||||
// Examples for AddPolicyOnSyscall:
|
// Examples for AddPolicyOnSyscall:
|
||||||
.AddPolicyOnSyscall(__NR_write,
|
.AddPolicyOnSyscall(__NR_write,
|
||||||
|
|
|
@ -113,6 +113,8 @@ absl::StatusOr<std::string> ExistingPathInsideDir(
|
||||||
absl::Status ValidateInterpreter(absl::string_view interpreter) {
|
absl::Status ValidateInterpreter(absl::string_view interpreter) {
|
||||||
const absl::flat_hash_set<std::string> allowed_interpreters = {
|
const absl::flat_hash_set<std::string> allowed_interpreters = {
|
||||||
"/lib64/ld-linux-x86-64.so.2",
|
"/lib64/ld-linux-x86-64.so.2",
|
||||||
|
"/lib64/ld64.so.2", // PPC64
|
||||||
|
"/lib/ld-linux-aarch64.so.1", // AArch64
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!allowed_interpreters.contains(interpreter)) {
|
if (!allowed_interpreters.contains(interpreter)) {
|
||||||
|
@ -139,6 +141,8 @@ constexpr absl::string_view GetPlatformCPUName() {
|
||||||
return "x86_64";
|
return "x86_64";
|
||||||
case cpu::kPPC64LE:
|
case cpu::kPPC64LE:
|
||||||
return "ppc64";
|
return "ppc64";
|
||||||
|
case cpu::kArm64:
|
||||||
|
return "aarch64";
|
||||||
default:
|
default:
|
||||||
return "unknown";
|
return "unknown";
|
||||||
}
|
}
|
||||||
|
|
|
@ -49,10 +49,14 @@ constexpr int kRegSyscall = 0;
|
||||||
constexpr int kRegArg0 = 3;
|
constexpr int kRegArg0 = 3;
|
||||||
constexpr int kRegArg1 = 4;
|
constexpr int kRegArg1 = 4;
|
||||||
constexpr int kRegArg2 = 5;
|
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
|
#endif
|
||||||
|
|
||||||
constexpr char NetworkProxyClient::kFDName[];
|
|
||||||
|
|
||||||
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
||||||
socklen_t addrlen) {
|
socklen_t addrlen) {
|
||||||
absl::Status status = Connect(sockfd, addr, 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 NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
void* void_context) {
|
void* void_context) {
|
||||||
ucontext_t* ctx = (ucontext_t*)(void_context);
|
|
||||||
if (info->si_code != SYS_SECCOMP) {
|
if (info->si_code != SYS_SECCOMP) {
|
||||||
InvokeOldAct(nr, info, void_context);
|
InvokeOldAct(nr, info, void_context);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (!ctx) return;
|
auto* ctx = static_cast<ucontext_t*>(void_context);
|
||||||
|
if (!ctx) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(SAPI_X86_64)
|
#if defined(SAPI_X86_64)
|
||||||
auto* registers = ctx->uc_mcontext.gregs;
|
auto* registers = ctx->uc_mcontext.gregs;
|
||||||
#elif defined(SAPI_PPC64_LE)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
auto* registers = ctx->uc_mcontext.gp_regs;
|
auto* registers = ctx->uc_mcontext.gp_regs;
|
||||||
using ppc_gpreg_t = std::decay<decltype(registers[0])>::type;
|
#elif defined(SAPI_ARM64)
|
||||||
|
auto* registers = ctx->uc_mcontext.regs;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
int syscall = registers[kRegSyscall];
|
int syscall = registers[kRegSyscall];
|
||||||
|
|
||||||
int sockfd;
|
int sockfd;
|
||||||
|
@ -181,11 +187,10 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
||||||
#if defined(SAPI_PPC64_LE)
|
#if defined(SAPI_PPC64_LE)
|
||||||
} else if (syscall == __NR_socketcall &&
|
} else if (syscall == __NR_socketcall &&
|
||||||
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
static_cast<int>(registers[kRegArg0]) == SYS_CONNECT) {
|
||||||
ppc_gpreg_t* args = reinterpret_cast<ppc_gpreg_t*>(registers[kRegArg1]);
|
auto* connect_args = reinterpret_cast<uint64_t*>(registers[kRegArg1]);
|
||||||
|
sockfd = static_cast<int>(connect_args[0]);
|
||||||
sockfd = static_cast<int>(args[0]);
|
addr = reinterpret_cast<const struct sockaddr*>(connect_args[1]);
|
||||||
addr = reinterpret_cast<const struct sockaddr*>(args[1]);
|
addrlen = static_cast<socklen_t>(connect_args[2]);
|
||||||
addrlen = static_cast<socklen_t>(args[2]);
|
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
InvokeOldAct(nr, info, void_context);
|
InvokeOldAct(nr, info, void_context);
|
||||||
|
|
|
@ -49,8 +49,12 @@ std::unique_ptr<Policy> NotifyTestcasePolicy() {
|
||||||
.AllowWrite()
|
.AllowWrite()
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.AddPolicyOnSyscall(__NR_personality, {SANDBOX2_TRACE})
|
.AddPolicyOnSyscall(__NR_personality, {SANDBOX2_TRACE})
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
|
@ -82,41 +82,41 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
bpf_labels l = {0};
|
bpf_labels l = {0};
|
||||||
|
|
||||||
std::vector<sock_filter> policy = {
|
std::vector<sock_filter> policy = {
|
||||||
// If compiled arch is different than the runtime one, inform the Monitor.
|
// If compiled arch is different than the runtime one, inform the Monitor.
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
JEQ32(Syscall::GetHostAuditArch(), JUMP(&l, past_arch_check_l)),
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
#if defined(SAPI_X86_64)
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)), // 32-bit sandboxee
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
#endif
|
||||||
TRACE(cpu::kUnknown),
|
TRACE(cpu::kUnknown),
|
||||||
LABEL(&l, past_arch_check_l),
|
LABEL(&l, past_arch_check_l),
|
||||||
|
|
||||||
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
// After the policy is uploaded, forkserver will execve the sandboxee. We
|
||||||
// need to allow this execve but not others. Since BPF does not have
|
// 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
|
// 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
|
// 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
|
// be secret, but just an optimization so that the monitor is not
|
||||||
// triggered on every call to execveat.
|
// triggered on every call to execveat.
|
||||||
LOAD_SYSCALL_NR,
|
LOAD_SYSCALL_NR,
|
||||||
JNE32(__NR_execveat, JUMP(&l, past_execveat_l)),
|
JNE32(__NR_execveat, JUMP(&l, past_execveat_l)),
|
||||||
ARG_32(4),
|
ARG_32(4),
|
||||||
JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)),
|
JNE32(AT_EMPTY_PATH, JUMP(&l, past_execveat_l)),
|
||||||
ARG_32(5),
|
ARG_32(5),
|
||||||
JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)),
|
JNE32(internal::kExecveMagic, JUMP(&l, past_execveat_l)),
|
||||||
SANDBOX2_TRACE,
|
SANDBOX2_TRACE,
|
||||||
LABEL(&l, past_execveat_l),
|
LABEL(&l, past_execveat_l),
|
||||||
|
|
||||||
// Forbid some syscalls because unsafe or too risky.
|
// Forbid some syscalls because unsafe or too risky.
|
||||||
LOAD_SYSCALL_NR,
|
LOAD_SYSCALL_NR,
|
||||||
JEQ32(__NR_ptrace, DENY),
|
JEQ32(__NR_ptrace, DENY),
|
||||||
JEQ32(__NR_bpf, DENY),
|
JEQ32(__NR_bpf, DENY),
|
||||||
|
|
||||||
// Disallow clone with CLONE_UNTRACED flag.
|
// Disallow clone with CLONE_UNTRACED flag.
|
||||||
JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)),
|
JNE32(__NR_clone, JUMP(&l, past_clone_untraced_l)),
|
||||||
// Regardless of arch, we only care about the lower 32-bits of the flags.
|
// Regardless of arch, we only care about the lower 32-bits of the flags.
|
||||||
ARG_32(0),
|
ARG_32(0),
|
||||||
JA32(CLONE_UNTRACED, DENY),
|
JA32(CLONE_UNTRACED, DENY),
|
||||||
LABEL(&l, past_clone_untraced_l),
|
LABEL(&l, past_clone_untraced_l),
|
||||||
};
|
};
|
||||||
|
|
||||||
if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) {
|
if (bpf_resolve_jumps(&l, policy.data(), policy.size()) != 0) {
|
||||||
|
@ -129,11 +129,16 @@ std::vector<sock_filter> Policy::GetDefaultPolicy() const {
|
||||||
|
|
||||||
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
||||||
return {
|
return {
|
||||||
LOAD_ARCH,
|
LOAD_ARCH,
|
||||||
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
#if defined(SAPI_X86_64)
|
||||||
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
JEQ32(AUDIT_ARCH_X86_64, TRACE(cpu::kX8664)),
|
||||||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
JEQ32(AUDIT_ARCH_I386, TRACE(cpu::kX86)),
|
||||||
TRACE(cpu::kUnknown),
|
#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),
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -50,9 +50,16 @@ std::unique_ptr<Policy> PolicyTestcasePolicy() {
|
||||||
.AllowSyscall(__NR_close)
|
.AllowSyscall(__NR_close)
|
||||||
.AllowSyscall(__NR_getppid)
|
.AllowSyscall(__NR_getppid)
|
||||||
.AllowTCGETS()
|
.AllowTCGETS()
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
|
#ifdef __NR_faccessat
|
||||||
|
.BlockSyscallWithErrno(__NR_faccessat, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
@ -162,7 +169,9 @@ std::unique_ptr<Policy> MinimalTestcasePolicy() {
|
||||||
.AllowStaticStartup()
|
.AllowStaticStartup()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -197,8 +206,10 @@ TEST(MinimalTest, MinimalSharedBinaryWorks) {
|
||||||
.AllowOpen()
|
.AllowOpen()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.AllowMmap()
|
.AllowMmap()
|
||||||
|
#ifdef __NR_access
|
||||||
// New glibc accesses /etc/ld.so.preload
|
// New glibc accesses /etc/ld.so.preload
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
.AddLibrariesForBinary(path)
|
.AddLibrariesForBinary(path)
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
@ -223,7 +234,9 @@ TEST(MallocTest, SystemMallocWorks) {
|
||||||
.AllowSystemMalloc()
|
.AllowSystemMalloc()
|
||||||
.AllowExit()
|
.AllowExit()
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||||
|
@ -247,7 +260,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
||||||
|
|
||||||
auto policy =
|
auto policy =
|
||||||
PolicyBuilder()
|
PolicyBuilder()
|
||||||
|
#ifdef __NR_open
|
||||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||||
|
#endif
|
||||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||||
.AllowStaticStartup()
|
.AllowStaticStartup()
|
||||||
.AllowTcMalloc()
|
.AllowTcMalloc()
|
||||||
|
@ -258,7 +273,9 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
||||||
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
||||||
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
||||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||||
|
#ifdef __NR_access
|
||||||
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
.BlockSyscallWithErrno(__NR_access, ENOENT)
|
||||||
|
#endif
|
||||||
.BuildOrDie();
|
.BuildOrDie();
|
||||||
|
|
||||||
Sandbox2 s2(std::move(executor), std::move(policy));
|
Sandbox2 s2(std::move(executor), std::move(policy));
|
||||||
|
|
|
@ -520,7 +520,12 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
||||||
});
|
});
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
if constexpr (host_cpu::IsArm64()) {
|
||||||
|
BlockSyscallWithErrno(__NR_readlinkat, ENOENT);
|
||||||
|
}
|
||||||
|
#ifdef __NR_readlink
|
||||||
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
||||||
|
#endif
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
@ -881,7 +886,9 @@ PolicyBuilder& PolicyBuilder::AddNetworkProxyPolicy() {
|
||||||
AllowFutexOp(FUTEX_WAIT);
|
AllowFutexOp(FUTEX_WAIT);
|
||||||
AllowFutexOp(FUTEX_WAIT_BITSET);
|
AllowFutexOp(FUTEX_WAIT_BITSET);
|
||||||
AllowSyscalls({
|
AllowSyscalls({
|
||||||
|
#ifdef __NR_dup2
|
||||||
__NR_dup2,
|
__NR_dup2,
|
||||||
|
#endif
|
||||||
__NR_recvmsg,
|
__NR_recvmsg,
|
||||||
__NR_close,
|
__NR_close,
|
||||||
__NR_gettid,
|
__NR_gettid,
|
||||||
|
|
|
@ -101,7 +101,7 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
||||||
builder.AllowSystemMalloc(); assert_increased();
|
builder.AllowSystemMalloc(); assert_increased();
|
||||||
builder.AllowSyscall(__NR_munmap); assert_same();
|
builder.AllowSyscall(__NR_munmap); assert_same();
|
||||||
builder.BlockSyscallWithErrno(__NR_munmap, 1); assert_same();
|
builder.BlockSyscallWithErrno(__NR_munmap, 1); assert_same();
|
||||||
builder.BlockSyscallWithErrno(__NR_open, 1);
|
builder.BlockSyscallWithErrno(__NR_openat, 1);
|
||||||
assert_increased();
|
assert_increased();
|
||||||
|
|
||||||
builder.AllowTCGETS(); assert_increased();
|
builder.AllowTCGETS(); assert_increased();
|
||||||
|
|
|
@ -23,12 +23,18 @@
|
||||||
|
|
||||||
#include <cerrno>
|
#include <cerrno>
|
||||||
|
|
||||||
|
#include "absl/base/macros.h"
|
||||||
|
#include "absl/status/status.h"
|
||||||
#include "absl/strings/str_cat.h"
|
#include "absl/strings/str_cat.h"
|
||||||
#include "sandboxed_api/sandbox2/config.h"
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||||
|
|
||||||
namespace sandbox2 {
|
namespace sandbox2 {
|
||||||
|
|
||||||
|
#ifndef NT_ARM_SYSTEM_CALL
|
||||||
|
#define NT_ARM_SYSTEM_CALL 0x404
|
||||||
|
#endif
|
||||||
|
|
||||||
absl::Status Regs::Fetch() {
|
absl::Status Regs::Fetch() {
|
||||||
#ifdef SAPI_X86_64
|
#ifdef SAPI_X86_64
|
||||||
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
if (ptrace(PTRACE_GETREGS, pid_, 0, &user_regs_) == -1L) {
|
||||||
|
@ -36,7 +42,7 @@ absl::Status Regs::Fetch() {
|
||||||
") failed: ", StrError(errno)));
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if constexpr (host_cpu::IsPPC64LE()) {
|
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||||
|
@ -50,6 +56,24 @@ absl::Status Regs::Fetch() {
|
||||||
") size returned: ", pt_iov.iov_len,
|
") size returned: ", pt_iov.iov_len,
|
||||||
" different than sizeof(user_regs_): ", sizeof(user_regs_)));
|
" 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();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
@ -61,7 +85,7 @@ absl::Status Regs::Store() {
|
||||||
") failed: ", StrError(errno)));
|
") failed: ", StrError(errno)));
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if constexpr (host_cpu::IsPPC64LE()) {
|
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||||
|
|
||||||
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
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_,
|
absl::StrCat("ptrace(PTRACE_SETREGSET, pid=", pid_,
|
||||||
") failed: ", StrError(errno)));
|
") 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();
|
return absl::OkStatus();
|
||||||
}
|
}
|
||||||
|
@ -80,6 +115,9 @@ absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
||||||
#elif defined(SAPI_PPC64_LE)
|
#elif defined(SAPI_PPC64_LE)
|
||||||
user_regs_.gpr[0] = -1;
|
user_regs_.gpr[0] = -1;
|
||||||
user_regs_.gpr[3] = value;
|
user_regs_.gpr[3] = value;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
user_regs_.regs[0] = -1;
|
||||||
|
syscall_number_ = value;
|
||||||
#endif
|
#endif
|
||||||
return Store();
|
return Store();
|
||||||
}
|
}
|
||||||
|
@ -114,6 +152,22 @@ Syscall Regs::ToSyscall(cpu::Architecture syscall_arch) const {
|
||||||
auto ip = user_regs_.nip;
|
auto ip = user_regs_.nip;
|
||||||
return Syscall(syscall_arch, syscall, args, pid_, sp, ip);
|
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
|
#endif
|
||||||
return Syscall(pid_);
|
return Syscall(pid_);
|
||||||
}
|
}
|
||||||
|
@ -169,6 +223,14 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
||||||
regs->set_zero1(user_regs_.zero1);
|
regs->set_zero1(user_regs_.zero1);
|
||||||
regs->set_zero2(user_regs_.zero2);
|
regs->set_zero2(user_regs_.zero2);
|
||||||
regs->set_zero3(user_regs_.zero3);
|
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
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -105,6 +105,11 @@ class Regs {
|
||||||
uint64_t zero1;
|
uint64_t zero1;
|
||||||
uint64_t zero2;
|
uint64_t zero2;
|
||||||
uint64_t zero3;
|
uint64_t zero3;
|
||||||
|
#elif defined(SAPI_ARM64)
|
||||||
|
uint64_t regs[31];
|
||||||
|
uint64_t sp;
|
||||||
|
uint64_t pc;
|
||||||
|
uint64_t pstate;
|
||||||
#else
|
#else
|
||||||
static_assert(false, "Host CPU architecture not supported, see config.h");
|
static_assert(false, "Host CPU architecture not supported, see config.h");
|
||||||
#endif
|
#endif
|
||||||
|
@ -115,6 +120,9 @@ class Regs {
|
||||||
|
|
||||||
// Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid).
|
// Registers fetched with ptrace(PR_GETREGS/GETREGSET, pid).
|
||||||
PtraceRegisters user_regs_ = {};
|
PtraceRegisters user_regs_ = {};
|
||||||
|
|
||||||
|
// On AArch64, obtaining the syscall number needs a specific call to ptrace()
|
||||||
|
int syscall_number_ = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace sandbox2
|
} // namespace sandbox2
|
||||||
|
|
|
@ -31,6 +31,7 @@
|
||||||
#include "absl/strings/strip.h"
|
#include "absl/strings/strip.h"
|
||||||
#include "libcap/include/sys/capability.h"
|
#include "libcap/include/sys/capability.h"
|
||||||
#include "sandboxed_api/sandbox2/comms.h"
|
#include "sandboxed_api/sandbox2/comms.h"
|
||||||
|
#include "sandboxed_api/sandbox2/config.h"
|
||||||
#include "sandboxed_api/sandbox2/executor.h"
|
#include "sandboxed_api/sandbox2/executor.h"
|
||||||
#include "sandboxed_api/sandbox2/ipc.h"
|
#include "sandboxed_api/sandbox2/ipc.h"
|
||||||
#include "sandboxed_api/sandbox2/limits.h"
|
#include "sandboxed_api/sandbox2/limits.h"
|
||||||
|
@ -270,6 +271,9 @@ bool StackTracePeer::LaunchLibunwindSandbox(const Regs* regs,
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::string> GetStackTrace(const Regs* regs, const Mounts& mounts) {
|
std::vector<std::string> 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)) {
|
if (absl::GetFlag(FLAGS_sandbox_disable_all_stack_traces)) {
|
||||||
return {"[Stacktraces disabled]"};
|
return {"[Stacktraces disabled]"};
|
||||||
}
|
}
|
||||||
|
|
|
@ -42,6 +42,8 @@ std::string Syscall::GetArchDescription(cpu::Architecture arch) {
|
||||||
return "[X86-32]";
|
return "[X86-32]";
|
||||||
case cpu::kPPC64LE:
|
case cpu::kPPC64LE:
|
||||||
return "[PPC-64]";
|
return "[PPC-64]";
|
||||||
|
case cpu::kArm64:
|
||||||
|
return "[Arm-64]";
|
||||||
default:
|
default:
|
||||||
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
||||||
return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch);
|
return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch);
|
||||||
|
@ -54,6 +56,8 @@ uint32_t Syscall::GetHostAuditArch() {
|
||||||
return AUDIT_ARCH_X86_64;
|
return AUDIT_ARCH_X86_64;
|
||||||
case cpu::kPPC64LE:
|
case cpu::kPPC64LE:
|
||||||
return AUDIT_ARCH_PPC64LE;
|
return AUDIT_ARCH_PPC64LE;
|
||||||
|
case cpu::kArm64:
|
||||||
|
return AUDIT_ARCH_AARCH64;
|
||||||
default:
|
default:
|
||||||
// The static_assert() in config.h should prevent us from ever getting
|
// The static_assert() in config.h should prevent us from ever getting
|
||||||
// here.
|
// here.
|
||||||
|
|
|
@ -1216,6 +1216,291 @@ constexpr SyscallTable::Entry kSyscallDataPPC64LE[] = {
|
||||||
MakeEntry("pwritev2", kHex, kHex, kHex, kHex, kHex, kHex), // 381
|
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_UNUSED00_99
|
||||||
#undef SYSCALLS_UNUSED50_99
|
#undef SYSCALLS_UNUSED50_99
|
||||||
#undef SYSCALLS_UNUSED00_49
|
#undef SYSCALLS_UNUSED00_49
|
||||||
|
@ -1230,6 +1515,8 @@ SyscallTable SyscallTable::get(cpu::Architecture arch) {
|
||||||
return SyscallTable(kSyscallDataX8632);
|
return SyscallTable(kSyscallDataX8632);
|
||||||
case cpu::kPPC64LE:
|
case cpu::kPPC64LE:
|
||||||
return SyscallTable(kSyscallDataPPC64LE);
|
return SyscallTable(kSyscallDataPPC64LE);
|
||||||
|
case cpu::kArm64:
|
||||||
|
return SyscallTable(kSyscallDataArm64);
|
||||||
default:
|
default:
|
||||||
return SyscallTable();
|
return SyscallTable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -126,8 +126,9 @@ ABSL_ATTRIBUTE_NO_SANITIZE_ADDRESS
|
||||||
ABSL_ATTRIBUTE_NOINLINE
|
ABSL_ATTRIBUTE_NOINLINE
|
||||||
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
pid_t CloneAndJump(int flags, jmp_buf* env_ptr) {
|
||||||
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
uint8_t stack_buf[PTHREAD_STACK_MIN] ABSL_CACHELINE_ALIGNED;
|
||||||
static_assert(host_cpu::IsX8664() || host_cpu::IsPPC64LE(),
|
static_assert(
|
||||||
"Host CPU architecture not supported, see config.h");
|
host_cpu::IsX8664() || host_cpu::IsPPC64LE() || host_cpu::IsArm64(),
|
||||||
|
"Host CPU architecture not supported, see config.h");
|
||||||
// Stack grows down.
|
// Stack grows down.
|
||||||
void* stack = stack_buf + sizeof(stack_buf);
|
void* stack = stack_buf + sizeof(stack_buf);
|
||||||
int r;
|
int r;
|
||||||
|
|
|
@ -25,7 +25,6 @@ enum PBViolationType {
|
||||||
SYSCALL_ARCHITECTURE_MISMATCH = 3;
|
SYSCALL_ARCHITECTURE_MISMATCH = 3;
|
||||||
}
|
}
|
||||||
|
|
||||||
// X86_64 not allowed (naming convention...)
|
|
||||||
message RegisterX8664 {
|
message RegisterX8664 {
|
||||||
uint64 r15 = 1;
|
uint64 r15 = 1;
|
||||||
uint64 r14 = 2;
|
uint64 r14 = 2;
|
||||||
|
@ -77,7 +76,6 @@ message RegisterPowerpc64 {
|
||||||
uint64 zero3 = 17;
|
uint64 zero3 = 17;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Deprecated.
|
|
||||||
message RegisterAarch64 {
|
message RegisterAarch64 {
|
||||||
repeated uint64 regs = 1;
|
repeated uint64 regs = 1;
|
||||||
uint64 sp = 2;
|
uint64 sp = 2;
|
||||||
|
@ -90,7 +88,7 @@ message RegisterValues {
|
||||||
oneof register_values {
|
oneof register_values {
|
||||||
RegisterX8664 register_x86_64 = 2;
|
RegisterX8664 register_x86_64 = 2;
|
||||||
RegisterPowerpc64 register_powerpc64 = 3;
|
RegisterPowerpc64 register_powerpc64 = 3;
|
||||||
RegisterAarch64 register_aarch64 = 4; // Deprecated.
|
RegisterAarch64 register_aarch64 = 4;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue
Block a user