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