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