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 "sanitizer_common/sanitizer_allocator_internal.h"
18 #include "sanitizer_common/sanitizer_common.h"
19 #include "sanitizer_common/sanitizer_flags.h"
20 #include "sanitizer_common/sanitizer_mutex.h"
21 #include "sanitizer_common/sanitizer_report_decorator.h"
22 #include "sanitizer_common/sanitizer_stackdepot.h"
23 #include "sanitizer_common/sanitizer_symbolizer.h"
25 using namespace __sanitizer;
29 static StackTrace GetStackTraceFromId(u32 id) {
31 StackTrace res = StackDepotGet(id);
36 class Decorator: public __sanitizer::SanitizerCommonDecorator {
38 Decorator() : SanitizerCommonDecorator() { }
39 const char *Allocation() { return Magenta(); }
40 const char *Origin() { return Magenta(); }
41 const char *Name() { return Green(); }
44 struct HeapAddressDescription {
52 Printf("%sfreed here:%s\n", d.Allocation(), d.Default());
53 GetStackTraceFromId(free_stack_id).Print();
54 Printf("%spreviously allocated here:%s\n", d.Allocation(), d.Default());
56 Printf("%sallocated here:%s\n", d.Allocation(), d.Default());
58 GetStackTraceFromId(alloc_stack_id).Print();
62 bool GetHeapAddressInformation(uptr addr, uptr access_size,
63 HeapAddressDescription *description) {
64 HwasanChunkView chunk = FindHeapChunkByAddress(addr);
67 description->addr = addr;
68 description->alloc_stack_id = chunk.GetAllocStackId();
69 description->free_stack_id = chunk.GetFreeStackId();
73 void PrintAddressDescription(uptr addr, uptr access_size) {
74 HeapAddressDescription heap_description;
75 if (GetHeapAddressInformation(addr, access_size, &heap_description)) {
76 heap_description.Print();
79 // We exhausted our possibilities. Bail out.
80 Printf("HWAddressSanitizer can not describe address in more detail.\n");
83 void ReportInvalidAccess(StackTrace *stack, u32 origin) {
84 ScopedErrorReportLock l;
87 Printf("%s", d.Warning());
88 Report("WARNING: HWAddressSanitizer: invalid access\n");
89 Printf("%s", d.Default());
91 ReportErrorSummary("invalid-access", stack);
96 void ReportInvalidAccessInsideAddressRange(const char *what, const void *start,
97 uptr size, uptr offset) {
98 ScopedErrorReportLock l;
101 Printf("%s", d.Warning());
102 Printf("%sTag mismatch in %s%s%s at offset %zu inside [%p, %zu)%s\n",
103 d.Warning(), d.Name(), what, d.Warning(), offset, start, size,
105 PrintAddressDescription((uptr)start + offset, 1);
106 // if (__sanitizer::Verbosity())
107 // DescribeMemoryRange(start, size);
110 void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
112 ScopedErrorReportLock l;
115 Printf("%s", d.Warning());
116 uptr address = GetAddressFromPointer(addr);
117 Printf("%s of size %zu at %p\n", is_store ? "WRITE" : "READ", access_size,
120 tag_t ptr_tag = GetTagFromPointer(addr);
121 tag_t mem_tag = *(tag_t *)MEM_TO_SHADOW(address);
122 Printf("pointer tag 0x%x\nmemory tag 0x%x\n", ptr_tag, mem_tag);
123 Printf("%s", d.Default());
127 PrintAddressDescription(address, access_size);
129 ReportErrorSummary("tag-mismatch", stack);
133 } // namespace __hwasan