]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/compiler-rt/lib/hwasan/hwasan_report.cc
Import CK as of 21d3e319407d19dece16ee317c757ffc54a452bc, which makes its
[FreeBSD/FreeBSD.git] / contrib / compiler-rt / lib / hwasan / hwasan_report.cc
1 //===-- hwasan_report.cc ----------------------------------------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file is a part of HWAddressSanitizer.
11 //
12 // Error reporting.
13 //===----------------------------------------------------------------------===//
14
15 #include "hwasan.h"
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"
24
25 using namespace __sanitizer;
26
27 namespace __hwasan {
28
29 static StackTrace GetStackTraceFromId(u32 id) {
30   CHECK(id);
31   StackTrace res = StackDepotGet(id);
32   CHECK(res.trace);
33   return res;
34 }
35
36 class Decorator: public __sanitizer::SanitizerCommonDecorator {
37  public:
38   Decorator() : SanitizerCommonDecorator() { }
39   const char *Allocation() { return Magenta(); }
40   const char *Origin() { return Magenta(); }
41   const char *Name() { return Green(); }
42 };
43
44 struct HeapAddressDescription {
45   uptr addr;
46   u32 alloc_stack_id;
47   u32 free_stack_id;
48
49   void Print() const {
50     Decorator d;
51     if (free_stack_id) {
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());
55     } else {
56       Printf("%sallocated here:%s\n", d.Allocation(), d.Default());
57     }
58     GetStackTraceFromId(alloc_stack_id).Print();
59   }
60 };
61
62 bool GetHeapAddressInformation(uptr addr, uptr access_size,
63                                HeapAddressDescription *description) {
64   HwasanChunkView chunk = FindHeapChunkByAddress(addr);
65   if (!chunk.IsValid())
66     return false;
67   description->addr = addr;
68   description->alloc_stack_id = chunk.GetAllocStackId();
69   description->free_stack_id = chunk.GetFreeStackId();
70   return true;
71 }
72
73 void PrintAddressDescription(uptr addr, uptr access_size) {
74   HeapAddressDescription heap_description;
75   if (GetHeapAddressInformation(addr, access_size, &heap_description)) {
76     heap_description.Print();
77     return;
78   }
79   // We exhausted our possibilities. Bail out.
80   Printf("HWAddressSanitizer can not describe address in more detail.\n");
81 }
82
83 void ReportInvalidAccess(StackTrace *stack, u32 origin) {
84   ScopedErrorReportLock l;
85
86   Decorator d;
87   Printf("%s", d.Warning());
88   Report("WARNING: HWAddressSanitizer: invalid access\n");
89   Printf("%s", d.Default());
90   stack->Print();
91   ReportErrorSummary("invalid-access", stack);
92 }
93
94 void ReportStats() {}
95
96 void ReportInvalidAccessInsideAddressRange(const char *what, const void *start,
97                                            uptr size, uptr offset) {
98   ScopedErrorReportLock l;
99
100   Decorator d;
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,
104          d.Default());
105   PrintAddressDescription((uptr)start + offset, 1);
106   // if (__sanitizer::Verbosity())
107   //   DescribeMemoryRange(start, size);
108 }
109
110 void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size,
111                        bool is_store) {
112   ScopedErrorReportLock l;
113
114   Decorator d;
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,
118          address);
119
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());
124
125   stack->Print();
126
127   PrintAddressDescription(address, access_size);
128
129   ReportErrorSummary("tag-mismatch", stack);
130 }
131
132
133 }  // namespace __hwasan