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