asan_errors.h revision 327952
1193326Sed//===-- asan_errors.h -------------------------------------------*- C++ -*-===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file is a part of AddressSanitizer, an address sanity checker. 11193326Sed// 12193326Sed// ASan-private header for error structures. 13193326Sed//===----------------------------------------------------------------------===// 14252723Sdim#ifndef ASAN_ERRORS_H 15207619Srdivacky#define ASAN_ERRORS_H 16245431Sdim 17193326Sed#include "asan_descriptions.h" 18207619Srdivacky#include "asan_scariness_score.h" 19235633Sdim#include "sanitizer_common/sanitizer_common.h" 20245431Sdim 21252723Sdimnamespace __asan { 22198398Srdivacky 23221345Sdimstruct ErrorBase { 24193326Sed ErrorBase() = default; 25193326Sed explicit ErrorBase(u32 tid_) : tid(tid_) {} 26226890Sdim ScarinessScoreBase scariness; 27193326Sed u32 tid; 28193326Sed}; 29226890Sdim 30198398Srdivackystruct ErrorDeadlySignal : ErrorBase { 31226890Sdim SignalContext signal; 32224145Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 33235633Sdim // constructor 34193326Sed ErrorDeadlySignal() = default; 35193326Sed ErrorDeadlySignal(u32 tid, const SignalContext &sig) 36193326Sed : ErrorBase(tid), signal(sig) { 37193326Sed scariness.Clear(); 38193326Sed if (signal.IsStackOverflow()) { 39226890Sdim scariness.Scare(10, "stack-overflow"); 40235633Sdim } else if (!signal.is_memory_access) { 41245431Sdim scariness.Scare(10, "signal"); 42226890Sdim } else if (signal.addr < GetPageSizeCached()) { 43245431Sdim scariness.Scare(10, "null-deref"); 44245431Sdim } else if (signal.addr == signal.pc) { 45212904Sdim scariness.Scare(60, "wild-jump"); 46212904Sdim } else if (signal.write_flag == SignalContext::WRITE) { 47212904Sdim scariness.Scare(30, "wild-addr-write"); 48193326Sed } else if (signal.write_flag == SignalContext::READ) { 49193326Sed scariness.Scare(20, "wild-addr-read"); 50193326Sed } else { 51226890Sdim scariness.Scare(25, "wild-addr"); 52201361Srdivacky } 53193326Sed } 54198092Srdivacky void Print(); 55245431Sdim}; 56245431Sdim 57245431Sdimstruct ErrorDoubleFree : ErrorBase { 58210299Sed // ErrorDoubleFree doesn't own the stack trace. 59193326Sed const BufferedStackTrace *second_free_stack; 60198092Srdivacky HeapAddressDescription addr_description; 61207619Srdivacky // VS2013 doesn't implement unrestricted unions, so we need a trivial default 62207619Srdivacky // constructor 63235633Sdim ErrorDoubleFree() = default; 64198092Srdivacky ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr) 65212904Sdim : ErrorBase(tid), second_free_stack(stack) { 66193326Sed CHECK_GT(second_free_stack->size, 0); 67193326Sed GetHeapAddressInformation(addr, 1, &addr_description); 68226890Sdim scariness.Clear(); 69218893Sdim scariness.Scare(42, "double-free"); 70218893Sdim } 71193326Sed void Print(); 72193326Sed}; 73226890Sdim 74226890Sdimstruct ErrorNewDeleteTypeMismatch : ErrorBase { 75218893Sdim // ErrorNewDeleteTypeMismatch doesn't own the stack trace. 76218893Sdim const BufferedStackTrace *free_stack; 77218893Sdim HeapAddressDescription addr_description; 78218893Sdim uptr delete_size; 79218893Sdim uptr delete_alignment; 80218893Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 81198092Srdivacky // constructor 82226890Sdim ErrorNewDeleteTypeMismatch() = default; 83218893Sdim ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 84198092Srdivacky uptr delete_size_, uptr delete_alignment_) 85198092Srdivacky : ErrorBase(tid), free_stack(stack), delete_size(delete_size_), 86226890Sdim delete_alignment(delete_alignment_) { 87218893Sdim GetHeapAddressInformation(addr, 1, &addr_description); 88198092Srdivacky scariness.Clear(); 89198092Srdivacky scariness.Scare(10, "new-delete-type-mismatch"); 90218893Sdim } 91218893Sdim void Print(); 92218893Sdim}; 93218893Sdim 94218893Sdimstruct ErrorFreeNotMalloced : ErrorBase { 95198092Srdivacky // ErrorFreeNotMalloced doesn't own the stack trace. 96198092Srdivacky const BufferedStackTrace *free_stack; 97198092Srdivacky AddressDescription addr_description; 98226890Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 99212904Sdim // constructor 100252723Sdim ErrorFreeNotMalloced() = default; 101212904Sdim ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr) 102224145Sdim : ErrorBase(tid), 103212904Sdim free_stack(stack), 104212904Sdim addr_description(addr, /*shouldLockThreadRegistry=*/false) { 105212904Sdim scariness.Clear(); 106212904Sdim scariness.Scare(40, "bad-free"); 107226890Sdim } 108226890Sdim void Print(); 109224145Sdim}; 110212904Sdim 111252723Sdimstruct ErrorAllocTypeMismatch : ErrorBase { 112212904Sdim // ErrorAllocTypeMismatch doesn't own the stack trace. 113221345Sdim const BufferedStackTrace *dealloc_stack; 114221345Sdim HeapAddressDescription addr_description; 115221345Sdim AllocType alloc_type, dealloc_type; 116221345Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 117221345Sdim // constructor 118221345Sdim ErrorAllocTypeMismatch() = default; 119221345Sdim ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 120221345Sdim AllocType alloc_type_, AllocType dealloc_type_) 121221345Sdim : ErrorBase(tid), 122245431Sdim dealloc_stack(stack), 123212904Sdim alloc_type(alloc_type_), 124193326Sed dealloc_type(dealloc_type_) { 125226890Sdim GetHeapAddressInformation(addr, 1, &addr_description); 126235633Sdim scariness.Clear(); 127206084Srdivacky scariness.Scare(10, "alloc-dealloc-mismatch"); 128206084Srdivacky }; 129206084Srdivacky void Print(); 130206084Srdivacky}; 131206084Srdivacky 132206084Srdivackystruct ErrorMallocUsableSizeNotOwned : ErrorBase { 133206084Srdivacky // ErrorMallocUsableSizeNotOwned doesn't own the stack trace. 134206084Srdivacky const BufferedStackTrace *stack; 135226890Sdim AddressDescription addr_description; 136206084Srdivacky // VS2013 doesn't implement unrestricted unions, so we need a trivial default 137206084Srdivacky // constructor 138206084Srdivacky ErrorMallocUsableSizeNotOwned() = default; 139206084Srdivacky ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr) 140206084Srdivacky : ErrorBase(tid), 141206084Srdivacky stack(stack_), 142226890Sdim addr_description(addr, /*shouldLockThreadRegistry=*/false) { 143226890Sdim scariness.Clear(); 144218893Sdim scariness.Scare(10, "bad-malloc_usable_size"); 145218893Sdim } 146218893Sdim void Print(); 147198092Srdivacky}; 148245431Sdim 149245431Sdimstruct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase { 150245431Sdim // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace. 151218893Sdim const BufferedStackTrace *stack; 152218893Sdim AddressDescription addr_description; 153218893Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 154193326Sed // constructor 155218893Sdim ErrorSanitizerGetAllocatedSizeNotOwned() = default; 156218893Sdim ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_, 157218893Sdim uptr addr) 158218893Sdim : ErrorBase(tid), 159218893Sdim stack(stack_), 160218893Sdim addr_description(addr, /*shouldLockThreadRegistry=*/false) { 161218893Sdim scariness.Clear(); 162218893Sdim scariness.Scare(10, "bad-__sanitizer_get_allocated_size"); 163193326Sed } 164193326Sed void Print(); 165226890Sdim}; 166235633Sdim 167218893Sdimstruct ErrorStringFunctionMemoryRangesOverlap : ErrorBase { 168218893Sdim // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace. 169218893Sdim const BufferedStackTrace *stack; 170218893Sdim uptr length1, length2; 171218893Sdim AddressDescription addr1_description; 172218893Sdim AddressDescription addr2_description; 173245431Sdim const char *function; 174193326Sed // VS2013 doesn't implement unrestricted unions, so we need a trivial default 175245431Sdim // constructor 176218893Sdim ErrorStringFunctionMemoryRangesOverlap() = default; 177235633Sdim ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_, 178235633Sdim uptr addr1, uptr length1_, uptr addr2, 179235633Sdim uptr length2_, const char *function_) 180235633Sdim : ErrorBase(tid), 181235633Sdim stack(stack_), 182235633Sdim length1(length1_), 183226890Sdim length2(length2_), 184235633Sdim addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false), 185226890Sdim addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false), 186218893Sdim function(function_) { 187218893Sdim char bug_type[100]; 188226890Sdim internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 189218893Sdim scariness.Clear(); 190193326Sed scariness.Scare(10, bug_type); 191198092Srdivacky } 192218893Sdim void Print(); 193218893Sdim}; 194218893Sdim 195218893Sdimstruct ErrorStringFunctionSizeOverflow : ErrorBase { 196221345Sdim // ErrorStringFunctionSizeOverflow doesn't own the stack trace. 197218893Sdim const BufferedStackTrace *stack; 198218893Sdim AddressDescription addr_description; 199218893Sdim uptr size; 200218893Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 201226890Sdim // constructor 202218893Sdim ErrorStringFunctionSizeOverflow() = default; 203193326Sed ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_, 204193326Sed uptr addr, uptr size_) 205218893Sdim : ErrorBase(tid), 206218893Sdim stack(stack_), 207198092Srdivacky addr_description(addr, /*shouldLockThreadRegistry=*/false), 208218893Sdim size(size_) { 209218893Sdim scariness.Clear(); 210198092Srdivacky scariness.Scare(10, "negative-size-param"); 211218893Sdim } 212218893Sdim void Print(); 213218893Sdim}; 214226890Sdim 215193326Sedstruct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase { 216193326Sed // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace. 217218893Sdim const BufferedStackTrace *stack; 218218893Sdim uptr beg, end, old_mid, new_mid; 219226890Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 220218893Sdim // constructor 221198092Srdivacky ErrorBadParamsToAnnotateContiguousContainer() = default; 222193326Sed // PS4: Do we want an AddressDescription for beg? 223218893Sdim ErrorBadParamsToAnnotateContiguousContainer(u32 tid, 224218893Sdim BufferedStackTrace *stack_, 225218893Sdim uptr beg_, uptr end_, 226218893Sdim uptr old_mid_, uptr new_mid_) 227218893Sdim : ErrorBase(tid), 228226890Sdim stack(stack_), 229218893Sdim beg(beg_), 230218893Sdim end(end_), 231218893Sdim old_mid(old_mid_), 232212904Sdim new_mid(new_mid_) { 233226890Sdim scariness.Clear(); 234226890Sdim scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container"); 235226890Sdim } 236226890Sdim void Print(); 237252723Sdim}; 238226890Sdim 239226890Sdimstruct ErrorODRViolation : ErrorBase { 240226890Sdim __asan_global global1, global2; 241226890Sdim u32 stack_id1, stack_id2; 242226890Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 243226890Sdim // constructor 244226890Sdim ErrorODRViolation() = default; 245226890Sdim ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, 246226890Sdim const __asan_global *g2, u32 stack_id2_) 247226890Sdim : ErrorBase(tid), 248235633Sdim global1(*g1), 249235633Sdim global2(*g2), 250235633Sdim stack_id1(stack_id1_), 251235633Sdim stack_id2(stack_id2_) { 252235633Sdim scariness.Clear(); 253235633Sdim scariness.Scare(10, "odr-violation"); 254235633Sdim } 255235633Sdim void Print(); 256235633Sdim}; 257235633Sdim 258235633Sdimstruct ErrorInvalidPointerPair : ErrorBase { 259235633Sdim uptr pc, bp, sp; 260235633Sdim AddressDescription addr1_description; 261235633Sdim AddressDescription addr2_description; 262235633Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 263235633Sdim // constructor 264235633Sdim ErrorInvalidPointerPair() = default; 265235633Sdim ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1, 266226890Sdim uptr p2) 267226890Sdim : ErrorBase(tid), 268226890Sdim pc(pc_), 269226890Sdim bp(bp_), 270226890Sdim sp(sp_), 271226890Sdim addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false), 272226890Sdim addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) { 273226890Sdim scariness.Clear(); 274226890Sdim scariness.Scare(10, "invalid-pointer-pair"); 275226890Sdim } 276226890Sdim void Print(); 277252723Sdim}; 278226890Sdim 279226890Sdimstruct ErrorGeneric : ErrorBase { 280226890Sdim AddressDescription addr_description; 281226890Sdim uptr pc, bp, sp; 282226890Sdim uptr access_size; 283226890Sdim const char *bug_descr; 284226890Sdim bool is_write; 285226890Sdim u8 shadow_val; 286226890Sdim // VS2013 doesn't implement unrestricted unions, so we need a trivial default 287226890Sdim // constructor 288226890Sdim ErrorGeneric() = default; 289226890Sdim ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_, 290226890Sdim uptr access_size_); 291226890Sdim void Print(); 292226890Sdim}; 293226890Sdim 294226890Sdim// clang-format off 295226890Sdim#define ASAN_FOR_EACH_ERROR_KIND(macro) \ 296235633Sdim macro(DeadlySignal) \ 297235633Sdim macro(DoubleFree) \ 298235633Sdim macro(NewDeleteTypeMismatch) \ 299235633Sdim macro(FreeNotMalloced) \ 300235633Sdim macro(AllocTypeMismatch) \ 301235633Sdim macro(MallocUsableSizeNotOwned) \ 302235633Sdim macro(SanitizerGetAllocatedSizeNotOwned) \ 303235633Sdim macro(StringFunctionMemoryRangesOverlap) \ 304235633Sdim macro(StringFunctionSizeOverflow) \ 305235633Sdim macro(BadParamsToAnnotateContiguousContainer) \ 306235633Sdim macro(ODRViolation) \ 307235633Sdim macro(InvalidPointerPair) \ 308235633Sdim macro(Generic) 309235633Sdim// clang-format on 310235633Sdim 311235633Sdim#define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name, 312235633Sdim#define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name; 313226890Sdim#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \ 314226890Sdim ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {} 315226890Sdim#define ASAN_ERROR_DESCRIPTION_PRINT(name) \ 316226890Sdim case kErrorKind##name: \ 317226890Sdim return name.Print(); 318226890Sdim 319226890Sdimenum ErrorKind { 320226890Sdim kErrorKindInvalid = 0, 321226890Sdim ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND) 322226890Sdim}; 323226890Sdim 324252723Sdimstruct ErrorDescription { 325226890Sdim ErrorKind kind; 326226890Sdim // We're using a tagged union because it allows us to have a trivially 327226890Sdim // copiable type and use the same structures as the public interface. 328226890Sdim // 329226890Sdim // We can add a wrapper around it to make it "more c++-like", but that would 330226890Sdim // add a lot of code and the benefit wouldn't be that big. 331226890Sdim union { 332226890Sdim ErrorBase Base; 333226890Sdim ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER) 334226890Sdim }; 335226890Sdim 336226890Sdim ErrorDescription() { internal_memset(this, 0, sizeof(*this)); } 337226890Sdim ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR) 338226890Sdim 339226890Sdim bool IsValid() { return kind != kErrorKindInvalid; } 340226890Sdim void Print() { 341226890Sdim switch (kind) { 342235633Sdim ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT) 343235633Sdim case kErrorKindInvalid: 344235633Sdim CHECK(0); 345252723Sdim } 346235633Sdim CHECK(0); 347235633Sdim } 348235633Sdim}; 349235633Sdim 350235633Sdim#undef ASAN_FOR_EACH_ERROR_KIND 351235633Sdim#undef ASAN_DEFINE_ERROR_KIND 352235633Sdim#undef ASAN_ERROR_DESCRIPTION_MEMBER 353235633Sdim#undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR 354226890Sdim#undef ASAN_ERROR_DESCRIPTION_PRINT 355223017Sdim 356223017Sdim} // namespace __asan 357223017Sdim 358223017Sdim#endif // ASAN_ERRORS_H 359223017Sdim