asan_errors.h revision 1.1.1.1
1//===-- asan_errors.h -------------------------------------------*- C++ -*-===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// This file is a part of AddressSanitizer, an address sanity checker. 9// 10// ASan-private header for error structures. 11//===----------------------------------------------------------------------===// 12#ifndef ASAN_ERRORS_H 13#define ASAN_ERRORS_H 14 15#include "asan_descriptions.h" 16#include "asan_scariness_score.h" 17#include "sanitizer_common/sanitizer_common.h" 18 19namespace __asan { 20 21struct ErrorBase { 22 ErrorBase() = default; 23 explicit ErrorBase(u32 tid_) : tid(tid_) {} 24 ScarinessScoreBase scariness; 25 u32 tid; 26}; 27 28struct ErrorStackOverflow : ErrorBase { 29 uptr addr, pc, bp, sp; 30 // ErrorStackOverflow never owns the context. 31 void *context; 32 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 33 // constructor 34 ErrorStackOverflow() = default; 35 ErrorStackOverflow(u32 tid, const SignalContext &sig) 36 : ErrorBase(tid), 37 addr(sig.addr), 38 pc(sig.pc), 39 bp(sig.bp), 40 sp(sig.sp), 41 context(sig.context) { 42 scariness.Clear(); 43 scariness.Scare(10, "stack-overflow"); 44 } 45 void Print(); 46}; 47 48struct ErrorDeadlySignal : ErrorBase { 49 uptr addr, pc, bp, sp; 50 // ErrorDeadlySignal never owns the context. 51 void *context; 52 int signo; 53 SignalContext::WriteFlag write_flag; 54 bool is_memory_access; 55 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 56 // constructor 57 ErrorDeadlySignal() = default; 58 ErrorDeadlySignal(u32 tid, const SignalContext &sig, int signo_) 59 : ErrorBase(tid), 60 addr(sig.addr), 61 pc(sig.pc), 62 bp(sig.bp), 63 sp(sig.sp), 64 context(sig.context), 65 signo(signo_), 66 write_flag(sig.write_flag), 67 is_memory_access(sig.is_memory_access) { 68 scariness.Clear(); 69 if (is_memory_access) { 70 if (addr < GetPageSizeCached()) { 71 scariness.Scare(10, "null-deref"); 72 } else if (addr == pc) { 73 scariness.Scare(60, "wild-jump"); 74 } else if (write_flag == SignalContext::WRITE) { 75 scariness.Scare(30, "wild-addr-write"); 76 } else if (write_flag == SignalContext::READ) { 77 scariness.Scare(20, "wild-addr-read"); 78 } else { 79 scariness.Scare(25, "wild-addr"); 80 } 81 } else { 82 scariness.Scare(10, "signal"); 83 } 84 } 85 void Print(); 86}; 87 88struct ErrorDoubleFree : ErrorBase { 89 // ErrorDoubleFree doesn't own the stack trace. 90 const BufferedStackTrace *second_free_stack; 91 HeapAddressDescription addr_description; 92 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 93 // constructor 94 ErrorDoubleFree() = default; 95 ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr) 96 : ErrorBase(tid), second_free_stack(stack) { 97 CHECK_GT(second_free_stack->size, 0); 98 GetHeapAddressInformation(addr, 1, &addr_description); 99 scariness.Clear(); 100 scariness.Scare(42, "double-free"); 101 } 102 void Print(); 103}; 104 105struct ErrorNewDeleteSizeMismatch : ErrorBase { 106 // ErrorNewDeleteSizeMismatch doesn't own the stack trace. 107 const BufferedStackTrace *free_stack; 108 HeapAddressDescription addr_description; 109 uptr delete_size; 110 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 111 // constructor 112 ErrorNewDeleteSizeMismatch() = default; 113 ErrorNewDeleteSizeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 114 uptr delete_size_) 115 : ErrorBase(tid), free_stack(stack), delete_size(delete_size_) { 116 GetHeapAddressInformation(addr, 1, &addr_description); 117 scariness.Clear(); 118 scariness.Scare(10, "new-delete-type-mismatch"); 119 } 120 void Print(); 121}; 122 123struct ErrorFreeNotMalloced : ErrorBase { 124 // ErrorFreeNotMalloced doesn't own the stack trace. 125 const BufferedStackTrace *free_stack; 126 AddressDescription addr_description; 127 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 128 // constructor 129 ErrorFreeNotMalloced() = default; 130 ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr) 131 : ErrorBase(tid), 132 free_stack(stack), 133 addr_description(addr, /*shouldLockThreadRegistry=*/false) { 134 scariness.Clear(); 135 scariness.Scare(40, "bad-free"); 136 } 137 void Print(); 138}; 139 140struct ErrorAllocTypeMismatch : ErrorBase { 141 // ErrorAllocTypeMismatch doesn't own the stack trace. 142 const BufferedStackTrace *dealloc_stack; 143 HeapAddressDescription addr_description; 144 AllocType alloc_type, dealloc_type; 145 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 146 // constructor 147 ErrorAllocTypeMismatch() = default; 148 ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, 149 AllocType alloc_type_, AllocType dealloc_type_) 150 : ErrorBase(tid), 151 dealloc_stack(stack), 152 alloc_type(alloc_type_), 153 dealloc_type(dealloc_type_) { 154 GetHeapAddressInformation(addr, 1, &addr_description); 155 scariness.Clear(); 156 scariness.Scare(10, "alloc-dealloc-mismatch"); 157 }; 158 void Print(); 159}; 160 161struct ErrorMallocUsableSizeNotOwned : ErrorBase { 162 // ErrorMallocUsableSizeNotOwned doesn't own the stack trace. 163 const BufferedStackTrace *stack; 164 AddressDescription addr_description; 165 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 166 // constructor 167 ErrorMallocUsableSizeNotOwned() = default; 168 ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr) 169 : ErrorBase(tid), 170 stack(stack_), 171 addr_description(addr, /*shouldLockThreadRegistry=*/false) { 172 scariness.Clear(); 173 } 174 void Print(); 175}; 176 177struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase { 178 // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace. 179 const BufferedStackTrace *stack; 180 AddressDescription addr_description; 181 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 182 // constructor 183 ErrorSanitizerGetAllocatedSizeNotOwned() = default; 184 ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_, 185 uptr addr) 186 : ErrorBase(tid), 187 stack(stack_), 188 addr_description(addr, /*shouldLockThreadRegistry=*/false) { 189 scariness.Clear(); 190 } 191 void Print(); 192}; 193 194struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase { 195 // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace. 196 const BufferedStackTrace *stack; 197 uptr length1, length2; 198 AddressDescription addr1_description; 199 AddressDescription addr2_description; 200 const char *function; 201 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 202 // constructor 203 ErrorStringFunctionMemoryRangesOverlap() = default; 204 ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_, 205 uptr addr1, uptr length1_, uptr addr2, 206 uptr length2_, const char *function_) 207 : ErrorBase(tid), 208 stack(stack_), 209 length1(length1_), 210 length2(length2_), 211 addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false), 212 addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false), 213 function(function_) { 214 char bug_type[100]; 215 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 216 scariness.Clear(); 217 scariness.Scare(10, bug_type); 218 } 219 void Print(); 220}; 221 222struct ErrorStringFunctionSizeOverflow : ErrorBase { 223 // ErrorStringFunctionSizeOverflow doesn't own the stack trace. 224 const BufferedStackTrace *stack; 225 AddressDescription addr_description; 226 uptr size; 227 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 228 // constructor 229 ErrorStringFunctionSizeOverflow() = default; 230 ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_, 231 uptr addr, uptr size_) 232 : ErrorBase(tid), 233 stack(stack_), 234 addr_description(addr, /*shouldLockThreadRegistry=*/false), 235 size(size_) { 236 scariness.Clear(); 237 scariness.Scare(10, "negative-size-param"); 238 } 239 void Print(); 240}; 241 242struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase { 243 // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace. 244 const BufferedStackTrace *stack; 245 uptr beg, end, old_mid, new_mid; 246 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 247 // constructor 248 ErrorBadParamsToAnnotateContiguousContainer() = default; 249 // PS4: Do we want an AddressDescription for beg? 250 ErrorBadParamsToAnnotateContiguousContainer(u32 tid, 251 BufferedStackTrace *stack_, 252 uptr beg_, uptr end_, 253 uptr old_mid_, uptr new_mid_) 254 : ErrorBase(tid), 255 stack(stack_), 256 beg(beg_), 257 end(end_), 258 old_mid(old_mid_), 259 new_mid(new_mid_) {} 260 void Print(); 261}; 262 263struct ErrorODRViolation : ErrorBase { 264 __asan_global global1, global2; 265 u32 stack_id1, stack_id2; 266 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 267 // constructor 268 ErrorODRViolation() = default; 269 ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, 270 const __asan_global *g2, u32 stack_id2_) 271 : ErrorBase(tid), 272 global1(*g1), 273 global2(*g2), 274 stack_id1(stack_id1_), 275 stack_id2(stack_id2_) {} 276 void Print(); 277}; 278 279struct ErrorInvalidPointerPair : ErrorBase { 280 uptr pc, bp, sp; 281 AddressDescription addr1_description; 282 AddressDescription addr2_description; 283 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 284 // constructor 285 ErrorInvalidPointerPair() = default; 286 ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1, 287 uptr p2) 288 : ErrorBase(tid), 289 pc(pc_), 290 bp(bp_), 291 sp(sp_), 292 addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false), 293 addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {} 294 void Print(); 295}; 296 297struct ErrorGeneric : ErrorBase { 298 AddressDescription addr_description; 299 uptr pc, bp, sp; 300 uptr access_size; 301 const char *bug_descr; 302 bool is_write; 303 u8 shadow_val; 304 // VS2013 doesn't implement unrestricted unions, so we need a trivial default 305 // constructor 306 ErrorGeneric() = default; 307 ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_, 308 uptr access_size_); 309 void Print(); 310}; 311 312// clang-format off 313#define ASAN_FOR_EACH_ERROR_KIND(macro) \ 314 macro(StackOverflow) \ 315 macro(DeadlySignal) \ 316 macro(DoubleFree) \ 317 macro(NewDeleteSizeMismatch) \ 318 macro(FreeNotMalloced) \ 319 macro(AllocTypeMismatch) \ 320 macro(MallocUsableSizeNotOwned) \ 321 macro(SanitizerGetAllocatedSizeNotOwned) \ 322 macro(StringFunctionMemoryRangesOverlap) \ 323 macro(StringFunctionSizeOverflow) \ 324 macro(BadParamsToAnnotateContiguousContainer) \ 325 macro(ODRViolation) \ 326 macro(InvalidPointerPair) \ 327 macro(Generic) 328// clang-format on 329 330#define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name, 331#define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name; 332#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \ 333 ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {} 334#define ASAN_ERROR_DESCRIPTION_PRINT(name) \ 335 case kErrorKind##name: \ 336 return name.Print(); 337 338enum ErrorKind { 339 kErrorKindInvalid = 0, 340 ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND) 341}; 342 343struct ErrorDescription { 344 ErrorKind kind; 345 // We're using a tagged union because it allows us to have a trivially 346 // copiable type and use the same structures as the public interface. 347 // 348 // We can add a wrapper around it to make it "more c++-like", but that would 349 // add a lot of code and the benefit wouldn't be that big. 350 union { 351 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER) 352 }; 353 354 ErrorDescription() { internal_memset(this, 0, sizeof(*this)); } 355 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR) 356 357 bool IsValid() { return kind != kErrorKindInvalid; } 358 void Print() { 359 switch (kind) { 360 ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT) 361 case kErrorKindInvalid: 362 CHECK(0); 363 } 364 CHECK(0); 365 } 366}; 367 368#undef ASAN_FOR_EACH_ERROR_KIND 369#undef ASAN_DEFINE_ERROR_KIND 370#undef ASAN_ERROR_DESCRIPTION_MEMBER 371#undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR 372#undef ASAN_ERROR_DESCRIPTION_PRINT 373 374} // namespace __asan 375 376#endif // ASAN_ERRORS_H 377