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 ErrorDeadlySignal
: ErrorBase
{
30 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
32 ErrorDeadlySignal() = default;
33 ErrorDeadlySignal(u32 tid
, const SignalContext
&sig
)
34 : ErrorBase(tid
), signal(sig
) {
36 if (signal
.IsStackOverflow()) {
37 scariness
.Scare(10, "stack-overflow");
38 } else if (!signal
.is_memory_access
) {
39 scariness
.Scare(10, "signal");
40 } else if (signal
.addr
< GetPageSizeCached()) {
41 scariness
.Scare(10, "null-deref");
42 } else if (signal
.addr
== signal
.pc
) {
43 scariness
.Scare(60, "wild-jump");
44 } else if (signal
.write_flag
== SignalContext::WRITE
) {
45 scariness
.Scare(30, "wild-addr-write");
46 } else if (signal
.write_flag
== SignalContext::READ
) {
47 scariness
.Scare(20, "wild-addr-read");
49 scariness
.Scare(25, "wild-addr");
55 struct ErrorDoubleFree
: ErrorBase
{
56 // ErrorDoubleFree doesn't own the stack trace.
57 const BufferedStackTrace
*second_free_stack
;
58 HeapAddressDescription addr_description
;
59 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
61 ErrorDoubleFree() = default;
62 ErrorDoubleFree(u32 tid
, BufferedStackTrace
*stack
, uptr addr
)
63 : ErrorBase(tid
), second_free_stack(stack
) {
64 CHECK_GT(second_free_stack
->size
, 0);
65 GetHeapAddressInformation(addr
, 1, &addr_description
);
67 scariness
.Scare(42, "double-free");
72 struct ErrorNewDeleteSizeMismatch
: ErrorBase
{
73 // ErrorNewDeleteSizeMismatch doesn't own the stack trace.
74 const BufferedStackTrace
*free_stack
;
75 HeapAddressDescription addr_description
;
77 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
79 ErrorNewDeleteSizeMismatch() = default;
80 ErrorNewDeleteSizeMismatch(u32 tid
, BufferedStackTrace
*stack
, uptr addr
,
82 : ErrorBase(tid
), free_stack(stack
), delete_size(delete_size_
) {
83 GetHeapAddressInformation(addr
, 1, &addr_description
);
85 scariness
.Scare(10, "new-delete-type-mismatch");
90 struct ErrorFreeNotMalloced
: ErrorBase
{
91 // ErrorFreeNotMalloced doesn't own the stack trace.
92 const BufferedStackTrace
*free_stack
;
93 AddressDescription addr_description
;
94 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
96 ErrorFreeNotMalloced() = default;
97 ErrorFreeNotMalloced(u32 tid
, BufferedStackTrace
*stack
, uptr addr
)
100 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
102 scariness
.Scare(40, "bad-free");
107 struct ErrorAllocTypeMismatch
: ErrorBase
{
108 // ErrorAllocTypeMismatch doesn't own the stack trace.
109 const BufferedStackTrace
*dealloc_stack
;
110 HeapAddressDescription addr_description
;
111 AllocType alloc_type
, dealloc_type
;
112 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
114 ErrorAllocTypeMismatch() = default;
115 ErrorAllocTypeMismatch(u32 tid
, BufferedStackTrace
*stack
, uptr addr
,
116 AllocType alloc_type_
, AllocType dealloc_type_
)
118 dealloc_stack(stack
),
119 alloc_type(alloc_type_
),
120 dealloc_type(dealloc_type_
) {
121 GetHeapAddressInformation(addr
, 1, &addr_description
);
123 scariness
.Scare(10, "alloc-dealloc-mismatch");
128 struct ErrorMallocUsableSizeNotOwned
: ErrorBase
{
129 // ErrorMallocUsableSizeNotOwned doesn't own the stack trace.
130 const BufferedStackTrace
*stack
;
131 AddressDescription addr_description
;
132 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
134 ErrorMallocUsableSizeNotOwned() = default;
135 ErrorMallocUsableSizeNotOwned(u32 tid
, BufferedStackTrace
*stack_
, uptr addr
)
138 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
140 scariness
.Scare(10, "bad-malloc_usable_size");
145 struct ErrorSanitizerGetAllocatedSizeNotOwned
: ErrorBase
{
146 // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace.
147 const BufferedStackTrace
*stack
;
148 AddressDescription addr_description
;
149 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
151 ErrorSanitizerGetAllocatedSizeNotOwned() = default;
152 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid
, BufferedStackTrace
*stack_
,
156 addr_description(addr
, /*shouldLockThreadRegistry=*/false) {
158 scariness
.Scare(10, "bad-__sanitizer_get_allocated_size");
163 struct ErrorStringFunctionMemoryRangesOverlap
: ErrorBase
{
164 // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace.
165 const BufferedStackTrace
*stack
;
166 uptr length1
, length2
;
167 AddressDescription addr1_description
;
168 AddressDescription addr2_description
;
169 const char *function
;
170 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
172 ErrorStringFunctionMemoryRangesOverlap() = default;
173 ErrorStringFunctionMemoryRangesOverlap(u32 tid
, BufferedStackTrace
*stack_
,
174 uptr addr1
, uptr length1_
, uptr addr2
,
175 uptr length2_
, const char *function_
)
180 addr1_description(addr1
, length1
, /*shouldLockThreadRegistry=*/false),
181 addr2_description(addr2
, length2
, /*shouldLockThreadRegistry=*/false),
182 function(function_
) {
184 internal_snprintf(bug_type
, sizeof(bug_type
), "%s-param-overlap", function
);
186 scariness
.Scare(10, bug_type
);
191 struct ErrorStringFunctionSizeOverflow
: ErrorBase
{
192 // ErrorStringFunctionSizeOverflow doesn't own the stack trace.
193 const BufferedStackTrace
*stack
;
194 AddressDescription addr_description
;
196 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
198 ErrorStringFunctionSizeOverflow() = default;
199 ErrorStringFunctionSizeOverflow(u32 tid
, BufferedStackTrace
*stack_
,
200 uptr addr
, uptr size_
)
203 addr_description(addr
, /*shouldLockThreadRegistry=*/false),
206 scariness
.Scare(10, "negative-size-param");
211 struct ErrorBadParamsToAnnotateContiguousContainer
: ErrorBase
{
212 // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace.
213 const BufferedStackTrace
*stack
;
214 uptr beg
, end
, old_mid
, new_mid
;
215 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
217 ErrorBadParamsToAnnotateContiguousContainer() = default;
218 // PS4: Do we want an AddressDescription for beg?
219 ErrorBadParamsToAnnotateContiguousContainer(u32 tid
,
220 BufferedStackTrace
*stack_
,
221 uptr beg_
, uptr end_
,
222 uptr old_mid_
, uptr new_mid_
)
230 scariness
.Scare(10, "bad-__sanitizer_annotate_contiguous_container");
235 struct ErrorODRViolation
: ErrorBase
{
236 __asan_global global1
, global2
;
237 u32 stack_id1
, stack_id2
;
238 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
240 ErrorODRViolation() = default;
241 ErrorODRViolation(u32 tid
, const __asan_global
*g1
, u32 stack_id1_
,
242 const __asan_global
*g2
, u32 stack_id2_
)
246 stack_id1(stack_id1_
),
247 stack_id2(stack_id2_
) {
249 scariness
.Scare(10, "odr-violation");
254 struct ErrorInvalidPointerPair
: ErrorBase
{
256 AddressDescription addr1_description
;
257 AddressDescription addr2_description
;
258 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
260 ErrorInvalidPointerPair() = default;
261 ErrorInvalidPointerPair(u32 tid
, uptr pc_
, uptr bp_
, uptr sp_
, uptr p1
,
267 addr1_description(p1
, 1, /*shouldLockThreadRegistry=*/false),
268 addr2_description(p2
, 1, /*shouldLockThreadRegistry=*/false) {
270 scariness
.Scare(10, "invalid-pointer-pair");
275 struct ErrorGeneric
: ErrorBase
{
276 AddressDescription addr_description
;
279 const char *bug_descr
;
282 // VS2013 doesn't implement unrestricted unions, so we need a trivial default
284 ErrorGeneric() = default;
285 ErrorGeneric(u32 tid
, uptr addr
, uptr pc_
, uptr bp_
, uptr sp_
, bool is_write_
,
291 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
292 macro(DeadlySignal) \
294 macro(NewDeleteSizeMismatch) \
295 macro(FreeNotMalloced) \
296 macro(AllocTypeMismatch) \
297 macro(MallocUsableSizeNotOwned) \
298 macro(SanitizerGetAllocatedSizeNotOwned) \
299 macro(StringFunctionMemoryRangesOverlap) \
300 macro(StringFunctionSizeOverflow) \
301 macro(BadParamsToAnnotateContiguousContainer) \
302 macro(ODRViolation) \
303 macro(InvalidPointerPair) \
307 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
308 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
309 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
310 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
311 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
312 case kErrorKind##name: \
316 kErrorKindInvalid
= 0,
317 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND
)
320 struct ErrorDescription
{
322 // We're using a tagged union because it allows us to have a trivially
323 // copiable type and use the same structures as the public interface.
325 // We can add a wrapper around it to make it "more c++-like", but that would
326 // add a lot of code and the benefit wouldn't be that big.
329 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER
)
332 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
333 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
)
335 bool IsValid() { return kind
!= kErrorKindInvalid
; }
338 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT
)
339 case kErrorKindInvalid
:
346 #undef ASAN_FOR_EACH_ERROR_KIND
347 #undef ASAN_DEFINE_ERROR_KIND
348 #undef ASAN_ERROR_DESCRIPTION_MEMBER
349 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
350 #undef ASAN_ERROR_DESCRIPTION_PRINT
352 } // namespace __asan
354 #endif // ASAN_ERRORS_H