From dd6526daaee22eee64cb71d2b4af1eea552ddc76 Mon Sep 17 00:00:00 2001 From: Nia Alarie Date: Thu, 12 Sep 2024 09:42:44 +0200 Subject: [PATCH] js: Support for the MPROTECT security feature (PaX and NetBSD) On such platforms, remapping memory that was once writable to executable is forbidden unless the initial mmap() is declared to change in such a way using the PROT_MPROTECT macro. --- js/src/jit/ProcessExecutableMemory.cpp | 15 ++++++++++++++- js/src/vm/ArrayBufferObject.cpp | 7 ++++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/js/src/jit/ProcessExecutableMemory.cpp b/js/src/jit/ProcessExecutableMemory.cpp index 7c40d93c71..d9e7c28f66 100644 --- a/js/src/jit/ProcessExecutableMemory.cpp +++ b/js/src/jit/ProcessExecutableMemory.cpp @@ -287,8 +287,15 @@ ReserveProcessExecutableMemory(size_t bytes) // Note that randomAddr is just a hint: if the address is not available // mmap will pick a different address. void* randomAddr = ComputeRandomAllocationAddress(); +#ifdef PROT_MPROTECT + void* p = MozTaggedAnonymousMmap(randomAddr, bytes, + PROT_MPROTECT(PROT_EXEC | PROT_WRITE | PROT_READ), + MAP_PRIVATE | MAP_ANON, + -1, 0, "js-executable-memory"); +#else void* p = MozTaggedAnonymousMmap(randomAddr, bytes, PROT_NONE, MAP_PRIVATE | MAP_ANON, -1, 0, "js-executable-memory"); +#endif if (p == MAP_FAILED) return nullptr; return p; @@ -315,7 +322,13 @@ ProtectionSettingToFlags(ProtectionSetting protection) static void CommitPages(void* addr, size_t bytes, ProtectionSetting protection) { - void* p = MozTaggedAnonymousMmap(addr, bytes, ProtectionSettingToFlags(protection), + void* p = MozTaggedAnonymousMmap(addr, bytes, +#ifdef PROT_MPROTECT + ProtectionSettingToFlags(protection) | + PROT_MPROTECT(PROT_EXEC | PROT_WRITE | PROT_READ), +#else + ProtectionSettingToFlags(protection), +#endif MAP_FIXED | MAP_PRIVATE | MAP_ANON, -1, 0, "js-executable-memory"); MOZ_RELEASE_ASSERT(addr == p); diff --git a/js/src/vm/ArrayBufferObject.cpp b/js/src/vm/ArrayBufferObject.cpp index 6ace034adb..06e31f208c 100644 --- a/js/src/vm/ArrayBufferObject.cpp +++ b/js/src/vm/ArrayBufferObject.cpp @@ -644,7 +644,12 @@ WasmArrayRawBuffer::Allocate(uint32_t numBytes, Maybe maxSize) return nullptr; } # else // XP_WIN - void* data = MozTaggedAnonymousMmap(nullptr, (size_t) mappedSizeWithHeader, PROT_NONE, + void* data = MozTaggedAnonymousMmap(nullptr, (size_t) mappedSizeWithHeader, +#ifdef PROT_MPROTECT + PROT_MPROTECT(PROT_EXEC | PROT_WRITE | PROT_READ), +#else + PROT_NONE, +#endif MAP_PRIVATE | MAP_ANON, -1, 0, "wasm-reserved"); if (data == MAP_FAILED) return nullptr;