xref: /openbsd-src/gnu/llvm/compiler-rt/lib/asan/asan_errors.h (revision 810390e339a5425391477d5d41c78d7cab2424ac)
13cab2bb3Spatrick //===-- asan_errors.h -------------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick // ASan-private header for error structures.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick #ifndef ASAN_ERRORS_H
143cab2bb3Spatrick #define ASAN_ERRORS_H
153cab2bb3Spatrick 
163cab2bb3Spatrick #include "asan_descriptions.h"
173cab2bb3Spatrick #include "asan_scariness_score.h"
183cab2bb3Spatrick #include "sanitizer_common/sanitizer_common.h"
193cab2bb3Spatrick 
203cab2bb3Spatrick namespace __asan {
213cab2bb3Spatrick 
223cab2bb3Spatrick // (*) VS2013 does not implement unrestricted unions, so we need a trivial
233cab2bb3Spatrick // default constructor explicitly defined for each particular error.
243cab2bb3Spatrick 
253cab2bb3Spatrick // None of the error classes own the stack traces mentioned in them.
263cab2bb3Spatrick 
273cab2bb3Spatrick struct ErrorBase {
283cab2bb3Spatrick   ScarinessScoreBase scariness;
293cab2bb3Spatrick   u32 tid;
303cab2bb3Spatrick 
313cab2bb3Spatrick   ErrorBase() = default;  // (*)
ErrorBaseErrorBase323cab2bb3Spatrick   explicit ErrorBase(u32 tid_) : tid(tid_) {}
ErrorBaseErrorBase333cab2bb3Spatrick   ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
343cab2bb3Spatrick     scariness.Clear();
353cab2bb3Spatrick     scariness.Scare(initial_score, reason);
363cab2bb3Spatrick   }
373cab2bb3Spatrick };
383cab2bb3Spatrick 
393cab2bb3Spatrick struct ErrorDeadlySignal : ErrorBase {
403cab2bb3Spatrick   SignalContext signal;
413cab2bb3Spatrick 
423cab2bb3Spatrick   ErrorDeadlySignal() = default;  // (*)
ErrorDeadlySignalErrorDeadlySignal433cab2bb3Spatrick   ErrorDeadlySignal(u32 tid, const SignalContext &sig)
443cab2bb3Spatrick       : ErrorBase(tid),
453cab2bb3Spatrick         signal(sig) {
463cab2bb3Spatrick     scariness.Clear();
473cab2bb3Spatrick     if (signal.IsStackOverflow()) {
483cab2bb3Spatrick       scariness.Scare(10, "stack-overflow");
493cab2bb3Spatrick     } else if (!signal.is_memory_access) {
503cab2bb3Spatrick       scariness.Scare(10, "signal");
513cab2bb3Spatrick     } else if (signal.is_true_faulting_addr &&
523cab2bb3Spatrick                signal.addr < GetPageSizeCached()) {
533cab2bb3Spatrick       scariness.Scare(10, "null-deref");
543cab2bb3Spatrick     } else if (signal.addr == signal.pc) {
553cab2bb3Spatrick       scariness.Scare(60, "wild-jump");
56*810390e3Srobert     } else if (signal.write_flag == SignalContext::Write) {
573cab2bb3Spatrick       scariness.Scare(30, "wild-addr-write");
58*810390e3Srobert     } else if (signal.write_flag == SignalContext::Read) {
593cab2bb3Spatrick       scariness.Scare(20, "wild-addr-read");
603cab2bb3Spatrick     } else {
613cab2bb3Spatrick       scariness.Scare(25, "wild-addr");
623cab2bb3Spatrick     }
633cab2bb3Spatrick   }
643cab2bb3Spatrick   void Print();
653cab2bb3Spatrick };
663cab2bb3Spatrick 
673cab2bb3Spatrick struct ErrorDoubleFree : ErrorBase {
683cab2bb3Spatrick   const BufferedStackTrace *second_free_stack;
693cab2bb3Spatrick   HeapAddressDescription addr_description;
703cab2bb3Spatrick 
713cab2bb3Spatrick   ErrorDoubleFree() = default;  // (*)
ErrorDoubleFreeErrorDoubleFree723cab2bb3Spatrick   ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
733cab2bb3Spatrick       : ErrorBase(tid, 42, "double-free"),
743cab2bb3Spatrick         second_free_stack(stack) {
753cab2bb3Spatrick     CHECK_GT(second_free_stack->size, 0);
763cab2bb3Spatrick     GetHeapAddressInformation(addr, 1, &addr_description);
773cab2bb3Spatrick   }
783cab2bb3Spatrick   void Print();
793cab2bb3Spatrick };
803cab2bb3Spatrick 
813cab2bb3Spatrick struct ErrorNewDeleteTypeMismatch : ErrorBase {
823cab2bb3Spatrick   const BufferedStackTrace *free_stack;
833cab2bb3Spatrick   HeapAddressDescription addr_description;
843cab2bb3Spatrick   uptr delete_size;
853cab2bb3Spatrick   uptr delete_alignment;
863cab2bb3Spatrick 
873cab2bb3Spatrick   ErrorNewDeleteTypeMismatch() = default;  // (*)
ErrorNewDeleteTypeMismatchErrorNewDeleteTypeMismatch883cab2bb3Spatrick   ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
893cab2bb3Spatrick                              uptr delete_size_, uptr delete_alignment_)
903cab2bb3Spatrick       : ErrorBase(tid, 10, "new-delete-type-mismatch"),
913cab2bb3Spatrick         free_stack(stack),
923cab2bb3Spatrick         delete_size(delete_size_),
933cab2bb3Spatrick         delete_alignment(delete_alignment_) {
943cab2bb3Spatrick     GetHeapAddressInformation(addr, 1, &addr_description);
953cab2bb3Spatrick   }
963cab2bb3Spatrick   void Print();
973cab2bb3Spatrick };
983cab2bb3Spatrick 
993cab2bb3Spatrick struct ErrorFreeNotMalloced : ErrorBase {
1003cab2bb3Spatrick   const BufferedStackTrace *free_stack;
1013cab2bb3Spatrick   AddressDescription addr_description;
1023cab2bb3Spatrick 
1033cab2bb3Spatrick   ErrorFreeNotMalloced() = default;  // (*)
ErrorFreeNotMallocedErrorFreeNotMalloced1043cab2bb3Spatrick   ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
1053cab2bb3Spatrick       : ErrorBase(tid, 40, "bad-free"),
1063cab2bb3Spatrick         free_stack(stack),
1073cab2bb3Spatrick         addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
1083cab2bb3Spatrick   void Print();
1093cab2bb3Spatrick };
1103cab2bb3Spatrick 
1113cab2bb3Spatrick struct ErrorAllocTypeMismatch : ErrorBase {
1123cab2bb3Spatrick   const BufferedStackTrace *dealloc_stack;
1133cab2bb3Spatrick   AllocType alloc_type, dealloc_type;
1143cab2bb3Spatrick   AddressDescription addr_description;
1153cab2bb3Spatrick 
1163cab2bb3Spatrick   ErrorAllocTypeMismatch() = default;  // (*)
ErrorAllocTypeMismatchErrorAllocTypeMismatch1173cab2bb3Spatrick   ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
1183cab2bb3Spatrick                          AllocType alloc_type_, AllocType dealloc_type_)
1193cab2bb3Spatrick       : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
1203cab2bb3Spatrick         dealloc_stack(stack),
1213cab2bb3Spatrick         alloc_type(alloc_type_),
1223cab2bb3Spatrick         dealloc_type(dealloc_type_),
1233cab2bb3Spatrick         addr_description(addr, 1, false) {}
1243cab2bb3Spatrick   void Print();
1253cab2bb3Spatrick };
1263cab2bb3Spatrick 
1273cab2bb3Spatrick struct ErrorMallocUsableSizeNotOwned : ErrorBase {
1283cab2bb3Spatrick   const BufferedStackTrace *stack;
1293cab2bb3Spatrick   AddressDescription addr_description;
1303cab2bb3Spatrick 
1313cab2bb3Spatrick   ErrorMallocUsableSizeNotOwned() = default;  // (*)
ErrorMallocUsableSizeNotOwnedErrorMallocUsableSizeNotOwned1323cab2bb3Spatrick   ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
1333cab2bb3Spatrick       : ErrorBase(tid, 10, "bad-malloc_usable_size"),
1343cab2bb3Spatrick         stack(stack_),
1353cab2bb3Spatrick         addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
1363cab2bb3Spatrick   void Print();
1373cab2bb3Spatrick };
1383cab2bb3Spatrick 
1393cab2bb3Spatrick struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
1403cab2bb3Spatrick   const BufferedStackTrace *stack;
1413cab2bb3Spatrick   AddressDescription addr_description;
1423cab2bb3Spatrick 
1433cab2bb3Spatrick   ErrorSanitizerGetAllocatedSizeNotOwned() = default;  // (*)
ErrorSanitizerGetAllocatedSizeNotOwnedErrorSanitizerGetAllocatedSizeNotOwned1443cab2bb3Spatrick   ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
1453cab2bb3Spatrick                                          uptr addr)
1463cab2bb3Spatrick       : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
1473cab2bb3Spatrick         stack(stack_),
1483cab2bb3Spatrick         addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
1493cab2bb3Spatrick   void Print();
1503cab2bb3Spatrick };
1513cab2bb3Spatrick 
1523cab2bb3Spatrick struct ErrorCallocOverflow : ErrorBase {
1533cab2bb3Spatrick   const BufferedStackTrace *stack;
1543cab2bb3Spatrick   uptr count;
1553cab2bb3Spatrick   uptr size;
1563cab2bb3Spatrick 
1573cab2bb3Spatrick   ErrorCallocOverflow() = default;  // (*)
ErrorCallocOverflowErrorCallocOverflow1583cab2bb3Spatrick   ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
1593cab2bb3Spatrick                       uptr size_)
1603cab2bb3Spatrick       : ErrorBase(tid, 10, "calloc-overflow"),
1613cab2bb3Spatrick         stack(stack_),
1623cab2bb3Spatrick         count(count_),
1633cab2bb3Spatrick         size(size_) {}
1643cab2bb3Spatrick   void Print();
1653cab2bb3Spatrick };
1663cab2bb3Spatrick 
1673cab2bb3Spatrick struct ErrorReallocArrayOverflow : ErrorBase {
1683cab2bb3Spatrick   const BufferedStackTrace *stack;
1693cab2bb3Spatrick   uptr count;
1703cab2bb3Spatrick   uptr size;
1713cab2bb3Spatrick 
1723cab2bb3Spatrick   ErrorReallocArrayOverflow() = default;  // (*)
ErrorReallocArrayOverflowErrorReallocArrayOverflow1733cab2bb3Spatrick   ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
1743cab2bb3Spatrick                             uptr size_)
1753cab2bb3Spatrick       : ErrorBase(tid, 10, "reallocarray-overflow"),
1763cab2bb3Spatrick         stack(stack_),
1773cab2bb3Spatrick         count(count_),
1783cab2bb3Spatrick         size(size_) {}
1793cab2bb3Spatrick   void Print();
1803cab2bb3Spatrick };
1813cab2bb3Spatrick 
1823cab2bb3Spatrick struct ErrorPvallocOverflow : ErrorBase {
1833cab2bb3Spatrick   const BufferedStackTrace *stack;
1843cab2bb3Spatrick   uptr size;
1853cab2bb3Spatrick 
1863cab2bb3Spatrick   ErrorPvallocOverflow() = default;  // (*)
ErrorPvallocOverflowErrorPvallocOverflow1873cab2bb3Spatrick   ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
1883cab2bb3Spatrick       : ErrorBase(tid, 10, "pvalloc-overflow"),
1893cab2bb3Spatrick         stack(stack_),
1903cab2bb3Spatrick         size(size_) {}
1913cab2bb3Spatrick   void Print();
1923cab2bb3Spatrick };
1933cab2bb3Spatrick 
1943cab2bb3Spatrick struct ErrorInvalidAllocationAlignment : ErrorBase {
1953cab2bb3Spatrick   const BufferedStackTrace *stack;
1963cab2bb3Spatrick   uptr alignment;
1973cab2bb3Spatrick 
1983cab2bb3Spatrick   ErrorInvalidAllocationAlignment() = default;  // (*)
ErrorInvalidAllocationAlignmentErrorInvalidAllocationAlignment1993cab2bb3Spatrick   ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
2003cab2bb3Spatrick                                   uptr alignment_)
2013cab2bb3Spatrick       : ErrorBase(tid, 10, "invalid-allocation-alignment"),
2023cab2bb3Spatrick         stack(stack_),
2033cab2bb3Spatrick         alignment(alignment_) {}
2043cab2bb3Spatrick   void Print();
2053cab2bb3Spatrick };
2063cab2bb3Spatrick 
2073cab2bb3Spatrick struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
2083cab2bb3Spatrick   const BufferedStackTrace *stack;
2093cab2bb3Spatrick   uptr size;
2103cab2bb3Spatrick   uptr alignment;
2113cab2bb3Spatrick 
2123cab2bb3Spatrick   ErrorInvalidAlignedAllocAlignment() = default;  // (*)
ErrorInvalidAlignedAllocAlignmentErrorInvalidAlignedAllocAlignment2133cab2bb3Spatrick   ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
2143cab2bb3Spatrick                                     uptr size_, uptr alignment_)
2153cab2bb3Spatrick       : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
2163cab2bb3Spatrick         stack(stack_),
2173cab2bb3Spatrick         size(size_),
2183cab2bb3Spatrick         alignment(alignment_) {}
2193cab2bb3Spatrick   void Print();
2203cab2bb3Spatrick };
2213cab2bb3Spatrick 
2223cab2bb3Spatrick struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
2233cab2bb3Spatrick   const BufferedStackTrace *stack;
2243cab2bb3Spatrick   uptr alignment;
2253cab2bb3Spatrick 
2263cab2bb3Spatrick   ErrorInvalidPosixMemalignAlignment() = default;  // (*)
ErrorInvalidPosixMemalignAlignmentErrorInvalidPosixMemalignAlignment2273cab2bb3Spatrick   ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
2283cab2bb3Spatrick                                      uptr alignment_)
2293cab2bb3Spatrick       : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
2303cab2bb3Spatrick         stack(stack_),
2313cab2bb3Spatrick         alignment(alignment_) {}
2323cab2bb3Spatrick   void Print();
2333cab2bb3Spatrick };
2343cab2bb3Spatrick 
2353cab2bb3Spatrick struct ErrorAllocationSizeTooBig : ErrorBase {
2363cab2bb3Spatrick   const BufferedStackTrace *stack;
2373cab2bb3Spatrick   uptr user_size;
2383cab2bb3Spatrick   uptr total_size;
2393cab2bb3Spatrick   uptr max_size;
2403cab2bb3Spatrick 
2413cab2bb3Spatrick   ErrorAllocationSizeTooBig() = default;  // (*)
ErrorAllocationSizeTooBigErrorAllocationSizeTooBig2423cab2bb3Spatrick   ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
2433cab2bb3Spatrick                             uptr user_size_, uptr total_size_, uptr max_size_)
2443cab2bb3Spatrick       : ErrorBase(tid, 10, "allocation-size-too-big"),
2453cab2bb3Spatrick         stack(stack_),
2463cab2bb3Spatrick         user_size(user_size_),
2473cab2bb3Spatrick         total_size(total_size_),
2483cab2bb3Spatrick         max_size(max_size_) {}
2493cab2bb3Spatrick   void Print();
2503cab2bb3Spatrick };
2513cab2bb3Spatrick 
2523cab2bb3Spatrick struct ErrorRssLimitExceeded : ErrorBase {
2533cab2bb3Spatrick   const BufferedStackTrace *stack;
2543cab2bb3Spatrick 
2553cab2bb3Spatrick   ErrorRssLimitExceeded() = default;  // (*)
ErrorRssLimitExceededErrorRssLimitExceeded2563cab2bb3Spatrick   ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
2573cab2bb3Spatrick       : ErrorBase(tid, 10, "rss-limit-exceeded"),
2583cab2bb3Spatrick         stack(stack_) {}
2593cab2bb3Spatrick   void Print();
2603cab2bb3Spatrick };
2613cab2bb3Spatrick 
2623cab2bb3Spatrick struct ErrorOutOfMemory : ErrorBase {
2633cab2bb3Spatrick   const BufferedStackTrace *stack;
2643cab2bb3Spatrick   uptr requested_size;
2653cab2bb3Spatrick 
2663cab2bb3Spatrick   ErrorOutOfMemory() = default;  // (*)
ErrorOutOfMemoryErrorOutOfMemory2673cab2bb3Spatrick   ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
2683cab2bb3Spatrick       : ErrorBase(tid, 10, "out-of-memory"),
2693cab2bb3Spatrick         stack(stack_),
2703cab2bb3Spatrick         requested_size(requested_size_) {}
2713cab2bb3Spatrick   void Print();
2723cab2bb3Spatrick };
2733cab2bb3Spatrick 
2743cab2bb3Spatrick struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
2753cab2bb3Spatrick   const BufferedStackTrace *stack;
2763cab2bb3Spatrick   uptr length1, length2;
2773cab2bb3Spatrick   AddressDescription addr1_description;
2783cab2bb3Spatrick   AddressDescription addr2_description;
2793cab2bb3Spatrick   const char *function;
2803cab2bb3Spatrick 
2813cab2bb3Spatrick   ErrorStringFunctionMemoryRangesOverlap() = default;  // (*)
ErrorStringFunctionMemoryRangesOverlapErrorStringFunctionMemoryRangesOverlap2823cab2bb3Spatrick   ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
2833cab2bb3Spatrick                                          uptr addr1, uptr length1_, uptr addr2,
2843cab2bb3Spatrick                                          uptr length2_, const char *function_)
2853cab2bb3Spatrick       : ErrorBase(tid),
2863cab2bb3Spatrick         stack(stack_),
2873cab2bb3Spatrick         length1(length1_),
2883cab2bb3Spatrick         length2(length2_),
2893cab2bb3Spatrick         addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
2903cab2bb3Spatrick         addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
2913cab2bb3Spatrick         function(function_) {
2923cab2bb3Spatrick     char bug_type[100];
2933cab2bb3Spatrick     internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
2943cab2bb3Spatrick     scariness.Clear();
2953cab2bb3Spatrick     scariness.Scare(10, bug_type);
2963cab2bb3Spatrick   }
2973cab2bb3Spatrick   void Print();
2983cab2bb3Spatrick };
2993cab2bb3Spatrick 
3003cab2bb3Spatrick struct ErrorStringFunctionSizeOverflow : ErrorBase {
3013cab2bb3Spatrick   const BufferedStackTrace *stack;
3023cab2bb3Spatrick   AddressDescription addr_description;
3033cab2bb3Spatrick   uptr size;
3043cab2bb3Spatrick 
3053cab2bb3Spatrick   ErrorStringFunctionSizeOverflow() = default;  // (*)
ErrorStringFunctionSizeOverflowErrorStringFunctionSizeOverflow3063cab2bb3Spatrick   ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
3073cab2bb3Spatrick                                   uptr addr, uptr size_)
3083cab2bb3Spatrick       : ErrorBase(tid, 10, "negative-size-param"),
3093cab2bb3Spatrick         stack(stack_),
3103cab2bb3Spatrick         addr_description(addr, /*shouldLockThreadRegistry=*/false),
3113cab2bb3Spatrick         size(size_) {}
3123cab2bb3Spatrick   void Print();
3133cab2bb3Spatrick };
3143cab2bb3Spatrick 
3153cab2bb3Spatrick struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
3163cab2bb3Spatrick   const BufferedStackTrace *stack;
3173cab2bb3Spatrick   uptr beg, end, old_mid, new_mid;
3183cab2bb3Spatrick 
3193cab2bb3Spatrick   ErrorBadParamsToAnnotateContiguousContainer() = default;  // (*)
3203cab2bb3Spatrick   // PS4: Do we want an AddressDescription for beg?
ErrorBadParamsToAnnotateContiguousContainerErrorBadParamsToAnnotateContiguousContainer3213cab2bb3Spatrick   ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
3223cab2bb3Spatrick                                               BufferedStackTrace *stack_,
3233cab2bb3Spatrick                                               uptr beg_, uptr end_,
3243cab2bb3Spatrick                                               uptr old_mid_, uptr new_mid_)
3253cab2bb3Spatrick       : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
3263cab2bb3Spatrick         stack(stack_),
3273cab2bb3Spatrick         beg(beg_),
3283cab2bb3Spatrick         end(end_),
3293cab2bb3Spatrick         old_mid(old_mid_),
3303cab2bb3Spatrick         new_mid(new_mid_) {}
3313cab2bb3Spatrick   void Print();
3323cab2bb3Spatrick };
3333cab2bb3Spatrick 
334*810390e3Srobert struct ErrorBadParamsToAnnotateDoubleEndedContiguousContainer : ErrorBase {
335*810390e3Srobert   const BufferedStackTrace *stack;
336*810390e3Srobert   uptr storage_beg, storage_end, old_container_beg, old_container_end,
337*810390e3Srobert       new_container_beg, new_container_end;
338*810390e3Srobert 
339*810390e3Srobert   ErrorBadParamsToAnnotateDoubleEndedContiguousContainer() = default;  // (*)
ErrorBadParamsToAnnotateDoubleEndedContiguousContainerErrorBadParamsToAnnotateDoubleEndedContiguousContainer340*810390e3Srobert   ErrorBadParamsToAnnotateDoubleEndedContiguousContainer(
341*810390e3Srobert       u32 tid, BufferedStackTrace *stack_, uptr storage_beg_, uptr storage_end_,
342*810390e3Srobert       uptr old_container_beg_, uptr old_container_end_, uptr new_container_beg_,
343*810390e3Srobert       uptr new_container_end_)
344*810390e3Srobert       : ErrorBase(tid, 10,
345*810390e3Srobert                   "bad-__sanitizer_annotate_double_ended_contiguous_container"),
346*810390e3Srobert         stack(stack_),
347*810390e3Srobert         storage_beg(storage_beg_),
348*810390e3Srobert         storage_end(storage_end_),
349*810390e3Srobert         old_container_beg(old_container_beg_),
350*810390e3Srobert         old_container_end(old_container_end_),
351*810390e3Srobert         new_container_beg(new_container_beg_),
352*810390e3Srobert         new_container_end(new_container_end_) {}
353*810390e3Srobert   void Print();
354*810390e3Srobert };
355*810390e3Srobert 
3563cab2bb3Spatrick struct ErrorODRViolation : ErrorBase {
3573cab2bb3Spatrick   __asan_global global1, global2;
3583cab2bb3Spatrick   u32 stack_id1, stack_id2;
3593cab2bb3Spatrick 
3603cab2bb3Spatrick   ErrorODRViolation() = default;  // (*)
ErrorODRViolationErrorODRViolation3613cab2bb3Spatrick   ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
3623cab2bb3Spatrick                     const __asan_global *g2, u32 stack_id2_)
3633cab2bb3Spatrick       : ErrorBase(tid, 10, "odr-violation"),
3643cab2bb3Spatrick         global1(*g1),
3653cab2bb3Spatrick         global2(*g2),
3663cab2bb3Spatrick         stack_id1(stack_id1_),
3673cab2bb3Spatrick         stack_id2(stack_id2_) {}
3683cab2bb3Spatrick   void Print();
3693cab2bb3Spatrick };
3703cab2bb3Spatrick 
3713cab2bb3Spatrick struct ErrorInvalidPointerPair : ErrorBase {
3723cab2bb3Spatrick   uptr pc, bp, sp;
3733cab2bb3Spatrick   AddressDescription addr1_description;
3743cab2bb3Spatrick   AddressDescription addr2_description;
3753cab2bb3Spatrick 
3763cab2bb3Spatrick   ErrorInvalidPointerPair() = default;  // (*)
ErrorInvalidPointerPairErrorInvalidPointerPair3773cab2bb3Spatrick   ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
3783cab2bb3Spatrick                           uptr p2)
3793cab2bb3Spatrick       : ErrorBase(tid, 10, "invalid-pointer-pair"),
3803cab2bb3Spatrick         pc(pc_),
3813cab2bb3Spatrick         bp(bp_),
3823cab2bb3Spatrick         sp(sp_),
3833cab2bb3Spatrick         addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
3843cab2bb3Spatrick         addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
3853cab2bb3Spatrick   void Print();
3863cab2bb3Spatrick };
3873cab2bb3Spatrick 
3883cab2bb3Spatrick struct ErrorGeneric : ErrorBase {
3893cab2bb3Spatrick   AddressDescription addr_description;
3903cab2bb3Spatrick   uptr pc, bp, sp;
3913cab2bb3Spatrick   uptr access_size;
3923cab2bb3Spatrick   const char *bug_descr;
3933cab2bb3Spatrick   bool is_write;
3943cab2bb3Spatrick   u8 shadow_val;
3953cab2bb3Spatrick 
3963cab2bb3Spatrick   ErrorGeneric() = default;  // (*)
397*810390e3Srobert   ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, bool is_write_,
3983cab2bb3Spatrick                uptr access_size_);
3993cab2bb3Spatrick   void Print();
4003cab2bb3Spatrick };
4013cab2bb3Spatrick 
4023cab2bb3Spatrick // clang-format off
4033cab2bb3Spatrick #define ASAN_FOR_EACH_ERROR_KIND(macro)                    \
4043cab2bb3Spatrick   macro(DeadlySignal)                                      \
4053cab2bb3Spatrick   macro(DoubleFree)                                        \
4063cab2bb3Spatrick   macro(NewDeleteTypeMismatch)                             \
4073cab2bb3Spatrick   macro(FreeNotMalloced)                                   \
4083cab2bb3Spatrick   macro(AllocTypeMismatch)                                 \
4093cab2bb3Spatrick   macro(MallocUsableSizeNotOwned)                          \
4103cab2bb3Spatrick   macro(SanitizerGetAllocatedSizeNotOwned)                 \
4113cab2bb3Spatrick   macro(CallocOverflow)                                    \
4123cab2bb3Spatrick   macro(ReallocArrayOverflow)                              \
4133cab2bb3Spatrick   macro(PvallocOverflow)                                   \
4143cab2bb3Spatrick   macro(InvalidAllocationAlignment)                        \
4153cab2bb3Spatrick   macro(InvalidAlignedAllocAlignment)                      \
4163cab2bb3Spatrick   macro(InvalidPosixMemalignAlignment)                     \
4173cab2bb3Spatrick   macro(AllocationSizeTooBig)                              \
4183cab2bb3Spatrick   macro(RssLimitExceeded)                                  \
4193cab2bb3Spatrick   macro(OutOfMemory)                                       \
4203cab2bb3Spatrick   macro(StringFunctionMemoryRangesOverlap)                 \
4213cab2bb3Spatrick   macro(StringFunctionSizeOverflow)                        \
4223cab2bb3Spatrick   macro(BadParamsToAnnotateContiguousContainer)            \
423*810390e3Srobert   macro(BadParamsToAnnotateDoubleEndedContiguousContainer) \
4243cab2bb3Spatrick   macro(ODRViolation)                                      \
4253cab2bb3Spatrick   macro(InvalidPointerPair)                                \
4263cab2bb3Spatrick   macro(Generic)
4273cab2bb3Spatrick // clang-format on
4283cab2bb3Spatrick 
4293cab2bb3Spatrick #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
4303cab2bb3Spatrick #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
4313cab2bb3Spatrick #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name)                    \
4323cab2bb3Spatrick   ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \
4333cab2bb3Spatrick     internal_memcpy(&name, &e, sizeof(name));                       \
4343cab2bb3Spatrick   }
4353cab2bb3Spatrick #define ASAN_ERROR_DESCRIPTION_PRINT(name) \
4363cab2bb3Spatrick   case kErrorKind##name:                   \
4373cab2bb3Spatrick     return name.Print();
4383cab2bb3Spatrick 
4393cab2bb3Spatrick enum ErrorKind {
4403cab2bb3Spatrick   kErrorKindInvalid = 0,
4413cab2bb3Spatrick   ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
4423cab2bb3Spatrick };
4433cab2bb3Spatrick 
4443cab2bb3Spatrick struct ErrorDescription {
4453cab2bb3Spatrick   ErrorKind kind;
4463cab2bb3Spatrick   // We're using a tagged union because it allows us to have a trivially
4473cab2bb3Spatrick   // copiable type and use the same structures as the public interface.
4483cab2bb3Spatrick   //
4493cab2bb3Spatrick   // We can add a wrapper around it to make it "more c++-like", but that would
4503cab2bb3Spatrick   // add a lot of code and the benefit wouldn't be that big.
4513cab2bb3Spatrick   union {
4523cab2bb3Spatrick     ErrorBase Base;
4533cab2bb3Spatrick     ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
4543cab2bb3Spatrick   };
4553cab2bb3Spatrick 
ErrorDescriptionErrorDescription4563cab2bb3Spatrick   ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
ErrorDescriptionErrorDescription4573cab2bb3Spatrick   explicit ErrorDescription(LinkerInitialized) {}
ASAN_FOR_EACH_ERROR_KINDErrorDescription4583cab2bb3Spatrick   ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
4593cab2bb3Spatrick 
4603cab2bb3Spatrick   bool IsValid() { return kind != kErrorKindInvalid; }
PrintErrorDescription4613cab2bb3Spatrick   void Print() {
4623cab2bb3Spatrick     switch (kind) {
4633cab2bb3Spatrick       ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
4643cab2bb3Spatrick       case kErrorKindInvalid:
4653cab2bb3Spatrick         CHECK(0);
4663cab2bb3Spatrick     }
4673cab2bb3Spatrick     CHECK(0);
4683cab2bb3Spatrick   }
4693cab2bb3Spatrick };
4703cab2bb3Spatrick 
4713cab2bb3Spatrick #undef ASAN_FOR_EACH_ERROR_KIND
4723cab2bb3Spatrick #undef ASAN_DEFINE_ERROR_KIND
4733cab2bb3Spatrick #undef ASAN_ERROR_DESCRIPTION_MEMBER
4743cab2bb3Spatrick #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
4753cab2bb3Spatrick #undef ASAN_ERROR_DESCRIPTION_PRINT
4763cab2bb3Spatrick 
4773cab2bb3Spatrick }  // namespace __asan
4783cab2bb3Spatrick 
4793cab2bb3Spatrick #endif  // ASAN_ERRORS_H
480