[asan] Fix ASan preload issue. 39/130739/27
authorDenis Khalikov <d.khalikov@partner.samsung.com>
Thu, 8 Jun 2017 08:32:02 +0000 (11:32 +0300)
committerDongkyun Son <dongkyun.s@samsung.com>
Tue, 13 Jun 2017 07:10:41 +0000 (07:10 +0000)
There might be a situation when ASan initializing later
than shared library which has malloc in static constructor.
(rtld doesn't provide the order of initiazation)
In this case ASan doesn't initialize interceptors but already
intercepting malloc. If malloc is too big to be handled by static
local pool ASan will die with error:

Sanitizer CHECK failed: libsanitizer/asan/asan_malloc_linux.cc:40
((allocated_for_dlsym)) < ((kDlsymAllocPoolSize)) (1036, 1024)

Backported from LLVM mainline rL305058

Change-Id: I93c9662953629b373506fcacacee43edd791c68f
Signed-off-by: Denis Khalikov <d.khalikov@partner.samsung.com>
libsanitizer/asan/asan_malloc_linux.cc

index bfe72af..24829ef 100644 (file)
@@ -56,30 +56,42 @@ INTERCEPTOR(void, cfree, void *ptr) {
 }
 
 INTERCEPTOR(void*, malloc, uptr size) {
-  if (UNLIKELY(!asan_inited))
+  if (UNLIKELY(asan_init_is_running))
     // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
     return AllocateFromLocalPool(size);
+  ENSURE_ASAN_INITED();
   GET_STACK_TRACE_MALLOC;
   return asan_malloc(size, &stack);
 }
 
 INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
-  if (UNLIKELY(!asan_inited))
+  if (UNLIKELY(asan_init_is_running))
     // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
     return AllocateFromLocalPool(nmemb * size);
+  ENSURE_ASAN_INITED();
   GET_STACK_TRACE_MALLOC;
   return asan_calloc(nmemb, size, &stack);
 }
 
 INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
-  GET_STACK_TRACE_MALLOC;
   if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
-    uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
-    uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
-    void *new_ptr = asan_malloc(size, &stack);
+    const uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
+    const uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
+    void *new_ptr;
+    if (UNLIKELY(asan_init_is_running)) {
+      new_ptr = AllocateFromLocalPool(size);
+    } else {
+      ENSURE_ASAN_INITED();
+      GET_STACK_TRACE_MALLOC;
+      new_ptr = asan_malloc(size, &stack);
+    }
     internal_memcpy(new_ptr, ptr, copy_size);
     return new_ptr;
   }
+  if (UNLIKELY(asan_init_is_running))
+    return AllocateFromLocalPool(size);
+  ENSURE_ASAN_INITED();
+  GET_STACK_TRACE_MALLOC;
   return asan_realloc(ptr, size, &stack);
 }