Split Mprotect into MmapNoAccess and MprotectNoAccess to be more portable
On Windows, we have to know if a memory to be protected is mapped or not. On POSIX, Mprotect was semantically different from mprotect most people know. llvm-svn: 234602
This commit is contained in:
parent
3a09ef64ee
commit
ea1f332b79
|
@ -298,7 +298,7 @@ static void InitializeHighMemEnd() {
|
|||
}
|
||||
|
||||
static void ProtectGap(uptr a, uptr size) {
|
||||
void *res = Mprotect(a, size);
|
||||
void *res = MmapNoAccess(a, size);
|
||||
if (a == (uptr)res)
|
||||
return;
|
||||
Report("ERROR: Failed to protect the shadow gap. "
|
||||
|
|
|
@ -361,7 +361,7 @@ static void dfsan_init(int argc, char **argv, char **envp) {
|
|||
// case by disabling memory protection when ASLR is disabled.
|
||||
uptr init_addr = (uptr)&dfsan_init;
|
||||
if (!(init_addr >= kUnusedAddr && init_addr < kAppAddr))
|
||||
Mprotect(kUnusedAddr, kAppAddr - kUnusedAddr);
|
||||
MmapNoAccess(kUnusedAddr, kAppAddr - kUnusedAddr);
|
||||
|
||||
InitializeFlags();
|
||||
InitializeInterceptors();
|
||||
|
|
|
@ -56,7 +56,7 @@ static bool CheckMemoryRangeAvailability(uptr beg, uptr size) {
|
|||
static bool ProtectMemoryRange(uptr beg, uptr size) {
|
||||
if (size > 0) {
|
||||
uptr end = beg + size - 1;
|
||||
if (!Mprotect(beg, size)) {
|
||||
if (!MmapNoAccess(beg, size)) {
|
||||
Printf("FATAL: Cannot protect memory range %p - %p.\n", beg, end);
|
||||
return false;
|
||||
}
|
||||
|
|
|
@ -323,7 +323,7 @@ class SizeClassAllocator64 {
|
|||
|
||||
void Init() {
|
||||
CHECK_EQ(kSpaceBeg,
|
||||
reinterpret_cast<uptr>(Mprotect(kSpaceBeg, kSpaceSize)));
|
||||
reinterpret_cast<uptr>(MmapNoAccess(kSpaceBeg, kSpaceSize)));
|
||||
MapWithCallback(kSpaceEnd, AdditionalSize());
|
||||
}
|
||||
|
||||
|
|
|
@ -72,9 +72,13 @@ void UnmapOrDie(void *addr, uptr size);
|
|||
void *MmapFixedNoReserve(uptr fixed_addr, uptr size);
|
||||
void *MmapNoReserveOrDie(uptr size, const char *mem_type);
|
||||
void *MmapFixedOrDie(uptr fixed_addr, uptr size);
|
||||
void *Mprotect(uptr fixed_addr, uptr size);
|
||||
void *MmapNoAccess(uptr fixed_addr, uptr size);
|
||||
// Map aligned chunk of address space; size and alignment are powers of two.
|
||||
void *MmapAlignedOrDie(uptr size, uptr alignment, const char *mem_type);
|
||||
// Disallow access to a memory range. Use MmapNoAccess to allocate an
|
||||
// unaccessible memory.
|
||||
bool MprotectNoAccess(uptr addr, uptr size);
|
||||
|
||||
// Used to check if we can map shadow memory to a fixed location.
|
||||
bool MemoryRangeIsAvailable(uptr range_start, uptr range_end);
|
||||
void FlushUnneededShadowMemory(uptr addr, uptr size);
|
||||
|
|
|
@ -211,8 +211,9 @@ void CoverageData::Enable() {
|
|||
tr_event_array = reinterpret_cast<u32 *>(MmapNoReserveOrDie(
|
||||
sizeof(tr_event_array[0]) * kTrEventArrayMaxSize + GetMmapGranularity(),
|
||||
"CovInit::tr_event_array"));
|
||||
Mprotect(reinterpret_cast<uptr>(&tr_event_array[kTrEventArrayMaxSize]),
|
||||
GetMmapGranularity());
|
||||
MprotectNoAccess(
|
||||
reinterpret_cast<uptr>(&tr_event_array[kTrEventArrayMaxSize]),
|
||||
GetMmapGranularity());
|
||||
tr_event_array_size = kTrEventArrayMaxSize;
|
||||
tr_event_pointer = tr_event_array;
|
||||
|
||||
|
|
|
@ -127,6 +127,10 @@ uptr internal_munmap(void *addr, uptr length) {
|
|||
return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
|
||||
}
|
||||
|
||||
int internal_mprotect(void *addr, uptr length, int prot) {
|
||||
return internal_syscall(SYSCALL(mprotect), addr, length, prot);
|
||||
}
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
return internal_syscall(SYSCALL(close), fd);
|
||||
}
|
||||
|
|
|
@ -59,6 +59,10 @@ uptr internal_munmap(void *addr, uptr length) {
|
|||
return munmap(addr, length);
|
||||
}
|
||||
|
||||
int internal_mprotect(void *addr, uptr length, int prot) {
|
||||
return mprotect(addr, length, prot);
|
||||
}
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
return close(fd);
|
||||
}
|
||||
|
|
|
@ -199,13 +199,17 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) {
|
|||
return (void *)p;
|
||||
}
|
||||
|
||||
void *Mprotect(uptr fixed_addr, uptr size) {
|
||||
void *MmapNoAccess(uptr fixed_addr, uptr size) {
|
||||
return (void *)internal_mmap((void*)fixed_addr, size,
|
||||
PROT_NONE,
|
||||
MAP_PRIVATE | MAP_ANON | MAP_FIXED |
|
||||
MAP_NORESERVE, -1, 0);
|
||||
}
|
||||
|
||||
bool MprotectNoAccess(uptr addr, uptr size) {
|
||||
return 0 == internal_mprotect((void*)addr, size, PROT_NONE);
|
||||
}
|
||||
|
||||
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
|
||||
int flags;
|
||||
switch (mode) {
|
||||
|
|
|
@ -37,6 +37,7 @@ uptr internal_write(fd_t fd, const void *buf, uptr count);
|
|||
uptr internal_mmap(void *addr, uptr length, int prot, int flags,
|
||||
int fd, u64 offset);
|
||||
uptr internal_munmap(void *addr, uptr length);
|
||||
int internal_mprotect(void *addr, uptr length, int prot);
|
||||
|
||||
// OS
|
||||
uptr internal_filesize(fd_t fd); // -1 on error.
|
||||
|
|
|
@ -310,7 +310,7 @@ class ScopedStackSpaceWithGuard {
|
|||
// in the future.
|
||||
guard_start_ = (uptr)MmapOrDie(stack_size_ + guard_size_,
|
||||
"ScopedStackWithGuard");
|
||||
CHECK_EQ(guard_start_, (uptr)Mprotect((uptr)guard_start_, guard_size_));
|
||||
CHECK(MprotectNoAccess((uptr)guard_start_, guard_size_));
|
||||
}
|
||||
~ScopedStackSpaceWithGuard() {
|
||||
UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_);
|
||||
|
|
|
@ -125,7 +125,7 @@ void *MmapNoReserveOrDie(uptr size, const char *mem_type) {
|
|||
return MmapOrDie(size, mem_type);
|
||||
}
|
||||
|
||||
void *Mprotect(uptr fixed_addr, uptr size) {
|
||||
void *MmapNoAccess(uptr fixed_addr, uptr size) {
|
||||
void *res = VirtualAlloc((LPVOID)fixed_addr, size,
|
||||
MEM_RESERVE | MEM_COMMIT, PAGE_NOACCESS);
|
||||
if (res == 0)
|
||||
|
@ -135,6 +135,12 @@ void *Mprotect(uptr fixed_addr, uptr size) {
|
|||
return res;
|
||||
}
|
||||
|
||||
bool MprotectNoAccess(uptr addr, uptr size) {
|
||||
DWORD old_protection;
|
||||
return VirtualProtect((LPVOID)addr, size, PAGE_NOACCESS, &old_protection);
|
||||
}
|
||||
|
||||
|
||||
void FlushUnneededShadowMemory(uptr addr, uptr size) {
|
||||
// This is almost useless on 32-bits.
|
||||
// FIXME: add madvise-analog when we move to 64-bits.
|
||||
|
|
|
@ -45,7 +45,7 @@ static uptr PC(uptr idx) {
|
|||
void FastUnwindTest::SetUp() {
|
||||
size_t ps = GetPageSize();
|
||||
mapping = MmapOrDie(2 * ps, "FastUnwindTest");
|
||||
Mprotect((uptr)mapping, ps);
|
||||
MprotectNoAccess((uptr)mapping, ps);
|
||||
|
||||
// Unwinder may peek 1 word down from the starting FP.
|
||||
fake_stack = (uhwptr *)((uptr)mapping + ps + sizeof(uhwptr));
|
||||
|
|
|
@ -136,7 +136,7 @@ static void ProtectRange(uptr beg, uptr end) {
|
|||
CHECK_LE(beg, end);
|
||||
if (beg == end)
|
||||
return;
|
||||
if (beg != (uptr)Mprotect(beg, end - beg)) {
|
||||
if (beg != (uptr)MmapNoAccess(beg, end - beg)) {
|
||||
Printf("FATAL: ThreadSanitizer can not protect [%zx,%zx]\n", beg, end);
|
||||
Printf("FATAL: Make sure you are not using unlimited stack\n");
|
||||
Die();
|
||||
|
|
Loading…
Reference in New Issue