[compiler-rt] r340971 - Add a thread-local ring buffer of heap allocations
Kostya Serebryany via llvm-commits
llvm-commits at lists.llvm.org
Wed Aug 29 14:07:07 PDT 2018
Author: kcc
Date: Wed Aug 29 14:07:07 2018
New Revision: 340971
URL: http://llvm.org/viewvc/llvm-project?rev=340971&view=rev
Log:
Add a thread-local ring buffer of heap allocations
Summary:
We need this in order to properly report heap-use-after-free,
since we don't have a quarantine.
This is a first part of the code, more like a proof of concept.
But I'd like to commit at as is and proceed with refactoring,
adding a ThreadRegistry, and extending the functionality.
Reviewers: eugenis
Subscribers: kubamracek, delcypher, #sanitizers, llvm-commits
Differential Revision: https://reviews.llvm.org/D51394
Modified:
compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
compiler-rt/trunk/lib/hwasan/hwasan_allocator.h
compiler-rt/trunk/lib/hwasan/hwasan_flags.inc
compiler-rt/trunk/lib/hwasan/hwasan_report.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
compiler-rt/trunk/lib/hwasan/hwasan_thread.h
Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc Wed Aug 29 14:07:07 2018
@@ -36,7 +36,7 @@ enum {
struct Metadata {
u64 state : 2;
- u64 requested_size : 62;
+ u32 requested_size; // Current use cases of hwasan do not expect sizes > 4G.
u32 alloc_context_id;
u32 free_context_id;
};
@@ -155,7 +155,7 @@ static void *HwasanAllocate(StackTrace *
Metadata *meta =
reinterpret_cast<Metadata *>(allocator.GetMetaData(allocated));
meta->state = CHUNK_ALLOCATED;
- meta->requested_size = size;
+ meta->requested_size = static_cast<u32>(size);
meta->alloc_context_id = StackDepotPut(*stack);
if (zeroise) {
internal_memset(allocated, 0, size);
@@ -194,7 +194,8 @@ void HwasanDeallocate(StackTrace *stack,
uptr size = meta->requested_size;
meta->state = CHUNK_FREE;
meta->requested_size = 0;
- meta->free_context_id = StackDepotPut(*stack);
+ u32 free_context_id = StackDepotPut(*stack);
+ meta->free_context_id = free_context_id;
// This memory will not be reused by anyone else, so we are free to keep it
// poisoned.
HwasanThread *t = GetCurrentThread();
@@ -209,6 +210,9 @@ void HwasanDeallocate(StackTrace *stack,
if (t) {
AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
allocator.Deallocate(cache, p);
+ if (auto *ha = t->heap_allocations())
+ ha->push({reinterpret_cast<uptr>(user_ptr), free_context_id,
+ static_cast<u32>(size)});
} else {
SpinMutexLock l(&fallback_mutex);
AllocatorCache *cache = &fallback_allocator_cache;
@@ -252,6 +256,7 @@ void *HwasanReallocate(StackTrace *stack
internal_memcpy(new_p, old_p, memcpy_size);
HwasanDeallocate(stack, old_p);
}
+ // FIXME: update t->heap_allocations or simplify HwasanReallocate.
return new_p;
}
Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.h?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.h Wed Aug 29 14:07:07 2018
@@ -15,6 +15,7 @@
#define HWASAN_ALLOCATOR_H
#include "sanitizer_common/sanitizer_common.h"
+#include "sanitizer_common/sanitizer_ring_buffer.h"
namespace __hwasan {
@@ -49,6 +50,17 @@ class HwasanChunkView {
HwasanChunkView FindHeapChunkByAddress(uptr address);
+// Information about one (de)allocation that happened in the past.
+// These are recorded in a thread-local ring buffer.
+struct HeapAllocationRecord {
+ uptr tagged_addr;
+ u32 free_context_id;
+ u32 requested_size;
+};
+
+typedef RingBuffer<HeapAllocationRecord> HeapAllocationsRingBuffer;
+
+
} // namespace __hwasan
#endif // HWASAN_ALLOCATOR_H
Modified: compiler-rt/trunk/lib/hwasan/hwasan_flags.inc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_flags.inc?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_flags.inc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_flags.inc Wed Aug 29 14:07:07 2018
@@ -44,3 +44,7 @@ HWASAN_FLAG(int, malloc_fill_byte, 0xbe,
"Value used to fill the newly allocated memory.")
HWASAN_FLAG(int, free_fill_byte, 0x55,
"Value used to fill deallocated memory.")
+HWASAN_FLAG(int, heap_history_size, 1023,
+ "The number of heap (de)allocations remembered per thread. "
+ "Affects the quality of heap-related reports, but not the ability "
+ "to find bugs.")
Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Wed Aug 29 14:07:07 2018
@@ -15,6 +15,7 @@
#include "hwasan.h"
#include "hwasan_allocator.h"
#include "hwasan_mapping.h"
+#include "hwasan_thread.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
@@ -61,6 +62,21 @@ struct HeapAddressDescription {
}
};
+bool FindHeapAllocation(HeapAllocationsRingBuffer *rb,
+ uptr tagged_addr,
+ HeapAllocationRecord *har) {
+ if (!rb) return false;
+ for (uptr i = 0, size = rb->size(); i < size; i++) {
+ auto h = (*rb)[i];
+ if (h.tagged_addr <= tagged_addr &&
+ h.tagged_addr + h.requested_size > tagged_addr) {
+ *har = h;
+ return true;
+ }
+ }
+ return false;
+}
+
bool GetHeapAddressInformation(uptr addr, uptr access_size,
HeapAddressDescription *description) {
HwasanChunkView chunk = FindHeapChunkByAddress(addr);
@@ -182,6 +198,18 @@ void ReportTagMismatch(StackTrace *stack
PrintAddressDescription(address, access_size);
+ // Temporary functionality; to be folded into PrintAddressDescription.
+ // TODOs:
+ // * implement ThreadRegistry
+ // * check all threads, not just the current one.
+ // * remove reduntant fields from the allocator metadata
+ // * use the allocations found in the ring buffer for the main report.
+ HeapAllocationRecord har;
+ HwasanThread *t = GetCurrentThread();
+ if (t && FindHeapAllocation(t->heap_allocations(), addr, &har))
+ Printf("Address found in the ring buffer: %p %u %u\n", har.tagged_addr,
+ har.free_context_id, har.requested_size);
+
PrintTagsAroundAddr(tag_ptr);
ReportErrorSummary(bug_type, stack);
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.cc?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.cc Wed Aug 29 14:07:07 2018
@@ -32,7 +32,8 @@ HwasanThread *HwasanThread::Create(threa
thread->arg_ = arg;
thread->destructor_iterations_ = GetPthreadDestructorIterations();
thread->random_state_ = flags()->random_tags ? RandomSeed() : 0;
-
+ if (auto sz = flags()->heap_history_size)
+ thread->heap_allocations_ = RingBuffer<HeapAllocationRecord>::New(sz);
return thread;
}
@@ -76,6 +77,8 @@ void HwasanThread::Destroy() {
malloc_storage().CommitBack();
ClearShadowForThreadStackAndTLS();
uptr size = RoundUpTo(sizeof(HwasanThread), GetPageSizeCached());
+ if (heap_allocations_)
+ heap_allocations_->Delete();
UnmapOrDie(this, size);
DTLS_Destroy();
}
Modified: compiler-rt/trunk/lib/hwasan/hwasan_thread.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_thread.h?rev=340971&r1=340970&r2=340971&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_thread.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_thread.h Wed Aug 29 14:07:07 2018
@@ -50,6 +50,9 @@ class HwasanThread {
void LeaveInterceptorScope() { in_interceptor_scope_--; }
HwasanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
+ HeapAllocationsRingBuffer *heap_allocations() {
+ return heap_allocations_;
+ }
tag_t GenerateRandomTag();
@@ -75,6 +78,7 @@ class HwasanThread {
u32 random_buffer_;
HwasanThreadLocalMallocStorage malloc_storage_;
+ HeapAllocationsRingBuffer *heap_allocations_;
};
HwasanThread *GetCurrentThread();
More information about the llvm-commits
mailing list