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