10b57cec5SDimitry Andric //===-- asan_errors.h -------------------------------------------*- C++ -*-===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file is a part of AddressSanitizer, an address sanity checker. 100b57cec5SDimitry Andric // 110b57cec5SDimitry Andric // ASan-private header for error structures. 120b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 130b57cec5SDimitry Andric #ifndef ASAN_ERRORS_H 140b57cec5SDimitry Andric #define ASAN_ERRORS_H 150b57cec5SDimitry Andric 160b57cec5SDimitry Andric #include "asan_descriptions.h" 170b57cec5SDimitry Andric #include "asan_scariness_score.h" 180b57cec5SDimitry Andric #include "sanitizer_common/sanitizer_common.h" 190b57cec5SDimitry Andric 200b57cec5SDimitry Andric namespace __asan { 210b57cec5SDimitry Andric 220b57cec5SDimitry Andric // (*) VS2013 does not implement unrestricted unions, so we need a trivial 230b57cec5SDimitry Andric // default constructor explicitly defined for each particular error. 240b57cec5SDimitry Andric 250b57cec5SDimitry Andric // None of the error classes own the stack traces mentioned in them. 260b57cec5SDimitry Andric 270b57cec5SDimitry Andric struct ErrorBase { 280b57cec5SDimitry Andric ScarinessScoreBase scariness; 290b57cec5SDimitry Andric u32 tid; 300b57cec5SDimitry Andric 310b57cec5SDimitry Andric ErrorBase() = default; // (*) ErrorBaseErrorBase320b57cec5SDimitry Andric explicit ErrorBase(u32 tid_) : tid(tid_) {} ErrorBaseErrorBase330b57cec5SDimitry Andric ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) { 340b57cec5SDimitry Andric scariness.Clear(); 350b57cec5SDimitry Andric scariness.Scare(initial_score, reason); 360b57cec5SDimitry Andric } 370b57cec5SDimitry Andric }; 380b57cec5SDimitry Andric 390b57cec5SDimitry Andric struct ErrorDeadlySignal : ErrorBase { 400b57cec5SDimitry Andric SignalContext signal; 410b57cec5SDimitry Andric 420b57cec5SDimitry Andric ErrorDeadlySignal() = default; // (*) ErrorDeadlySignalErrorDeadlySignal430b57cec5SDimitry Andric ErrorDeadlySignal(u32 tid, const SignalContext &sig) 440b57cec5SDimitry Andric : ErrorBase(tid), 450b57cec5SDimitry Andric signal(sig) { 460b57cec5SDimitry Andric scariness.Clear(); 470b57cec5SDimitry Andric if (signal.IsStackOverflow()) { 480b57cec5SDimitry Andric scariness.Scare(10, "stack-overflow"); 490b57cec5SDimitry Andric } else if (!signal.is_memory_access) { 500b57cec5SDimitry Andric scariness.Scare(10, "signal"); 5168d75effSDimitry Andric } else if (signal.is_true_faulting_addr && 5268d75effSDimitry Andric signal.addr < GetPageSizeCached()) { 530b57cec5SDimitry Andric scariness.Scare(10, "null-deref"); 540b57cec5SDimitry Andric } else if (signal.addr == signal.pc) { 550b57cec5SDimitry Andric scariness.Scare(60, "wild-jump"); 56d56accc7SDimitry Andric } else if (signal.write_flag == SignalContext::Write) { 570b57cec5SDimitry Andric scariness.Scare(30, "wild-addr-write"); 58d56accc7SDimitry Andric } else if (signal.write_flag == SignalContext::Read) { 590b57cec5SDimitry Andric scariness.Scare(20, "wild-addr-read"); 600b57cec5SDimitry Andric } else { 610b57cec5SDimitry Andric scariness.Scare(25, "wild-addr"); 620b57cec5SDimitry Andric } 630b57cec5SDimitry Andric } 640b57cec5SDimitry Andric void Print(); 650b57cec5SDimitry Andric }; 660b57cec5SDimitry Andric 670b57cec5SDimitry Andric struct ErrorDoubleFree : ErrorBase { 680b57cec5SDimitry Andric const BufferedStackTrace *second_free_stack; 690b57cec5SDimitry Andric HeapAddressDescription addr_description; 700b57cec5SDimitry Andric 710b57cec5SDimitry Andric ErrorDoubleFree() = default; // (*) ErrorDoubleFreeErrorDoubleFree720b57cec5SDimitry Andric ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr) 730b57cec5SDimitry Andric : ErrorBase(tid, 42, "double-free"), 740b57cec5SDimitry Andric second_free_stack(stack) { 750b57cec5SDimitry Andric CHECK_GT(second_free_stack->size, 0); 760b57cec5SDimitry Andric GetHeapAddressInformation(addr, 1, &addr_description); 770b57cec5SDimitry Andric } 780b57cec5SDimitry Andric void Print(); 790b57cec5SDimitry Andric }; 800b57cec5SDimitry Andric 810b57cec5SDimitry Andric struct ErrorNewDeleteTypeMismatch : ErrorBase { 820b57cec5SDimitry Andric const BufferedStackTrace *free_stack; 830b57cec5SDimitry Andric HeapAddressDescription addr_description; 840b57cec5SDimitry Andric uptr delete_size; 850b57cec5SDimitry Andric uptr delete_alignment; 860b57cec5SDimitry Andric 870b57cec5SDimitry Andric ErrorNewDeleteTypeMismatch() = default; // (*) ErrorNewDeleteTypeMismatchErrorNewDeleteTypeMismatch880b57cec5SDimitry Andric ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 890b57cec5SDimitry Andric uptr delete_size_, uptr delete_alignment_) 900b57cec5SDimitry Andric : ErrorBase(tid, 10, "new-delete-type-mismatch"), 910b57cec5SDimitry Andric free_stack(stack), 920b57cec5SDimitry Andric delete_size(delete_size_), 930b57cec5SDimitry Andric delete_alignment(delete_alignment_) { 940b57cec5SDimitry Andric GetHeapAddressInformation(addr, 1, &addr_description); 950b57cec5SDimitry Andric } 960b57cec5SDimitry Andric void Print(); 970b57cec5SDimitry Andric }; 980b57cec5SDimitry Andric 990b57cec5SDimitry Andric struct ErrorFreeNotMalloced : ErrorBase { 1000b57cec5SDimitry Andric const BufferedStackTrace *free_stack; 1010b57cec5SDimitry Andric AddressDescription addr_description; 1020b57cec5SDimitry Andric 1030b57cec5SDimitry Andric ErrorFreeNotMalloced() = default; // (*) ErrorFreeNotMallocedErrorFreeNotMalloced1040b57cec5SDimitry Andric ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr) 1050b57cec5SDimitry Andric : ErrorBase(tid, 40, "bad-free"), 1060b57cec5SDimitry Andric free_stack(stack), 1070b57cec5SDimitry Andric addr_description(addr, /*shouldLockThreadRegistry=*/false) {} 1080b57cec5SDimitry Andric void Print(); 1090b57cec5SDimitry Andric }; 1100b57cec5SDimitry Andric 1110b57cec5SDimitry Andric struct ErrorAllocTypeMismatch : ErrorBase { 1120b57cec5SDimitry Andric const BufferedStackTrace *dealloc_stack; 1130b57cec5SDimitry Andric AllocType alloc_type, dealloc_type; 1140b57cec5SDimitry Andric AddressDescription addr_description; 1150b57cec5SDimitry Andric 1160b57cec5SDimitry Andric ErrorAllocTypeMismatch() = default; // (*) ErrorAllocTypeMismatchErrorAllocTypeMismatch1170b57cec5SDimitry Andric ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 1180b57cec5SDimitry Andric AllocType alloc_type_, AllocType dealloc_type_) 1190b57cec5SDimitry Andric : ErrorBase(tid, 10, "alloc-dealloc-mismatch"), 1200b57cec5SDimitry Andric dealloc_stack(stack), 1210b57cec5SDimitry Andric alloc_type(alloc_type_), 1220b57cec5SDimitry Andric dealloc_type(dealloc_type_), 1230b57cec5SDimitry Andric addr_description(addr, 1, false) {} 1240b57cec5SDimitry Andric void Print(); 1250b57cec5SDimitry Andric }; 1260b57cec5SDimitry Andric 1270b57cec5SDimitry Andric struct ErrorMallocUsableSizeNotOwned : ErrorBase { 1280b57cec5SDimitry Andric const BufferedStackTrace *stack; 1290b57cec5SDimitry Andric AddressDescription addr_description; 1300b57cec5SDimitry Andric 1310b57cec5SDimitry Andric ErrorMallocUsableSizeNotOwned() = default; // (*) ErrorMallocUsableSizeNotOwnedErrorMallocUsableSizeNotOwned1320b57cec5SDimitry Andric ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr) 1330b57cec5SDimitry Andric : ErrorBase(tid, 10, "bad-malloc_usable_size"), 1340b57cec5SDimitry Andric stack(stack_), 1350b57cec5SDimitry Andric addr_description(addr, /*shouldLockThreadRegistry=*/false) {} 1360b57cec5SDimitry Andric void Print(); 1370b57cec5SDimitry Andric }; 1380b57cec5SDimitry Andric 1390b57cec5SDimitry Andric struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase { 1400b57cec5SDimitry Andric const BufferedStackTrace *stack; 1410b57cec5SDimitry Andric AddressDescription addr_description; 1420b57cec5SDimitry Andric 1430b57cec5SDimitry Andric ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*) ErrorSanitizerGetAllocatedSizeNotOwnedErrorSanitizerGetAllocatedSizeNotOwned1440b57cec5SDimitry Andric ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_, 1450b57cec5SDimitry Andric uptr addr) 1460b57cec5SDimitry Andric : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"), 1470b57cec5SDimitry Andric stack(stack_), 1480b57cec5SDimitry Andric addr_description(addr, /*shouldLockThreadRegistry=*/false) {} 1490b57cec5SDimitry Andric void Print(); 1500b57cec5SDimitry Andric }; 1510b57cec5SDimitry Andric 1520b57cec5SDimitry Andric struct ErrorCallocOverflow : ErrorBase { 1530b57cec5SDimitry Andric const BufferedStackTrace *stack; 1540b57cec5SDimitry Andric uptr count; 1550b57cec5SDimitry Andric uptr size; 1560b57cec5SDimitry Andric 1570b57cec5SDimitry Andric ErrorCallocOverflow() = default; // (*) ErrorCallocOverflowErrorCallocOverflow1580b57cec5SDimitry Andric ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_, 1590b57cec5SDimitry Andric uptr size_) 1600b57cec5SDimitry Andric : ErrorBase(tid, 10, "calloc-overflow"), 1610b57cec5SDimitry Andric stack(stack_), 1620b57cec5SDimitry Andric count(count_), 1630b57cec5SDimitry Andric size(size_) {} 1640b57cec5SDimitry Andric void Print(); 1650b57cec5SDimitry Andric }; 1660b57cec5SDimitry Andric 1670b57cec5SDimitry Andric struct ErrorReallocArrayOverflow : ErrorBase { 1680b57cec5SDimitry Andric const BufferedStackTrace *stack; 1690b57cec5SDimitry Andric uptr count; 1700b57cec5SDimitry Andric uptr size; 1710b57cec5SDimitry Andric 1720b57cec5SDimitry Andric ErrorReallocArrayOverflow() = default; // (*) ErrorReallocArrayOverflowErrorReallocArrayOverflow1730b57cec5SDimitry Andric ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_, 1740b57cec5SDimitry Andric uptr size_) 1750b57cec5SDimitry Andric : ErrorBase(tid, 10, "reallocarray-overflow"), 1760b57cec5SDimitry Andric stack(stack_), 1770b57cec5SDimitry Andric count(count_), 1780b57cec5SDimitry Andric size(size_) {} 1790b57cec5SDimitry Andric void Print(); 1800b57cec5SDimitry Andric }; 1810b57cec5SDimitry Andric 1820b57cec5SDimitry Andric struct ErrorPvallocOverflow : ErrorBase { 1830b57cec5SDimitry Andric const BufferedStackTrace *stack; 1840b57cec5SDimitry Andric uptr size; 1850b57cec5SDimitry Andric 1860b57cec5SDimitry Andric ErrorPvallocOverflow() = default; // (*) ErrorPvallocOverflowErrorPvallocOverflow1870b57cec5SDimitry Andric ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_) 1880b57cec5SDimitry Andric : ErrorBase(tid, 10, "pvalloc-overflow"), 1890b57cec5SDimitry Andric stack(stack_), 1900b57cec5SDimitry Andric size(size_) {} 1910b57cec5SDimitry Andric void Print(); 1920b57cec5SDimitry Andric }; 1930b57cec5SDimitry Andric 1940b57cec5SDimitry Andric struct ErrorInvalidAllocationAlignment : ErrorBase { 1950b57cec5SDimitry Andric const BufferedStackTrace *stack; 1960b57cec5SDimitry Andric uptr alignment; 1970b57cec5SDimitry Andric 1980b57cec5SDimitry Andric ErrorInvalidAllocationAlignment() = default; // (*) ErrorInvalidAllocationAlignmentErrorInvalidAllocationAlignment1990b57cec5SDimitry Andric ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_, 2000b57cec5SDimitry Andric uptr alignment_) 2010b57cec5SDimitry Andric : ErrorBase(tid, 10, "invalid-allocation-alignment"), 2020b57cec5SDimitry Andric stack(stack_), 2030b57cec5SDimitry Andric alignment(alignment_) {} 2040b57cec5SDimitry Andric void Print(); 2050b57cec5SDimitry Andric }; 2060b57cec5SDimitry Andric 2070b57cec5SDimitry Andric struct ErrorInvalidAlignedAllocAlignment : ErrorBase { 2080b57cec5SDimitry Andric const BufferedStackTrace *stack; 2090b57cec5SDimitry Andric uptr size; 2100b57cec5SDimitry Andric uptr alignment; 2110b57cec5SDimitry Andric 2120b57cec5SDimitry Andric ErrorInvalidAlignedAllocAlignment() = default; // (*) ErrorInvalidAlignedAllocAlignmentErrorInvalidAlignedAllocAlignment2130b57cec5SDimitry Andric ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_, 2140b57cec5SDimitry Andric uptr size_, uptr alignment_) 2150b57cec5SDimitry Andric : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"), 2160b57cec5SDimitry Andric stack(stack_), 2170b57cec5SDimitry Andric size(size_), 2180b57cec5SDimitry Andric alignment(alignment_) {} 2190b57cec5SDimitry Andric void Print(); 2200b57cec5SDimitry Andric }; 2210b57cec5SDimitry Andric 2220b57cec5SDimitry Andric struct ErrorInvalidPosixMemalignAlignment : ErrorBase { 2230b57cec5SDimitry Andric const BufferedStackTrace *stack; 2240b57cec5SDimitry Andric uptr alignment; 2250b57cec5SDimitry Andric 2260b57cec5SDimitry Andric ErrorInvalidPosixMemalignAlignment() = default; // (*) ErrorInvalidPosixMemalignAlignmentErrorInvalidPosixMemalignAlignment2270b57cec5SDimitry Andric ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_, 2280b57cec5SDimitry Andric uptr alignment_) 2290b57cec5SDimitry Andric : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"), 2300b57cec5SDimitry Andric stack(stack_), 2310b57cec5SDimitry Andric alignment(alignment_) {} 2320b57cec5SDimitry Andric void Print(); 2330b57cec5SDimitry Andric }; 2340b57cec5SDimitry Andric 2350b57cec5SDimitry Andric struct ErrorAllocationSizeTooBig : ErrorBase { 2360b57cec5SDimitry Andric const BufferedStackTrace *stack; 2370b57cec5SDimitry Andric uptr user_size; 2380b57cec5SDimitry Andric uptr total_size; 2390b57cec5SDimitry Andric uptr max_size; 2400b57cec5SDimitry Andric 2410b57cec5SDimitry Andric ErrorAllocationSizeTooBig() = default; // (*) ErrorAllocationSizeTooBigErrorAllocationSizeTooBig2420b57cec5SDimitry Andric ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_, 2430b57cec5SDimitry Andric uptr user_size_, uptr total_size_, uptr max_size_) 2440b57cec5SDimitry Andric : ErrorBase(tid, 10, "allocation-size-too-big"), 2450b57cec5SDimitry Andric stack(stack_), 2460b57cec5SDimitry Andric user_size(user_size_), 2470b57cec5SDimitry Andric total_size(total_size_), 2480b57cec5SDimitry Andric max_size(max_size_) {} 2490b57cec5SDimitry Andric void Print(); 2500b57cec5SDimitry Andric }; 2510b57cec5SDimitry Andric 2520b57cec5SDimitry Andric struct ErrorRssLimitExceeded : ErrorBase { 2530b57cec5SDimitry Andric const BufferedStackTrace *stack; 2540b57cec5SDimitry Andric 2550b57cec5SDimitry Andric ErrorRssLimitExceeded() = default; // (*) ErrorRssLimitExceededErrorRssLimitExceeded2560b57cec5SDimitry Andric ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_) 2570b57cec5SDimitry Andric : ErrorBase(tid, 10, "rss-limit-exceeded"), 2580b57cec5SDimitry Andric stack(stack_) {} 2590b57cec5SDimitry Andric void Print(); 2600b57cec5SDimitry Andric }; 2610b57cec5SDimitry Andric 2620b57cec5SDimitry Andric struct ErrorOutOfMemory : ErrorBase { 2630b57cec5SDimitry Andric const BufferedStackTrace *stack; 2640b57cec5SDimitry Andric uptr requested_size; 2650b57cec5SDimitry Andric 2660b57cec5SDimitry Andric ErrorOutOfMemory() = default; // (*) ErrorOutOfMemoryErrorOutOfMemory2670b57cec5SDimitry Andric ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_) 2680b57cec5SDimitry Andric : ErrorBase(tid, 10, "out-of-memory"), 2690b57cec5SDimitry Andric stack(stack_), 2700b57cec5SDimitry Andric requested_size(requested_size_) {} 2710b57cec5SDimitry Andric void Print(); 2720b57cec5SDimitry Andric }; 2730b57cec5SDimitry Andric 2740b57cec5SDimitry Andric struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase { 2750b57cec5SDimitry Andric const BufferedStackTrace *stack; 2760b57cec5SDimitry Andric uptr length1, length2; 2770b57cec5SDimitry Andric AddressDescription addr1_description; 2780b57cec5SDimitry Andric AddressDescription addr2_description; 2790b57cec5SDimitry Andric const char *function; 2800b57cec5SDimitry Andric 2810b57cec5SDimitry Andric ErrorStringFunctionMemoryRangesOverlap() = default; // (*) ErrorStringFunctionMemoryRangesOverlapErrorStringFunctionMemoryRangesOverlap2820b57cec5SDimitry Andric ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_, 2830b57cec5SDimitry Andric uptr addr1, uptr length1_, uptr addr2, 2840b57cec5SDimitry Andric uptr length2_, const char *function_) 2850b57cec5SDimitry Andric : ErrorBase(tid), 2860b57cec5SDimitry Andric stack(stack_), 2870b57cec5SDimitry Andric length1(length1_), 2880b57cec5SDimitry Andric length2(length2_), 2890b57cec5SDimitry Andric addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false), 2900b57cec5SDimitry Andric addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false), 2910b57cec5SDimitry Andric function(function_) { 2920b57cec5SDimitry Andric char bug_type[100]; 2930b57cec5SDimitry Andric internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 2940b57cec5SDimitry Andric scariness.Clear(); 2950b57cec5SDimitry Andric scariness.Scare(10, bug_type); 2960b57cec5SDimitry Andric } 2970b57cec5SDimitry Andric void Print(); 2980b57cec5SDimitry Andric }; 2990b57cec5SDimitry Andric 3000b57cec5SDimitry Andric struct ErrorStringFunctionSizeOverflow : ErrorBase { 3010b57cec5SDimitry Andric const BufferedStackTrace *stack; 3020b57cec5SDimitry Andric AddressDescription addr_description; 3030b57cec5SDimitry Andric uptr size; 3040b57cec5SDimitry Andric 3050b57cec5SDimitry Andric ErrorStringFunctionSizeOverflow() = default; // (*) ErrorStringFunctionSizeOverflowErrorStringFunctionSizeOverflow3060b57cec5SDimitry Andric ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_, 3070b57cec5SDimitry Andric uptr addr, uptr size_) 3080b57cec5SDimitry Andric : ErrorBase(tid, 10, "negative-size-param"), 3090b57cec5SDimitry Andric stack(stack_), 3100b57cec5SDimitry Andric addr_description(addr, /*shouldLockThreadRegistry=*/false), 3110b57cec5SDimitry Andric size(size_) {} 3120b57cec5SDimitry Andric void Print(); 3130b57cec5SDimitry Andric }; 3140b57cec5SDimitry Andric 3150b57cec5SDimitry Andric struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase { 3160b57cec5SDimitry Andric const BufferedStackTrace *stack; 3170b57cec5SDimitry Andric uptr beg, end, old_mid, new_mid; 3180b57cec5SDimitry Andric 3190b57cec5SDimitry Andric ErrorBadParamsToAnnotateContiguousContainer() = default; // (*) 3200b57cec5SDimitry Andric // PS4: Do we want an AddressDescription for beg? ErrorBadParamsToAnnotateContiguousContainerErrorBadParamsToAnnotateContiguousContainer3210b57cec5SDimitry Andric ErrorBadParamsToAnnotateContiguousContainer(u32 tid, 3220b57cec5SDimitry Andric BufferedStackTrace *stack_, 3230b57cec5SDimitry Andric uptr beg_, uptr end_, 3240b57cec5SDimitry Andric uptr old_mid_, uptr new_mid_) 3250b57cec5SDimitry Andric : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"), 3260b57cec5SDimitry Andric stack(stack_), 3270b57cec5SDimitry Andric beg(beg_), 3280b57cec5SDimitry Andric end(end_), 3290b57cec5SDimitry Andric old_mid(old_mid_), 3300b57cec5SDimitry Andric new_mid(new_mid_) {} 3310b57cec5SDimitry Andric void Print(); 3320b57cec5SDimitry Andric }; 3330b57cec5SDimitry Andric 334bdd1243dSDimitry Andric struct ErrorBadParamsToAnnotateDoubleEndedContiguousContainer : ErrorBase { 335bdd1243dSDimitry Andric const BufferedStackTrace *stack; 336bdd1243dSDimitry Andric uptr storage_beg, storage_end, old_container_beg, old_container_end, 337bdd1243dSDimitry Andric new_container_beg, new_container_end; 338bdd1243dSDimitry Andric 339bdd1243dSDimitry Andric ErrorBadParamsToAnnotateDoubleEndedContiguousContainer() = default; // (*) ErrorBadParamsToAnnotateDoubleEndedContiguousContainerErrorBadParamsToAnnotateDoubleEndedContiguousContainer340bdd1243dSDimitry Andric ErrorBadParamsToAnnotateDoubleEndedContiguousContainer( 341bdd1243dSDimitry Andric u32 tid, BufferedStackTrace *stack_, uptr storage_beg_, uptr storage_end_, 342bdd1243dSDimitry Andric uptr old_container_beg_, uptr old_container_end_, uptr new_container_beg_, 343bdd1243dSDimitry Andric uptr new_container_end_) 344bdd1243dSDimitry Andric : ErrorBase(tid, 10, 345bdd1243dSDimitry Andric "bad-__sanitizer_annotate_double_ended_contiguous_container"), 346bdd1243dSDimitry Andric stack(stack_), 347bdd1243dSDimitry Andric storage_beg(storage_beg_), 348bdd1243dSDimitry Andric storage_end(storage_end_), 349bdd1243dSDimitry Andric old_container_beg(old_container_beg_), 350bdd1243dSDimitry Andric old_container_end(old_container_end_), 351bdd1243dSDimitry Andric new_container_beg(new_container_beg_), 352bdd1243dSDimitry Andric new_container_end(new_container_end_) {} 353bdd1243dSDimitry Andric void Print(); 354bdd1243dSDimitry Andric }; 355bdd1243dSDimitry Andric 3560b57cec5SDimitry Andric struct ErrorODRViolation : ErrorBase { 3570b57cec5SDimitry Andric __asan_global global1, global2; 3580b57cec5SDimitry Andric u32 stack_id1, stack_id2; 3590b57cec5SDimitry Andric 3600b57cec5SDimitry Andric ErrorODRViolation() = default; // (*) ErrorODRViolationErrorODRViolation3610b57cec5SDimitry Andric ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, 3620b57cec5SDimitry Andric const __asan_global *g2, u32 stack_id2_) 3630b57cec5SDimitry Andric : ErrorBase(tid, 10, "odr-violation"), 3640b57cec5SDimitry Andric global1(*g1), 3650b57cec5SDimitry Andric global2(*g2), 3660b57cec5SDimitry Andric stack_id1(stack_id1_), 3670b57cec5SDimitry Andric stack_id2(stack_id2_) {} 3680b57cec5SDimitry Andric void Print(); 3690b57cec5SDimitry Andric }; 3700b57cec5SDimitry Andric 3710b57cec5SDimitry Andric struct ErrorInvalidPointerPair : ErrorBase { 3720b57cec5SDimitry Andric uptr pc, bp, sp; 3730b57cec5SDimitry Andric AddressDescription addr1_description; 3740b57cec5SDimitry Andric AddressDescription addr2_description; 3750b57cec5SDimitry Andric 3760b57cec5SDimitry Andric ErrorInvalidPointerPair() = default; // (*) ErrorInvalidPointerPairErrorInvalidPointerPair3770b57cec5SDimitry Andric ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1, 3780b57cec5SDimitry Andric uptr p2) 3790b57cec5SDimitry Andric : ErrorBase(tid, 10, "invalid-pointer-pair"), 3800b57cec5SDimitry Andric pc(pc_), 3810b57cec5SDimitry Andric bp(bp_), 3820b57cec5SDimitry Andric sp(sp_), 3830b57cec5SDimitry Andric addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false), 3840b57cec5SDimitry Andric addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {} 3850b57cec5SDimitry Andric void Print(); 3860b57cec5SDimitry Andric }; 3870b57cec5SDimitry Andric 3880b57cec5SDimitry Andric struct ErrorGeneric : ErrorBase { 3890b57cec5SDimitry Andric AddressDescription addr_description; 3900b57cec5SDimitry Andric uptr pc, bp, sp; 3910b57cec5SDimitry Andric uptr access_size; 3920b57cec5SDimitry Andric const char *bug_descr; 3930b57cec5SDimitry Andric bool is_write; 3940b57cec5SDimitry Andric u8 shadow_val; 3950b57cec5SDimitry Andric 3960b57cec5SDimitry Andric ErrorGeneric() = default; // (*) 39781ad6265SDimitry Andric ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, bool is_write_, 3980b57cec5SDimitry Andric uptr access_size_); 3990b57cec5SDimitry Andric void Print(); 4000b57cec5SDimitry Andric }; 4010b57cec5SDimitry Andric 4020b57cec5SDimitry Andric // clang-format off 4030b57cec5SDimitry Andric #define ASAN_FOR_EACH_ERROR_KIND(macro) \ 4040b57cec5SDimitry Andric macro(DeadlySignal) \ 4050b57cec5SDimitry Andric macro(DoubleFree) \ 4060b57cec5SDimitry Andric macro(NewDeleteTypeMismatch) \ 4070b57cec5SDimitry Andric macro(FreeNotMalloced) \ 4080b57cec5SDimitry Andric macro(AllocTypeMismatch) \ 4090b57cec5SDimitry Andric macro(MallocUsableSizeNotOwned) \ 4100b57cec5SDimitry Andric macro(SanitizerGetAllocatedSizeNotOwned) \ 4110b57cec5SDimitry Andric macro(CallocOverflow) \ 4120b57cec5SDimitry Andric macro(ReallocArrayOverflow) \ 4130b57cec5SDimitry Andric macro(PvallocOverflow) \ 4140b57cec5SDimitry Andric macro(InvalidAllocationAlignment) \ 4150b57cec5SDimitry Andric macro(InvalidAlignedAllocAlignment) \ 4160b57cec5SDimitry Andric macro(InvalidPosixMemalignAlignment) \ 4170b57cec5SDimitry Andric macro(AllocationSizeTooBig) \ 4180b57cec5SDimitry Andric macro(RssLimitExceeded) \ 4190b57cec5SDimitry Andric macro(OutOfMemory) \ 4200b57cec5SDimitry Andric macro(StringFunctionMemoryRangesOverlap) \ 4210b57cec5SDimitry Andric macro(StringFunctionSizeOverflow) \ 4220b57cec5SDimitry Andric macro(BadParamsToAnnotateContiguousContainer) \ 423bdd1243dSDimitry Andric macro(BadParamsToAnnotateDoubleEndedContiguousContainer) \ 4240b57cec5SDimitry Andric macro(ODRViolation) \ 4250b57cec5SDimitry Andric macro(InvalidPointerPair) \ 4260b57cec5SDimitry Andric macro(Generic) 4270b57cec5SDimitry Andric // clang-format on 4280b57cec5SDimitry Andric 4290b57cec5SDimitry Andric #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name, 4300b57cec5SDimitry Andric #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name; 4310b57cec5SDimitry Andric #define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \ 4320b57cec5SDimitry Andric ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \ 4330b57cec5SDimitry Andric internal_memcpy(&name, &e, sizeof(name)); \ 4340b57cec5SDimitry Andric } 4350b57cec5SDimitry Andric #define ASAN_ERROR_DESCRIPTION_PRINT(name) \ 4360b57cec5SDimitry Andric case kErrorKind##name: \ 4370b57cec5SDimitry Andric return name.Print(); 4380b57cec5SDimitry Andric 4390b57cec5SDimitry Andric enum ErrorKind { 4400b57cec5SDimitry Andric kErrorKindInvalid = 0, 4410b57cec5SDimitry Andric ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND) 4420b57cec5SDimitry Andric }; 4430b57cec5SDimitry Andric 4440b57cec5SDimitry Andric struct ErrorDescription { 4450b57cec5SDimitry Andric ErrorKind kind; 4460b57cec5SDimitry Andric // We're using a tagged union because it allows us to have a trivially 4470b57cec5SDimitry Andric // copiable type and use the same structures as the public interface. 4480b57cec5SDimitry Andric // 4490b57cec5SDimitry Andric // We can add a wrapper around it to make it "more c++-like", but that would 4500b57cec5SDimitry Andric // add a lot of code and the benefit wouldn't be that big. 4510b57cec5SDimitry Andric union { 4520b57cec5SDimitry Andric ErrorBase Base; 4530b57cec5SDimitry Andric ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER) 4540b57cec5SDimitry Andric }; 4550b57cec5SDimitry Andric ErrorDescriptionErrorDescription4560b57cec5SDimitry Andric ErrorDescription() { internal_memset(this, 0, sizeof(*this)); } ErrorDescriptionErrorDescription4570b57cec5SDimitry Andric explicit ErrorDescription(LinkerInitialized) {} ASAN_FOR_EACH_ERROR_KINDErrorDescription4580b57cec5SDimitry Andric ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR) 4590b57cec5SDimitry Andric 4600b57cec5SDimitry Andric bool IsValid() { return kind != kErrorKindInvalid; } PrintErrorDescription4610b57cec5SDimitry Andric void Print() { 4620b57cec5SDimitry Andric switch (kind) { 4630b57cec5SDimitry Andric ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT) 4640b57cec5SDimitry Andric case kErrorKindInvalid: 4650b57cec5SDimitry Andric CHECK(0); 4660b57cec5SDimitry Andric } 4670b57cec5SDimitry Andric CHECK(0); 4680b57cec5SDimitry Andric } 4690b57cec5SDimitry Andric }; 4700b57cec5SDimitry Andric 4710b57cec5SDimitry Andric #undef ASAN_FOR_EACH_ERROR_KIND 4720b57cec5SDimitry Andric #undef ASAN_DEFINE_ERROR_KIND 4730b57cec5SDimitry Andric #undef ASAN_ERROR_DESCRIPTION_MEMBER 4740b57cec5SDimitry Andric #undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR 4750b57cec5SDimitry Andric #undef ASAN_ERROR_DESCRIPTION_PRINT 4760b57cec5SDimitry Andric 4770b57cec5SDimitry Andric } // namespace __asan 4780b57cec5SDimitry Andric 4790b57cec5SDimitry Andric #endif // ASAN_ERRORS_H 480