[compiler-rt] r195244 - [msan] Unpoison memory that is returned to the OS and flush its shadow.

Evgeniy Stepanov eugeni.stepanov at gmail.com
Wed Nov 20 04:51:14 PST 2013


Author: eugenis
Date: Wed Nov 20 06:51:14 2013
New Revision: 195244

URL: http://llvm.org/viewvc/llvm-project?rev=195244&view=rev
Log:
[msan] Unpoison memory that is returned to the OS and flush its shadow.

Modified:
    compiler-rt/trunk/lib/msan/msan_allocator.cc
    compiler-rt/trunk/lib/msan/tests/msan_test.cc

Modified: compiler-rt/trunk/lib/msan/msan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_allocator.cc?rev=195244&r1=195243&r2=195244&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_allocator.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_allocator.cc Wed Nov 20 06:51:14 2013
@@ -22,15 +22,29 @@ struct Metadata {
   uptr requested_size;
 };
 
+struct MsanMapUnmapCallback {
+  void OnMap(uptr p, uptr size) const {}
+  void OnUnmap(uptr p, uptr size) const {
+    __msan_unpoison((void *)p, size);
+
+    // We are about to unmap a chunk of user memory.
+    // Mark the corresponding shadow memory as not needed.
+    FlushUnneededShadowMemory(MEM_TO_SHADOW(p), size);
+    if (__msan_get_track_origins())
+      FlushUnneededShadowMemory(MEM_TO_ORIGIN(p), size);
+  }
+};
+
 static const uptr kAllocatorSpace = 0x600000000000ULL;
 static const uptr kAllocatorSize   = 0x80000000000;  // 8T.
 static const uptr kMetadataSize  = sizeof(Metadata);
 static const uptr kMaxAllowedMallocSize = 8UL << 30;
 
 typedef SizeClassAllocator64<kAllocatorSpace, kAllocatorSize, kMetadataSize,
-                             DefaultSizeClassMap> PrimaryAllocator;
+                             DefaultSizeClassMap,
+                             MsanMapUnmapCallback> PrimaryAllocator;
 typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<> SecondaryAllocator;
+typedef LargeMmapAllocator<MsanMapUnmapCallback> SecondaryAllocator;
 typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
                           SecondaryAllocator> Allocator;
 

Modified: compiler-rt/trunk/lib/msan/tests/msan_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/tests/msan_test.cc?rev=195244&r1=195243&r2=195244&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/tests/msan_test.cc (original)
+++ compiler-rt/trunk/lib/msan/tests/msan_test.cc Wed Nov 20 06:51:14 2013
@@ -3571,3 +3571,26 @@ TEST(MemorySanitizer, MlockTest) {
   EXPECT_EQ(0, munlockall());
   EXPECT_EQ(0, munlock((void*)0x987, 0x654));
 }
+
+// Test that LargeAllocator unpoisons memory before releasing it to the OS.
+TEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) {
+  void *p = malloc(1024 * 1024);
+  free(p);
+
+  typedef void *(*mmap_fn)(void *, size_t, int, int, int, off_t);
+  mmap_fn real_mmap = (mmap_fn)dlsym(RTLD_NEXT, "mmap");
+
+  // Allocate the page that was released to the OS in free() with the real mmap,
+  // bypassing the interceptor.
+  char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, 0, 0);
+  ASSERT_NE((char *)0, q);
+
+  ASSERT_TRUE(q <= p);
+  ASSERT_TRUE(q + 4096 > p);
+
+  EXPECT_NOT_POISONED(q[0]);
+  EXPECT_NOT_POISONED(q[10]);
+  EXPECT_NOT_POISONED(q[100]);
+
+  munmap(q, 4096);
+}





More information about the llvm-commits mailing list