1//===-- asan_descriptions.h -------------------------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This file is a part of AddressSanitizer, an address sanity checker.
10//
11// ASan-private header for asan_descriptions.cpp.
12// TODO(filcab): Most struct definitions should move to the interface headers.
13//===----------------------------------------------------------------------===//
14#ifndef ASAN_DESCRIPTIONS_H
15#define ASAN_DESCRIPTIONS_H
16
17#include "asan_allocator.h"
18#include "asan_thread.h"
19#include "sanitizer_common/sanitizer_common.h"
20#include "sanitizer_common/sanitizer_report_decorator.h"
21
22namespace __asan {
23
24void DescribeThread(AsanThreadContext *context);
25static inline void DescribeThread(AsanThread *t) {
26 if (t) DescribeThread(context: t->context());
27}
28
29class AsanThreadIdAndName {
30 public:
31 explicit AsanThreadIdAndName(AsanThreadContext *t);
32 explicit AsanThreadIdAndName(u32 tid);
33
34 // Contains "T%tid (%name)" or "T%tid" if the name is empty.
35 const char *c_str() const { return &name[0]; }
36
37 private:
38 char name[128];
39};
40
41class Decorator : public __sanitizer::SanitizerCommonDecorator {
42 public:
43 Decorator() : SanitizerCommonDecorator() {}
44 const char *Access() { return Blue(); }
45 const char *Location() { return Green(); }
46 const char *Allocation() { return Magenta(); }
47
48 const char *ShadowByte(u8 byte) {
49 switch (byte) {
50 case kAsanHeapLeftRedzoneMagic:
51 case kAsanArrayCookieMagic:
52 return Red();
53 case kAsanHeapFreeMagic:
54 return Magenta();
55 case kAsanStackLeftRedzoneMagic:
56 case kAsanStackMidRedzoneMagic:
57 case kAsanStackRightRedzoneMagic:
58 return Red();
59 case kAsanStackAfterReturnMagic:
60 return Magenta();
61 case kAsanInitializationOrderMagic:
62 return Cyan();
63 case kAsanUserPoisonedMemoryMagic:
64 case kAsanContiguousContainerOOBMagic:
65 case kAsanAllocaLeftMagic:
66 case kAsanAllocaRightMagic:
67 return Blue();
68 case kAsanStackUseAfterScopeMagic:
69 return Magenta();
70 case kAsanGlobalRedzoneMagic:
71 return Red();
72 case kAsanInternalHeapMagic:
73 return Yellow();
74 case kAsanIntraObjectRedzone:
75 return Yellow();
76 default:
77 return Default();
78 }
79 }
80};
81
82enum ShadowKind : u8 {
83 kShadowKindLow,
84 kShadowKindGap,
85 kShadowKindHigh,
86};
87static const char *const ShadowNames[] = {"low shadow", "shadow gap",
88 "high shadow"};
89
90struct ShadowAddressDescription {
91 uptr addr;
92 ShadowKind kind;
93 u8 shadow_byte;
94
95 void Print() const;
96};
97
98bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr);
99bool DescribeAddressIfShadow(uptr addr);
100
101enum AccessType {
102 kAccessTypeLeft,
103 kAccessTypeRight,
104 kAccessTypeInside,
105 kAccessTypeUnknown, // This means we have an AddressSanitizer bug!
106};
107
108struct ChunkAccess {
109 uptr bad_addr;
110 sptr offset;
111 uptr chunk_begin;
112 uptr chunk_size;
113 u32 user_requested_alignment : 12;
114 u32 access_type : 2;
115 u32 alloc_type : 2;
116};
117
118struct HeapAddressDescription {
119 uptr addr;
120 uptr alloc_tid;
121 uptr free_tid;
122 u32 alloc_stack_id;
123 u32 free_stack_id;
124 ChunkAccess chunk_access;
125
126 void Print() const;
127};
128
129bool GetHeapAddressInformation(uptr addr, uptr access_size,
130 HeapAddressDescription *descr);
131bool DescribeAddressIfHeap(uptr addr, uptr access_size = 1);
132
133struct StackAddressDescription {
134 uptr addr;
135 uptr tid;
136 uptr offset;
137 uptr frame_pc;
138 uptr access_size;
139 const char *frame_descr;
140
141 void Print() const;
142};
143
144bool GetStackAddressInformation(uptr addr, uptr access_size,
145 StackAddressDescription *descr);
146
147struct WildAddressDescription {
148 uptr addr;
149 uptr access_size;
150
151 void Print() const;
152};
153
154struct GlobalAddressDescription {
155 uptr addr;
156 // Assume address is close to at most four globals.
157 static const int kMaxGlobals = 4;
158 __asan_global globals[kMaxGlobals];
159 u32 reg_sites[kMaxGlobals];
160 uptr access_size;
161 u8 size;
162
163 void Print(const char *bug_type = "") const;
164
165 // Returns true when this descriptions points inside the same global variable
166 // as other. Descriptions can have different address within the variable
167 bool PointsInsideTheSameVariable(const GlobalAddressDescription &other) const;
168};
169
170bool GetGlobalAddressInformation(uptr addr, uptr access_size,
171 GlobalAddressDescription *descr);
172bool DescribeAddressIfGlobal(uptr addr, uptr access_size, const char *bug_type);
173
174// General function to describe an address. Will try to describe the address as
175// a shadow, global (variable), stack, or heap address.
176// bug_type is optional and is used for checking if we're reporting an
177// initialization-order-fiasco
178// The proper access_size should be passed for stack, global, and heap
179// addresses. Defaults to 1.
180// Each of the *AddressDescription functions has its own Print() member, which
181// may take access_size and bug_type parameters if needed.
182void PrintAddressDescription(uptr addr, uptr access_size = 1,
183 const char *bug_type = "");
184
185enum AddressKind {
186 kAddressKindWild,
187 kAddressKindShadow,
188 kAddressKindHeap,
189 kAddressKindStack,
190 kAddressKindGlobal,
191};
192
193class AddressDescription {
194 struct AddressDescriptionData {
195 AddressKind kind;
196 union {
197 ShadowAddressDescription shadow;
198 HeapAddressDescription heap;
199 StackAddressDescription stack;
200 GlobalAddressDescription global;
201 WildAddressDescription wild;
202 };
203 };
204
205 AddressDescriptionData data;
206
207 public:
208 AddressDescription() = default;
209 // shouldLockThreadRegistry allows us to skip locking if we're sure we already
210 // have done it.
211 explicit AddressDescription(uptr addr, bool shouldLockThreadRegistry = true)
212 : AddressDescription(addr, 1, shouldLockThreadRegistry) {}
213 AddressDescription(uptr addr, uptr access_size,
214 bool shouldLockThreadRegistry = true);
215
216 uptr Address() const {
217 switch (data.kind) {
218 case kAddressKindWild:
219 return data.wild.addr;
220 case kAddressKindShadow:
221 return data.shadow.addr;
222 case kAddressKindHeap:
223 return data.heap.addr;
224 case kAddressKindStack:
225 return data.stack.addr;
226 case kAddressKindGlobal:
227 return data.global.addr;
228 }
229 UNREACHABLE("AddressInformation kind is invalid");
230 }
231 void Print(const char *bug_descr = nullptr) const {
232 switch (data.kind) {
233 case kAddressKindWild:
234 data.wild.Print();
235 return;
236 case kAddressKindShadow:
237 return data.shadow.Print();
238 case kAddressKindHeap:
239 return data.heap.Print();
240 case kAddressKindStack:
241 return data.stack.Print();
242 case kAddressKindGlobal:
243 // initialization-order-fiasco has a special Print()
244 return data.global.Print(bug_type: bug_descr);
245 }
246 UNREACHABLE("AddressInformation kind is invalid");
247 }
248
249 void StoreTo(AddressDescriptionData *dst) const { *dst = data; }
250
251 const ShadowAddressDescription *AsShadow() const {
252 return data.kind == kAddressKindShadow ? &data.shadow : nullptr;
253 }
254 const HeapAddressDescription *AsHeap() const {
255 return data.kind == kAddressKindHeap ? &data.heap : nullptr;
256 }
257 const StackAddressDescription *AsStack() const {
258 return data.kind == kAddressKindStack ? &data.stack : nullptr;
259 }
260 const GlobalAddressDescription *AsGlobal() const {
261 return data.kind == kAddressKindGlobal ? &data.global : nullptr;
262 }
263};
264
265} // namespace __asan
266
267#endif // ASAN_DESCRIPTIONS_H
268

Provided by KDAB

Privacy Policy
Update your C++ knowledge – Modern C++11/14/17 Training
Find out more

source code of compiler-rt/lib/asan/asan_descriptions.h