1 //===-- hwasan_report.cc --------------------------------------------------===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of HWAddressSanitizer.
13 //===----------------------------------------------------------------------===//
16 #include "hwasan_allocator.h"
17 #include "hwasan_mapping.h"
18 #include "sanitizer_common/sanitizer_allocator_internal.h"
19 #include "sanitizer_common/sanitizer_common.h"
20 #include "sanitizer_common/sanitizer_flags.h"
21 #include "sanitizer_common/sanitizer_mutex.h"
22 #include "sanitizer_common/sanitizer_report_decorator.h"
23 #include "sanitizer_common/sanitizer_stackdepot.h"
24 #include "sanitizer_common/sanitizer_symbolizer.h"
26 using namespace __sanitizer;
30 static StackTrace GetStackTraceFromId(u32 id) {
32 StackTrace res = StackDepotGet(id);
37 class Decorator: public __sanitizer::SanitizerCommonDecorator {
39 Decorator() : SanitizerCommonDecorator() { }
40 const char *Allocation() const { return Magenta(); }
41 const char *Origin() const { return Magenta(); }
42 const char *Name() const { return Green(); }
45 struct HeapAddressDescription {
53 Printf("%sfreed here:%s\n", d.Allocation(), d.Default());
54 GetStackTraceFromId(free_stack_id).Print();
55 Printf("%spreviously allocated here:%s\n", d.Allocation(), d.Default());
57 Printf("%sallocated here:%s\n", d.Allocation(), d.Default());
59 GetStackTraceFromId(alloc_stack_id).Print();
63 bool GetHeapAddressInformation(uptr addr, uptr access_size,
64 HeapAddressDescription *description) {
65 HwasanChunkView chunk = FindHeapChunkByAddress(addr);
68 description->addr = addr;
69 description->alloc_stack_id = chunk.GetAllocStackId();
70 description->free_stack_id = chunk.GetFreeStackId();
74 void PrintAddressDescription(uptr addr, uptr access_size) {
75 HeapAddressDescription heap_description;
76 if (GetHeapAddressInformation(addr, access_size, &heap_description)) {
77 heap_description.Print();
80 // We exhausted our possibilities. Bail out.
81 Printf("HWAddressSanitizer can not describe address in more detail.\n");
84 void ReportInvalidAccess(StackTrace *stack, u32 origin) {
85 ScopedErrorReportLock l;
88 Printf("%s", d.Warning());
89 Report("WARNING: HWAddressSanitizer: invalid access\n");
90 Printf("%s", d.Default());
92 ReportErrorSummary("invalid-access", stack);
97 void ReportInvalidAccessInsideAddressRange(const char *what, const void *start,
98 uptr size, uptr offset) {
99 ScopedErrorReportLock l;
102 Printf("%s", d.Warning());
103 Printf("%sTag mismatch in %s%s%s at offset %zu inside [%p, %zu)%s\n",
104 d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
106 PrintAddressDescription((uptr)start + offset, 1);
107 // if (__sanitizer::Verbosity())
108 // DescribeMemoryRange(start, size);
111 void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
113 ScopedErrorReportLock l;
116 Printf("%s", d.Warning());
117 uptr address = GetAddressFromPointer(addr);
118 Printf("%s of size %zu at %p\n", is_store ? "WRITE" : "READ", access_size,
121 tag_t ptr_tag = GetTagFromPointer(addr);
122 tag_t mem_tag = *(tag_t *)MEM_TO_SHADOW(address);
123 Printf("pointer tag 0x%x\nmemory tag 0x%x\n", ptr_tag, mem_tag);
124 Printf("%s", d.Default());
128 PrintAddressDescription(address, access_size);
130 ReportErrorSummary("tag-mismatch", stack);
133 } // namespace __hwasan