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:
Timur Iskhodzhanov 2015-04-10 15:02:19 +00:00
parent 3a09ef64ee
commit ea1f332b79
14 changed files with 36 additions and 12 deletions

View File

@ -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. "

View File

@ -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();

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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);

View File

@ -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;

View File

@ -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);
}

View File

@ -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);
}

View File

@ -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) {

View File

@ -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.

View File

@ -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_);

View File

@ -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.

View File

@ -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));

View File

@ -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();