[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
This commit is contained in:
Kostya Serebryany 2018-10-10 22:24:44 +00:00
parent 0e192395f1
commit d7c60e42e3
5 changed files with 45 additions and 8 deletions

View File

@ -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);

View File

@ -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_;

View File

@ -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,

View File

@ -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);
}

View File

@ -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