676 lines · cpp
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-exception6//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 23namespace __asan {24 25static 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_NETBSD30 // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()31 // yields the call stack of the signal's handler and not of the code32 // that raised the signal (as it does on Linux).33 fast = true;34#endif35 // Tests and maybe some users expect that scariness is going to be printed36 // just before the stack. As only asan has scariness score we have no37 // corresponding code in the sanitizer_common and we use this callback to38 // 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 44void ErrorDeadlySignal::Print() {45 ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);46}47 48void 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 63void 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 103void 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 119void 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 142void 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 155void 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 168void 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 181void 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 194void 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 208void 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 221void ErrorInvalidAlignedAllocAlignment::Print() {222 Decorator d;223 Printf("%s", d.Error());224#if SANITIZER_POSIX225 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#else230 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#endif235 Printf("%s", d.Default());236 stack->Print();237 PrintHintAllocatorCannotReturnNull();238 ReportErrorSummary(scariness.GetDescription(), stack);239}240 241void 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 255void 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 269void 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 281void 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 291void 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 311void 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 323void 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 336void 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 353void 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 367void 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 397void 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 411static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {412 return s[-1] > 127 && s[1] > 127;413}414 415ErrorGeneric::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 516static void PrintContainerOverflowHint() {517 Printf(518 "HINT: if you don't care about these errors you may set "519 "ASAN_OPTIONS=detect_container_overflow=0.\n"520 "Or if supported by the container library, pass "521 "-D__SANITIZER_DISABLE_CONTAINER_OVERFLOW__ to the compiler to disable "522 " instrumentation.\n"523 "If you suspect a false positive see also: "524 "https://github.com/google/sanitizers/wiki/"525 "AddressSanitizerContainerOverflow.\n");526}527 528static void PrintShadowByte(InternalScopedString *str, const char *before,529 u8 byte, const char *after = "\n") {530 PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);531}532 533static void PrintLegend(InternalScopedString *str) {534 str->AppendF(535 "Shadow byte legend (one shadow byte represents %d "536 "application bytes):\n",537 (int)ASAN_SHADOW_GRANULARITY);538 PrintShadowByte(str, " Addressable: ", 0);539 str->AppendF(" Partially addressable: ");540 for (u8 i = 1; i < ASAN_SHADOW_GRANULARITY; i++)541 PrintShadowByte(str, "", i, " ");542 str->AppendF("\n");543 PrintShadowByte(str, " Heap left redzone: ",544 kAsanHeapLeftRedzoneMagic);545 PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic);546 PrintShadowByte(str, " Stack left redzone: ",547 kAsanStackLeftRedzoneMagic);548 PrintShadowByte(str, " Stack mid redzone: ",549 kAsanStackMidRedzoneMagic);550 PrintShadowByte(str, " Stack right redzone: ",551 kAsanStackRightRedzoneMagic);552 PrintShadowByte(str, " Stack after return: ",553 kAsanStackAfterReturnMagic);554 PrintShadowByte(str, " Stack use after scope: ",555 kAsanStackUseAfterScopeMagic);556 PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic);557 PrintShadowByte(str, " Global init order: ",558 kAsanInitializationOrderMagic);559 PrintShadowByte(str, " Poisoned by user: ",560 kAsanUserPoisonedMemoryMagic);561 PrintShadowByte(str, " Container overflow: ",562 kAsanContiguousContainerOOBMagic);563 PrintShadowByte(str, " Array cookie: ",564 kAsanArrayCookieMagic);565 PrintShadowByte(str, " Intra object redzone: ",566 kAsanIntraObjectRedzone);567 PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic);568 PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic);569 PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic);570}571 572static void PrintShadowBytes(InternalScopedString *str, const char *before,573 u8 *bytes, u8 *guilty, uptr n) {574 Decorator d;575 if (before)576 str->AppendF("%s%p:", before,577 (void *)ShadowToMem(reinterpret_cast<uptr>(bytes)));578 for (uptr i = 0; i < n; i++) {579 u8 *p = bytes + i;580 const char *before =581 p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";582 const char *after = p == guilty ? "]" : "";583 PrintShadowByte(str, before, *p, after);584 }585 str->AppendF("\n");586}587 588static void PrintShadowMemoryForAddress(uptr addr) {589 if (!AddrIsInMem(addr)) return;590 uptr shadow_addr = MemToShadow(addr);591 const uptr n_bytes_per_row = 16;592 uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);593 InternalScopedString str;594 str.AppendF("Shadow bytes around the buggy address:\n");595 for (int i = -5; i <= 5; i++) {596 uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;597 // Skip rows that would be outside the shadow range. This can happen when598 // the user address is near the bottom, top, or shadow gap of the address599 // space.600 if (!AddrIsInShadow(row_shadow_addr)) continue;601 const char *prefix = (i == 0) ? "=>" : " ";602 PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,603 n_bytes_per_row);604 }605 if (flags()->print_legend) PrintLegend(&str);606 Printf("%s", str.data());607}608 609static void CheckPoisonRecords(uptr addr) {610 if (!AddrIsInMem(addr))611 return;612 613 u8 *shadow_addr = (u8 *)MemToShadow(addr);614 // If we are in the partial right redzone, look at the next shadow byte.615 if (*shadow_addr > 0 && *shadow_addr < 128)616 shadow_addr++;617 u8 shadow_val = *shadow_addr;618 619 if (shadow_val != kAsanUserPoisonedMemoryMagic)620 return;621 622 Printf("\n");623 624 if (flags()->poison_history_size <= 0) {625 Printf(626 "NOTE: the stack trace above identifies the code that *accessed* "627 "the poisoned memory.\n");628 Printf(629 "To identify the code that *poisoned* the memory, try the "630 "experimental setting ASAN_OPTIONS=poison_history_size=<size>.\n");631 return;632 }633 634 PoisonRecord record;635 if (FindPoisonRecord(addr, record)) {636 StackTrace poison_stack = StackDepotGet(record.stack_id);637 if (poison_stack.size > 0) {638 Printf("Memory was manually poisoned by thread T%u:\n", record.thread_id);639 poison_stack.Print();640 }641 } else {642 Printf("ERROR: no matching poison tracking record found.\n");643 Printf("Try a larger value for ASAN_OPTIONS=poison_history_size=<size>.\n");644 }645}646 647void ErrorGeneric::Print() {648 Decorator d;649 Printf("%s", d.Error());650 uptr addr = addr_description.Address();651 Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",652 bug_descr, (void *)addr, (void *)pc, (void *)bp, (void *)sp);653 Printf("%s", d.Default());654 655 Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),656 access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,657 (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());658 659 scariness.Print();660 GET_STACK_TRACE_FATAL(pc, bp);661 stack.Print();662 663 // Pass bug_descr because we have a special case for664 // initialization-order-fiasco665 addr_description.Print(bug_descr);666 if (shadow_val == kAsanContiguousContainerOOBMagic)667 PrintContainerOverflowHint();668 ReportErrorSummary(bug_descr, &stack);669 PrintShadowMemoryForAddress(addr);670 671 // This is an experimental flag, hence we don't make a special handler.672 CheckPoisonRecords(addr);673}674 675} // namespace __asan676