Skip to content

Commit 5cd0e5d

Browse files
committed
[NFC][hwasan] Set more fields by value and make them const (#66682)
1 parent 58fdfe7 commit 5cd0e5d

File tree

1 file changed

+63
-50
lines changed

1 file changed

+63
-50
lines changed

compiler-rt/lib/hwasan/hwasan_report.cpp

Lines changed: 63 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -387,14 +387,10 @@ class BaseReport {
387387
tagged_addr(tagged_addr),
388388
access_size(access_size),
389389
untagged_addr(UntagAddr(tagged_addr)),
390-
ptr_tag(GetTagFromPointer(tagged_addr)) {
391-
if (MemIsShadow(untagged_addr))
392-
return;
393-
394-
CopyHeapChunk();
395-
CopyAllocations();
396-
candidate = FindBufferOverflowCandidate();
397-
}
390+
ptr_tag(GetTagFromPointer(tagged_addr)),
391+
heap(CopyHeapChunk()),
392+
allocations(CopyAllocations()),
393+
candidate(FindBufferOverflowCandidate()) {}
398394

399395
protected:
400396
struct OverflowCandidate {
@@ -411,66 +407,80 @@ class BaseReport {
411407
} heap;
412408
};
413409

414-
void CopyHeapChunk();
415-
void CopyAllocations();
410+
struct HeapAllocation {
411+
HeapAllocationRecord har = {};
412+
uptr ring_index = 0;
413+
uptr num_matching_addrs = 0;
414+
uptr num_matching_addrs_4b = 0;
415+
u32 free_thread_id = 0;
416+
};
417+
418+
struct Allocations {
419+
ArrayRef<SavedStackAllocations> stack;
420+
ArrayRef<HeapAllocation> heap;
421+
};
422+
423+
struct HeapChunk {
424+
uptr begin = 0;
425+
uptr size = 0;
426+
bool from_small_heap = false;
427+
bool is_allocated = false;
428+
};
429+
430+
HeapChunk CopyHeapChunk() const;
431+
Allocations CopyAllocations();
416432
OverflowCandidate FindBufferOverflowCandidate() const;
417433
void PrintAddressDescription() const;
418434
void PrintHeapOrGlobalCandidate() const;
419435

436+
SavedStackAllocations stack_allocations_storage[16];
437+
HeapAllocation heap_allocations_storage[256];
438+
420439
const ScopedReport scoped_report;
421440
const StackTrace *stack = nullptr;
422441
const uptr tagged_addr = 0;
423442
const uptr access_size = 0;
424443
const uptr untagged_addr = 0;
425444
const tag_t ptr_tag = 0;
426445

427-
uptr stack_allocations_count = 0;
428-
SavedStackAllocations stack_allocations[16];
429-
430-
struct {
431-
uptr begin = 0;
432-
uptr size = 0;
433-
bool from_small_heap = false;
434-
bool is_allocated = false;
435-
} heap;
436-
437-
OverflowCandidate candidate;
438-
439-
uptr heap_allocations_count = 0;
440-
struct {
441-
HeapAllocationRecord har = {};
442-
uptr ring_index = 0;
443-
uptr num_matching_addrs = 0;
444-
uptr num_matching_addrs_4b = 0;
445-
u32 free_thread_id = 0;
446-
} heap_allocations[256];
446+
const HeapChunk heap;
447+
const Allocations allocations;
448+
const OverflowCandidate candidate;
447449
};
448450

449-
void BaseReport::CopyHeapChunk() {
451+
BaseReport::HeapChunk BaseReport::CopyHeapChunk() const {
452+
HeapChunk result = {};
453+
if (MemIsShadow(untagged_addr))
454+
return result;
450455
HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
451-
heap.begin = chunk.Beg();
452-
if (heap.begin) {
453-
heap.size = chunk.ActualSize();
454-
heap.from_small_heap = chunk.FromSmallHeap();
455-
heap.is_allocated = chunk.IsAllocated();
456+
result.begin = chunk.Beg();
457+
if (result.begin) {
458+
result.size = chunk.ActualSize();
459+
result.from_small_heap = chunk.FromSmallHeap();
460+
result.is_allocated = chunk.IsAllocated();
456461
}
462+
return result;
457463
}
458464

459-
void BaseReport::CopyAllocations() {
465+
BaseReport::Allocations BaseReport::CopyAllocations() {
466+
if (MemIsShadow(untagged_addr))
467+
return {};
468+
uptr stack_allocations_count = 0;
469+
uptr heap_allocations_count = 0;
460470
hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
461-
if (stack_allocations_count < ARRAY_SIZE(stack_allocations) &&
471+
if (stack_allocations_count < ARRAY_SIZE(stack_allocations_storage) &&
462472
t->AddrIsInStack(untagged_addr)) {
463-
stack_allocations[stack_allocations_count++].CopyFrom(t);
473+
stack_allocations_storage[stack_allocations_count++].CopyFrom(t);
464474
}
465475

466-
if (heap_allocations_count < ARRAY_SIZE(heap_allocations)) {
476+
if (heap_allocations_count < ARRAY_SIZE(heap_allocations_storage)) {
467477
// Scan all threads' ring buffers to find if it's a heap-use-after-free.
468478
HeapAllocationRecord har;
469479
uptr ring_index, num_matching_addrs, num_matching_addrs_4b;
470480
if (FindHeapAllocation(t->heap_allocations(), tagged_addr, &har,
471481
&ring_index, &num_matching_addrs,
472482
&num_matching_addrs_4b)) {
473-
auto &ha = heap_allocations[heap_allocations_count++];
483+
auto &ha = heap_allocations_storage[heap_allocations_count++];
474484
ha.har = har;
475485
ha.ring_index = ring_index;
476486
ha.num_matching_addrs = num_matching_addrs;
@@ -479,9 +489,15 @@ void BaseReport::CopyAllocations() {
479489
}
480490
}
481491
});
492+
493+
return {{stack_allocations_storage, stack_allocations_count},
494+
{heap_allocations_storage, heap_allocations_count}};
482495
}
483496

484497
BaseReport::OverflowCandidate BaseReport::FindBufferOverflowCandidate() const {
498+
OverflowCandidate result = {};
499+
if (MemIsShadow(untagged_addr))
500+
return result;
485501
// Check if this looks like a heap buffer overflow by scanning
486502
// the shadow left and right and looking for the first adjacent
487503
// object with a different memory tag. If that tag matches ptr_tag,
@@ -503,7 +519,6 @@ BaseReport::OverflowCandidate BaseReport::FindBufferOverflowCandidate() const {
503519
++right;
504520
}
505521

506-
OverflowCandidate result = {};
507522
constexpr auto kCloseCandidateDistance = 1;
508523
result.is_close = candidate_distance <= kCloseCandidateDistance;
509524

@@ -621,29 +636,27 @@ void BaseReport::PrintAddressDescription() const {
621636

622637
// Check stack first. If the address is on the stack of a live thread, we
623638
// know it cannot be a heap / global overflow.
624-
for (uptr i = 0; i < stack_allocations_count; ++i) {
625-
const auto &allocations = stack_allocations[i];
639+
for (const auto &sa : allocations.stack) {
626640
// TODO(fmayer): figure out how to distinguish use-after-return and
627641
// stack-buffer-overflow.
628642
Printf("%s", d.Error());
629643
Printf("\nCause: stack tag-mismatch\n");
630644
Printf("%s", d.Location());
631645
Printf("Address %p is located in stack of thread T%zd\n", untagged_addr,
632-
allocations.thread_id());
646+
sa.thread_id());
633647
Printf("%s", d.Default());
634-
announce_by_id(allocations.thread_id());
635-
PrintStackAllocations(allocations.get(), ptr_tag, untagged_addr);
648+
announce_by_id(sa.thread_id());
649+
PrintStackAllocations(sa.get(), ptr_tag, untagged_addr);
636650
num_descriptions_printed++;
637651
}
638652

639-
if (!stack_allocations_count && candidate.untagged_addr &&
653+
if (allocations.stack.empty() && candidate.untagged_addr &&
640654
candidate.is_close) {
641655
PrintHeapOrGlobalCandidate();
642656
num_descriptions_printed++;
643657
}
644658

645-
for (uptr i = 0; i < heap_allocations_count; ++i) {
646-
const auto &ha = heap_allocations[i];
659+
for (const auto &ha : allocations.heap) {
647660
const HeapAllocationRecord har = ha.har;
648661

649662
Printf("%s", d.Error());

0 commit comments

Comments
 (0)