1 //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // ASan-private header for error structures.
11 //===----------------------------------------------------------------------===//
15 #include "asan_descriptions.h"
16 #include "asan_scariness_score.h"
17 #include "sanitizer_common/sanitizer_common.h"
22 ErrorBase() = default;
23 explicit ErrorBase(u32 tid_
) : tid(tid_
) {}
24 ScarinessScoreBase scariness
;
28 struct ErrorStackOverflow
: ErrorBase
{
29 uptr addr
, pc
, bp
, sp
;
30 // ErrorStackOverflow never owns the context.
32 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
34 ErrorStackOverflow() = default;
35 ErrorStackOverflow(u32 tid
, const SignalContext
&sig
)
41 context(sig
.context
) {
43 scariness
.Scare(10, "stack-overflow");
48 struct ErrorDeadlySignal
: ErrorBase
{
49 uptr addr
, pc
, bp
, sp
;
50 // ErrorDeadlySignal never owns the context.
53 SignalContext::WriteFlag write_flag
;
54 bool is_memory_access
;
55 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
57 ErrorDeadlySignal() = default;
58 ErrorDeadlySignal(u32 tid
, const SignalContext
&sig
, int signo_
)
66 write_flag(sig
.write_flag
),
67 is_memory_access(sig
.is_memory_access
) {
69 if (is_memory_access
) {
70 if (addr
< GetPageSizeCached()) {
71 scariness
.Scare(10, "null-deref");
72 } else if (addr
== pc
) {
73 scariness
.Scare(60, "wild-jump");
74 } else if (write_flag
== SignalContext::WRITE
) {
75 scariness
.Scare(30, "wild-addr-write");
76 } else if (write_flag
== SignalContext::READ
) {
77 scariness
.Scare(20, "wild-addr-read");
79 scariness
.Scare(25, "wild-addr");
82 scariness
.Scare(10, "signal");
88 struct ErrorDoubleFree
: ErrorBase
{
89 // ErrorDoubleFree doesn't own the stack trace.
90 const BufferedStackTrace
*second_free_stack
;
91 HeapAddressDescription addr_description
;
92 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
94 ErrorDoubleFree() = default;
95 ErrorDoubleFree(u32 tid
, BufferedStackTrace
*stack
, uptr addr
)
96 : ErrorBase(tid
), second_free_stack(stack
) {
97 CHECK_GT(second_free_stack
->size
, 0);
98 GetHeapAddressInformation(addr
, 1, &addr_description
);
100 scariness
.Scare(42, "double-free");
105 struct ErrorNewDeleteSizeMismatch
: ErrorBase
{
106 // ErrorNewDeleteSizeMismatch doesn't own the stack trace.
107 const BufferedStackTrace
*free_stack
;
108 HeapAddressDescription addr_description
;
110 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
112 ErrorNewDeleteSizeMismatch() = default;
113 ErrorNewDeleteSizeMismatch(u32 tid
, BufferedStackTrace
*stack
, uptr addr
,
115 : ErrorBase(tid
), free_stack(stack
), delete_size(delete_size_
) {
116 GetHeapAddressInformation(addr
, 1, &addr_description
);
118 scariness
.Scare(10, "new-delete-type-mismatch");
123 struct ErrorFreeNotMalloced
: ErrorBase
{
124 // ErrorFreeNotMalloced doesn't own the stack trace.
125 const BufferedStackTrace
*free_stack
;
126 AddressDescription addr_description
;
127 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
129 ErrorFreeNotMalloced() = default;
130 ErrorFreeNotMalloced(u32 tid
, BufferedStackTrace
*stack
, uptr addr
)
133 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
135 scariness
.Scare(40, "bad-free");
140 struct ErrorAllocTypeMismatch
: ErrorBase
{
141 // ErrorAllocTypeMismatch doesn't own the stack trace.
142 const BufferedStackTrace
*dealloc_stack
;
143 HeapAddressDescription addr_description
;
144 AllocType alloc_type
, dealloc_type
;
145 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
147 ErrorAllocTypeMismatch() = default;
148 ErrorAllocTypeMismatch(u32 tid
, BufferedStackTrace
*stack
, uptr addr
,
149 AllocType alloc_type_
, AllocType dealloc_type_
)
151 dealloc_stack(stack
),
152 alloc_type(alloc_type_
),
153 dealloc_type(dealloc_type_
) {
154 GetHeapAddressInformation(addr
, 1, &addr_description
);
156 scariness
.Scare(10, "alloc-dealloc-mismatch");
161 struct ErrorMallocUsableSizeNotOwned
: ErrorBase
{
162 // ErrorMallocUsableSizeNotOwned doesn't own the stack trace.
163 const BufferedStackTrace
*stack
;
164 AddressDescription addr_description
;
165 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
167 ErrorMallocUsableSizeNotOwned() = default;
168 ErrorMallocUsableSizeNotOwned(u32 tid
, BufferedStackTrace
*stack_
, uptr addr
)
171 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
177 struct ErrorSanitizerGetAllocatedSizeNotOwned
: ErrorBase
{
178 // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace.
179 const BufferedStackTrace
*stack
;
180 AddressDescription addr_description
;
181 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
183 ErrorSanitizerGetAllocatedSizeNotOwned() = default;
184 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid
, BufferedStackTrace
*stack_
,
188 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
194 struct ErrorStringFunctionMemoryRangesOverlap
: ErrorBase
{
195 // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace.
196 const BufferedStackTrace
*stack
;
197 uptr length1
, length2
;
198 AddressDescription addr1_description
;
199 AddressDescription addr2_description
;
200 const char *function
;
201 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
203 ErrorStringFunctionMemoryRangesOverlap() = default;
204 ErrorStringFunctionMemoryRangesOverlap(u32 tid
, BufferedStackTrace
*stack_
,
205 uptr addr1
, uptr length1_
, uptr addr2
,
206 uptr length2_
, const char *function_
)
211 addr1_description(addr1
, length1
, /*shouldLockThreadRegistry=*/false),
212 addr2_description(addr2
, length2
, /*shouldLockThreadRegistry=*/false),
213 function(function_
) {
215 internal_snprintf(bug_type
, sizeof(bug_type
), "%s-param-overlap", function
);
217 scariness
.Scare(10, bug_type
);
222 struct ErrorStringFunctionSizeOverflow
: ErrorBase
{
223 // ErrorStringFunctionSizeOverflow doesn't own the stack trace.
224 const BufferedStackTrace
*stack
;
225 AddressDescription addr_description
;
227 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
229 ErrorStringFunctionSizeOverflow() = default;
230 ErrorStringFunctionSizeOverflow(u32 tid
, BufferedStackTrace
*stack_
,
231 uptr addr
, uptr size_
)
234 addr_description(addr
, /*shouldLockThreadRegistry=*/false),
237 scariness
.Scare(10, "negative-size-param");
242 struct ErrorBadParamsToAnnotateContiguousContainer
: ErrorBase
{
243 // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace.
244 const BufferedStackTrace
*stack
;
245 uptr beg
, end
, old_mid
, new_mid
;
246 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
248 ErrorBadParamsToAnnotateContiguousContainer() = default;
249 // PS4: Do we want an AddressDescription for beg?
250 ErrorBadParamsToAnnotateContiguousContainer(u32 tid
,
251 BufferedStackTrace
*stack_
,
252 uptr beg_
, uptr end_
,
253 uptr old_mid_
, uptr new_mid_
)
263 struct ErrorODRViolation
: ErrorBase
{
264 __asan_global global1
, global2
;
265 u32 stack_id1
, stack_id2
;
266 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
268 ErrorODRViolation() = default;
269 ErrorODRViolation(u32 tid
, const __asan_global
*g1
, u32 stack_id1_
,
270 const __asan_global
*g2
, u32 stack_id2_
)
274 stack_id1(stack_id1_
),
275 stack_id2(stack_id2_
) {}
279 struct ErrorInvalidPointerPair
: ErrorBase
{
281 AddressDescription addr1_description
;
282 AddressDescription addr2_description
;
283 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
285 ErrorInvalidPointerPair() = default;
286 ErrorInvalidPointerPair(u32 tid
, uptr pc_
, uptr bp_
, uptr sp_
, uptr p1
,
292 addr1_description(p1
, 1, /*shouldLockThreadRegistry=*/false),
293 addr2_description(p2
, 1, /*shouldLockThreadRegistry=*/false) {}
297 struct ErrorGeneric
: ErrorBase
{
298 AddressDescription addr_description
;
301 const char *bug_descr
;
304 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
306 ErrorGeneric() = default;
307 ErrorGeneric(u32 tid
, uptr addr
, uptr pc_
, uptr bp_
, uptr sp_
, bool is_write_
,
313 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
314 macro(StackOverflow) \
315 macro(DeadlySignal) \
317 macro(NewDeleteSizeMismatch) \
318 macro(FreeNotMalloced) \
319 macro(AllocTypeMismatch) \
320 macro(MallocUsableSizeNotOwned) \
321 macro(SanitizerGetAllocatedSizeNotOwned) \
322 macro(StringFunctionMemoryRangesOverlap) \
323 macro(StringFunctionSizeOverflow) \
324 macro(BadParamsToAnnotateContiguousContainer) \
325 macro(ODRViolation) \
326 macro(InvalidPointerPair) \
330 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
331 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
332 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
333 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
334 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
335 case kErrorKind##name: \
339 kErrorKindInvalid
= 0,
340 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND
)
343 struct ErrorDescription
{
345 // We're using a tagged union because it allows us to have a trivially
346 // copiable type and use the same structures as the public interface.
348 // We can add a wrapper around it to make it "more c++-like", but that would
349 // add a lot of code and the benefit wouldn't be that big.
351 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER
)
354 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
355 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
)
357 bool IsValid() { return kind
!= kErrorKindInvalid
; }
360 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT
)
361 case kErrorKindInvalid
:
368 #undef ASAN_FOR_EACH_ERROR_KIND
369 #undef ASAN_DEFINE_ERROR_KIND
370 #undef ASAN_ERROR_DESCRIPTION_MEMBER
371 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
372 #undef ASAN_ERROR_DESCRIPTION_PRINT
374 } // namespace __asan
376 #endif // ASAN_ERRORS_H