diff options
| author | Kostya Serebryany <kcc@google.com> | 2018-10-10 22:24:44 +0000 |
|---|---|---|
| committer | Kostya Serebryany <kcc@google.com> | 2018-10-10 22:24:44 +0000 |
| commit | d7c60e42e376ee31d70c1312604c64cbd6fd85fb (patch) | |
| tree | cfbc4238ebfb87a773a9e1a99add75ed50a3cc70 | |
| parent | 0e192395f162e7571a1f92ba1528a8080e507777 (diff) | |
| download | bcm5719-llvm-d7c60e42e376ee31d70c1312604c64cbd6fd85fb.tar.gz bcm5719-llvm-d7c60e42e376ee31d70c1312604c64cbd6fd85fb.zip | |
[hwasan] when reporting a bug, print some very basic information about the heap chunk (in addition to the more detailed info that we may fail to show)
llvm-svn: 344193
| -rw-r--r-- | compiler-rt/lib/hwasan/hwasan_allocator.cc | 20 | ||||
| -rw-r--r-- | compiler-rt/lib/hwasan/hwasan_allocator.h | 2 | ||||
| -rw-r--r-- | compiler-rt/lib/hwasan/hwasan_report.cc | 15 | ||||
| -rw-r--r-- | compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c | 9 | ||||
| -rw-r--r-- | compiler-rt/test/hwasan/TestCases/use-after-free.c | 7 |
5 files changed, 45 insertions, 8 deletions
diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cc b/compiler-rt/lib/hwasan/hwasan_allocator.cc index b9c379ea449..ddc0928625a 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cc +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cc @@ -23,6 +23,14 @@ namespace __hwasan { +static Allocator allocator; +static AllocatorCache fallback_allocator_cache; +static SpinMutex fallback_mutex; +static atomic_uint8_t hwasan_allocator_tagging_enabled; + +static const tag_t kFallbackAllocTag = 0xBB; +static const tag_t kFallbackFreeTag = 0xBC; + bool HwasanChunkView::IsAllocated() const { return metadata_ && metadata_->alloc_context_id && metadata_->requested_size; } @@ -40,13 +48,13 @@ u32 HwasanChunkView::GetAllocStackId() const { return metadata_->alloc_context_id; } -static Allocator allocator; -static AllocatorCache fallback_allocator_cache; -static SpinMutex fallback_mutex; -static atomic_uint8_t hwasan_allocator_tagging_enabled; +uptr HwasanChunkView::ActualSize() const { + return allocator.GetActuallyAllocatedSize(reinterpret_cast<void *>(block_)); +} -static const tag_t kFallbackAllocTag = 0xBB; -static const tag_t kFallbackFreeTag = 0xBC; +bool HwasanChunkView::FromSmallHeap() const { + return allocator.FromPrimary(reinterpret_cast<void *>(block_)); +} void GetAllocatorStats(AllocatorStatCounters s) { allocator.GetStats(s); diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.h b/compiler-rt/lib/hwasan/hwasan_allocator.h index 3589212d852..119ead886c0 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.h +++ b/compiler-rt/lib/hwasan/hwasan_allocator.h @@ -76,7 +76,9 @@ class HwasanChunkView { uptr Beg() const; // First byte of user memory uptr End() const; // Last byte of user memory uptr UsedSize() const; // Size requested by the user + uptr ActualSize() const; // Size allocated by the allocator. u32 GetAllocStackId() const; + bool FromSmallHeap() const; private: uptr block_; Metadata *const metadata_; diff --git a/compiler-rt/lib/hwasan/hwasan_report.cc b/compiler-rt/lib/hwasan/hwasan_report.cc index 4c69b86c7c4..46373b9f145 100644 --- a/compiler-rt/lib/hwasan/hwasan_report.cc +++ b/compiler-rt/lib/hwasan/hwasan_report.cc @@ -95,6 +95,21 @@ void PrintAddressDescription( Decorator d; int num_descriptions_printed = 0; uptr untagged_addr = UntagAddr(tagged_addr); + + // Print some very basic information about the address, if it's a heap. + HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr); + if (uptr beg = chunk.Beg()) { + uptr size = chunk.ActualSize(); + Printf("%s[%p,%p) is a %s %s heap chunk; " + "size: %zd offset: %zd\n%s", + d.Location(), + beg, beg + size, + chunk.FromSmallHeap() ? "small" : "large", + chunk.IsAllocated() ? "allocated" : "unallocated", + size, untagged_addr - beg, + d.Default()); + } + // Check if this looks like a heap buffer overflow by scanning // the shadow left and right and looking for the first adjacent // object with a different memory tag. If that tag matches addr_tag, diff --git a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c index 40b6e6e9d1d..6b0cf311d2e 100644 --- a/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c +++ b/compiler-rt/test/hwasan/TestCases/heap-buffer-overflow.c @@ -17,10 +17,19 @@ int main(int argc, char **argv) { int size = argc < 3 ? 30 : atoi(argv[2]); char * volatile x = (char*)malloc(size); x[offset] = 42; +// CHECK40: is a small unallocated heap chunk; size: 32 offset: 8 // CHECK40: is located 10 bytes to the right of 30-byte region +// +// CHECK80: is a small unallocated heap chunk; size: 32 offset: 16 // CHECK80: is located 50 bytes to the right of 30-byte region +// +// CHECKm30: is a small unallocated heap chunk; size: 32 offset: 2 // CHECKm30: is located 30 bytes to the left of 30-byte region +// +// CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30 // CHECKMm30: is located 30 bytes to the left of 1000000-byte region +// +// CHECKM: is a large allocated heap chunk; size: 1003520 offset: 1000000 // CHECKM: is located 0 bytes to the right of 1000000-byte region free(x); } diff --git a/compiler-rt/test/hwasan/TestCases/use-after-free.c b/compiler-rt/test/hwasan/TestCases/use-after-free.c index 3dae97b0caa..bc2c8d48f9d 100644 --- a/compiler-rt/test/hwasan/TestCases/use-after-free.c +++ b/compiler-rt/test/hwasan/TestCases/use-after-free.c @@ -23,13 +23,16 @@ int main() { // CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem) // CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]] + // CHECK: is a small unallocated heap chunk; size: 16 offset: 5 + // CHECK: is located 5 bytes inside of 10-byte region + // // CHECK: freed by thread {{.*}} here: // CHECK: #0 {{.*}} in {{.*}}free{{.*}} {{.*}}hwasan_interceptors.cc - // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-11]] + // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-14]] // CHECK: previously allocated here: // CHECK: #0 {{.*}} in {{.*}}malloc{{.*}} {{.*}}hwasan_interceptors.cc - // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-16]] + // CHECK: #1 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-19]] // CHECK: Memory tags around the buggy address (one tag corresponds to 16 bytes): // CHECK: =>{{.*}}[[MEM_TAG]] // CHECK: SUMMARY: HWAddressSanitizer: tag-mismatch {{.*}} in main |

