[compiler-rt] 13e0460 - [asan] Provide an interface to update an allocation stack trace.

Evgenii Stepanov via llvm-commits llvm-commits at lists.llvm.org
Thu Oct 31 13:55:08 PDT 2019


Author: Evgenii Stepanov
Date: 2019-10-31T13:54:46-07:00
New Revision: 13e04607f75bdf0e4de08b6f240501c15e8891f1

URL: https://github.com/llvm/llvm-project/commit/13e04607f75bdf0e4de08b6f240501c15e8891f1
DIFF: https://github.com/llvm/llvm-project/commit/13e04607f75bdf0e4de08b6f240501c15e8891f1.diff

LOG: [asan] Provide an interface to update an allocation stack trace.

Summary:
Sometimes an allocation stack trace is not very informative. Provide a
way to replace it with a stack trace of the user's choice.

Reviewers: pcc, kcc

Subscribers: #sanitizers, llvm-commits

Tags: #sanitizers, #llvm

Differential Revision: https://reviews.llvm.org/D69208

Added: 
    compiler-rt/test/asan/TestCases/asan_update_allocation.cpp

Modified: 
    compiler-rt/include/sanitizer/asan_interface.h
    compiler-rt/lib/asan/asan_allocator.cpp
    compiler-rt/lib/asan/asan_interface.inc
    compiler-rt/lib/asan/asan_interface_internal.h

Removed: 
    


################################################################################
diff  --git a/compiler-rt/include/sanitizer/asan_interface.h b/compiler-rt/include/sanitizer/asan_interface.h
index ab2dc97ed24a..6af93aad6512 100644
--- a/compiler-rt/include/sanitizer/asan_interface.h
+++ b/compiler-rt/include/sanitizer/asan_interface.h
@@ -315,6 +315,10 @@ void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
 /// functions like <c>_exit()</c> and <c>execl()</c>.
 void __asan_handle_no_return(void);
 
+/// Update allocation stack trace for the given allocation to the current stack
+/// trace. Returns 1 if successfull, 0 if not.
+int __asan_update_allocation_context(void* addr);
+
 #ifdef __cplusplus
 }  // extern "C"
 #endif

diff  --git a/compiler-rt/lib/asan/asan_allocator.cpp b/compiler-rt/lib/asan/asan_allocator.cpp
index dd78247f5a47..65c51fbafdd0 100644
--- a/compiler-rt/lib/asan/asan_allocator.cpp
+++ b/compiler-rt/lib/asan/asan_allocator.cpp
@@ -399,6 +399,16 @@ struct Allocator {
     return right_chunk;
   }
 
+  bool UpdateAllocationStack(uptr addr, BufferedStackTrace *stack) {
+    AsanChunk *m = GetAsanChunkByAddr(addr);
+    if (!m) return false;
+    if (m->chunk_state != CHUNK_ALLOCATED) return false;
+    if (m->Beg() != addr) return false;
+    atomic_store((atomic_uint32_t *)&m->alloc_context_id, StackDepotPut(*stack),
+                 memory_order_relaxed);
+    return true;
+  }
+
   // -------------------- Allocation/Deallocation routines ---------------
   void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
                  AllocType alloc_type, bool can_fill) {
@@ -1112,6 +1122,11 @@ void __sanitizer_purge_allocator() {
   instance.Purge(&stack);
 }
 
+int __asan_update_allocation_context(void* addr) {
+  GET_STACK_TRACE_MALLOC;
+  return instance.UpdateAllocationStack((uptr)addr, &stack);
+}
+
 #if !SANITIZER_SUPPORTS_WEAK_HOOKS
 // Provide default (no-op) implementation of malloc hooks.
 SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook,

diff  --git a/compiler-rt/lib/asan/asan_interface.inc b/compiler-rt/lib/asan/asan_interface.inc
index 7c341f22e15f..948010439827 100644
--- a/compiler-rt/lib/asan/asan_interface.inc
+++ b/compiler-rt/lib/asan/asan_interface.inc
@@ -164,6 +164,7 @@ INTERFACE_FUNCTION(__sanitizer_unaligned_load64)
 INTERFACE_FUNCTION(__sanitizer_unaligned_store16)
 INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
 INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
+INTERFACE_FUNCTION(__asan_update_allocation_context)
 INTERFACE_WEAK_FUNCTION(__asan_default_options)
 INTERFACE_WEAK_FUNCTION(__asan_default_suppressions)
 INTERFACE_WEAK_FUNCTION(__asan_on_error)

diff  --git a/compiler-rt/lib/asan/asan_interface_internal.h b/compiler-rt/lib/asan/asan_interface_internal.h
index c83aa11d741a..a152e178c305 100644
--- a/compiler-rt/lib/asan/asan_interface_internal.h
+++ b/compiler-rt/lib/asan/asan_interface_internal.h
@@ -251,6 +251,8 @@ extern "C" {
   const char* __asan_default_suppressions();
 
   SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp);
+
+  SANITIZER_INTERFACE_ATTRIBUTE int __asan_update_allocation_context(void* addr);
 }  // extern "C"
 
 #endif  // ASAN_INTERFACE_INTERNAL_H

diff  --git a/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp
new file mode 100644
index 000000000000..d703fe024aa0
--- /dev/null
+++ b/compiler-rt/test/asan/TestCases/asan_update_allocation.cpp
@@ -0,0 +1,19 @@
+// RUN: %clangxx_asan -O0 -DSIZE=10 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK
+// RUN: %clangxx_asan -O0 -DSIZE=10000000 %s -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-%os --check-prefix=CHECK
+// REQUIRES: stable-runtime
+
+#include <stdlib.h>
+#include <sanitizer/asan_interface.h>
+
+void UPDATE(void *p) {
+  __asan_update_allocation_context(p);
+}
+
+int main() {
+  char *x = (char*)malloc(SIZE * sizeof(char));
+  UPDATE(x);
+  free(x);
+  return x[5];
+  // CHECK: {{.*ERROR: AddressSanitizer: heap-use-after-free on address}}
+  // CHECK: UPDATE
+}


        


More information about the llvm-commits mailing list