[PATCH] Add ASan hooks to BumpPtrAllocator

Pete Cooper peter_cooper at apple.com
Wed May 13 11:20:36 PDT 2015


BumpPtrAllocator already has MSan hooks to teach the sanitizer about what memory is valid.

This patch adds the equivalent for ASan.  New slabs are initially poisoned then each individual allocation is unopposed.

BumpPtrAllocator has an empty Deallocate method, however, we can use that here to ensure that once a region has been Deallocated, we poison it and don't continue to use it.  A similar change should probably be made for MSan.

Unfortunately this patch can't yet be committed due to a bug found in clang with this applied (https://llvm.org/bugs/show_bug.cgi?id=23516).  I'm putting this up on Phab in case anyone else wants to try it out.  It may also be better to move most of the #ifdefs to Compiler.h where __msan_allocated_memory is currently defined, so i expect to change this patch in future.

http://reviews.llvm.org/D9757

Files:
  include/llvm/Support/Allocator.h

Index: include/llvm/Support/Allocator.h
===================================================================
--- include/llvm/Support/Allocator.h
+++ include/llvm/Support/Allocator.h
@@ -31,6 +31,10 @@
 #include <cstddef>
 #include <cstdlib>
 
+#if LLVM_ADDRESS_SANITIZER_BUILD
+#include <sanitizer/asan_interface.h>
+#endif
+
 namespace llvm {
 
 /// \brief CRTP base class providing obvious overloads for the core \c
@@ -221,19 +225,33 @@
       // Without this, MemorySanitizer messages for values originated from here
       // will point to the allocation of the entire slab.
       __msan_allocated_memory(AlignedPtr, Size);
+      // Similarly, tell ASan about this space.
+#if LLVM_ADDRESS_SANITIZER_BUILD
+      ASAN_UNPOISON_MEMORY_REGION(AlignedPtr, Size);
+#endif
       return AlignedPtr;
     }
 
     // If Size is really big, allocate a separate slab for it.
     size_t PaddedSize = Size + Alignment - 1;
     if (PaddedSize > SizeThreshold) {
       void *NewSlab = Allocator.Allocate(PaddedSize, 0);
+
+      // We own the new slab and don't want anyone reading anyting other than
+      // pieces returned from this method.  So poison the whole slab.
+#if LLVM_ADDRESS_SANITIZER_BUILD
+      ASAN_POISON_MEMORY_REGION(NewSlab, PaddedSize);
+#endif
       CustomSizedSlabs.push_back(std::make_pair(NewSlab, PaddedSize));
 
       uintptr_t AlignedAddr = alignAddr(NewSlab, Alignment);
       assert(AlignedAddr + Size <= (uintptr_t)NewSlab + PaddedSize);
       char *AlignedPtr = (char*)AlignedAddr;
       __msan_allocated_memory(AlignedPtr, Size);
+      // Tell ASan about this space.
+#if LLVM_ADDRESS_SANITIZER_BUILD
+      ASAN_UNPOISON_MEMORY_REGION(AlignedPtr, Size);
+#endif
       return AlignedPtr;
     }
 
@@ -245,13 +263,23 @@
     char *AlignedPtr = (char*)AlignedAddr;
     CurPtr = AlignedPtr + Size;
     __msan_allocated_memory(AlignedPtr, Size);
+    // Similarly, tell ASan about this space.
+#if LLVM_ADDRESS_SANITIZER_BUILD
+    ASAN_UNPOISON_MEMORY_REGION(AlignedPtr, Size);
+#endif
     return AlignedPtr;
   }
 
   // Pull in base class overloads.
   using AllocatorBase<BumpPtrAllocatorImpl>::Allocate;
 
-  void Deallocate(const void * /*Ptr*/, size_t /*Size*/) {}
+  void Deallocate(const void * Ptr, size_t Size) {
+    // For speed reasons we don't want the BumpPtrAllocator itself to
+    //
+#if LLVM_ADDRESS_SANITIZER_BUILD
+    ASAN_POISON_MEMORY_REGION(Ptr, Size);
+#endif
+  }
 
   // Pull in base class overloads.
   using AllocatorBase<BumpPtrAllocatorImpl>::Deallocate;
@@ -309,6 +337,13 @@
     size_t AllocatedSlabSize = computeSlabSize(Slabs.size());
 
     void *NewSlab = Allocator.Allocate(AllocatedSlabSize, 0);
+
+    // We own the new slab and don't want anyone reading anyting other than
+    // pieces returned from this method.  So poison the whole slab.
+#if LLVM_ADDRESS_SANITIZER_BUILD
+    ASAN_POISON_MEMORY_REGION(NewSlab, AllocatedSlabSize);
+#endif
+
     Slabs.push_back(NewSlab);
     CurPtr = (char *)(NewSlab);
     End = ((char *)NewSlab) + AllocatedSlabSize;

EMAIL PREFERENCES
  http://reviews.llvm.org/settings/panel/emailpreferences/
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D9757.25716.patch
Type: text/x-patch
Size: 3044 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20150513/991d3109/attachment.bin>


More information about the llvm-commits mailing list