[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