mirror of
https://github.com/google/sandboxed-api.git
synced 2024-03-22 13:11:30 +08:00
Add support for ARM32 (hard float target)
This change enables support for 32-bit ARM, as used by embedded controllers and older phones. Note: This does not support 32-bit sandboxees on AArch64. Both sandboxee and host code must have the same bitness. PiperOrigin-RevId: 347835193 Change-Id: I6395882677530f9862f118d2dc10230a61049836
This commit is contained in:
parent
324ab5974c
commit
d0c8224e61
|
@ -83,6 +83,23 @@ elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "aarch64")
|
|||
list(APPEND _unwind_ptrace_srcs
|
||||
${_unwind_src}/src/aarch64/Ginit_remote.c
|
||||
)
|
||||
elseif(CMAKE_SYSTEM_PROCESSOR STREQUAL "arm")
|
||||
set(_unwind_cpu "arm")
|
||||
list(APPEND _unwind_platform_srcs
|
||||
${_unwind_src}/src/arm/Gcreate_addr_space.c
|
||||
${_unwind_src}/src/arm/Gex_tables.c
|
||||
${_unwind_src}/src/arm/Gglobal.c
|
||||
${_unwind_src}/src/arm/Ginit.c
|
||||
${_unwind_src}/src/arm/Gis_signal_frame.c
|
||||
${_unwind_src}/src/arm/Gregs.c
|
||||
${_unwind_src}/src/arm/Gresume.c
|
||||
${_unwind_src}/src/arm/Gstash_frame.c
|
||||
${_unwind_src}/src/arm/Gstep.c
|
||||
${_unwind_src}/src/arm/is_fpreg.c
|
||||
)
|
||||
list(APPEND _unwind_ptrace_srcs
|
||||
${_unwind_src}/src/arm/Ginit_remote.c
|
||||
)
|
||||
endif()
|
||||
|
||||
add_library(unwind_ptrace_wrapped STATIC
|
||||
|
@ -165,6 +182,7 @@ add_library(unwind::unwind_ptrace_wrapped ALIAS unwind_ptrace_wrapped)
|
|||
target_include_directories(unwind_ptrace_wrapped PUBLIC
|
||||
${_unwind_src}/include
|
||||
${_unwind_src}/include/tdep
|
||||
${_unwind_src}/include/tdep-${_unwind_cpu}
|
||||
${_unwind_src}/src
|
||||
)
|
||||
target_compile_options(unwind_ptrace_wrapped PRIVATE
|
||||
|
|
|
@ -55,15 +55,14 @@ ffi_type* GetFFIType(size_t size, v::Type type) {
|
|||
case v::Type::kFd:
|
||||
return &ffi_type_sint;
|
||||
case v::Type::kFloat:
|
||||
switch (size) {
|
||||
case sizeof(float):
|
||||
return &ffi_type_float;
|
||||
case sizeof(double):
|
||||
return &ffi_type_double;
|
||||
case sizeof(long double):
|
||||
return &ffi_type_longdouble;
|
||||
default:
|
||||
LOG(FATAL) << "Unknown floating-point size: " << size;
|
||||
if (size == sizeof(float)) {
|
||||
return &ffi_type_float;
|
||||
} else if (size == sizeof(double)) {
|
||||
return &ffi_type_double;
|
||||
} else if (size == sizeof(long double)) {
|
||||
return &ffi_type_longdouble;
|
||||
} else {
|
||||
LOG(FATAL) << "Unknown floating-point size: " << size;
|
||||
}
|
||||
case v::Type::kInt:
|
||||
switch (size) {
|
||||
|
|
|
@ -32,6 +32,11 @@
|
|||
// Spellings for AArch64
|
||||
#elif defined(__aarch64__) || defined(_M_ARM64)
|
||||
#define SAPI_ARM64 1
|
||||
|
||||
// 32-bit ARM
|
||||
#elif defined(__arm__) || defined(_M_ARM)
|
||||
#define SAPI_ARM 1
|
||||
|
||||
#endif
|
||||
|
||||
namespace sandbox2 {
|
||||
|
@ -48,6 +53,7 @@ enum Architecture : uint16_t {
|
|||
kX86,
|
||||
kPPC64LE,
|
||||
kArm64,
|
||||
kArm,
|
||||
};
|
||||
|
||||
} // namespace cpu
|
||||
|
@ -63,6 +69,8 @@ constexpr cpu::Architecture Architecture() {
|
|||
return cpu::kPPC64LE;
|
||||
#elif defined(SAPI_ARM64)
|
||||
return cpu::kArm64;
|
||||
#elif defined(SAPI_ARM)
|
||||
return cpu::kArm;
|
||||
#else
|
||||
return cpu::kUnknown;
|
||||
#endif
|
||||
|
@ -74,11 +82,15 @@ constexpr bool IsPPC64LE() { return Architecture() == cpu::kPPC64LE; }
|
|||
|
||||
constexpr bool IsArm64() { return Architecture() == cpu::kArm64; }
|
||||
|
||||
constexpr bool IsArm() { return Architecture() == cpu::kArm; }
|
||||
|
||||
constexpr bool Is64Bit() { return sizeof(uintptr_t) == 8; }
|
||||
|
||||
} // namespace host_cpu
|
||||
|
||||
static_assert(host_cpu::Architecture() != cpu::kUnknown,
|
||||
"Host CPU architecture is not supported: One of x86-64, POWER64 "
|
||||
"(little endian) or AArch64 is required.");
|
||||
"(little endian), Arm or AArch64 is required.");
|
||||
|
||||
} // namespace sandbox2
|
||||
|
||||
|
|
|
@ -115,6 +115,7 @@ absl::Status ValidateInterpreter(absl::string_view interpreter) {
|
|||
"/lib64/ld-linux-x86-64.so.2",
|
||||
"/lib64/ld64.so.2", // PPC64
|
||||
"/lib/ld-linux-aarch64.so.1", // AArch64
|
||||
"/lib/ld-linux-armhf.so.3", // Arm
|
||||
};
|
||||
|
||||
if (!allowed_interpreters.contains(interpreter)) {
|
||||
|
|
|
@ -55,6 +55,12 @@ constexpr int kRegSyscall = 8;
|
|||
constexpr int kRegArg0 = 0;
|
||||
constexpr int kRegArg1 = 1;
|
||||
constexpr int kRegArg2 = 2;
|
||||
#elif defined(SAPI_ARM)
|
||||
constexpr int kRegResult = 0;
|
||||
constexpr int kRegSyscall = 8;
|
||||
constexpr int kRegArg0 = 0;
|
||||
constexpr int kRegArg1 = 1;
|
||||
constexpr int kRegArg2 = 2;
|
||||
#endif
|
||||
|
||||
int NetworkProxyClient::ConnectHandler(int sockfd, const struct sockaddr* addr,
|
||||
|
@ -173,6 +179,8 @@ void NetworkProxyHandler::ProcessSeccompTrap(int nr, siginfo_t* info,
|
|||
auto* registers = ctx->uc_mcontext.gp_regs;
|
||||
#elif defined(SAPI_ARM64)
|
||||
auto* registers = ctx->uc_mcontext.regs;
|
||||
#elif defined(SAPI_ARM)
|
||||
auto* registers = &ctx->uc_mcontext.arm_r0;
|
||||
#endif
|
||||
int syscall = registers[kRegSyscall];
|
||||
|
||||
|
|
|
@ -145,6 +145,8 @@ std::vector<sock_filter> Policy::GetTrackingPolicy() const {
|
|||
JEQ32(AUDIT_ARCH_PPC64LE, TRACE(cpu::kPPC64LE)),
|
||||
#elif defined(SAPI_ARM64)
|
||||
JEQ32(AUDIT_ARCH_AARCH64, TRACE(cpu::kArm64)),
|
||||
#elif defined(SAPI_ARM)
|
||||
JEQ32(AUDIT_ARCH_ARM, TRACE(cpu::kArm)),
|
||||
#endif
|
||||
TRACE(cpu::kUnknown),
|
||||
};
|
||||
|
|
|
@ -280,25 +280,53 @@ TEST(MultipleSyscalls, AddPolicyOnSyscallsWorks) {
|
|||
std::vector<std::string> args = {path};
|
||||
auto executor = absl::make_unique<Executor>(path, args);
|
||||
|
||||
auto policy =
|
||||
PolicyBuilder()
|
||||
auto policy = PolicyBuilder()
|
||||
#ifdef __NR_open
|
||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||
.BlockSyscallWithErrno(__NR_open, ENOENT)
|
||||
#endif
|
||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||
.AllowStaticStartup()
|
||||
.AllowTcMalloc()
|
||||
.AllowExit()
|
||||
.AddPolicyOnSyscalls(
|
||||
{__NR_getuid, __NR_getgid, __NR_geteuid, __NR_getegid}, {ALLOW})
|
||||
.AddPolicyOnSyscalls({__NR_getresuid, __NR_getresgid}, {ERRNO(42)})
|
||||
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
||||
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
||||
.BlockSyscallWithErrno(__NR_prlimit64, EPERM)
|
||||
.BlockSyscallWithErrno(__NR_openat, ENOENT)
|
||||
.AllowStaticStartup()
|
||||
.AllowTcMalloc()
|
||||
.AllowExit()
|
||||
.AddPolicyOnSyscalls(
|
||||
{
|
||||
__NR_getuid,
|
||||
__NR_getgid,
|
||||
__NR_geteuid,
|
||||
__NR_getegid,
|
||||
#ifdef __NR_getuid32
|
||||
__NR_getuid32,
|
||||
#endif
|
||||
#ifdef __NR_getgid32
|
||||
__NR_getgid32,
|
||||
#endif
|
||||
#ifdef __NR_geteuid32
|
||||
__NR_geteuid32,
|
||||
#endif
|
||||
#ifdef __NR_getegid32
|
||||
__NR_getegid32,
|
||||
#endif
|
||||
},
|
||||
{ALLOW})
|
||||
.AddPolicyOnSyscalls(
|
||||
{
|
||||
__NR_getresuid,
|
||||
__NR_getresgid,
|
||||
#ifdef __NR_getresuid32
|
||||
__NR_getresuid32,
|
||||
#endif
|
||||
#ifdef __NR_getresgid32
|
||||
__NR_getresgid32,
|
||||
#endif
|
||||
},
|
||||
{ERRNO(42)})
|
||||
.AddPolicyOnSyscalls({__NR_read, __NR_write}, {ERRNO(43)})
|
||||
.AddPolicyOnSyscall(__NR_umask, {DENY})
|
||||
.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));
|
||||
auto result = s2.Run();
|
||||
|
|
|
@ -428,7 +428,9 @@ PolicyBuilder& PolicyBuilder::AllowGetPIDs() {
|
|||
|
||||
PolicyBuilder& PolicyBuilder::AllowGetRlimit() {
|
||||
return AllowSyscalls({
|
||||
#ifdef __NR_getrlimit
|
||||
__NR_getrlimit,
|
||||
#endif
|
||||
#ifdef __NR_ugetrlimit
|
||||
__NR_ugetrlimit,
|
||||
#endif
|
||||
|
@ -437,7 +439,9 @@ PolicyBuilder& PolicyBuilder::AllowGetRlimit() {
|
|||
|
||||
PolicyBuilder& PolicyBuilder::AllowSetRlimit() {
|
||||
return AllowSyscalls({
|
||||
#ifdef __NR_setrlimit
|
||||
__NR_setrlimit,
|
||||
#endif
|
||||
#ifdef __NR_usetrlimit
|
||||
__NR_usetrlimit,
|
||||
#endif
|
||||
|
@ -504,13 +508,16 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
|||
AllowGetRlimit();
|
||||
AllowSyscalls({
|
||||
// These syscalls take a pointer, so no restriction.
|
||||
__NR_uname,
|
||||
__NR_brk,
|
||||
__NR_set_tid_address,
|
||||
__NR_uname, __NR_brk, __NR_set_tid_address,
|
||||
|
||||
// This syscall takes a pointer and a length.
|
||||
// We could restrict length, but it might change, so not worth it.
|
||||
__NR_set_robust_list,
|
||||
#if defined(__ARM_NR_set_tls)
|
||||
// libc sets the TLS during startup
|
||||
__ARM_NR_set_tls,
|
||||
#endif
|
||||
|
||||
// This syscall takes a pointer and a length.
|
||||
// We could restrict length, but it might change, so not worth it.
|
||||
__NR_set_robust_list,
|
||||
});
|
||||
|
||||
AllowFutexOp(FUTEX_WAIT_BITSET);
|
||||
|
@ -543,6 +550,13 @@ PolicyBuilder& PolicyBuilder::AllowStaticStartup() {
|
|||
BlockSyscallWithErrno(__NR_readlink, ENOENT);
|
||||
#endif
|
||||
|
||||
if constexpr (host_cpu::IsArm()) {
|
||||
AddPolicyOnSyscall(__NR_mprotect, {
|
||||
ARG_32(2),
|
||||
JEQ32(PROT_READ, ALLOW),
|
||||
});
|
||||
}
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
|
|
@ -93,8 +93,8 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
|||
|
||||
builder.AllowSyscall(__NR_chroot); assert_increased();
|
||||
builder.AllowSyscall(__NR_chroot); assert_same();
|
||||
builder.AllowSyscall(__NR_mmap); assert_increased();
|
||||
builder.AllowSyscall(__NR_mmap); assert_same();
|
||||
builder.AllowSyscall(__NR_umask); assert_increased();
|
||||
builder.AllowSyscall(__NR_umask); assert_same();
|
||||
builder.AllowSyscall(__NR_chroot); assert_same();
|
||||
builder.AllowSyscall(__NR_chroot); assert_same();
|
||||
|
||||
|
@ -120,8 +120,8 @@ TEST_F(PolicyBuilderTest, Testpolicy_size) {
|
|||
builder.AddPolicyOnSyscalls({ }, { ALLOW }); assert_increased();
|
||||
|
||||
// This might change in the future if we implement an optimization.
|
||||
builder.AddPolicyOnSyscall(__NR_mmap, { ALLOW }); assert_increased();
|
||||
builder.AddPolicyOnSyscall(__NR_mmap, { ALLOW }); assert_increased();
|
||||
builder.AddPolicyOnSyscall(__NR_umask, { ALLOW }); assert_increased();
|
||||
builder.AddPolicyOnSyscall(__NR_umask, { ALLOW }); assert_increased();
|
||||
|
||||
// None of the namespace functions should alter the seccomp policy.
|
||||
builder.AddFile("/usr/bin/find"); assert_same();
|
||||
|
|
|
@ -42,7 +42,8 @@ absl::Status Regs::Fetch() {
|
|||
") failed: ", StrError(errno)));
|
||||
}
|
||||
#endif
|
||||
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64() ||
|
||||
host_cpu::IsArm()) {
|
||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||
|
||||
if (ptrace(PTRACE_GETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||
|
@ -85,7 +86,8 @@ absl::Status Regs::Store() {
|
|||
") failed: ", StrError(errno)));
|
||||
}
|
||||
#endif
|
||||
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64()) {
|
||||
if constexpr (host_cpu::IsPPC64LE() || host_cpu::IsArm64() ||
|
||||
host_cpu::IsArm()) {
|
||||
iovec pt_iov = {&user_regs_, sizeof(user_regs_)};
|
||||
|
||||
if (ptrace(PTRACE_SETREGSET, pid_, NT_PRSTATUS, &pt_iov) == -1L) {
|
||||
|
@ -108,7 +110,7 @@ absl::Status Regs::Store() {
|
|||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
||||
absl::Status Regs::SkipSyscallReturnValue(uintptr_t value) {
|
||||
#if defined(SAPI_X86_64)
|
||||
user_regs_.orig_rax = -1;
|
||||
user_regs_.rax = value;
|
||||
|
@ -118,6 +120,9 @@ absl::Status Regs::SkipSyscallReturnValue(uint64_t value) {
|
|||
#elif defined(SAPI_ARM64)
|
||||
user_regs_.regs[0] = -1;
|
||||
syscall_number_ = value;
|
||||
#elif defined(SAPI_ARM)
|
||||
user_regs_.orig_x0 = -1;
|
||||
user_regs_.regs[7] = value;
|
||||
#endif
|
||||
return Store();
|
||||
}
|
||||
|
@ -168,6 +173,16 @@ Syscall Regs::ToSyscall(cpu::Architecture syscall_arch) const {
|
|||
auto ip = user_regs_.pc;
|
||||
return Syscall(syscall_arch, syscall_number_, args, pid_, sp, ip);
|
||||
}
|
||||
#elif defined(SAPI_ARM)
|
||||
if (ABSL_PREDICT_TRUE(syscall_arch == cpu::kArm)) {
|
||||
Syscall::Args args = {
|
||||
user_regs_.orig_x0, user_regs_.regs[1], user_regs_.regs[2],
|
||||
user_regs_.regs[3], user_regs_.regs[4], user_regs_.regs[5],
|
||||
};
|
||||
auto sp = user_regs_.regs[13];
|
||||
auto ip = user_regs_.pc;
|
||||
return Syscall(syscall_arch, user_regs_.regs[7], args, pid_, sp, ip);
|
||||
}
|
||||
#endif
|
||||
return Syscall(pid_);
|
||||
}
|
||||
|
@ -231,6 +246,14 @@ void Regs::StoreRegisterValuesInProtobuf(RegisterValues* values) const {
|
|||
regs->set_sp(user_regs_.sp);
|
||||
regs->set_pc(user_regs_.pc);
|
||||
regs->set_pstate(user_regs_.pstate);
|
||||
#elif defined(SAPI_ARM)
|
||||
RegisterArm* regs = values->mutable_register_arm();
|
||||
for (int i = 0; i < ABSL_ARRAYSIZE(user_regs_.regs); ++i) {
|
||||
regs->add_regs(user_regs_.regs[i]);
|
||||
}
|
||||
regs->set_pc(user_regs_.pc);
|
||||
regs->set_cpsr(user_regs_.cpsr);
|
||||
regs->set_orig_x0(user_regs_.orig_x0);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ class Regs {
|
|||
absl::Status Store();
|
||||
|
||||
// Causes the process to skip current syscall and return given value instead
|
||||
absl::Status SkipSyscallReturnValue(uint64_t value);
|
||||
absl::Status SkipSyscallReturnValue(uintptr_t value);
|
||||
|
||||
// Converts raw register values obtained on syscall entry to syscall info
|
||||
Syscall ToSyscall(cpu::Architecture syscall_arch) const;
|
||||
|
@ -110,6 +110,11 @@ class Regs {
|
|||
uint64_t sp;
|
||||
uint64_t pc;
|
||||
uint64_t pstate;
|
||||
#elif defined(SAPI_ARM)
|
||||
uint32_t regs[15];
|
||||
uint32_t pc;
|
||||
uint32_t cpsr;
|
||||
uint32_t orig_x0;
|
||||
#else
|
||||
static_assert(false, "Host CPU architecture not supported, see config.h");
|
||||
#endif
|
||||
|
|
|
@ -85,6 +85,9 @@ std::unique_ptr<Policy> StackTracePeer::GetPolicy(pid_t target_pid,
|
|||
|
||||
// libunwind
|
||||
.AllowSyscall(__NR_fstat)
|
||||
#ifdef __NR_fstat64
|
||||
.AllowSyscall(__NR_fstat64)
|
||||
#endif
|
||||
.AllowSyscall(__NR_lseek)
|
||||
#ifdef __NR__llseek
|
||||
.AllowSyscall(__NR__llseek) // Newer glibc on PPC
|
||||
|
|
|
@ -44,6 +44,8 @@ std::string Syscall::GetArchDescription(cpu::Architecture arch) {
|
|||
return "[PPC-64]";
|
||||
case cpu::kArm64:
|
||||
return "[Arm-64]";
|
||||
case cpu::kArm:
|
||||
return "[Arm-32]";
|
||||
default:
|
||||
LOG(ERROR) << "Unknown CPU architecture: " << arch;
|
||||
return absl::StrFormat("[UNKNOWN_ARCH:%d]", arch);
|
||||
|
@ -58,6 +60,8 @@ uint32_t Syscall::GetHostAuditArch() {
|
|||
return AUDIT_ARCH_PPC64LE;
|
||||
case cpu::kArm64:
|
||||
return AUDIT_ARCH_AARCH64;
|
||||
case cpu::kArm:
|
||||
return AUDIT_ARCH_ARM;
|
||||
default:
|
||||
// The static_assert() in config.h should prevent us from ever getting
|
||||
// here.
|
||||
|
|
|
@ -1524,6 +1524,368 @@ constexpr std::array kSyscallDataArm64 = {
|
|||
static_assert(IsSorted(kSyscallDataArm64, SyscallTable::Entry::BySyscallNr),
|
||||
"Syscalls should be sorted");
|
||||
|
||||
constexpr std::array kSyscallDataArm32 = {
|
||||
// clang-format off
|
||||
MakeEntry(0, "restart_syscall", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(1, "exit", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(2, "fork", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(3, "read", kInt, kHex, kInt),
|
||||
MakeEntry(4, "write", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(5, "open", kPath, kHex, kOct),
|
||||
MakeEntry(6, "close", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(8, "creat", kPath, kHex, kHex, kHex),
|
||||
MakeEntry(9, "link", kPath, kPath),
|
||||
MakeEntry(10, "unlink", kPath),
|
||||
MakeEntry(11, "execve", kPath, kHex, kHex),
|
||||
MakeEntry(12, "chdir", kPath),
|
||||
MakeEntry(14, "mknod", kPath, kOct, kHex),
|
||||
MakeEntry(15, "chmod", kPath, kOct),
|
||||
MakeEntry(16, "lchown", kPath, kInt, kInt),
|
||||
MakeEntry(19, "lseek", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(20, "getpid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(21, "mount", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(23, "setuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(24, "getuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(26, "ptrace", kGen, kGen, kGen),
|
||||
MakeEntry(29, "pause", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(33, "access", kPath, kHex),
|
||||
MakeEntry(34, "nice", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(36, "sync", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(37, "kill", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(38, "rename", kPath, kPath),
|
||||
MakeEntry(39, "mkdir", kPath, kHex, kHex, kHex),
|
||||
MakeEntry(40, "rmdir", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(41, "dup", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(42, "pipe", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(43, "times", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(45, "brk", kHex),
|
||||
MakeEntry(46, "setgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(47, "getgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(49, "geteuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(50, "getegid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(51, "acct", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(52, "umount2", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(54, "ioctl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(55, "fcntl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(57, "setpgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(60, "umask", kHex),
|
||||
MakeEntry(61, "chroot", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(62, "ustat", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(63, "dup2", kGen, kGen),
|
||||
MakeEntry(64, "getppid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(65, "getpgrp", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(66, "setsid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(67, "sigaction", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(70, "setreuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(71, "setregid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(72, "sigsuspend", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(73, "sigpending", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(74, "sethostname", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(75, "setrlimit", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(77, "getrusage", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(78, "gettimeofday", kHex, kHex),
|
||||
MakeEntry(79, "settimeofday", kHex, kHex),
|
||||
MakeEntry(80, "getgroups", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(81, "setgroups", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(83, "symlink", kPath, kPath),
|
||||
MakeEntry(85, "readlink", kPath, kGen, kInt),
|
||||
MakeEntry(86, "uselib", kPath),
|
||||
MakeEntry(87, "swapon", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(88, "reboot", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(91, "munmap", kHex, kHex),
|
||||
MakeEntry(92, "truncate", kPath, kHex, kHex, kHex),
|
||||
MakeEntry(93, "ftruncate", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(94, "fchmod", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(95, "fchown", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(96, "getpriority", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(97, "setpriority", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(99, "statfs", kPath, kGen, kGen, kGen),
|
||||
MakeEntry(100, "fstatfs", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(103, "syslog", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(104, "setitimer", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(105, "getitimer", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(106, "stat", kPath, kGen),
|
||||
MakeEntry(107, "lstat", kPath, kGen),
|
||||
MakeEntry(108, "fstat", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(111, "vhangup", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(114, "wait4", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(115, "swapoff", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(116, "sysinfo", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(118, "fsync", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(119, "sigreturn", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(120, "clone", kCloneFlag, kHex, kHex, kHex),
|
||||
MakeEntry(121, "setdomainname", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(122, "uname", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(124, "adjtimex", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(125, "mprotect", kHex, kHex, kHex),
|
||||
MakeEntry(126, "sigprocmask", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(128, "init_module", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(129, "delete_module", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(131, "quotactl", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(132, "getpgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(133, "fchdir", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(134, "bdflush", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(135, "sysfs", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(136, "personality", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(138, "setfsuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(139, "setfsgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(140, "_llseek", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(141, "getdents", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(142, "_newselect", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(143, "flock", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(144, "msync", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(145, "readv", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(146, "writev", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(147, "getsid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(148, "fdatasync", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(149, "_sysctl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(150, "mlock", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(151, "munlock", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(152, "mlockall", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(153, "munlockall", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(154, "sched_setparam", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(155, "sched_getparam", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(156, "sched_setscheduler", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(157, "sched_getscheduler", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(158, "sched_yield", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(159, "sched_get_priority_max", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(160, "sched_get_priority_min", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(161, "sched_rr_get_interval", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(162, "nanosleep", kHex, kHex),
|
||||
MakeEntry(163, "mremap", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(164, "setresuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(165, "getresuid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(168, "poll", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(169, "nfsservctl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(170, "setresgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(171, "getresgid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(172, "prctl", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(173, "rt_sigreturn", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(174, "rt_sigaction", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(175, "rt_sigprocmask", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(176, "rt_sigpending", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(177, "rt_sigtimedwait", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(178, "rt_sigqueueinfo", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(179, "rt_sigsuspend", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(180, "pread64", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(181, "pwrite64", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(182, "chown", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(183, "getcwd", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(184, "capget", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(185, "capset", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(186, "sigaltstack", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(187, "sendfile", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(190, "vfork", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(191, "ugetrlimit", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(192, "mmap2", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(193, "truncate64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(194, "ftruncate64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(195, "stat64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(196, "lstat64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(197, "fstat64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(198, "lchown32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(199, "getuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(200, "getgid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(201, "geteuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(202, "getegid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(203, "setreuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(204, "setregid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(205, "getgroups32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(206, "setgroups32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(207, "fchown32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(208, "setresuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(209, "getresuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(210, "setresgid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(211, "getresgid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(212, "chown32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(213, "setuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(214, "setgid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(215, "setfsuid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(216, "setfsgid32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(217, "getdents64", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(218, "pivot_root", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(219, "mincore", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(220, "madvise", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(221, "fcntl64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(224, "gettid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(225, "readahead", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(226, "setxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(227, "lsetxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(228, "fsetxattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(229, "getxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(230, "lgetxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(231, "fgetxattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(232, "listxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(233, "llistxattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(234, "flistxattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(235, "removexattr", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(236, "lremovexattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(237, "fremovexattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(238, "tkill", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(239, "sendfile64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(240, "futex", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(241, "sched_setaffinity", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(242, "sched_getaffinity", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(243, "io_setup", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(244, "io_destroy", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(245, "io_getevents", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(246, "io_submit", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(247, "io_cancel", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(248, "exit_group", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(249, "lookup_dcookie", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(250, "epoll_create", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(251, "epoll_ctl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(252, "epoll_wait", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(253, "remap_file_pages", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(256, "set_tid_address", kHex),
|
||||
MakeEntry(257, "timer_create", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(258, "timer_settime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(259, "timer_gettime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(260, "timer_getoverrun", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(261, "timer_delete", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(262, "clock_settime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(263, "clock_gettime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(264, "clock_getres", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(265, "clock_nanosleep", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(266, "statfs64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(267, "fstatfs64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(268, "tgkill", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(269, "utimes", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(271, "pciconfig_iobase", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(272, "pciconfig_read", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(273, "pciconfig_write", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(274, "mq_open", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(275, "mq_unlink", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(276, "mq_timedsend", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(277, "mq_timedreceive", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(278, "mq_notify", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(279, "mq_getsetattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(280, "waitid", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(281, "socket", kAddressFamily, kInt, kInt),
|
||||
MakeEntry(282, "bind", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(283, "connect", kInt, kSockaddr, kInt),
|
||||
MakeEntry(284, "listen", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(285, "accept", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(286, "getsockname", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(287, "getpeername", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(288, "socketpair", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(289, "send", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(290, "sendto", kInt, kGen, kInt, kHex),
|
||||
MakeEntry(291, "recv", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(292, "recvfrom", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(293, "shutdown", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(294, "setsockopt", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(295, "getsockopt", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(296, "sendmsg", kInt, kSockmsghdr, kHex),
|
||||
MakeEntry(297, "recvmsg", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(298, "semop", UnknownArguments()),
|
||||
MakeEntry(299, "semget", UnknownArguments()),
|
||||
MakeEntry(300, "semctl", UnknownArguments()),
|
||||
MakeEntry(301, "msgsnd", UnknownArguments()),
|
||||
MakeEntry(302, "msgrcv", UnknownArguments()),
|
||||
MakeEntry(303, "msgget", UnknownArguments()),
|
||||
MakeEntry(304, "msgctl", UnknownArguments()),
|
||||
MakeEntry(305, "shmat", UnknownArguments()),
|
||||
MakeEntry(306, "shmdt", UnknownArguments()),
|
||||
MakeEntry(307, "shmget", UnknownArguments()),
|
||||
MakeEntry(308, "shmctl", UnknownArguments()),
|
||||
MakeEntry(309, "add_key", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(310, "request_key", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(311, "keyctl", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(312, "semtimedop", UnknownArguments()),
|
||||
MakeEntry(313, "vserver", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(314, "ioprio_set", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(315, "ioprio_get", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(316, "inotify_init", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(317, "inotify_add_watch", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(318, "inotify_rm_watch", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(319, "mbind", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(320, "get_mempolicy", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(321, "set_mempolicy", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(322, "openat", kGen, kPath, kOct, kHex),
|
||||
MakeEntry(323, "mkdirat", kGen, kPath),
|
||||
MakeEntry(324, "mknodat", kGen, kPath),
|
||||
MakeEntry(325, "fchownat", kGen, kPath),
|
||||
MakeEntry(326, "futimesat", kGen, kPath),
|
||||
MakeEntry(327, "fstatat64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(328, "unlinkat", kGen, kPath),
|
||||
MakeEntry(329, "renameat", kGen, kPath, kGen, kPath),
|
||||
MakeEntry(330, "linkat", kGen, kPath, kGen, kPath),
|
||||
MakeEntry(331, "symlinkat", kPath, kGen, kPath),
|
||||
MakeEntry(332, "readlinkat", kGen, kPath),
|
||||
MakeEntry(333, "fchmodat", kGen, kPath),
|
||||
MakeEntry(334, "faccessat", kGen, kPath),
|
||||
MakeEntry(335, "pselect6", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(336, "ppoll", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(337, "unshare", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(338, "set_robust_list", kGen, kGen),
|
||||
MakeEntry(339, "get_robust_list", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(340, "splice", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(342, "tee", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(343, "vmsplice", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(344, "move_pages", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(345, "getcpu", kHex, kHex, kHex),
|
||||
MakeEntry(346, "epoll_pwait", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(347, "kexec_load", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(348, "utimensat", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(349, "signalfd", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(350, "timerfd_create", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(351, "eventfd", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(352, "fallocate", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(353, "timerfd_settime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(354, "timerfd_gettime", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(355, "signalfd4", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(356, "eventfd2", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(357, "epoll_create1", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(358, "dup3", kGen, kGen, kGen),
|
||||
MakeEntry(359, "pipe2", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(360, "inotify_init1", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(361, "preadv", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(362, "pwritev", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(363, "rt_tgsigqueueinfo", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(364, "perf_event_open", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(365, "recvmmsg", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(366, "accept4", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(367, "fanotify_init", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(368, "fanotify_mark", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(369, "prlimit64", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(370, "name_to_handle_at", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(371, "open_by_handle_at", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(372, "clock_adjtime", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(373, "syncfs", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(374, "sendmmsg", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(375, "setns", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(376, "process_vm_readv", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(377, "process_vm_writev", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(378, "kcmp", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(379, "finit_module", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(380, "sched_setattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(381, "sched_getattr", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(382, "renameat2", kGen, kPath, kGen, kPath),
|
||||
MakeEntry(383, "seccomp", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(384, "getrandom", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(385, "memfd_create", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(386, "bpf", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(387, "execveat", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(388, "userfaultfd", kHex),
|
||||
MakeEntry(389, "membarrier", kHex, kHex),
|
||||
MakeEntry(390, "mlock2", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(391, "copy_file_range", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(392, "preadv2", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(393, "pwritev2", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(400, "migrate_pages", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(401, "kexec_file_load", kGen, kGen, kGen, kGen),
|
||||
MakeEntry(0xf0001, "ARM_breakpoint", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(0xf0002, "ARM_cacheflush", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(0xf0003, "ARM_usr26", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(0xf0004, "ARM_usr32", kHex, kHex, kHex, kHex),
|
||||
MakeEntry(0xf0005, "ARM_set_tls", kHex, kHex, kHex, kHex),
|
||||
// clang-format on
|
||||
};
|
||||
|
||||
static_assert(IsSorted(kSyscallDataArm32, SyscallTable::Entry::BySyscallNr),
|
||||
"Syscalls should be sorted");
|
||||
|
||||
} // namespace
|
||||
|
||||
SyscallTable SyscallTable::get(cpu::Architecture arch) {
|
||||
|
@ -1536,6 +1898,8 @@ SyscallTable SyscallTable::get(cpu::Architecture arch) {
|
|||
return SyscallTable(kSyscallDataPPC64LE);
|
||||
case cpu::kArm64:
|
||||
return SyscallTable(kSyscallDataArm64);
|
||||
case cpu::kArm:
|
||||
return SyscallTable(kSyscallDataArm32);
|
||||
default:
|
||||
return SyscallTable();
|
||||
}
|
||||
|
|
|
@ -18,7 +18,10 @@
|
|||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include <cstdint>
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
syscall(__NR_personality, 1ULL, 2ULL, 3ULL, 4ULL, 5ULL, 6ULL);
|
||||
syscall(__NR_personality, uintptr_t{1}, uintptr_t{2}, uintptr_t{3},
|
||||
uintptr_t{4}, uintptr_t{5}, uintptr_t{6});
|
||||
return 22;
|
||||
}
|
||||
|
|
|
@ -127,9 +127,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::IsArm64(),
|
||||
"Host CPU architecture not supported, see config.h");
|
||||
static_assert(host_cpu::IsX8664() || host_cpu::IsPPC64LE() ||
|
||||
host_cpu::IsArm64() || host_cpu::IsArm(),
|
||||
"Host CPU architecture not supported, see config.h");
|
||||
// Stack grows down.
|
||||
void* stack = stack_buf + sizeof(stack_buf);
|
||||
int r;
|
||||
|
|
|
@ -137,6 +137,7 @@ cc_library(
|
|||
copts = sapi_platform_copts(),
|
||||
deps = [
|
||||
":strerror",
|
||||
"//sandboxed_api/sandbox2:config",
|
||||
"//sandboxed_api/sandbox2:util",
|
||||
"//sandboxed_api/util:raw_logging",
|
||||
"//sandboxed_api/util:status",
|
||||
|
|
|
@ -24,6 +24,7 @@
|
|||
#include "absl/status/statusor.h"
|
||||
#include "absl/strings/match.h"
|
||||
#include "absl/strings/str_cat.h"
|
||||
#include "sandboxed_api/sandbox2/config.h"
|
||||
#include "sandboxed_api/sandbox2/util.h"
|
||||
#include "sandboxed_api/sandbox2/util/strerror.h"
|
||||
#include "sandboxed_api/util/raw_logging.h"
|
||||
|
@ -31,15 +32,20 @@
|
|||
|
||||
namespace sandbox2 {
|
||||
|
||||
constexpr int kElfHeaderSize =
|
||||
sizeof(Elf64_Ehdr); // Maximum size for 64-bit binaries
|
||||
using ElfEhdr = std::conditional_t<host_cpu::Is64Bit(), Elf64_Ehdr, Elf32_Ehdr>;
|
||||
using ElfShdr = std::conditional_t<host_cpu::Is64Bit(), Elf64_Shdr, Elf32_Shdr>;
|
||||
using ElfPhdr = std::conditional_t<host_cpu::Is64Bit(), Elf64_Phdr, Elf32_Phdr>;
|
||||
using ElfDyn = std::conditional_t<host_cpu::Is64Bit(), Elf64_Dyn, Elf32_Dyn>;
|
||||
using ElfSym = std::conditional_t<host_cpu::Is64Bit(), Elf64_Sym, Elf32_Sym>;
|
||||
|
||||
constexpr int kElfHeaderSize = sizeof(ElfEhdr); // Maximum size for binaries
|
||||
|
||||
constexpr char kElfMagic[] =
|
||||
"\x7F"
|
||||
"ELF";
|
||||
|
||||
constexpr int kEiClassOffset = 0x04;
|
||||
constexpr int kEiClass64 = 2; // 64-bit binary
|
||||
constexpr int kEiClass = host_cpu::Is64Bit() ? ELFCLASS64 : ELFCLASS32;
|
||||
|
||||
constexpr int kEiDataOffset = 0x05;
|
||||
constexpr int kEiDataLittle = 1; // Little Endian
|
||||
|
@ -134,29 +140,29 @@ class ElfParser {
|
|||
// Reads elf header.
|
||||
absl::Status ReadFileHeader();
|
||||
// Reads a single elf program header.
|
||||
absl::StatusOr<Elf64_Phdr> ReadProgramHeader(absl::string_view src);
|
||||
absl::StatusOr<ElfPhdr> ReadProgramHeader(absl::string_view src);
|
||||
// Reads all elf program headers.
|
||||
absl::Status ReadProgramHeaders();
|
||||
// Reads a single elf section header.
|
||||
absl::StatusOr<Elf64_Shdr> ReadSectionHeader(absl::string_view src);
|
||||
absl::StatusOr<ElfShdr> ReadSectionHeader(absl::string_view src);
|
||||
// Reads all elf section headers.
|
||||
absl::Status ReadSectionHeaders();
|
||||
// Reads contents of an elf section.
|
||||
absl::StatusOr<std::string> ReadSectionContents(int idx);
|
||||
absl::StatusOr<std::string> ReadSectionContents(
|
||||
const Elf64_Shdr& section_header);
|
||||
const ElfShdr& section_header);
|
||||
// Reads all symbols from symtab section.
|
||||
absl::Status ReadSymbolsFromSymtab(const Elf64_Shdr& symtab);
|
||||
absl::Status ReadSymbolsFromSymtab(const ElfShdr& symtab);
|
||||
// Reads all imported libraries from dynamic section.
|
||||
absl::Status ReadImportedLibrariesFromDynamic(const Elf64_Shdr& dynamic);
|
||||
absl::Status ReadImportedLibrariesFromDynamic(const ElfShdr& dynamic);
|
||||
|
||||
ElfFile result_;
|
||||
FILE* elf_ = nullptr;
|
||||
size_t file_size_ = 0;
|
||||
bool elf_little_ = false;
|
||||
Elf64_Ehdr file_header_;
|
||||
std::vector<Elf64_Phdr> program_headers_;
|
||||
std::vector<Elf64_Shdr> section_headers_;
|
||||
ElfEhdr file_header_;
|
||||
std::vector<ElfPhdr> program_headers_;
|
||||
std::vector<ElfShdr> section_headers_;
|
||||
|
||||
int symbol_entries_read = 0;
|
||||
int dynamic_entries_read = 0;
|
||||
|
@ -191,7 +197,7 @@ absl::Status ElfParser::ReadFileHeader() {
|
|||
return absl::FailedPreconditionError("magic not found, not an ELF");
|
||||
}
|
||||
|
||||
if (header[kEiClassOffset] != kEiClass64) {
|
||||
if (header[kEiClassOffset] != kEiClass) {
|
||||
return absl::FailedPreconditionError("invalid ELF class");
|
||||
}
|
||||
const auto elf_data = header[kEiDataOffset];
|
||||
|
@ -220,13 +226,13 @@ absl::Status ElfParser::ReadFileHeader() {
|
|||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::StatusOr<Elf64_Shdr> ElfParser::ReadSectionHeader(absl::string_view src) {
|
||||
if (src.size() < sizeof(Elf64_Shdr)) {
|
||||
absl::StatusOr<ElfShdr> ElfParser::ReadSectionHeader(absl::string_view src) {
|
||||
if (src.size() < sizeof(ElfShdr)) {
|
||||
return absl::FailedPreconditionError(
|
||||
absl::StrCat("invalid section header data: got ", src.size(),
|
||||
" bytes, ", sizeof(Elf64_Shdr), " bytes expected."));
|
||||
" bytes, ", sizeof(ElfShdr), " bytes expected."));
|
||||
}
|
||||
Elf64_Shdr rv;
|
||||
ElfShdr rv;
|
||||
LOAD_MEMBER(rv, sh_name, src.data());
|
||||
LOAD_MEMBER(rv, sh_type, src.data());
|
||||
LOAD_MEMBER(rv, sh_flags, src.data());
|
||||
|
@ -245,10 +251,10 @@ absl::Status ElfParser::ReadSectionHeaders() {
|
|||
return absl::FailedPreconditionError(
|
||||
absl::StrCat("invalid section header offset: ", file_header_.e_shoff));
|
||||
}
|
||||
if (file_header_.e_shentsize != sizeof(Elf64_Shdr)) {
|
||||
if (file_header_.e_shentsize != sizeof(ElfShdr)) {
|
||||
return absl::FailedPreconditionError(absl::StrCat(
|
||||
"section header entry size incorrect: ", file_header_.e_shentsize,
|
||||
" bytes, ", sizeof(Elf64_Shdr), " expected."));
|
||||
" bytes, ", sizeof(ElfShdr), " expected."));
|
||||
}
|
||||
if (file_header_.e_shnum > kMaxSectionHeaderEntries) {
|
||||
return absl::FailedPreconditionError(
|
||||
|
@ -276,7 +282,7 @@ absl::StatusOr<std::string> ElfParser::ReadSectionContents(int idx) {
|
|||
}
|
||||
|
||||
absl::StatusOr<std::string> ElfParser::ReadSectionContents(
|
||||
const Elf64_Shdr& section_header) {
|
||||
const ElfShdr& section_header) {
|
||||
auto offset = section_header.sh_offset;
|
||||
if (offset > file_size_) {
|
||||
return absl::FailedPreconditionError(
|
||||
|
@ -293,13 +299,13 @@ absl::StatusOr<std::string> ElfParser::ReadSectionContents(
|
|||
return rv;
|
||||
}
|
||||
|
||||
absl::StatusOr<Elf64_Phdr> ElfParser::ReadProgramHeader(absl::string_view src) {
|
||||
if (src.size() < sizeof(Elf64_Phdr)) {
|
||||
absl::StatusOr<ElfPhdr> ElfParser::ReadProgramHeader(absl::string_view src) {
|
||||
if (src.size() < sizeof(ElfPhdr)) {
|
||||
return absl::FailedPreconditionError(
|
||||
absl::StrCat("invalid program header data: got ", src.size(),
|
||||
" bytes, ", sizeof(Elf64_Phdr), " bytes expected."));
|
||||
" bytes, ", sizeof(ElfPhdr), " bytes expected."));
|
||||
}
|
||||
Elf64_Phdr rv;
|
||||
ElfPhdr rv;
|
||||
LOAD_MEMBER(rv, p_type, src.data());
|
||||
LOAD_MEMBER(rv, p_flags, src.data());
|
||||
LOAD_MEMBER(rv, p_offset, src.data());
|
||||
|
@ -316,10 +322,10 @@ absl::Status ElfParser::ReadProgramHeaders() {
|
|||
return absl::FailedPreconditionError(
|
||||
absl::StrCat("invalid program header offset: ", file_header_.e_phoff));
|
||||
}
|
||||
if (file_header_.e_phentsize != sizeof(Elf64_Phdr)) {
|
||||
if (file_header_.e_phentsize != sizeof(ElfPhdr)) {
|
||||
return absl::FailedPreconditionError(absl::StrCat(
|
||||
"section header entry size incorrect: ", file_header_.e_phentsize,
|
||||
" bytes, ", sizeof(Elf64_Phdr), " expected."));
|
||||
" bytes, ", sizeof(ElfPhdr), " expected."));
|
||||
}
|
||||
if (file_header_.e_phnum > kMaxProgramHeaderEntries) {
|
||||
return absl::FailedPreconditionError(
|
||||
|
@ -338,11 +344,11 @@ absl::Status ElfParser::ReadProgramHeaders() {
|
|||
return absl::OkStatus();
|
||||
}
|
||||
|
||||
absl::Status ElfParser::ReadSymbolsFromSymtab(const Elf64_Shdr& symtab) {
|
||||
absl::Status ElfParser::ReadSymbolsFromSymtab(const ElfShdr& symtab) {
|
||||
if (symtab.sh_type != SHT_SYMTAB) {
|
||||
return absl::FailedPreconditionError("invalid symtab type");
|
||||
}
|
||||
if (symtab.sh_entsize != sizeof(Elf64_Sym)) {
|
||||
if (symtab.sh_entsize != sizeof(ElfSym)) {
|
||||
return absl::InternalError(
|
||||
absl::StrCat("invalid symbol entry size: ", symtab.sh_entsize));
|
||||
}
|
||||
|
@ -366,7 +372,7 @@ absl::Status ElfParser::ReadSymbolsFromSymtab(const Elf64_Shdr& symtab) {
|
|||
result_.symbols_.reserve(result_.symbols_.size() + symbol_entries);
|
||||
for (absl::string_view src = symbols; !src.empty();
|
||||
src = src.substr(symtab.sh_entsize)) {
|
||||
Elf64_Sym symbol;
|
||||
ElfSym symbol;
|
||||
LOAD_MEMBER(symbol, st_name, src.data());
|
||||
LOAD_MEMBER(symbol, st_info, src.data());
|
||||
LOAD_MEMBER(symbol, st_other, src.data());
|
||||
|
@ -396,11 +402,11 @@ absl::Status ElfParser::ReadSymbolsFromSymtab(const Elf64_Shdr& symtab) {
|
|||
}
|
||||
|
||||
absl::Status ElfParser::ReadImportedLibrariesFromDynamic(
|
||||
const Elf64_Shdr& dynamic) {
|
||||
const ElfShdr& dynamic) {
|
||||
if (dynamic.sh_type != SHT_DYNAMIC) {
|
||||
return absl::FailedPreconditionError("invalid dynamic type");
|
||||
}
|
||||
if (dynamic.sh_entsize != sizeof(Elf64_Dyn)) {
|
||||
if (dynamic.sh_entsize != sizeof(ElfDyn)) {
|
||||
return absl::InternalError(
|
||||
absl::StrCat("invalid dynamic entry size: ", dynamic.sh_entsize));
|
||||
}
|
||||
|
@ -435,7 +441,7 @@ absl::Status ElfParser::ReadImportedLibrariesFromDynamic(
|
|||
SAPI_ASSIGN_OR_RETURN(std::string dynamic_entries, ReadSectionContents(dynamic));
|
||||
for (absl::string_view src = dynamic_entries; !src.empty();
|
||||
src = src.substr(dynamic.sh_entsize)) {
|
||||
Elf64_Dyn dyn;
|
||||
ElfDyn dyn;
|
||||
LOAD_MEMBER(dyn, d_tag, src.data());
|
||||
LOAD_MEMBER(dyn, d_un.d_val, src.data());
|
||||
if (dyn.d_tag != DT_NEEDED) {
|
||||
|
@ -478,7 +484,7 @@ absl::StatusOr<ElfFile> ElfParser::Parse(FILE* elf, uint32_t features) {
|
|||
std::string interpreter;
|
||||
auto it = std::find_if(
|
||||
program_headers_.begin(), program_headers_.end(),
|
||||
[](const Elf64_Phdr& hdr) { return hdr.p_type == PT_INTERP; });
|
||||
[](const ElfPhdr& hdr) { return hdr.p_type == PT_INTERP; });
|
||||
// No interpreter usually means that the executable was statically linked.
|
||||
if (it != program_headers_.end()) {
|
||||
if (it->p_filesz > kMaxInterpreterSize) {
|
||||
|
|
|
@ -15,6 +15,7 @@
|
|||
#ifndef SANDBOXED_API_SANDBOX2_UTIL_MINIELF_H_
|
||||
#define SANDBOXED_API_SANDBOX2_UTIL_MINIELF_H_
|
||||
|
||||
#include <cstdint>
|
||||
#include <cstdio>
|
||||
#include <memory>
|
||||
#include <string>
|
||||
|
@ -25,11 +26,10 @@
|
|||
namespace sandbox2 {
|
||||
|
||||
// Minimal implementation of an ELF file parser to read the program interpreter.
|
||||
// Only understands 64-bit ELFs.
|
||||
class ElfFile {
|
||||
public:
|
||||
struct Symbol {
|
||||
uint64_t address;
|
||||
uintptr_t address;
|
||||
std::string name;
|
||||
};
|
||||
|
||||
|
|
|
@ -83,12 +83,20 @@ message RegisterAarch64 {
|
|||
uint64 pstate = 4;
|
||||
}
|
||||
|
||||
message RegisterArm {
|
||||
repeated uint32 regs = 1;
|
||||
uint32 pc = 2;
|
||||
uint32 cpsr = 3;
|
||||
uint32 orig_x0 = 4;
|
||||
}
|
||||
|
||||
message RegisterValues {
|
||||
// Architecture architecture = 1;
|
||||
oneof register_values {
|
||||
RegisterX8664 register_x86_64 = 2;
|
||||
RegisterPowerpc64 register_powerpc64 = 3;
|
||||
RegisterAarch64 register_aarch64 = 4;
|
||||
RegisterArm register_arm = 5;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user