1 //===-- asan_errors.cpp -----------------------------------------*- C++ -*-===// 2 // 3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4 // See https://llvm.org/LICENSE.txt for license information. 5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6 // 7 //===----------------------------------------------------------------------===// 8 // 9 // This file is a part of AddressSanitizer, an address sanity checker. 10 // 11 // ASan implementation for error structures. 12 //===----------------------------------------------------------------------===// 13 14 #include "asan_errors.h" 15 16 #include "asan_descriptions.h" 17 #include "asan_mapping.h" 18 #include "asan_poisoning.h" 19 #include "asan_report.h" 20 #include "asan_stack.h" 21 #include "sanitizer_common/sanitizer_stackdepot.h" 22 23 namespace __asan { 24 25 static void OnStackUnwind(const SignalContext &sig, 26 const void *callback_context, 27 BufferedStackTrace *stack) { 28 bool fast = common_flags()->fast_unwind_on_fatal; 29 #if SANITIZER_FREEBSD || SANITIZER_NETBSD 30 // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace() 31 // yields the call stack of the signal's handler and not of the code 32 // that raised the signal (as it does on Linux). 33 fast = true; 34 #endif 35 // Tests and maybe some users expect that scariness is going to be printed 36 // just before the stack. As only asan has scariness score we have no 37 // corresponding code in the sanitizer_common and we use this callback to 38 // print it. 39 static_cast<const ScarinessScoreBase *>(callback_context)->Print(); 40 stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, 41 fast); 42 } 43 44 void ErrorDeadlySignal::Print() { 45 ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness); 46 } 47 48 void ErrorDoubleFree::Print() { 49 Decorator d; 50 Printf("%s", d.Error()); 51 Report("ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n", 52 scariness.GetDescription(), (void *)addr_description.addr, 53 AsanThreadIdAndName(tid).c_str()); 54 Printf("%s", d.Default()); 55 scariness.Print(); 56 GET_STACK_TRACE_FATAL(second_free_stack->trace[0], 57 second_free_stack->top_frame_bp); 58 stack.Print(); 59 addr_description.Print(); 60 ReportErrorSummary(scariness.GetDescription(), &stack); 61 } 62 63 void ErrorNewDeleteTypeMismatch::Print() { 64 Decorator d; 65 Printf("%s", d.Error()); 66 Report("ERROR: AddressSanitizer: %s on %p in thread %s:\n", 67 scariness.GetDescription(), (void *)addr_description.addr, 68 AsanThreadIdAndName(tid).c_str()); 69 Printf("%s object passed to delete has wrong type:\n", d.Default()); 70 if (delete_size != 0) { 71 Printf( 72 " size of the allocated type: %zd bytes;\n" 73 " size of the deallocated type: %zd bytes.\n", 74 addr_description.chunk_access.chunk_size, delete_size); 75 } 76 const uptr user_alignment = 77 addr_description.chunk_access.user_requested_alignment; 78 if (delete_alignment != user_alignment) { 79 char user_alignment_str[32]; 80 char delete_alignment_str[32]; 81 internal_snprintf(user_alignment_str, sizeof(user_alignment_str), 82 "%zd bytes", user_alignment); 83 internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str), 84 "%zd bytes", delete_alignment); 85 static const char *kDefaultAlignment = "default-aligned"; 86 Printf( 87 " alignment of the allocated type: %s;\n" 88 " alignment of the deallocated type: %s.\n", 89 user_alignment > 0 ? user_alignment_str : kDefaultAlignment, 90 delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment); 91 } 92 CHECK_GT(free_stack->size, 0); 93 scariness.Print(); 94 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); 95 stack.Print(); 96 addr_description.Print(); 97 ReportErrorSummary(scariness.GetDescription(), &stack); 98 Report( 99 "HINT: if you don't care about these errors you may set " 100 "ASAN_OPTIONS=new_delete_type_mismatch=0\n"); 101 } 102 103 void ErrorFreeNotMalloced::Print() { 104 Decorator d; 105 Printf("%s", d.Error()); 106 Report( 107 "ERROR: AddressSanitizer: attempting free on address " 108 "which was not malloc()-ed: %p in thread %s\n", 109 (void *)addr_description.Address(), AsanThreadIdAndName(tid).c_str()); 110 Printf("%s", d.Default()); 111 CHECK_GT(free_stack->size, 0); 112 scariness.Print(); 113 GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); 114 stack.Print(); 115 addr_description.Print(); 116 ReportErrorSummary(scariness.GetDescription(), &stack); 117 } 118 119 void ErrorAllocTypeMismatch::Print() { 120 static const char *alloc_names[] = {"INVALID", "malloc", "operator new", 121 "operator new []"}; 122 static const char *dealloc_names[] = {"INVALID", "free", "operator delete", 123 "operator delete []"}; 124 CHECK_NE(alloc_type, dealloc_type); 125 Decorator d; 126 Printf("%s", d.Error()); 127 Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n", 128 scariness.GetDescription(), alloc_names[alloc_type], 129 dealloc_names[dealloc_type], (void *)addr_description.Address()); 130 Printf("%s", d.Default()); 131 CHECK_GT(dealloc_stack->size, 0); 132 scariness.Print(); 133 GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp); 134 stack.Print(); 135 addr_description.Print(); 136 ReportErrorSummary(scariness.GetDescription(), &stack); 137 Report( 138 "HINT: if you don't care about these errors you may set " 139 "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); 140 } 141 142 void ErrorMallocUsableSizeNotOwned::Print() { 143 Decorator d; 144 Printf("%s", d.Error()); 145 Report( 146 "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for " 147 "pointer which is not owned: %p\n", 148 (void *)addr_description.Address()); 149 Printf("%s", d.Default()); 150 stack->Print(); 151 addr_description.Print(); 152 ReportErrorSummary(scariness.GetDescription(), stack); 153 } 154 155 void ErrorSanitizerGetAllocatedSizeNotOwned::Print() { 156 Decorator d; 157 Printf("%s", d.Error()); 158 Report( 159 "ERROR: AddressSanitizer: attempting to call " 160 "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n", 161 (void *)addr_description.Address()); 162 Printf("%s", d.Default()); 163 stack->Print(); 164 addr_description.Print(); 165 ReportErrorSummary(scariness.GetDescription(), stack); 166 } 167 168 void ErrorCallocOverflow::Print() { 169 Decorator d; 170 Printf("%s", d.Error()); 171 Report( 172 "ERROR: AddressSanitizer: calloc parameters overflow: count * size " 173 "(%zd * %zd) cannot be represented in type size_t (thread %s)\n", 174 count, size, AsanThreadIdAndName(tid).c_str()); 175 Printf("%s", d.Default()); 176 stack->Print(); 177 PrintHintAllocatorCannotReturnNull(); 178 ReportErrorSummary(scariness.GetDescription(), stack); 179 } 180 181 void ErrorReallocArrayOverflow::Print() { 182 Decorator d; 183 Printf("%s", d.Error()); 184 Report( 185 "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size " 186 "(%zd * %zd) cannot be represented in type size_t (thread %s)\n", 187 count, size, AsanThreadIdAndName(tid).c_str()); 188 Printf("%s", d.Default()); 189 stack->Print(); 190 PrintHintAllocatorCannotReturnNull(); 191 ReportErrorSummary(scariness.GetDescription(), stack); 192 } 193 194 void ErrorPvallocOverflow::Print() { 195 Decorator d; 196 Printf("%s", d.Error()); 197 Report( 198 "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx " 199 "rounded up to system page size 0x%zx cannot be represented in type " 200 "size_t (thread %s)\n", 201 size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str()); 202 Printf("%s", d.Default()); 203 stack->Print(); 204 PrintHintAllocatorCannotReturnNull(); 205 ReportErrorSummary(scariness.GetDescription(), stack); 206 } 207 208 void ErrorInvalidAllocationAlignment::Print() { 209 Decorator d; 210 Printf("%s", d.Error()); 211 Report( 212 "ERROR: AddressSanitizer: invalid allocation alignment: %zd, " 213 "alignment must be a power of two (thread %s)\n", 214 alignment, AsanThreadIdAndName(tid).c_str()); 215 Printf("%s", d.Default()); 216 stack->Print(); 217 PrintHintAllocatorCannotReturnNull(); 218 ReportErrorSummary(scariness.GetDescription(), stack); 219 } 220 221 void ErrorInvalidAlignedAllocAlignment::Print() { 222 Decorator d; 223 Printf("%s", d.Error()); 224 #if SANITIZER_POSIX 225 Report("ERROR: AddressSanitizer: invalid alignment requested in " 226 "aligned_alloc: %zd, alignment must be a power of two and the " 227 "requested size 0x%zx must be a multiple of alignment " 228 "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str()); 229 #else 230 Report("ERROR: AddressSanitizer: invalid alignment requested in " 231 "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of " 232 "alignment (thread %s)\n", alignment, size, 233 AsanThreadIdAndName(tid).c_str()); 234 #endif 235 Printf("%s", d.Default()); 236 stack->Print(); 237 PrintHintAllocatorCannotReturnNull(); 238 ReportErrorSummary(scariness.GetDescription(), stack); 239 } 240 241 void ErrorInvalidPosixMemalignAlignment::Print() { 242 Decorator d; 243 Printf("%s", d.Error()); 244 Report( 245 "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: " 246 "%zd, alignment must be a power of two and a multiple of sizeof(void*) " 247 "== %zd (thread %s)\n", 248 alignment, sizeof(void *), AsanThreadIdAndName(tid).c_str()); 249 Printf("%s", d.Default()); 250 stack->Print(); 251 PrintHintAllocatorCannotReturnNull(); 252 ReportErrorSummary(scariness.GetDescription(), stack); 253 } 254 255 void ErrorAllocationSizeTooBig::Print() { 256 Decorator d; 257 Printf("%s", d.Error()); 258 Report( 259 "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after " 260 "adjustments for alignment, red zones etc.) exceeds maximum supported " 261 "size of 0x%zx (thread %s)\n", 262 user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str()); 263 Printf("%s", d.Default()); 264 stack->Print(); 265 PrintHintAllocatorCannotReturnNull(); 266 ReportErrorSummary(scariness.GetDescription(), stack); 267 } 268 269 void ErrorRssLimitExceeded::Print() { 270 Decorator d; 271 Printf("%s", d.Error()); 272 Report( 273 "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to " 274 "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb); 275 Printf("%s", d.Default()); 276 stack->Print(); 277 PrintHintAllocatorCannotReturnNull(); 278 ReportErrorSummary(scariness.GetDescription(), stack); 279 } 280 281 void ErrorOutOfMemory::Print() { 282 Decorator d; 283 Printf("%s", d.Error()); 284 ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size); 285 Printf("%s", d.Default()); 286 stack->Print(); 287 PrintHintAllocatorCannotReturnNull(); 288 ReportErrorSummary(scariness.GetDescription(), stack); 289 } 290 291 void ErrorStringFunctionMemoryRangesOverlap::Print() { 292 Decorator d; 293 char bug_type[100]; 294 internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); 295 Printf("%s", d.Error()); 296 Report( 297 "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) " 298 "overlap\n", 299 bug_type, (void *)addr1_description.Address(), 300 (void *)(addr1_description.Address() + length1), 301 (void *)addr2_description.Address(), 302 (void *)(addr2_description.Address() + length2)); 303 Printf("%s", d.Default()); 304 scariness.Print(); 305 stack->Print(); 306 addr1_description.Print(); 307 addr2_description.Print(); 308 ReportErrorSummary(bug_type, stack); 309 } 310 311 void ErrorStringFunctionSizeOverflow::Print() { 312 Decorator d; 313 Printf("%s", d.Error()); 314 Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", 315 scariness.GetDescription(), size); 316 Printf("%s", d.Default()); 317 scariness.Print(); 318 stack->Print(); 319 addr_description.Print(); 320 ReportErrorSummary(scariness.GetDescription(), stack); 321 } 322 323 void ErrorBadParamsToAnnotateContiguousContainer::Print() { 324 Report( 325 "ERROR: AddressSanitizer: bad parameters to " 326 "__sanitizer_annotate_contiguous_container:\n" 327 " beg : %p\n" 328 " end : %p\n" 329 " old_mid : %p\n" 330 " new_mid : %p\n", 331 (void *)beg, (void *)end, (void *)old_mid, (void *)new_mid); 332 stack->Print(); 333 ReportErrorSummary(scariness.GetDescription(), stack); 334 } 335 336 void ErrorBadParamsToAnnotateDoubleEndedContiguousContainer::Print() { 337 Report( 338 "ERROR: AddressSanitizer: bad parameters to " 339 "__sanitizer_annotate_double_ended_contiguous_container:\n" 340 " storage_beg : %p\n" 341 " storage_end : %p\n" 342 " old_container_beg : %p\n" 343 " old_container_end : %p\n" 344 " new_container_beg : %p\n" 345 " new_container_end : %p\n", 346 (void *)storage_beg, (void *)storage_end, (void *)old_container_beg, 347 (void *)old_container_end, (void *)new_container_beg, 348 (void *)new_container_end); 349 stack->Print(); 350 ReportErrorSummary(scariness.GetDescription(), stack); 351 } 352 353 void ErrorBadParamsToCopyContiguousContainerAnnotations::Print() { 354 Report( 355 "ERROR: AddressSanitizer: bad parameters to " 356 "__sanitizer_copy_contiguous_container_annotations:\n" 357 " src_storage_beg : %p\n" 358 " src_storage_end : %p\n" 359 " dst_storage_beg : %p\n" 360 " new_storage_end : %p\n", 361 (void *)old_storage_beg, (void *)old_storage_end, (void *)new_storage_beg, 362 (void *)new_storage_end); 363 stack->Print(); 364 ReportErrorSummary(scariness.GetDescription(), stack); 365 } 366 367 void ErrorODRViolation::Print() { 368 Decorator d; 369 Printf("%s", d.Error()); 370 Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(), 371 (void *)global1.beg); 372 Printf("%s", d.Default()); 373 InternalScopedString g1_loc; 374 InternalScopedString g2_loc; 375 PrintGlobalLocation(&g1_loc, global1, /*print_module_name=*/true); 376 PrintGlobalLocation(&g2_loc, global2, /*print_module_name=*/true); 377 Printf(" [1] size=%zd '%s' %s\n", global1.size, 378 MaybeDemangleGlobalName(global1.name), g1_loc.data()); 379 Printf(" [2] size=%zd '%s' %s\n", global2.size, 380 MaybeDemangleGlobalName(global2.name), g2_loc.data()); 381 if (stack_id1 && stack_id2) { 382 Printf("These globals were registered at these points:\n"); 383 Printf(" [1]:\n"); 384 StackDepotGet(stack_id1).Print(); 385 Printf(" [2]:\n"); 386 StackDepotGet(stack_id2).Print(); 387 } 388 Report( 389 "HINT: if you don't care about these errors you may set " 390 "ASAN_OPTIONS=detect_odr_violation=0\n"); 391 InternalScopedString error_msg; 392 error_msg.AppendF("%s: global '%s' at %s", scariness.GetDescription(), 393 MaybeDemangleGlobalName(global1.name), g1_loc.data()); 394 ReportErrorSummary(error_msg.data()); 395 } 396 397 void ErrorInvalidPointerPair::Print() { 398 Decorator d; 399 Printf("%s", d.Error()); 400 Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(), 401 (void *)addr1_description.Address(), 402 (void *)addr2_description.Address()); 403 Printf("%s", d.Default()); 404 GET_STACK_TRACE_FATAL(pc, bp); 405 stack.Print(); 406 addr1_description.Print(); 407 addr2_description.Print(); 408 ReportErrorSummary(scariness.GetDescription(), &stack); 409 } 410 411 static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) { 412 return s[-1] > 127 && s[1] > 127; 413 } 414 415 ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr, 416 bool is_write_, uptr access_size_) 417 : ErrorBase(tid), 418 addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false), 419 pc(pc_), 420 bp(bp_), 421 sp(sp_), 422 access_size(access_size_), 423 is_write(is_write_), 424 shadow_val(0) { 425 scariness.Clear(); 426 if (access_size) { 427 if (access_size <= 9) { 428 char desr[] = "?-byte"; 429 desr[0] = '0' + access_size; 430 scariness.Scare(access_size + access_size / 2, desr); 431 } else if (access_size >= 10) { 432 scariness.Scare(15, "multi-byte"); 433 } 434 is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read"); 435 436 // Determine the error type. 437 bug_descr = "unknown-crash"; 438 if (AddrIsInMem(addr)) { 439 u8 *shadow_addr = (u8 *)MemToShadow(addr); 440 // If we are accessing 16 bytes, look at the second shadow byte. 441 if (*shadow_addr == 0 && access_size > ASAN_SHADOW_GRANULARITY) 442 shadow_addr++; 443 // If we are in the partial right redzone, look at the next shadow byte. 444 if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++; 445 bool far_from_bounds = false; 446 shadow_val = *shadow_addr; 447 int bug_type_score = 0; 448 // For use-after-frees reads are almost as bad as writes. 449 int read_after_free_bonus = 0; 450 switch (shadow_val) { 451 case kAsanHeapLeftRedzoneMagic: 452 case kAsanArrayCookieMagic: 453 bug_descr = "heap-buffer-overflow"; 454 bug_type_score = 10; 455 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); 456 break; 457 case kAsanHeapFreeMagic: 458 bug_descr = "heap-use-after-free"; 459 bug_type_score = 20; 460 if (!is_write) read_after_free_bonus = 18; 461 break; 462 case kAsanStackLeftRedzoneMagic: 463 bug_descr = "stack-buffer-underflow"; 464 bug_type_score = 25; 465 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); 466 break; 467 case kAsanInitializationOrderMagic: 468 bug_descr = "initialization-order-fiasco"; 469 bug_type_score = 1; 470 break; 471 case kAsanStackMidRedzoneMagic: 472 case kAsanStackRightRedzoneMagic: 473 bug_descr = "stack-buffer-overflow"; 474 bug_type_score = 25; 475 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); 476 break; 477 case kAsanStackAfterReturnMagic: 478 bug_descr = "stack-use-after-return"; 479 bug_type_score = 30; 480 if (!is_write) read_after_free_bonus = 18; 481 break; 482 case kAsanUserPoisonedMemoryMagic: 483 bug_descr = "use-after-poison"; 484 bug_type_score = 20; 485 break; 486 case kAsanContiguousContainerOOBMagic: 487 bug_descr = "container-overflow"; 488 bug_type_score = 10; 489 break; 490 case kAsanStackUseAfterScopeMagic: 491 bug_descr = "stack-use-after-scope"; 492 bug_type_score = 10; 493 break; 494 case kAsanGlobalRedzoneMagic: 495 bug_descr = "global-buffer-overflow"; 496 bug_type_score = 10; 497 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); 498 break; 499 case kAsanIntraObjectRedzone: 500 bug_descr = "intra-object-overflow"; 501 bug_type_score = 10; 502 break; 503 case kAsanAllocaLeftMagic: 504 case kAsanAllocaRightMagic: 505 bug_descr = "dynamic-stack-buffer-overflow"; 506 bug_type_score = 25; 507 far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr); 508 break; 509 } 510 scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr); 511 if (far_from_bounds) scariness.Scare(10, "far-from-bounds"); 512 } 513 } 514 } 515 516 static void PrintContainerOverflowHint() { 517 Printf("HINT: if you don't care about these errors you may set " 518 "ASAN_OPTIONS=detect_container_overflow=0.\n" 519 "If you suspect a false positive see also: " 520 "https://github.com/google/sanitizers/wiki/" 521 "AddressSanitizerContainerOverflow.\n"); 522 } 523 524 static void PrintShadowByte(InternalScopedString *str, const char *before, 525 u8 byte, const char *after = "\n") { 526 PrintMemoryByte(str, before, byte, /*in_shadow*/true, after); 527 } 528 529 static void PrintLegend(InternalScopedString *str) { 530 str->AppendF( 531 "Shadow byte legend (one shadow byte represents %d " 532 "application bytes):\n", 533 (int)ASAN_SHADOW_GRANULARITY); 534 PrintShadowByte(str, " Addressable: ", 0); 535 str->AppendF(" Partially addressable: "); 536 for (u8 i = 1; i < ASAN_SHADOW_GRANULARITY; i++) 537 PrintShadowByte(str, "", i, " "); 538 str->AppendF("\n"); 539 PrintShadowByte(str, " Heap left redzone: ", 540 kAsanHeapLeftRedzoneMagic); 541 PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic); 542 PrintShadowByte(str, " Stack left redzone: ", 543 kAsanStackLeftRedzoneMagic); 544 PrintShadowByte(str, " Stack mid redzone: ", 545 kAsanStackMidRedzoneMagic); 546 PrintShadowByte(str, " Stack right redzone: ", 547 kAsanStackRightRedzoneMagic); 548 PrintShadowByte(str, " Stack after return: ", 549 kAsanStackAfterReturnMagic); 550 PrintShadowByte(str, " Stack use after scope: ", 551 kAsanStackUseAfterScopeMagic); 552 PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic); 553 PrintShadowByte(str, " Global init order: ", 554 kAsanInitializationOrderMagic); 555 PrintShadowByte(str, " Poisoned by user: ", 556 kAsanUserPoisonedMemoryMagic); 557 PrintShadowByte(str, " Container overflow: ", 558 kAsanContiguousContainerOOBMagic); 559 PrintShadowByte(str, " Array cookie: ", 560 kAsanArrayCookieMagic); 561 PrintShadowByte(str, " Intra object redzone: ", 562 kAsanIntraObjectRedzone); 563 PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic); 564 PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic); 565 PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic); 566 } 567 568 static void PrintShadowBytes(InternalScopedString *str, const char *before, 569 u8 *bytes, u8 *guilty, uptr n) { 570 Decorator d; 571 if (before) 572 str->AppendF("%s%p:", before, 573 (void *)ShadowToMem(reinterpret_cast<uptr>(bytes))); 574 for (uptr i = 0; i < n; i++) { 575 u8 *p = bytes + i; 576 const char *before = 577 p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " "; 578 const char *after = p == guilty ? "]" : ""; 579 PrintShadowByte(str, before, *p, after); 580 } 581 str->AppendF("\n"); 582 } 583 584 static void PrintShadowMemoryForAddress(uptr addr) { 585 if (!AddrIsInMem(addr)) return; 586 uptr shadow_addr = MemToShadow(addr); 587 const uptr n_bytes_per_row = 16; 588 uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1); 589 InternalScopedString str; 590 str.AppendF("Shadow bytes around the buggy address:\n"); 591 for (int i = -5; i <= 5; i++) { 592 uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row; 593 // Skip rows that would be outside the shadow range. This can happen when 594 // the user address is near the bottom, top, or shadow gap of the address 595 // space. 596 if (!AddrIsInShadow(row_shadow_addr)) continue; 597 const char *prefix = (i == 0) ? "=>" : " "; 598 PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr, 599 n_bytes_per_row); 600 } 601 if (flags()->print_legend) PrintLegend(&str); 602 Printf("%s", str.data()); 603 } 604 605 static void CheckPoisonRecords(uptr addr) { 606 if (!AddrIsInMem(addr)) 607 return; 608 609 u8 *shadow_addr = (u8 *)MemToShadow(addr); 610 // If we are in the partial right redzone, look at the next shadow byte. 611 if (*shadow_addr > 0 && *shadow_addr < 128) 612 shadow_addr++; 613 u8 shadow_val = *shadow_addr; 614 615 if (shadow_val != kAsanUserPoisonedMemoryMagic) 616 return; 617 618 Printf("\n"); 619 620 if (flags()->poison_history_size <= 0) { 621 Printf( 622 "NOTE: the stack trace above identifies the code that *accessed* " 623 "the poisoned memory.\n"); 624 Printf( 625 "To identify the code that *poisoned* the memory, try the " 626 "experimental setting ASAN_OPTIONS=poison_history_size=<size>.\n"); 627 return; 628 } 629 630 PoisonRecord record; 631 if (FindPoisonRecord(addr, record)) { 632 StackTrace poison_stack = StackDepotGet(record.stack_id); 633 if (poison_stack.size > 0) { 634 Printf("Memory was manually poisoned by thread T%u:\n", record.thread_id); 635 poison_stack.Print(); 636 } 637 } else { 638 Printf("ERROR: no matching poison tracking record found.\n"); 639 Printf("Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n"); 640 } 641 } 642 643 void ErrorGeneric::Print() { 644 Decorator d; 645 Printf("%s", d.Error()); 646 uptr addr = addr_description.Address(); 647 Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n", 648 bug_descr, (void *)addr, (void *)pc, (void *)bp, (void *)sp); 649 Printf("%s", d.Default()); 650 651 Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(), 652 access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size, 653 (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default()); 654 655 scariness.Print(); 656 GET_STACK_TRACE_FATAL(pc, bp); 657 stack.Print(); 658 659 // Pass bug_descr because we have a special case for 660 // initialization-order-fiasco 661 addr_description.Print(bug_descr); 662 if (shadow_val == kAsanContiguousContainerOOBMagic) 663 PrintContainerOverflowHint(); 664 ReportErrorSummary(bug_descr, &stack); 665 PrintShadowMemoryForAddress(addr); 666 667 // This is an experimental flag, hence we don't make a special handler. 668 CheckPoisonRecords(addr); 669 } 670 671 } // namespace __asan 672