xref: /openbsd-src/gnu/llvm/compiler-rt/lib/asan/asan_errors.cpp (revision 810390e339a5425391477d5d41c78d7cab2424ac)
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