[compiler-rt] r178757 - [asan] fill first 4K of malloc-ed memory with garbage, implement flags max_malloc_fill_size and malloc_fill_byte

Kostya Serebryany kcc at google.com
Thu Apr 4 04:17:14 PDT 2013


Author: kcc
Date: Thu Apr  4 06:17:14 2013
New Revision: 178757

URL: http://llvm.org/viewvc/llvm-project?rev=178757&view=rev
Log:
[asan] fill first 4K of malloc-ed memory with garbage, implement flags max_malloc_fill_size and malloc_fill_byte

Added:
    compiler-rt/trunk/lib/asan/lit_tests/malloc_fill.cc
Modified:
    compiler-rt/trunk/lib/asan/asan_allocator2.cc
    compiler-rt/trunk/lib/asan/asan_flags.h
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/lit_tests/use-after-poison.cc

Modified: compiler-rt/trunk/lib/asan/asan_allocator2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator2.cc?rev=178757&r1=178756&r2=178757&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Thu Apr  4 06:17:14 2013
@@ -298,9 +298,10 @@ void InitializeAllocator() {
 }
 
 static void *Allocate(uptr size, uptr alignment, StackTrace *stack,
-                      AllocType alloc_type) {
+                      AllocType alloc_type, bool can_fill) {
   if (!asan_inited)
     __asan_init();
+  Flags &fl = *flags();
   CHECK(stack);
   const uptr min_alignment = SHADOW_GRANULARITY;
   if (alignment < min_alignment)
@@ -384,7 +385,7 @@ static void *Allocate(uptr size, uptr al
     meta[1] = chunk_beg;
   }
 
-  if (flags()->use_stack_depot) {
+  if (fl.use_stack_depot) {
     m->alloc_context_id = StackDepotPut(stack->trace, stack->size);
   } else {
     m->alloc_context_id = 0;
@@ -396,7 +397,7 @@ static void *Allocate(uptr size, uptr al
   if (size_rounded_down_to_granularity)
     PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);
   // Deal with the end of the region if size is not aligned to granularity.
-  if (size != size_rounded_down_to_granularity && flags()->poison_heap) {
+  if (size != size_rounded_down_to_granularity && fl.poison_heap) {
     u8 *shadow = (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity);
     *shadow = size & (SHADOW_GRANULARITY - 1);
   }
@@ -411,6 +412,10 @@ static void *Allocate(uptr size, uptr al
     thread_stats.malloc_large++;
 
   void *res = reinterpret_cast<void *>(user_beg);
+  if (can_fill && fl.max_malloc_fill_size) {
+    uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size);
+    REAL(memset)(res, fl.malloc_fill_byte, fill_size);
+  }
   ASAN_MALLOC_HOOK(res, size);
   return res;
 }
@@ -485,7 +490,7 @@ static void *Reallocate(void *old_ptr, u
   CHECK(m->chunk_state == CHUNK_ALLOCATED);
   uptr old_size = m->UsedSize();
   uptr memcpy_size = Min(new_size, old_size);
-  void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC);
+  void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC, true);
   if (new_ptr) {
     CHECK_NE(REAL(memcpy), (void*)0);
     REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
@@ -590,7 +595,7 @@ void PrintInternalAllocatorStats() {
 SANITIZER_INTERFACE_ATTRIBUTE
 void *asan_memalign(uptr alignment, uptr size, StackTrace *stack,
                     AllocType alloc_type) {
-  return Allocate(size, alignment, stack, alloc_type);
+  return Allocate(size, alignment, stack, alloc_type, true);
 }
 
 SANITIZER_INTERFACE_ATTRIBUTE
@@ -600,12 +605,12 @@ void asan_free(void *ptr, StackTrace *st
 
 SANITIZER_INTERFACE_ATTRIBUTE
 void *asan_malloc(uptr size, StackTrace *stack) {
-  return Allocate(size, 8, stack, FROM_MALLOC);
+  return Allocate(size, 8, stack, FROM_MALLOC, true);
 }
 
 void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
   if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0;
-  void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC);
+  void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false);
   // If the memory comes from the secondary allocator no need to clear it
   // as it comes directly from mmap.
   if (ptr && allocator.FromPrimary(ptr))
@@ -615,7 +620,7 @@ void *asan_calloc(uptr nmemb, uptr size,
 
 void *asan_realloc(void *p, uptr size, StackTrace *stack) {
   if (p == 0)
-    return Allocate(size, 8, stack, FROM_MALLOC);
+    return Allocate(size, 8, stack, FROM_MALLOC, true);
   if (size == 0) {
     Deallocate(p, stack, FROM_MALLOC);
     return 0;
@@ -624,7 +629,7 @@ void *asan_realloc(void *p, uptr size, S
 }
 
 void *asan_valloc(uptr size, StackTrace *stack) {
-  return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC);
+  return Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC, true);
 }
 
 void *asan_pvalloc(uptr size, StackTrace *stack) {
@@ -634,12 +639,12 @@ void *asan_pvalloc(uptr size, StackTrace
     // pvalloc(0) should allocate one page.
     size = PageSize;
   }
-  return Allocate(size, PageSize, stack, FROM_MALLOC);
+  return Allocate(size, PageSize, stack, FROM_MALLOC, true);
 }
 
 int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
                         StackTrace *stack) {
-  void *ptr = Allocate(size, alignment, stack, FROM_MALLOC);
+  void *ptr = Allocate(size, alignment, stack, FROM_MALLOC, true);
   CHECK(IsAligned((uptr)ptr, alignment));
   *memptr = ptr;
   return 0;

Modified: compiler-rt/trunk/lib/asan/asan_flags.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_flags.h?rev=178757&r1=178756&r2=178757&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Thu Apr  4 06:17:14 2013
@@ -58,9 +58,9 @@ struct Flags {
   bool mac_ignore_invalid_free;
   // ASan allocator flag. See asan_allocator.cc.
   bool use_fake_stack;
-  // ASan allocator flag. Sets the maximal size of allocation request
-  // that would return memory filled with zero bytes.
-  int  max_malloc_fill_size;
+  // ASan allocator flag. max_malloc_fill_size is the maximal amount of bytes
+  // that will be filled with malloc_fill_byte on malloc.
+  int max_malloc_fill_size, malloc_fill_byte;
   // Override exit status if something was reported.
   int  exitcode;
   // If set, user may manually mark memory regions as poisoned or unpoisoned.

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=178757&r1=178756&r2=178757&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Apr  4 06:17:14 2013
@@ -106,6 +106,7 @@ static void ParseFlagsFromString(Flags *
   ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free");
   ParseFlag(str, &f->use_fake_stack, "use_fake_stack");
   ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size");
+  ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte");
   ParseFlag(str, &f->exitcode, "exitcode");
   ParseFlag(str, &f->allow_user_poisoning, "allow_user_poisoning");
   ParseFlag(str, &f->sleep_before_dying, "sleep_before_dying");
@@ -147,7 +148,8 @@ void InitializeFlags(Flags *f, const cha
   f->replace_intrin = true;
   f->mac_ignore_invalid_free = false;
   f->use_fake_stack = true;
-  f->max_malloc_fill_size = 0;
+  f->max_malloc_fill_size = 0x1000;  // By default, fill only the first 4K.
+  f->malloc_fill_byte = 0xbe;
   f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE;
   f->allow_user_poisoning = true;
   f->sleep_before_dying = 0;

Added: compiler-rt/trunk/lib/asan/lit_tests/malloc_fill.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/malloc_fill.cc?rev=178757&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/malloc_fill.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/malloc_fill.cc Thu Apr  4 06:17:14 2013
@@ -0,0 +1,22 @@
+// Check that we fill malloc-ed memory correctly.
+// RUN: %clangxx_asan -m64 %s -o %t
+// RUN: %t | FileCheck %s
+// RUN: ASAN_OPTIONS=max_malloc_fill_size=10:malloc_fill_byte=8 %t | FileCheck %s --check-prefix=CHECK-10-8
+// RUN: ASAN_OPTIONS=max_malloc_fill_size=20:malloc_fill_byte=171 %t | FileCheck %s --check-prefix=CHECK-20-ab
+
+#include <stdio.h>
+int main(int argc, char **argv) {
+  // With asan allocator this makes sure we get memory from mmap.
+  static const int kSize = 1 << 25;
+  unsigned char *x = new unsigned char[kSize];
+  printf("-");
+  for (int i = 0; i <= 32; i++) {
+    printf("%02x", x[i]);
+  }
+  printf("-\n");
+  delete [] x;
+}
+
+// CHECK: -bebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebebe-
+// CHECK-10-8: -080808080808080808080000000000000000000000000000000000000000000000-
+// CHECK-20-ab: -abababababababababababababababababababab00000000000000000000000000-

Modified: compiler-rt/trunk/lib/asan/lit_tests/use-after-poison.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/use-after-poison.cc?rev=178757&r1=178756&r2=178757&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/use-after-poison.cc (original)
+++ compiler-rt/trunk/lib/asan/lit_tests/use-after-poison.cc Thu Apr  4 06:17:14 2013
@@ -10,6 +10,7 @@ extern "C" void __asan_poison_memory_reg
 
 int main(int argc, char **argv) {
   char *x = new char[16];
+  x[10] = 0;
   __asan_poison_memory_region(x, 16);
   int res = x[argc * 10];  // BOOOM
   // CHECK: ERROR: AddressSanitizer: use-after-poison





More information about the llvm-commits mailing list