[compiler-rt] r199377 - [asan] Implement delayed activation of AddressSanitizer

Evgeniy Stepanov eugeni.stepanov at gmail.com
Thu Jan 16 04:31:50 PST 2014


Author: eugenis
Date: Thu Jan 16 06:31:50 2014
New Revision: 199377

URL: http://llvm.org/viewvc/llvm-project?rev=199377&view=rev
Log:
[asan] Implement delayed activation of AddressSanitizer

This change adds ASAN_OPTIONS=start_deactivated=1 flag. When present, ASan will
start in "deactivated" mode, with no heap poisoning, no quarantine, no stack
trace gathering, and minimal redzones. All this features come back when
__asan_init is called for the constructor of an instrumented library.

The primary use case for this feature is Android. Code itself is not
Android-specific, and this patch includes a Linux test for it.


Added:
    compiler-rt/trunk/lib/asan/asan_activation.cc   (with props)
    compiler-rt/trunk/lib/asan/asan_activation.h   (with props)
    compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc   (with props)
    compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc   (with props)
Modified:
    compiler-rt/trunk/lib/asan/CMakeLists.txt
    compiler-rt/trunk/lib/asan/asan_allocator2.cc
    compiler-rt/trunk/lib/asan/asan_flags.h
    compiler-rt/trunk/lib/asan/asan_interceptors.cc
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_malloc_mac.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc

Modified: compiler-rt/trunk/lib/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/CMakeLists.txt?rev=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/CMakeLists.txt Thu Jan 16 06:31:50 2014
@@ -2,6 +2,7 @@
 
 set(ASAN_SOURCES
   asan_allocator2.cc
+  asan_activation.cc
   asan_fake_stack.cc
   asan_globals.cc
   asan_interceptors.cc

Added: compiler-rt/trunk/lib/asan/asan_activation.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.cc?rev=199377&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_activation.cc (added)
+++ compiler-rt/trunk/lib/asan/asan_activation.cc Thu Jan 16 06:31:50 2014
@@ -0,0 +1,69 @@
+//===-- asan_activation.cc --------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// ASan activation/deactivation logic.
+//===----------------------------------------------------------------------===//
+
+#include "asan_activation.h"
+#include "asan_flags.h"
+#include "asan_internal.h"
+#include "sanitizer_common/sanitizer_flags.h"
+
+namespace __asan {
+
+static struct AsanDeactivatedFlags {
+  int quarantine_size;
+  int max_redzone;
+  int poison_heap;
+  int malloc_context_size;
+} asan_deactivated_flags;
+
+static bool asan_is_deactivated;
+
+void AsanStartDeactivated() {
+  VReport(1, "Deactivating asan\n");
+  // Save flag values.
+  asan_deactivated_flags.quarantine_size = flags()->quarantine_size;
+  asan_deactivated_flags.max_redzone = flags()->max_redzone;
+  asan_deactivated_flags.poison_heap = flags()->poison_heap;
+  asan_deactivated_flags.malloc_context_size =
+      common_flags()->malloc_context_size;
+
+  flags()->quarantine_size = 0;
+  flags()->max_redzone = 16;
+  flags()->poison_heap = false;
+  common_flags()->malloc_context_size = 0;
+
+  asan_is_deactivated = true;
+}
+
+void AsanActivate() {
+  if (!asan_is_deactivated) return;
+  VReport(1, "Activating asan\n");
+
+  // Restore flag values.
+  // FIXME: this is not atomic, and there may be other threads alive.
+  flags()->quarantine_size = asan_deactivated_flags.quarantine_size;
+  flags()->max_redzone = asan_deactivated_flags.max_redzone;
+  flags()->poison_heap = asan_deactivated_flags.poison_heap;
+  common_flags()->malloc_context_size =
+      asan_deactivated_flags.malloc_context_size;
+
+  asan_is_deactivated = false;
+  VReport(
+      1,
+      "quarantine_size %d, max_redzone %d, poison_heap %d, malloc_context_size "
+      "%d\n",
+      flags()->quarantine_size, flags()->max_redzone, flags()->poison_heap,
+      common_flags()->malloc_context_size);
+}
+
+} // namespace __asan

Propchange: compiler-rt/trunk/lib/asan/asan_activation.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: compiler-rt/trunk/lib/asan/asan_activation.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_activation.h?rev=199377&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_activation.h (added)
+++ compiler-rt/trunk/lib/asan/asan_activation.h Thu Jan 16 06:31:50 2014
@@ -0,0 +1,23 @@
+//===-- asan_activation.h ---------------------------------------*- C++ -*-===//
+//
+//                     The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// This file is a part of AddressSanitizer, an address sanity checker.
+//
+// ASan activation/deactivation logic.
+//===----------------------------------------------------------------------===//
+
+#ifndef ASAN_ACTIVATION_H
+#define ASAN_ACTIVATION_H
+
+namespace __asan {
+void AsanStartDeactivated();
+void AsanActivate();
+} // namespace __asan
+
+#endif // ASAN_ACTIVATION_H

Propchange: compiler-rt/trunk/lib/asan/asan_activation.h
------------------------------------------------------------------------------
    svn:eol-style = LF

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=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator2.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator2.cc Thu Jan 16 06:31:50 2014
@@ -312,7 +312,7 @@ void InitializeAllocator() {
 static void *Allocate(uptr size, uptr alignment, StackTrace *stack,
                       AllocType alloc_type, bool can_fill) {
   if (!asan_inited)
-    __asan_init();
+    AsanInitFromRtl();
   Flags &fl = *flags();
   CHECK(stack);
   const uptr min_alignment = SHADOW_GRANULARITY;
@@ -357,6 +357,16 @@ static void *Allocate(uptr size, uptr al
     AllocatorCache *cache = &fallback_allocator_cache;
     allocated = allocator.Allocate(cache, needed_size, 8, false);
   }
+
+  if (*(u8 *)MEM_TO_SHADOW((u64)allocated) == 0 && flags()->poison_heap) {
+    // Heap poisoning is enabled, but the allocator provides an unpoisoned
+    // chunk. This is possible if flags()->poison_heap was disabled for some
+    // time, for example, due to flags()->start_disabled.
+    // Anyway, poison the block before using it for anything else.
+    uptr allocated_size = allocator.GetActuallyAllocatedSize(allocated);
+    PoisonShadow((uptr)allocated, allocated_size, kAsanHeapLeftRedzoneMagic);
+  }
+
   uptr alloc_beg = reinterpret_cast<uptr>(allocated);
   uptr alloc_end = alloc_beg + needed_size;
   uptr beg_plus_redzone = alloc_beg + rz_size;

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=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_flags.h (original)
+++ compiler-rt/trunk/lib/asan/asan_flags.h Thu Jan 16 06:31:50 2014
@@ -115,6 +115,11 @@ struct Flags {
   // If true, assume that dynamic initializers can never access globals from
   // other modules, even if the latter are already initialized.
   bool strict_init_order;
+  // If true, ASan tweaks a bunch of other flags (quarantine, redzone, heap
+  // poisoning) to reduce memory consumption as much as possible, and restores
+  // them to original values when the first instrumented module is loaded into
+  // the process. This is mainly intended to be used on Android.
+  bool start_deactivated;
 };
 
 extern Flags asan_flags_dont_use_directly;

Modified: compiler-rt/trunk/lib/asan/asan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_interceptors.cc?rev=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_interceptors.cc Thu Jan 16 06:31:50 2014
@@ -73,7 +73,7 @@ static inline bool RangesOverlap(const c
 #define ENSURE_ASAN_INITED() do { \
   CHECK(!asan_init_is_running); \
   if (!asan_inited) { \
-    __asan_init(); \
+    AsanInitFromRtl(); \
   } \
 } while (0)
 

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Thu Jan 16 06:31:50 2014
@@ -67,6 +67,8 @@ namespace __asan {
 class AsanThread;
 using __sanitizer::StackTrace;
 
+void AsanInitFromRtl();
+
 // asan_rtl.cc
 void NORETURN ShowStatsAndAbort();
 

Modified: compiler-rt/trunk/lib/asan/asan_malloc_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_mac.cc?rev=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_mac.cc Thu Jan 16 06:31:50 2014
@@ -41,7 +41,7 @@ static malloc_zone_t asan_zone;
 
 INTERCEPTOR(malloc_zone_t *, malloc_create_zone,
                              vm_size_t start_size, unsigned zone_flags) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   GET_STACK_TRACE_MALLOC;
   uptr page_size = GetPageSizeCached();
   uptr allocated_size = RoundUpTo(sizeof(asan_zone), page_size);
@@ -60,34 +60,34 @@ INTERCEPTOR(malloc_zone_t *, malloc_crea
 }
 
 INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   return &asan_zone;
 }
 
 INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) {
   // FIXME: ASan should support purgeable allocations.
   // https://code.google.com/p/address-sanitizer/issues/detail?id=139
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   return &asan_zone;
 }
 
 INTERCEPTOR(void, malloc_make_purgeable, void *ptr) {
   // FIXME: ASan should support purgeable allocations. Ignoring them is fine
   // for now.
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
 }
 
 INTERCEPTOR(int, malloc_make_nonpurgeable, void *ptr) {
   // FIXME: ASan should support purgeable allocations. Ignoring them is fine
   // for now.
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   // Must return 0 if the contents were not purged since the last call to
   // malloc_make_purgeable().
   return 0;
 }
 
 INTERCEPTOR(void, malloc_set_zone_name, malloc_zone_t *zone, const char *name) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   // Allocate |strlen("asan-") + 1 + internal_strlen(name)| bytes.
   size_t buflen = 6 + (name ? internal_strlen(name) : 0);
   InternalScopedBuffer<char> new_name(buflen);
@@ -102,44 +102,44 @@ INTERCEPTOR(void, malloc_set_zone_name,
 }
 
 INTERCEPTOR(void *, malloc, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   GET_STACK_TRACE_MALLOC;
   void *res = asan_malloc(size, &stack);
   return res;
 }
 
 INTERCEPTOR(void, free, void *ptr) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   if (!ptr) return;
   GET_STACK_TRACE_FREE;
   asan_free(ptr, &stack, FROM_MALLOC);
 }
 
 INTERCEPTOR(void *, realloc, void *ptr, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   GET_STACK_TRACE_MALLOC;
   return asan_realloc(ptr, size, &stack);
 }
 
 INTERCEPTOR(void *, calloc, size_t nmemb, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   GET_STACK_TRACE_MALLOC;
   return asan_calloc(nmemb, size, &stack);
 }
 
 INTERCEPTOR(void *, valloc, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   GET_STACK_TRACE_MALLOC;
   return asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
 }
 
 INTERCEPTOR(size_t, malloc_good_size, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   return asan_zone.introspect->good_size(&asan_zone, size);
 }
 
 INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) {
-  if (!asan_inited) __asan_init();
+  if (!asan_inited) AsanInitFromRtl();
   CHECK(memptr);
   GET_STACK_TRACE_MALLOC;
   void *result = asan_memalign(alignment, size, &stack, FROM_MALLOC);

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=199377&r1=199376&r2=199377&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Thu Jan 16 06:31:50 2014
@@ -11,6 +11,7 @@
 //
 // Main file of the ASan run-time library.
 //===----------------------------------------------------------------------===//
+#include "asan_activation.h"
 #include "asan_allocator.h"
 #include "asan_interceptors.h"
 #include "asan_interface_internal.h"
@@ -138,6 +139,7 @@ static void ParseFlagsFromString(Flags *
   ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch");
   ParseFlag(str, &f->strict_memcmp, "strict_memcmp");
   ParseFlag(str, &f->strict_init_order, "strict_init_order");
+  ParseFlag(str, &f->start_deactivated, "start_deactivated");
 }
 
 void InitializeFlags(Flags *f, const char *env) {
@@ -185,6 +187,7 @@ void InitializeFlags(Flags *f, const cha
   f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0);
   f->strict_memcmp = true;
   f->strict_init_order = false;
+  f->start_deactivated = false;
 
   // Override from compile definition.
   ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton());
@@ -397,55 +400,7 @@ static void PrintAddressSpaceLayout() {
           kHighShadowBeg > kMidMemEnd);
 }
 
-}  // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan;  // NOLINT
-
-#if !SANITIZER_SUPPORTS_WEAK_HOOKS
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
-const char* __asan_default_options() { return ""; }
-}  // extern "C"
-#endif
-
-int NOINLINE __asan_set_error_exit_code(int exit_code) {
-  int old = flags()->exitcode;
-  flags()->exitcode = exit_code;
-  return old;
-}
-
-void NOINLINE __asan_handle_no_return() {
-  int local_stack;
-  AsanThread *curr_thread = GetCurrentThread();
-  CHECK(curr_thread);
-  uptr PageSize = GetPageSizeCached();
-  uptr top = curr_thread->stack_top();
-  uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
-  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
-  if (top - bottom > kMaxExpectedCleanupSize) {
-    static bool reported_warning = false;
-    if (reported_warning)
-      return;
-    reported_warning = true;
-    Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
-           "stack top: %p; bottom %p; size: %p (%zd)\n"
-           "False positive error reports may follow\n"
-           "For details see "
-           "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
-           top, bottom, top - bottom, top - bottom);
-    return;
-  }
-  PoisonShadow(bottom, top - bottom, 0);
-  if (curr_thread->has_fake_stack())
-    curr_thread->fake_stack()->HandleNoReturn();
-}
-
-void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
-  death_callback = callback;
-}
-
-void __asan_init() {
+static void AsanInitInternal() {
   if (asan_inited) return;
   SanitizerToolName = "AddressSanitizer";
   CHECK(!asan_init_is_running && "ASan init calls itself!");
@@ -473,6 +428,9 @@ void __asan_init() {
     VReport(1, "Parsed ASAN_OPTIONS: %s\n", options);
   }
 
+  if (flags()->start_deactivated)
+    AsanStartDeactivated();
+
   // Re-exec ourselves if we need to set additional env or command line args.
   MaybeReexec();
 
@@ -575,3 +533,64 @@ void __asan_init() {
 
   VReport(1, "AddressSanitizer Init done\n");
 }
+
+// Initialize as requested from some part of ASan runtime library (interceptors,
+// allocator, etc).
+void AsanInitFromRtl() {
+  AsanInitInternal();
+}
+
+}  // namespace __asan
+
+// ---------------------- Interface ---------------- {{{1
+using namespace __asan;  // NOLINT
+
+#if !SANITIZER_SUPPORTS_WEAK_HOOKS
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
+const char* __asan_default_options() { return ""; }
+}  // extern "C"
+#endif
+
+int NOINLINE __asan_set_error_exit_code(int exit_code) {
+  int old = flags()->exitcode;
+  flags()->exitcode = exit_code;
+  return old;
+}
+
+void NOINLINE __asan_handle_no_return() {
+  int local_stack;
+  AsanThread *curr_thread = GetCurrentThread();
+  CHECK(curr_thread);
+  uptr PageSize = GetPageSizeCached();
+  uptr top = curr_thread->stack_top();
+  uptr bottom = ((uptr)&local_stack - PageSize) & ~(PageSize-1);
+  static const uptr kMaxExpectedCleanupSize = 64 << 20;  // 64M
+  if (top - bottom > kMaxExpectedCleanupSize) {
+    static bool reported_warning = false;
+    if (reported_warning)
+      return;
+    reported_warning = true;
+    Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
+           "stack top: %p; bottom %p; size: %p (%zd)\n"
+           "False positive error reports may follow\n"
+           "For details see "
+           "http://code.google.com/p/address-sanitizer/issues/detail?id=189\n",
+           top, bottom, top - bottom, top - bottom);
+    return;
+  }
+  PoisonShadow(bottom, top - bottom, 0);
+  if (curr_thread->has_fake_stack())
+    curr_thread->fake_stack()->HandleNoReturn();
+}
+
+void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
+  death_callback = callback;
+}
+
+// Initialize as requested from instrumented application code.
+// We use this call as a trigger to wake up ASan from deactivated state.
+void __asan_init() {
+  AsanActivate();
+  AsanInitInternal();
+}

Added: compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc?rev=199377&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc Thu Jan 16 06:31:50 2014
@@ -0,0 +1,7 @@
+#include <stdio.h>
+#include <stdlib.h>
+
+extern "C" void do_another_bad_thing() {
+  char *volatile p = (char *)malloc(100);
+  printf("%hhx\n", p[105]);
+}

Propchange: compiler-rt/trunk/lib/asan/lit_tests/TestCases/SharedLibs/start-deactivated-so.cc
------------------------------------------------------------------------------
    svn:eol-style = LF

Added: compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc?rev=199377&view=auto
==============================================================================
--- compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc (added)
+++ compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc Thu Jan 16 06:31:50 2014
@@ -0,0 +1,58 @@
+// Test for ASAN_OPTIONS=start_deactivated=1 mode.
+// Main executable is uninstrumented, but linked to ASan runtime. The shared
+// library is instrumented. Memory errors before dlopen are not detected.
+
+// RUN: %clangxx_asan -O0 %p/SharedLibs/start-deactivated-so.cc \
+// RUN:     -fPIC -shared -o %t-so.so
+// RUN: %clangxx -O0 %s -c -o %t.o
+// RUN: %clangxx_asan -O0 %t.o -o %t
+// RUN: ASAN_OPTIONS=start_deactivated=1 not %t 2>&1 | FileCheck %s
+
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+#include <string>
+
+#include "sanitizer/asan_interface.h"
+
+void test_malloc_shadow() {
+  char *p = (char *)malloc(100);
+  char *q = (char *)__asan_region_is_poisoned(p + 95, 8);
+  fprintf(stderr, "=%zd=\n", q ? q - (p + 95) : -1);
+  free(p);
+}
+
+typedef void (*Fn)();
+
+int main(int argc, char *argv[]) {
+  test_malloc_shadow();
+  // CHECK: =-1=
+
+  std::string path = std::string(argv[0]) + "-so.so";
+  void *dso = dlopen(path.c_str(), RTLD_NOW);
+  if (!dso) {
+    fprintf(stderr, "dlopen failed: %s\n", dlerror());
+    return 1;
+  }
+
+  test_malloc_shadow();
+  // CHECK: =5=
+
+  void *fn = dlsym(dso, "do_another_bad_thing");
+  if (!fn) {
+    fprintf(stderr, "dlsym failed: %s\n", dlerror());
+    return 1;
+  }
+
+  ((Fn)fn)();
+  // CHECK: AddressSanitizer: heap-buffer-overflow
+  // CHECK: READ of size 1
+  // CHECK: {{#0 .* in do_another_bad_thing}}
+  // CHECK: is located 5 bytes to the right of 100-byte region
+  // CHECK: in do_another_bad_thing
+
+  return 0;
+}

Propchange: compiler-rt/trunk/lib/asan/lit_tests/TestCases/start-deactivated.cc
------------------------------------------------------------------------------
    svn:eol-style = LF





More information about the llvm-commits mailing list