[llvm-commits] [compiler-rt] r150391 - /compiler-rt/trunk/lib/asan/asan_rtl.cc
Alexander Potapenko
glider at google.com
Mon Feb 13 07:11:23 PST 2012
Author: glider
Date: Mon Feb 13 09:11:23 2012
New Revision: 150391
URL: http://llvm.org/viewvc/llvm-project?rev=150391&view=rev
Log:
Check whether the shadow memory range intersects with an existing mapping.
This should help to detect problems with ASLR or linker tricks early.
Modified:
compiler-rt/trunk/lib/asan/asan_rtl.cc
Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=150391&r1=150390&r2=150391&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Mon Feb 13 09:11:23 2012
@@ -118,6 +118,42 @@
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 @@
AsanDisableCoreDumper();
}
- {
+ if (AsanShadowRangeIsAvailable()) {
if (kLowShadowBeg != kLowShadowEnd) {
// mmap the low shadow plus at least one page.
ReserveShadowMemoryRange(kLowShadowBeg - kMmapGranularity, kLowShadowEnd);
@@ -474,6 +510,10 @@
// 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
More information about the llvm-commits
mailing list