forked from OSchip/llvm-project
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:
parent
fe52523b4c
commit
ef4521e239
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue