Check whether the shadow memory range intersects with an existing mapping.

This should help to detect problems with ASLR or linker tricks early.

llvm-svn: 150391
This commit is contained in:
Alexander Potapenko 2012-02-13 15:11:23 +00:00
parent fe52523b4c
commit ef4521e239
1 changed files with 41 additions and 1 deletions

View File

@ -118,6 +118,42 @@ static void ReserveShadowMemoryRange(uintptr_t beg, uintptr_t end) {
CHECK(res == (void*)beg && "ReserveShadowMemoryRange failed");
}
inline bool IntervalsAreSeparate(uintptr_t start1, uintptr_t end1,
uintptr_t start2, uintptr_t end2) {
CHECK(start1 <= end1);
CHECK(start2 <= end2);
if (start1 == start2) {
return false;
} else {
if (start1 < start2) {
return (end1 < start2);
} else {
return (end2 < start1);
}
}
return false;
}
// FIXME: this is thread-unsafe, but should not cause problems most of the time.
// When the shadow is mapped only a single thread usually exists (plus maybe
// several worker threads on Mac, which aren't expected to map big chunks of
// memory.
bool AsanShadowRangeIsAvailable() {
AsanProcMaps procmaps;
uintptr_t start, end;
bool available = true;
while (procmaps.Next(&start, &end,
/*offset*/NULL, /*filename*/NULL, /*size*/NULL)) {
if (!IntervalsAreSeparate(start, end,
kLowShadowBeg - kMmapGranularity,
kHighShadowEnd)) {
available = false;
break;
}
}
return available;
}
// ---------------------- LowLevelAllocator ------------- {{{1
void *LowLevelAllocator::Allocate(size_t size) {
CHECK((size & (size - 1)) == 0 && "size must be a power of two");
@ -464,7 +500,7 @@ void __asan_init() {
AsanDisableCoreDumper();
}
{
if (AsanShadowRangeIsAvailable()) {
if (kLowShadowBeg != kLowShadowEnd) {
// mmap the low shadow plus at least one page.
ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd);
@ -474,6 +510,10 @@ void __asan_init() {
// protect the gap
void *prot = AsanMprotect(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
CHECK(prot == (void*)kShadowGapBeg);
} else {
Report("Shadow memory range interleaves with an existing memory mapping. "
"ASan cannot proceed correctly. ABORTING.\n");
AsanDie();
}
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited