1 //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file is a part of AddressSanitizer, an address sanity checker.
12 // ASan-private header for error structures.
13 //===----------------------------------------------------------------------===//
17 #include "asan_descriptions.h"
18 #include "asan_scariness_score.h"
19 #include "sanitizer_common/sanitizer_common.h"
23 // (*) VS2013 does not implement unrestricted unions, so we need a trivial
24 // default constructor explicitly defined for each particular error.
26 // None of the error classes own the stack traces mentioned in them.
29 ScarinessScoreBase scariness;
32 ErrorBase() = default; // (*)
33 explicit ErrorBase(u32 tid_) : tid(tid_) {}
34 ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
36 scariness.Scare(initial_score, reason);
40 struct ErrorDeadlySignal : ErrorBase {
43 ErrorDeadlySignal() = default; // (*)
44 ErrorDeadlySignal(u32 tid, const SignalContext &sig)
48 if (signal.IsStackOverflow()) {
49 scariness.Scare(10, "stack-overflow");
50 } else if (!signal.is_memory_access) {
51 scariness.Scare(10, "signal");
52 } else if (signal.addr < GetPageSizeCached()) {
53 scariness.Scare(10, "null-deref");
54 } else if (signal.addr == signal.pc) {
55 scariness.Scare(60, "wild-jump");
56 } else if (signal.write_flag == SignalContext::WRITE) {
57 scariness.Scare(30, "wild-addr-write");
58 } else if (signal.write_flag == SignalContext::READ) {
59 scariness.Scare(20, "wild-addr-read");
61 scariness.Scare(25, "wild-addr");
67 struct ErrorDoubleFree : ErrorBase {
68 const BufferedStackTrace *second_free_stack;
69 HeapAddressDescription addr_description;
71 ErrorDoubleFree() = default; // (*)
72 ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
73 : ErrorBase(tid, 42, "double-free"),
74 second_free_stack(stack) {
75 CHECK_GT(second_free_stack->size, 0);
76 GetHeapAddressInformation(addr, 1, &addr_description);
81 struct ErrorNewDeleteTypeMismatch : ErrorBase {
82 const BufferedStackTrace *free_stack;
83 HeapAddressDescription addr_description;
85 uptr delete_alignment;
87 ErrorNewDeleteTypeMismatch() = default; // (*)
88 ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
89 uptr delete_size_, uptr delete_alignment_)
90 : ErrorBase(tid, 10, "new-delete-type-mismatch"),
92 delete_size(delete_size_),
93 delete_alignment(delete_alignment_) {
94 GetHeapAddressInformation(addr, 1, &addr_description);
99 struct ErrorFreeNotMalloced : ErrorBase {
100 const BufferedStackTrace *free_stack;
101 AddressDescription addr_description;
103 ErrorFreeNotMalloced() = default; // (*)
104 ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
105 : ErrorBase(tid, 40, "bad-free"),
107 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
111 struct ErrorAllocTypeMismatch : ErrorBase {
112 const BufferedStackTrace *dealloc_stack;
113 AllocType alloc_type, dealloc_type;
114 AddressDescription addr_description;
116 ErrorAllocTypeMismatch() = default; // (*)
117 ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
118 AllocType alloc_type_, AllocType dealloc_type_)
119 : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
120 dealloc_stack(stack),
121 alloc_type(alloc_type_),
122 dealloc_type(dealloc_type_),
123 addr_description(addr, 1, false) {}
127 struct ErrorMallocUsableSizeNotOwned : ErrorBase {
128 const BufferedStackTrace *stack;
129 AddressDescription addr_description;
131 ErrorMallocUsableSizeNotOwned() = default; // (*)
132 ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
133 : ErrorBase(tid, 10, "bad-malloc_usable_size"),
135 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
139 struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
140 const BufferedStackTrace *stack;
141 AddressDescription addr_description;
143 ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*)
144 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
146 : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
148 addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
152 struct ErrorCallocOverflow : ErrorBase {
153 const BufferedStackTrace *stack;
157 ErrorCallocOverflow() = default; // (*)
158 ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
160 : ErrorBase(tid, 10, "calloc-overflow"),
167 struct ErrorPvallocOverflow : ErrorBase {
168 const BufferedStackTrace *stack;
171 ErrorPvallocOverflow() = default; // (*)
172 ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
173 : ErrorBase(tid, 10, "pvalloc-overflow"),
179 struct ErrorInvalidAllocationAlignment : ErrorBase {
180 const BufferedStackTrace *stack;
183 ErrorInvalidAllocationAlignment() = default; // (*)
184 ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
186 : ErrorBase(tid, 10, "invalid-allocation-alignment"),
188 alignment(alignment_) {}
192 struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
193 const BufferedStackTrace *stack;
197 ErrorInvalidAlignedAllocAlignment() = default; // (*)
198 ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
199 uptr size_, uptr alignment_)
200 : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
203 alignment(alignment_) {}
207 struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
208 const BufferedStackTrace *stack;
211 ErrorInvalidPosixMemalignAlignment() = default; // (*)
212 ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
214 : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
216 alignment(alignment_) {}
220 struct ErrorAllocationSizeTooBig : ErrorBase {
221 const BufferedStackTrace *stack;
226 ErrorAllocationSizeTooBig() = default; // (*)
227 ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
228 uptr user_size_, uptr total_size_, uptr max_size_)
229 : ErrorBase(tid, 10, "allocation-size-too-big"),
231 user_size(user_size_),
232 total_size(total_size_),
233 max_size(max_size_) {}
237 struct ErrorRssLimitExceeded : ErrorBase {
238 const BufferedStackTrace *stack;
240 ErrorRssLimitExceeded() = default; // (*)
241 ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
242 : ErrorBase(tid, 10, "rss-limit-exceeded"),
247 struct ErrorOutOfMemory : ErrorBase {
248 const BufferedStackTrace *stack;
251 ErrorOutOfMemory() = default; // (*)
252 ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
253 : ErrorBase(tid, 10, "out-of-memory"),
255 requested_size(requested_size_) {}
259 struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
260 const BufferedStackTrace *stack;
261 uptr length1, length2;
262 AddressDescription addr1_description;
263 AddressDescription addr2_description;
264 const char *function;
266 ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
267 ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
268 uptr addr1, uptr length1_, uptr addr2,
269 uptr length2_, const char *function_)
274 addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
275 addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
276 function(function_) {
278 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
280 scariness.Scare(10, bug_type);
285 struct ErrorStringFunctionSizeOverflow : ErrorBase {
286 const BufferedStackTrace *stack;
287 AddressDescription addr_description;
290 ErrorStringFunctionSizeOverflow() = default; // (*)
291 ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
292 uptr addr, uptr size_)
293 : ErrorBase(tid, 10, "negative-size-param"),
295 addr_description(addr, /*shouldLockThreadRegistry=*/false),
300 struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
301 const BufferedStackTrace *stack;
302 uptr beg, end, old_mid, new_mid;
304 ErrorBadParamsToAnnotateContiguousContainer() = default; // (*)
305 // PS4: Do we want an AddressDescription for beg?
306 ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
307 BufferedStackTrace *stack_,
308 uptr beg_, uptr end_,
309 uptr old_mid_, uptr new_mid_)
310 : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
319 struct ErrorODRViolation : ErrorBase {
320 __asan_global global1, global2;
321 u32 stack_id1, stack_id2;
323 ErrorODRViolation() = default; // (*)
324 ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
325 const __asan_global *g2, u32 stack_id2_)
326 : ErrorBase(tid, 10, "odr-violation"),
329 stack_id1(stack_id1_),
330 stack_id2(stack_id2_) {}
334 struct ErrorInvalidPointerPair : ErrorBase {
336 AddressDescription addr1_description;
337 AddressDescription addr2_description;
339 ErrorInvalidPointerPair() = default; // (*)
340 ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
342 : ErrorBase(tid, 10, "invalid-pointer-pair"),
346 addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
347 addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
351 struct ErrorGeneric : ErrorBase {
352 AddressDescription addr_description;
355 const char *bug_descr;
359 ErrorGeneric() = default; // (*)
360 ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
366 #define ASAN_FOR_EACH_ERROR_KIND(macro) \
367 macro(DeadlySignal) \
369 macro(NewDeleteTypeMismatch) \
370 macro(FreeNotMalloced) \
371 macro(AllocTypeMismatch) \
372 macro(MallocUsableSizeNotOwned) \
373 macro(SanitizerGetAllocatedSizeNotOwned) \
374 macro(CallocOverflow) \
375 macro(PvallocOverflow) \
376 macro(InvalidAllocationAlignment) \
377 macro(InvalidAlignedAllocAlignment) \
378 macro(InvalidPosixMemalignAlignment) \
379 macro(AllocationSizeTooBig) \
380 macro(RssLimitExceeded) \
382 macro(StringFunctionMemoryRangesOverlap) \
383 macro(StringFunctionSizeOverflow) \
384 macro(BadParamsToAnnotateContiguousContainer) \
385 macro(ODRViolation) \
386 macro(InvalidPointerPair) \
390 #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
391 #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
392 #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
393 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
394 #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
395 case kErrorKind##name: \
399 kErrorKindInvalid = 0,
400 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
403 struct ErrorDescription {
405 // We're using a tagged union because it allows us to have a trivially
406 // copiable type and use the same structures as the public interface.
408 // We can add a wrapper around it to make it "more c++-like", but that would
409 // add a lot of code and the benefit wouldn't be that big.
412 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
415 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
416 explicit ErrorDescription(LinkerInitialized) {}
417 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
419 bool IsValid() { return kind != kErrorKindInvalid; }
422 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
423 case kErrorKindInvalid:
430 #undef ASAN_FOR_EACH_ERROR_KIND
431 #undef ASAN_DEFINE_ERROR_KIND
432 #undef ASAN_ERROR_DESCRIPTION_MEMBER
433 #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
434 #undef ASAN_ERROR_DESCRIPTION_PRINT
436 } // namespace __asan
438 #endif // ASAN_ERRORS_H