13cab2bb3Spatrick //===-- asan_errors.cpp -----------------------------------------*- C++ -*-===//
23cab2bb3Spatrick //
33cab2bb3Spatrick // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
43cab2bb3Spatrick // See https://llvm.org/LICENSE.txt for license information.
53cab2bb3Spatrick // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
63cab2bb3Spatrick //
73cab2bb3Spatrick //===----------------------------------------------------------------------===//
83cab2bb3Spatrick //
93cab2bb3Spatrick // This file is a part of AddressSanitizer, an address sanity checker.
103cab2bb3Spatrick //
113cab2bb3Spatrick // ASan implementation for error structures.
123cab2bb3Spatrick //===----------------------------------------------------------------------===//
133cab2bb3Spatrick
143cab2bb3Spatrick #include "asan_errors.h"
153cab2bb3Spatrick #include "asan_descriptions.h"
163cab2bb3Spatrick #include "asan_mapping.h"
173cab2bb3Spatrick #include "asan_report.h"
183cab2bb3Spatrick #include "asan_stack.h"
193cab2bb3Spatrick #include "sanitizer_common/sanitizer_stackdepot.h"
203cab2bb3Spatrick
213cab2bb3Spatrick namespace __asan {
223cab2bb3Spatrick
OnStackUnwind(const SignalContext & sig,const void * callback_context,BufferedStackTrace * stack)233cab2bb3Spatrick static void OnStackUnwind(const SignalContext &sig,
243cab2bb3Spatrick const void *callback_context,
253cab2bb3Spatrick BufferedStackTrace *stack) {
263cab2bb3Spatrick bool fast = common_flags()->fast_unwind_on_fatal;
273cab2bb3Spatrick #if SANITIZER_FREEBSD || SANITIZER_NETBSD
283cab2bb3Spatrick // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
293cab2bb3Spatrick // yields the call stack of the signal's handler and not of the code
303cab2bb3Spatrick // that raised the signal (as it does on Linux).
313cab2bb3Spatrick fast = true;
323cab2bb3Spatrick #endif
333cab2bb3Spatrick // Tests and maybe some users expect that scariness is going to be printed
343cab2bb3Spatrick // just before the stack. As only asan has scariness score we have no
353cab2bb3Spatrick // corresponding code in the sanitizer_common and we use this callback to
363cab2bb3Spatrick // print it.
373cab2bb3Spatrick static_cast<const ScarinessScoreBase *>(callback_context)->Print();
383cab2bb3Spatrick stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
393cab2bb3Spatrick fast);
403cab2bb3Spatrick }
413cab2bb3Spatrick
Print()423cab2bb3Spatrick void ErrorDeadlySignal::Print() {
433cab2bb3Spatrick ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);
443cab2bb3Spatrick }
453cab2bb3Spatrick
Print()463cab2bb3Spatrick void ErrorDoubleFree::Print() {
473cab2bb3Spatrick Decorator d;
483cab2bb3Spatrick Printf("%s", d.Error());
49*810390e3Srobert Report("ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n",
50*810390e3Srobert scariness.GetDescription(), (void *)addr_description.addr,
513cab2bb3Spatrick AsanThreadIdAndName(tid).c_str());
523cab2bb3Spatrick Printf("%s", d.Default());
533cab2bb3Spatrick scariness.Print();
543cab2bb3Spatrick GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
553cab2bb3Spatrick second_free_stack->top_frame_bp);
563cab2bb3Spatrick stack.Print();
573cab2bb3Spatrick addr_description.Print();
583cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), &stack);
593cab2bb3Spatrick }
603cab2bb3Spatrick
Print()613cab2bb3Spatrick void ErrorNewDeleteTypeMismatch::Print() {
623cab2bb3Spatrick Decorator d;
633cab2bb3Spatrick Printf("%s", d.Error());
64*810390e3Srobert Report("ERROR: AddressSanitizer: %s on %p in thread %s:\n",
65*810390e3Srobert scariness.GetDescription(), (void *)addr_description.addr,
663cab2bb3Spatrick AsanThreadIdAndName(tid).c_str());
673cab2bb3Spatrick Printf("%s object passed to delete has wrong type:\n", d.Default());
683cab2bb3Spatrick if (delete_size != 0) {
693cab2bb3Spatrick Printf(
703cab2bb3Spatrick " size of the allocated type: %zd bytes;\n"
713cab2bb3Spatrick " size of the deallocated type: %zd bytes.\n",
723cab2bb3Spatrick addr_description.chunk_access.chunk_size, delete_size);
733cab2bb3Spatrick }
743cab2bb3Spatrick const uptr user_alignment =
753cab2bb3Spatrick addr_description.chunk_access.user_requested_alignment;
763cab2bb3Spatrick if (delete_alignment != user_alignment) {
773cab2bb3Spatrick char user_alignment_str[32];
783cab2bb3Spatrick char delete_alignment_str[32];
793cab2bb3Spatrick internal_snprintf(user_alignment_str, sizeof(user_alignment_str),
803cab2bb3Spatrick "%zd bytes", user_alignment);
813cab2bb3Spatrick internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str),
823cab2bb3Spatrick "%zd bytes", delete_alignment);
833cab2bb3Spatrick static const char *kDefaultAlignment = "default-aligned";
843cab2bb3Spatrick Printf(
853cab2bb3Spatrick " alignment of the allocated type: %s;\n"
863cab2bb3Spatrick " alignment of the deallocated type: %s.\n",
873cab2bb3Spatrick user_alignment > 0 ? user_alignment_str : kDefaultAlignment,
883cab2bb3Spatrick delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment);
893cab2bb3Spatrick }
903cab2bb3Spatrick CHECK_GT(free_stack->size, 0);
913cab2bb3Spatrick scariness.Print();
923cab2bb3Spatrick GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
933cab2bb3Spatrick stack.Print();
943cab2bb3Spatrick addr_description.Print();
953cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), &stack);
963cab2bb3Spatrick Report(
973cab2bb3Spatrick "HINT: if you don't care about these errors you may set "
983cab2bb3Spatrick "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
993cab2bb3Spatrick }
1003cab2bb3Spatrick
Print()1013cab2bb3Spatrick void ErrorFreeNotMalloced::Print() {
1023cab2bb3Spatrick Decorator d;
1033cab2bb3Spatrick Printf("%s", d.Error());
1043cab2bb3Spatrick Report(
1053cab2bb3Spatrick "ERROR: AddressSanitizer: attempting free on address "
1063cab2bb3Spatrick "which was not malloc()-ed: %p in thread %s\n",
107*810390e3Srobert (void *)addr_description.Address(), AsanThreadIdAndName(tid).c_str());
1083cab2bb3Spatrick Printf("%s", d.Default());
1093cab2bb3Spatrick CHECK_GT(free_stack->size, 0);
1103cab2bb3Spatrick scariness.Print();
1113cab2bb3Spatrick GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
1123cab2bb3Spatrick stack.Print();
1133cab2bb3Spatrick addr_description.Print();
1143cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), &stack);
1153cab2bb3Spatrick }
1163cab2bb3Spatrick
Print()1173cab2bb3Spatrick void ErrorAllocTypeMismatch::Print() {
1183cab2bb3Spatrick static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
1193cab2bb3Spatrick "operator new []"};
1203cab2bb3Spatrick static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
1213cab2bb3Spatrick "operator delete []"};
1223cab2bb3Spatrick CHECK_NE(alloc_type, dealloc_type);
1233cab2bb3Spatrick Decorator d;
1243cab2bb3Spatrick Printf("%s", d.Error());
1253cab2bb3Spatrick Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
1263cab2bb3Spatrick scariness.GetDescription(), alloc_names[alloc_type],
127*810390e3Srobert dealloc_names[dealloc_type], (void *)addr_description.Address());
1283cab2bb3Spatrick Printf("%s", d.Default());
1293cab2bb3Spatrick CHECK_GT(dealloc_stack->size, 0);
1303cab2bb3Spatrick scariness.Print();
1313cab2bb3Spatrick GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
1323cab2bb3Spatrick stack.Print();
1333cab2bb3Spatrick addr_description.Print();
1343cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), &stack);
1353cab2bb3Spatrick Report(
1363cab2bb3Spatrick "HINT: if you don't care about these errors you may set "
1373cab2bb3Spatrick "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
1383cab2bb3Spatrick }
1393cab2bb3Spatrick
Print()1403cab2bb3Spatrick void ErrorMallocUsableSizeNotOwned::Print() {
1413cab2bb3Spatrick Decorator d;
1423cab2bb3Spatrick Printf("%s", d.Error());
1433cab2bb3Spatrick Report(
1443cab2bb3Spatrick "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
1453cab2bb3Spatrick "pointer which is not owned: %p\n",
146*810390e3Srobert (void *)addr_description.Address());
1473cab2bb3Spatrick Printf("%s", d.Default());
1483cab2bb3Spatrick stack->Print();
1493cab2bb3Spatrick addr_description.Print();
1503cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
1513cab2bb3Spatrick }
1523cab2bb3Spatrick
Print()1533cab2bb3Spatrick void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
1543cab2bb3Spatrick Decorator d;
1553cab2bb3Spatrick Printf("%s", d.Error());
1563cab2bb3Spatrick Report(
1573cab2bb3Spatrick "ERROR: AddressSanitizer: attempting to call "
1583cab2bb3Spatrick "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
159*810390e3Srobert (void *)addr_description.Address());
1603cab2bb3Spatrick Printf("%s", d.Default());
1613cab2bb3Spatrick stack->Print();
1623cab2bb3Spatrick addr_description.Print();
1633cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
1643cab2bb3Spatrick }
1653cab2bb3Spatrick
Print()1663cab2bb3Spatrick void ErrorCallocOverflow::Print() {
1673cab2bb3Spatrick Decorator d;
1683cab2bb3Spatrick Printf("%s", d.Error());
1693cab2bb3Spatrick Report(
1703cab2bb3Spatrick "ERROR: AddressSanitizer: calloc parameters overflow: count * size "
1713cab2bb3Spatrick "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
1723cab2bb3Spatrick count, size, AsanThreadIdAndName(tid).c_str());
1733cab2bb3Spatrick Printf("%s", d.Default());
1743cab2bb3Spatrick stack->Print();
1753cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
1763cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
1773cab2bb3Spatrick }
1783cab2bb3Spatrick
Print()1793cab2bb3Spatrick void ErrorReallocArrayOverflow::Print() {
1803cab2bb3Spatrick Decorator d;
1813cab2bb3Spatrick Printf("%s", d.Error());
1823cab2bb3Spatrick Report(
1833cab2bb3Spatrick "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size "
1843cab2bb3Spatrick "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
1853cab2bb3Spatrick count, size, AsanThreadIdAndName(tid).c_str());
1863cab2bb3Spatrick Printf("%s", d.Default());
1873cab2bb3Spatrick stack->Print();
1883cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
1893cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
1903cab2bb3Spatrick }
1913cab2bb3Spatrick
Print()1923cab2bb3Spatrick void ErrorPvallocOverflow::Print() {
1933cab2bb3Spatrick Decorator d;
1943cab2bb3Spatrick Printf("%s", d.Error());
1953cab2bb3Spatrick Report(
1963cab2bb3Spatrick "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx "
1973cab2bb3Spatrick "rounded up to system page size 0x%zx cannot be represented in type "
1983cab2bb3Spatrick "size_t (thread %s)\n",
1993cab2bb3Spatrick size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str());
2003cab2bb3Spatrick Printf("%s", d.Default());
2013cab2bb3Spatrick stack->Print();
2023cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2033cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2043cab2bb3Spatrick }
2053cab2bb3Spatrick
Print()2063cab2bb3Spatrick void ErrorInvalidAllocationAlignment::Print() {
2073cab2bb3Spatrick Decorator d;
2083cab2bb3Spatrick Printf("%s", d.Error());
2093cab2bb3Spatrick Report(
2103cab2bb3Spatrick "ERROR: AddressSanitizer: invalid allocation alignment: %zd, "
2113cab2bb3Spatrick "alignment must be a power of two (thread %s)\n",
2123cab2bb3Spatrick alignment, AsanThreadIdAndName(tid).c_str());
2133cab2bb3Spatrick Printf("%s", d.Default());
2143cab2bb3Spatrick stack->Print();
2153cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2163cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2173cab2bb3Spatrick }
2183cab2bb3Spatrick
Print()2193cab2bb3Spatrick void ErrorInvalidAlignedAllocAlignment::Print() {
2203cab2bb3Spatrick Decorator d;
2213cab2bb3Spatrick Printf("%s", d.Error());
2223cab2bb3Spatrick #if SANITIZER_POSIX
2233cab2bb3Spatrick Report("ERROR: AddressSanitizer: invalid alignment requested in "
2243cab2bb3Spatrick "aligned_alloc: %zd, alignment must be a power of two and the "
2253cab2bb3Spatrick "requested size 0x%zx must be a multiple of alignment "
2263cab2bb3Spatrick "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str());
2273cab2bb3Spatrick #else
2283cab2bb3Spatrick Report("ERROR: AddressSanitizer: invalid alignment requested in "
2293cab2bb3Spatrick "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of "
2303cab2bb3Spatrick "alignment (thread %s)\n", alignment, size,
2313cab2bb3Spatrick AsanThreadIdAndName(tid).c_str());
2323cab2bb3Spatrick #endif
2333cab2bb3Spatrick Printf("%s", d.Default());
2343cab2bb3Spatrick stack->Print();
2353cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2363cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2373cab2bb3Spatrick }
2383cab2bb3Spatrick
Print()2393cab2bb3Spatrick void ErrorInvalidPosixMemalignAlignment::Print() {
2403cab2bb3Spatrick Decorator d;
2413cab2bb3Spatrick Printf("%s", d.Error());
2423cab2bb3Spatrick Report(
2433cab2bb3Spatrick "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: "
2443cab2bb3Spatrick "%zd, alignment must be a power of two and a multiple of sizeof(void*) "
2453cab2bb3Spatrick "== %zd (thread %s)\n",
2463cab2bb3Spatrick alignment, sizeof(void *), AsanThreadIdAndName(tid).c_str());
2473cab2bb3Spatrick Printf("%s", d.Default());
2483cab2bb3Spatrick stack->Print();
2493cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2503cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2513cab2bb3Spatrick }
2523cab2bb3Spatrick
Print()2533cab2bb3Spatrick void ErrorAllocationSizeTooBig::Print() {
2543cab2bb3Spatrick Decorator d;
2553cab2bb3Spatrick Printf("%s", d.Error());
2563cab2bb3Spatrick Report(
2573cab2bb3Spatrick "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after "
2583cab2bb3Spatrick "adjustments for alignment, red zones etc.) exceeds maximum supported "
2593cab2bb3Spatrick "size of 0x%zx (thread %s)\n",
2603cab2bb3Spatrick user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str());
2613cab2bb3Spatrick Printf("%s", d.Default());
2623cab2bb3Spatrick stack->Print();
2633cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2643cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2653cab2bb3Spatrick }
2663cab2bb3Spatrick
Print()2673cab2bb3Spatrick void ErrorRssLimitExceeded::Print() {
2683cab2bb3Spatrick Decorator d;
2693cab2bb3Spatrick Printf("%s", d.Error());
2703cab2bb3Spatrick Report(
2713cab2bb3Spatrick "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to "
2723cab2bb3Spatrick "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb);
2733cab2bb3Spatrick Printf("%s", d.Default());
2743cab2bb3Spatrick stack->Print();
2753cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2763cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2773cab2bb3Spatrick }
2783cab2bb3Spatrick
Print()2793cab2bb3Spatrick void ErrorOutOfMemory::Print() {
2803cab2bb3Spatrick Decorator d;
2813cab2bb3Spatrick Printf("%s", d.Error());
282*810390e3Srobert ERROR_OOM("allocator is trying to allocate 0x%zx bytes\n", requested_size);
2833cab2bb3Spatrick Printf("%s", d.Default());
2843cab2bb3Spatrick stack->Print();
2853cab2bb3Spatrick PrintHintAllocatorCannotReturnNull();
2863cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
2873cab2bb3Spatrick }
2883cab2bb3Spatrick
Print()2893cab2bb3Spatrick void ErrorStringFunctionMemoryRangesOverlap::Print() {
2903cab2bb3Spatrick Decorator d;
2913cab2bb3Spatrick char bug_type[100];
2923cab2bb3Spatrick internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
2933cab2bb3Spatrick Printf("%s", d.Error());
2943cab2bb3Spatrick Report(
2953cab2bb3Spatrick "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
2963cab2bb3Spatrick "overlap\n",
297*810390e3Srobert bug_type, (void *)addr1_description.Address(),
298*810390e3Srobert (void *)(addr1_description.Address() + length1),
299*810390e3Srobert (void *)addr2_description.Address(),
300*810390e3Srobert (void *)(addr2_description.Address() + length2));
3013cab2bb3Spatrick Printf("%s", d.Default());
3023cab2bb3Spatrick scariness.Print();
3033cab2bb3Spatrick stack->Print();
3043cab2bb3Spatrick addr1_description.Print();
3053cab2bb3Spatrick addr2_description.Print();
3063cab2bb3Spatrick ReportErrorSummary(bug_type, stack);
3073cab2bb3Spatrick }
3083cab2bb3Spatrick
Print()3093cab2bb3Spatrick void ErrorStringFunctionSizeOverflow::Print() {
3103cab2bb3Spatrick Decorator d;
3113cab2bb3Spatrick Printf("%s", d.Error());
3123cab2bb3Spatrick Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
3133cab2bb3Spatrick scariness.GetDescription(), size);
3143cab2bb3Spatrick Printf("%s", d.Default());
3153cab2bb3Spatrick scariness.Print();
3163cab2bb3Spatrick stack->Print();
3173cab2bb3Spatrick addr_description.Print();
3183cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
3193cab2bb3Spatrick }
3203cab2bb3Spatrick
Print()3213cab2bb3Spatrick void ErrorBadParamsToAnnotateContiguousContainer::Print() {
3223cab2bb3Spatrick Report(
3233cab2bb3Spatrick "ERROR: AddressSanitizer: bad parameters to "
3243cab2bb3Spatrick "__sanitizer_annotate_contiguous_container:\n"
3253cab2bb3Spatrick " beg : %p\n"
3263cab2bb3Spatrick " end : %p\n"
3273cab2bb3Spatrick " old_mid : %p\n"
3283cab2bb3Spatrick " new_mid : %p\n",
329*810390e3Srobert (void *)beg, (void *)end, (void *)old_mid, (void *)new_mid);
330*810390e3Srobert uptr granularity = ASAN_SHADOW_GRANULARITY;
3313cab2bb3Spatrick if (!IsAligned(beg, granularity))
332*810390e3Srobert Report("ERROR: beg is not aligned by %zu\n", granularity);
333*810390e3Srobert stack->Print();
334*810390e3Srobert ReportErrorSummary(scariness.GetDescription(), stack);
335*810390e3Srobert }
336*810390e3Srobert
Print()337*810390e3Srobert void ErrorBadParamsToAnnotateDoubleEndedContiguousContainer::Print() {
338*810390e3Srobert Report(
339*810390e3Srobert "ERROR: AddressSanitizer: bad parameters to "
340*810390e3Srobert "__sanitizer_annotate_double_ended_contiguous_container:\n"
341*810390e3Srobert " storage_beg : %p\n"
342*810390e3Srobert " storage_end : %p\n"
343*810390e3Srobert " old_container_beg : %p\n"
344*810390e3Srobert " old_container_end : %p\n"
345*810390e3Srobert " new_container_beg : %p\n"
346*810390e3Srobert " new_container_end : %p\n",
347*810390e3Srobert (void *)storage_beg, (void *)storage_end, (void *)old_container_beg,
348*810390e3Srobert (void *)old_container_end, (void *)new_container_beg,
349*810390e3Srobert (void *)new_container_end);
350*810390e3Srobert uptr granularity = ASAN_SHADOW_GRANULARITY;
351*810390e3Srobert if (!IsAligned(storage_beg, granularity))
352*810390e3Srobert Report("ERROR: storage_beg is not aligned by %zu\n", granularity);
3533cab2bb3Spatrick stack->Print();
3543cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), stack);
3553cab2bb3Spatrick }
3563cab2bb3Spatrick
Print()3573cab2bb3Spatrick void ErrorODRViolation::Print() {
3583cab2bb3Spatrick Decorator d;
3593cab2bb3Spatrick Printf("%s", d.Error());
3603cab2bb3Spatrick Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
361*810390e3Srobert (void *)global1.beg);
3623cab2bb3Spatrick Printf("%s", d.Default());
363d89ec533Spatrick InternalScopedString g1_loc;
364d89ec533Spatrick InternalScopedString g2_loc;
3653cab2bb3Spatrick PrintGlobalLocation(&g1_loc, global1);
3663cab2bb3Spatrick PrintGlobalLocation(&g2_loc, global2);
3673cab2bb3Spatrick Printf(" [1] size=%zd '%s' %s\n", global1.size,
3683cab2bb3Spatrick MaybeDemangleGlobalName(global1.name), g1_loc.data());
3693cab2bb3Spatrick Printf(" [2] size=%zd '%s' %s\n", global2.size,
3703cab2bb3Spatrick MaybeDemangleGlobalName(global2.name), g2_loc.data());
3713cab2bb3Spatrick if (stack_id1 && stack_id2) {
3723cab2bb3Spatrick Printf("These globals were registered at these points:\n");
3733cab2bb3Spatrick Printf(" [1]:\n");
3743cab2bb3Spatrick StackDepotGet(stack_id1).Print();
3753cab2bb3Spatrick Printf(" [2]:\n");
3763cab2bb3Spatrick StackDepotGet(stack_id2).Print();
3773cab2bb3Spatrick }
3783cab2bb3Spatrick Report(
3793cab2bb3Spatrick "HINT: if you don't care about these errors you may set "
3803cab2bb3Spatrick "ASAN_OPTIONS=detect_odr_violation=0\n");
381d89ec533Spatrick InternalScopedString error_msg;
3823cab2bb3Spatrick error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
3833cab2bb3Spatrick MaybeDemangleGlobalName(global1.name), g1_loc.data());
3843cab2bb3Spatrick ReportErrorSummary(error_msg.data());
3853cab2bb3Spatrick }
3863cab2bb3Spatrick
Print()3873cab2bb3Spatrick void ErrorInvalidPointerPair::Print() {
3883cab2bb3Spatrick Decorator d;
3893cab2bb3Spatrick Printf("%s", d.Error());
3903cab2bb3Spatrick Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
391*810390e3Srobert (void *)addr1_description.Address(),
392*810390e3Srobert (void *)addr2_description.Address());
3933cab2bb3Spatrick Printf("%s", d.Default());
3943cab2bb3Spatrick GET_STACK_TRACE_FATAL(pc, bp);
3953cab2bb3Spatrick stack.Print();
3963cab2bb3Spatrick addr1_description.Print();
3973cab2bb3Spatrick addr2_description.Print();
3983cab2bb3Spatrick ReportErrorSummary(scariness.GetDescription(), &stack);
3993cab2bb3Spatrick }
4003cab2bb3Spatrick
AdjacentShadowValuesAreFullyPoisoned(u8 * s)4013cab2bb3Spatrick static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
4023cab2bb3Spatrick return s[-1] > 127 && s[1] > 127;
4033cab2bb3Spatrick }
4043cab2bb3Spatrick
ErrorGeneric(u32 tid,uptr pc_,uptr bp_,uptr sp_,uptr addr,bool is_write_,uptr access_size_)4053cab2bb3Spatrick ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
4063cab2bb3Spatrick bool is_write_, uptr access_size_)
4073cab2bb3Spatrick : ErrorBase(tid),
4083cab2bb3Spatrick addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
4093cab2bb3Spatrick pc(pc_),
4103cab2bb3Spatrick bp(bp_),
4113cab2bb3Spatrick sp(sp_),
4123cab2bb3Spatrick access_size(access_size_),
4133cab2bb3Spatrick is_write(is_write_),
4143cab2bb3Spatrick shadow_val(0) {
4153cab2bb3Spatrick scariness.Clear();
4163cab2bb3Spatrick if (access_size) {
4173cab2bb3Spatrick if (access_size <= 9) {
4183cab2bb3Spatrick char desr[] = "?-byte";
4193cab2bb3Spatrick desr[0] = '0' + access_size;
4203cab2bb3Spatrick scariness.Scare(access_size + access_size / 2, desr);
4213cab2bb3Spatrick } else if (access_size >= 10) {
4223cab2bb3Spatrick scariness.Scare(15, "multi-byte");
4233cab2bb3Spatrick }
4243cab2bb3Spatrick is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");
4253cab2bb3Spatrick
4263cab2bb3Spatrick // Determine the error type.
4273cab2bb3Spatrick bug_descr = "unknown-crash";
4283cab2bb3Spatrick if (AddrIsInMem(addr)) {
4293cab2bb3Spatrick u8 *shadow_addr = (u8 *)MemToShadow(addr);
4303cab2bb3Spatrick // If we are accessing 16 bytes, look at the second shadow byte.
431*810390e3Srobert if (*shadow_addr == 0 && access_size > ASAN_SHADOW_GRANULARITY)
432*810390e3Srobert shadow_addr++;
4333cab2bb3Spatrick // If we are in the partial right redzone, look at the next shadow byte.
4343cab2bb3Spatrick if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;
4353cab2bb3Spatrick bool far_from_bounds = false;
4363cab2bb3Spatrick shadow_val = *shadow_addr;
4373cab2bb3Spatrick int bug_type_score = 0;
4383cab2bb3Spatrick // For use-after-frees reads are almost as bad as writes.
4393cab2bb3Spatrick int read_after_free_bonus = 0;
4403cab2bb3Spatrick switch (shadow_val) {
4413cab2bb3Spatrick case kAsanHeapLeftRedzoneMagic:
4423cab2bb3Spatrick case kAsanArrayCookieMagic:
4433cab2bb3Spatrick bug_descr = "heap-buffer-overflow";
4443cab2bb3Spatrick bug_type_score = 10;
4453cab2bb3Spatrick far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
4463cab2bb3Spatrick break;
4473cab2bb3Spatrick case kAsanHeapFreeMagic:
4483cab2bb3Spatrick bug_descr = "heap-use-after-free";
4493cab2bb3Spatrick bug_type_score = 20;
4503cab2bb3Spatrick if (!is_write) read_after_free_bonus = 18;
4513cab2bb3Spatrick break;
4523cab2bb3Spatrick case kAsanStackLeftRedzoneMagic:
4533cab2bb3Spatrick bug_descr = "stack-buffer-underflow";
4543cab2bb3Spatrick bug_type_score = 25;
4553cab2bb3Spatrick far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
4563cab2bb3Spatrick break;
4573cab2bb3Spatrick case kAsanInitializationOrderMagic:
4583cab2bb3Spatrick bug_descr = "initialization-order-fiasco";
4593cab2bb3Spatrick bug_type_score = 1;
4603cab2bb3Spatrick break;
4613cab2bb3Spatrick case kAsanStackMidRedzoneMagic:
4623cab2bb3Spatrick case kAsanStackRightRedzoneMagic:
4633cab2bb3Spatrick bug_descr = "stack-buffer-overflow";
4643cab2bb3Spatrick bug_type_score = 25;
4653cab2bb3Spatrick far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
4663cab2bb3Spatrick break;
4673cab2bb3Spatrick case kAsanStackAfterReturnMagic:
4683cab2bb3Spatrick bug_descr = "stack-use-after-return";
4693cab2bb3Spatrick bug_type_score = 30;
4703cab2bb3Spatrick if (!is_write) read_after_free_bonus = 18;
4713cab2bb3Spatrick break;
4723cab2bb3Spatrick case kAsanUserPoisonedMemoryMagic:
4733cab2bb3Spatrick bug_descr = "use-after-poison";
4743cab2bb3Spatrick bug_type_score = 20;
4753cab2bb3Spatrick break;
4763cab2bb3Spatrick case kAsanContiguousContainerOOBMagic:
4773cab2bb3Spatrick bug_descr = "container-overflow";
4783cab2bb3Spatrick bug_type_score = 10;
4793cab2bb3Spatrick break;
4803cab2bb3Spatrick case kAsanStackUseAfterScopeMagic:
4813cab2bb3Spatrick bug_descr = "stack-use-after-scope";
4823cab2bb3Spatrick bug_type_score = 10;
4833cab2bb3Spatrick break;
4843cab2bb3Spatrick case kAsanGlobalRedzoneMagic:
4853cab2bb3Spatrick bug_descr = "global-buffer-overflow";
4863cab2bb3Spatrick bug_type_score = 10;
4873cab2bb3Spatrick far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
4883cab2bb3Spatrick break;
4893cab2bb3Spatrick case kAsanIntraObjectRedzone:
4903cab2bb3Spatrick bug_descr = "intra-object-overflow";
4913cab2bb3Spatrick bug_type_score = 10;
4923cab2bb3Spatrick break;
4933cab2bb3Spatrick case kAsanAllocaLeftMagic:
4943cab2bb3Spatrick case kAsanAllocaRightMagic:
4953cab2bb3Spatrick bug_descr = "dynamic-stack-buffer-overflow";
4963cab2bb3Spatrick bug_type_score = 25;
4973cab2bb3Spatrick far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
4983cab2bb3Spatrick break;
4993cab2bb3Spatrick }
5003cab2bb3Spatrick scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
5013cab2bb3Spatrick if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
5023cab2bb3Spatrick }
5033cab2bb3Spatrick }
5043cab2bb3Spatrick }
5053cab2bb3Spatrick
PrintContainerOverflowHint()5063cab2bb3Spatrick static void PrintContainerOverflowHint() {
5073cab2bb3Spatrick Printf("HINT: if you don't care about these errors you may set "
5083cab2bb3Spatrick "ASAN_OPTIONS=detect_container_overflow=0.\n"
5093cab2bb3Spatrick "If you suspect a false positive see also: "
5103cab2bb3Spatrick "https://github.com/google/sanitizers/wiki/"
5113cab2bb3Spatrick "AddressSanitizerContainerOverflow.\n");
5123cab2bb3Spatrick }
5133cab2bb3Spatrick
PrintShadowByte(InternalScopedString * str,const char * before,u8 byte,const char * after="\\n")5143cab2bb3Spatrick static void PrintShadowByte(InternalScopedString *str, const char *before,
5153cab2bb3Spatrick u8 byte, const char *after = "\n") {
5163cab2bb3Spatrick PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
5173cab2bb3Spatrick }
5183cab2bb3Spatrick
PrintLegend(InternalScopedString * str)5193cab2bb3Spatrick static void PrintLegend(InternalScopedString *str) {
5203cab2bb3Spatrick str->append(
5213cab2bb3Spatrick "Shadow byte legend (one shadow byte represents %d "
5223cab2bb3Spatrick "application bytes):\n",
523*810390e3Srobert (int)ASAN_SHADOW_GRANULARITY);
5243cab2bb3Spatrick PrintShadowByte(str, " Addressable: ", 0);
5253cab2bb3Spatrick str->append(" Partially addressable: ");
526*810390e3Srobert for (u8 i = 1; i < ASAN_SHADOW_GRANULARITY; i++)
527*810390e3Srobert PrintShadowByte(str, "", i, " ");
5283cab2bb3Spatrick str->append("\n");
5293cab2bb3Spatrick PrintShadowByte(str, " Heap left redzone: ",
5303cab2bb3Spatrick kAsanHeapLeftRedzoneMagic);
5313cab2bb3Spatrick PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic);
5323cab2bb3Spatrick PrintShadowByte(str, " Stack left redzone: ",
5333cab2bb3Spatrick kAsanStackLeftRedzoneMagic);
5343cab2bb3Spatrick PrintShadowByte(str, " Stack mid redzone: ",
5353cab2bb3Spatrick kAsanStackMidRedzoneMagic);
5363cab2bb3Spatrick PrintShadowByte(str, " Stack right redzone: ",
5373cab2bb3Spatrick kAsanStackRightRedzoneMagic);
5383cab2bb3Spatrick PrintShadowByte(str, " Stack after return: ",
5393cab2bb3Spatrick kAsanStackAfterReturnMagic);
5403cab2bb3Spatrick PrintShadowByte(str, " Stack use after scope: ",
5413cab2bb3Spatrick kAsanStackUseAfterScopeMagic);
5423cab2bb3Spatrick PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic);
5433cab2bb3Spatrick PrintShadowByte(str, " Global init order: ",
5443cab2bb3Spatrick kAsanInitializationOrderMagic);
5453cab2bb3Spatrick PrintShadowByte(str, " Poisoned by user: ",
5463cab2bb3Spatrick kAsanUserPoisonedMemoryMagic);
5473cab2bb3Spatrick PrintShadowByte(str, " Container overflow: ",
5483cab2bb3Spatrick kAsanContiguousContainerOOBMagic);
5493cab2bb3Spatrick PrintShadowByte(str, " Array cookie: ",
5503cab2bb3Spatrick kAsanArrayCookieMagic);
5513cab2bb3Spatrick PrintShadowByte(str, " Intra object redzone: ",
5523cab2bb3Spatrick kAsanIntraObjectRedzone);
5533cab2bb3Spatrick PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic);
5543cab2bb3Spatrick PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic);
5553cab2bb3Spatrick PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic);
5563cab2bb3Spatrick }
5573cab2bb3Spatrick
PrintShadowBytes(InternalScopedString * str,const char * before,u8 * bytes,u8 * guilty,uptr n)5583cab2bb3Spatrick static void PrintShadowBytes(InternalScopedString *str, const char *before,
5593cab2bb3Spatrick u8 *bytes, u8 *guilty, uptr n) {
5603cab2bb3Spatrick Decorator d;
561*810390e3Srobert if (before)
562*810390e3Srobert str->append("%s%p:", before,
563*810390e3Srobert (void *)ShadowToMem(reinterpret_cast<uptr>(bytes)));
5643cab2bb3Spatrick for (uptr i = 0; i < n; i++) {
5653cab2bb3Spatrick u8 *p = bytes + i;
5663cab2bb3Spatrick const char *before =
5673cab2bb3Spatrick p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
5683cab2bb3Spatrick const char *after = p == guilty ? "]" : "";
5693cab2bb3Spatrick PrintShadowByte(str, before, *p, after);
5703cab2bb3Spatrick }
5713cab2bb3Spatrick str->append("\n");
5723cab2bb3Spatrick }
5733cab2bb3Spatrick
PrintShadowMemoryForAddress(uptr addr)5743cab2bb3Spatrick static void PrintShadowMemoryForAddress(uptr addr) {
5753cab2bb3Spatrick if (!AddrIsInMem(addr)) return;
5763cab2bb3Spatrick uptr shadow_addr = MemToShadow(addr);
5773cab2bb3Spatrick const uptr n_bytes_per_row = 16;
5783cab2bb3Spatrick uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
579d89ec533Spatrick InternalScopedString str;
5803cab2bb3Spatrick str.append("Shadow bytes around the buggy address:\n");
5813cab2bb3Spatrick for (int i = -5; i <= 5; i++) {
5823cab2bb3Spatrick uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;
5833cab2bb3Spatrick // Skip rows that would be outside the shadow range. This can happen when
5843cab2bb3Spatrick // the user address is near the bottom, top, or shadow gap of the address
5853cab2bb3Spatrick // space.
5863cab2bb3Spatrick if (!AddrIsInShadow(row_shadow_addr)) continue;
5873cab2bb3Spatrick const char *prefix = (i == 0) ? "=>" : " ";
5883cab2bb3Spatrick PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,
5893cab2bb3Spatrick n_bytes_per_row);
5903cab2bb3Spatrick }
5913cab2bb3Spatrick if (flags()->print_legend) PrintLegend(&str);
5923cab2bb3Spatrick Printf("%s", str.data());
5933cab2bb3Spatrick }
5943cab2bb3Spatrick
Print()5953cab2bb3Spatrick void ErrorGeneric::Print() {
5963cab2bb3Spatrick Decorator d;
5973cab2bb3Spatrick Printf("%s", d.Error());
5983cab2bb3Spatrick uptr addr = addr_description.Address();
5993cab2bb3Spatrick Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
600*810390e3Srobert bug_descr, (void *)addr, (void *)pc, (void *)bp, (void *)sp);
6013cab2bb3Spatrick Printf("%s", d.Default());
6023cab2bb3Spatrick
6033cab2bb3Spatrick Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),
6043cab2bb3Spatrick access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
6053cab2bb3Spatrick (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());
6063cab2bb3Spatrick
6073cab2bb3Spatrick scariness.Print();
6083cab2bb3Spatrick GET_STACK_TRACE_FATAL(pc, bp);
6093cab2bb3Spatrick stack.Print();
6103cab2bb3Spatrick
6113cab2bb3Spatrick // Pass bug_descr because we have a special case for
6123cab2bb3Spatrick // initialization-order-fiasco
6133cab2bb3Spatrick addr_description.Print(bug_descr);
6143cab2bb3Spatrick if (shadow_val == kAsanContiguousContainerOOBMagic)
6153cab2bb3Spatrick PrintContainerOverflowHint();
6163cab2bb3Spatrick ReportErrorSummary(bug_descr, &stack);
6173cab2bb3Spatrick PrintShadowMemoryForAddress(addr);
6183cab2bb3Spatrick }
6193cab2bb3Spatrick
6203cab2bb3Spatrick } // namespace __asan
621