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.
This commit is contained in:
Nia Alarie
2024-09-12 09:42:44 +02:00
committed by roytam1
parent ec8793a094
commit dd6526daae
2 changed files with 20 additions and 2 deletions
+14 -1
View File
@@ -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);
+6 -1
View File
@@ -644,7 +644,12 @@ WasmArrayRawBuffer::Allocate(uint32_t numBytes, Maybe<uint32_t> 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;