From 36e4b80f9a70c62ab1a52a864504b50a47981353 Mon Sep 17 00:00:00 2001 From: Wiktor Garbacz Date: Wed, 27 Dec 2023 02:50:16 -0800 Subject: [PATCH] Introduce and prefer `AllowMmapWithoutExec` PiperOrigin-RevId: 593968486 Change-Id: I4f7d4d8a6f593d94c0a7e7672826074c4cefc230 --- contrib/zopfli/sandboxed.h | 2 +- oss-internship-2020/curl/sandbox.h | 2 +- oss-internship-2020/libpng/sandboxed.h | 2 +- oss-internship-2020/libuv/examples/uvcat.cc | 2 +- oss-internship-2020/libuv/tests/test_os.cc | 2 +- .../sandbox2/examples/network/network_sandbox.cc | 2 +- .../examples/network_proxy/networkproxy_sandbox.cc | 2 +- sandboxed_api/sandbox2/policybuilder.cc | 10 +++++++++- sandboxed_api/sandbox2/policybuilder.h | 5 +++++ sandboxed_api/sandbox2/stack_trace.cc | 2 +- 10 files changed, 22 insertions(+), 9 deletions(-) diff --git a/contrib/zopfli/sandboxed.h b/contrib/zopfli/sandboxed.h index 80442e3..7f25069 100644 --- a/contrib/zopfli/sandboxed.h +++ b/contrib/zopfli/sandboxed.h @@ -31,7 +31,7 @@ class ZopfliSapiSandbox : public ZopfliSandbox { .AllowDynamicStartup() .AllowWrite() .AllowExit() - .AllowMmap() + .AllowMmapWithoutExec() .AllowSystemMalloc() .AllowSyscalls({ __NR_recvmsg, diff --git a/oss-internship-2020/curl/sandbox.h b/oss-internship-2020/curl/sandbox.h index 29bbbc2..49cf7ad 100644 --- a/oss-internship-2020/curl/sandbox.h +++ b/oss-internship-2020/curl/sandbox.h @@ -38,7 +38,7 @@ class CurlSapiSandbox : public curl::CurlSandbox { .AllowFutexOp(FUTEX_WAIT_PRIVATE) .AllowFutexOp(FUTEX_WAKE_PRIVATE) .AllowFutexOp(FUTEX_REQUEUE_PRIVATE) - .AllowMmap() + .AllowMmapWithoutExec() .AllowOpen() .AllowSafeFcntl() .AllowWrite() diff --git a/oss-internship-2020/libpng/sandboxed.h b/oss-internship-2020/libpng/sandboxed.h index c811ddc..d55247e 100644 --- a/oss-internship-2020/libpng/sandboxed.h +++ b/oss-internship-2020/libpng/sandboxed.h @@ -38,7 +38,7 @@ class LibPNGSapiSandbox : public LibPNGSandbox { .AllowOpen() .AllowExit() .AllowStat() - .AllowMmap() + .AllowMmapWithoutExec() .AllowSystemMalloc() .AllowSyscalls({ __NR_futex, diff --git a/oss-internship-2020/libuv/examples/uvcat.cc b/oss-internship-2020/libuv/examples/uvcat.cc index 7b54f76..cc930fa 100644 --- a/oss-internship-2020/libuv/examples/uvcat.cc +++ b/oss-internship-2020/libuv/examples/uvcat.cc @@ -37,7 +37,7 @@ class UVSapiUVCatSandbox : public uv::UVSandbox { .AllowFork() .AllowFutexOp(FUTEX_WAKE_PRIVATE) .AllowFutexOp(FUTEX_WAIT_PRIVATE) - .AllowMmap() + .AllowMmapWithoutExec() .AllowOpen() .AllowEpoll() .AllowSyscall(__NR_eventfd2) diff --git a/oss-internship-2020/libuv/tests/test_os.cc b/oss-internship-2020/libuv/tests/test_os.cc index 1e5da3b..a96a5ce 100644 --- a/oss-internship-2020/libuv/tests/test_os.cc +++ b/oss-internship-2020/libuv/tests/test_os.cc @@ -32,7 +32,7 @@ class UVTestOSSapiSandbox : public uv::UVSandbox { .AllowExit() .AllowFutexOp(FUTEX_WAKE_PRIVATE) .AllowGetIDs() - .AllowMmap() + .AllowMmapWithoutExec() .AllowOpen() .AllowWrite() .AllowSyscalls({__NR_connect, __NR_socket}) diff --git a/sandboxed_api/sandbox2/examples/network/network_sandbox.cc b/sandboxed_api/sandbox2/examples/network/network_sandbox.cc index 684cbde..7dca5f6 100644 --- a/sandboxed_api/sandbox2/examples/network/network_sandbox.cc +++ b/sandboxed_api/sandbox2/examples/network/network_sandbox.cc @@ -49,7 +49,7 @@ namespace { std::unique_ptr GetPolicy(absl::string_view sandboxee_path) { return sandbox2::PolicyBuilder() .AllowExit() - .AllowMmap() + .AllowMmapWithoutExec() .AllowRead() .AllowWrite() .AllowSyscall(__NR_close) diff --git a/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_sandbox.cc b/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_sandbox.cc index 490718a..76208d1 100644 --- a/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_sandbox.cc +++ b/sandboxed_api/sandbox2/examples/network_proxy/networkproxy_sandbox.cc @@ -41,7 +41,7 @@ constexpr char kSandboxeePath[] = std::unique_ptr GetPolicy(absl::string_view sandboxee_path) { sandbox2::PolicyBuilder builder; builder.AllowExit() - .AllowMmap() + .AllowMmapWithoutExec() .AllowRead() .AllowWrite() .AllowStat() // printf, puts diff --git a/sandboxed_api/sandbox2/policybuilder.cc b/sandboxed_api/sandbox2/policybuilder.cc index 92f10bb..e7c1ac8 100644 --- a/sandboxed_api/sandbox2/policybuilder.cc +++ b/sandboxed_api/sandbox2/policybuilder.cc @@ -329,7 +329,7 @@ PolicyBuilder& PolicyBuilder::AllowLlvmSanitizers() { // example: // https://github.com/llvm/llvm-project/blob/596d534ac3524052df210be8d3c01a33b2260a42/compiler-rt/lib/asan/asan_allocator.cpp#L980 // https://github.com/llvm/llvm-project/blob/62ec4ac90738a5f2d209ed28c822223e58aaaeb7/compiler-rt/lib/sanitizer_common/sanitizer_allocator_secondary.h#L98 - AllowMmap(); + AllowMmapWithoutExec(); AllowSyscall(__NR_munmap); AllowSyscall(__NR_sched_yield); @@ -415,6 +415,14 @@ PolicyBuilder& PolicyBuilder::AllowLimitedMadvise() { }); } +PolicyBuilder& PolicyBuilder::AllowMmapWithoutExec() { + return AddPolicyOnMmap({ + ARG_32(2), + BPF_JUMP(BPF_JMP | BPF_JSET | BPF_K, PROT_EXEC, 1, 0), + ALLOW, + }); +} + PolicyBuilder& PolicyBuilder::AllowMmap() { return AllowSyscalls(kMmapSyscalls); } diff --git a/sandboxed_api/sandbox2/policybuilder.h b/sandboxed_api/sandbox2/policybuilder.h index c832d00..d7f1df1 100644 --- a/sandboxed_api/sandbox2/policybuilder.h +++ b/sandboxed_api/sandbox2/policybuilder.h @@ -245,8 +245,13 @@ class PolicyBuilder final { // Appends code to allow mmap. Specifically this allows mmap and mmap2 syscall // on architectures where this syscalls exist. + // Prefer using AllowMmapWithoutExec as allowing mapping executable pages + // makes exploitation easier. PolicyBuilder& AllowMmap(); + // Appends code to allow mmap calls that don't specify PROT_EXEC. + PolicyBuilder& AllowMmapWithoutExec(); + // Appends code to allow calling futex with the given operation. PolicyBuilder& AllowFutexOp(int op); diff --git a/sandboxed_api/sandbox2/stack_trace.cc b/sandboxed_api/sandbox2/stack_trace.cc index 2b970ad..11f9b6f 100644 --- a/sandboxed_api/sandbox2/stack_trace.cc +++ b/sandboxed_api/sandbox2/stack_trace.cc @@ -145,7 +145,7 @@ absl::StatusOr> StackTracePeer::GetPolicy( .AllowSyscall(__NR_recvmsg) // libunwind - .AllowMmap() + .AllowMmapWithoutExec() .AllowStat() .AllowSyscall(__NR_lseek) #ifdef __NR__llseek