diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp index c7b30d988365..9b5f6f1da1a1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -274,6 +274,15 @@ void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) { UNIMPLEMENTED(); } +bool MprotectNoAccess(uptr addr, uptr size) { + return _zx_vmar_protect(_zx_vmar_root_self(), 0, Addr, Size) == ZX_OK; +} + +bool MprotectReadOnly(uptr addr, uptr size) { + return _zx_vmar_protect(_zx_vmar_root_self(), ZX_VM_PERM_READ, Addr, Size) == + ZX_OK; +} + void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, const char *mem_type) { CHECK_GE(size, GetPageSize()); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp index c3607dbed23e..1a31ce02af4c 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cpp @@ -337,6 +337,11 @@ bool MprotectNoAccess(uptr addr, uptr size) { return VirtualProtect((LPVOID)addr, size, PAGE_NOACCESS, &old_protection); } +bool MprotectReadOnly(uptr addr, uptr size) { + DWORD old_protection; + return VirtualProtect((LPVOID)addr, size, PAGE_READONLY, &old_protection); +} + void ReleaseMemoryPagesToOS(uptr beg, uptr end) { uptr beg_aligned = RoundDownTo(beg, GetPageSizeCached()), end_aligned = RoundDownTo(end, GetPageSizeCached()); diff --git a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp index 9008a65d0e3e..c76644f5dba2 100644 --- a/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp +++ b/compiler-rt/lib/sanitizer_common/tests/sanitizer_common_test.cpp @@ -87,6 +87,24 @@ TEST(SanitizerCommon, MmapAlignedOrDieOnFatalError) { } } +TEST(SanitizerCommon, Mprotect) { + uptr PageSize = GetPageSizeCached(); + u8 *mem = reinterpret_cast(MmapOrDie(PageSize, "MprotectTest")); + for (u8 *p = mem; p < mem + PageSize; ++p) ++(*p); + + MprotectReadOnly(reinterpret_cast(mem), PageSize); + for (u8 *p = mem; p < mem + PageSize; ++p) EXPECT_EQ(1u, *p); + EXPECT_DEATH(++mem[0], ""); + EXPECT_DEATH(++mem[PageSize / 2], ""); + EXPECT_DEATH(++mem[PageSize - 1], ""); + + MprotectNoAccess(reinterpret_cast(mem), PageSize); + volatile u8 t; + EXPECT_DEATH(t = mem[0], ""); + EXPECT_DEATH(t = mem[PageSize / 2], ""); + EXPECT_DEATH(t = mem[PageSize - 1], ""); +} + TEST(SanitizerCommon, InternalMmapVectorRoundUpCapacity) { InternalMmapVector v; v.reserve(1);