//===-- asan_errors.cpp -----------------------------------------*- C++ -*-===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// ASan implementation for error structures.
//===----------------------------------------------------------------------===//

#include "asan_errors.h"
#include "asan_descriptions.h"
#include "asan_mapping.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "sanitizer_common/sanitizer_stackdepot.h"

namespace __asan {

static void OnStackUnwind(const SignalContext &sig,
                          const void *callback_context,
                          BufferedStackTrace *stack) {
  bool fast = common_flags()->fast_unwind_on_fatal;
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
  // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
  // yields the call stack of the signal's handler and not of the code
  // that raised the signal (as it does on Linux).
  fast = true;
#endif
  // Tests and maybe some users expect that scariness is going to be printed
  // just before the stack. As only asan has scariness score we have no
  // corresponding code in the sanitizer_common and we use this callback to
  // print it.
  static_cast<const ScarinessScoreBase *>(callback_context)->Print();
  stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context,
                fast);
}

void ErrorDeadlySignal::Print() {
  ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);
}

void ErrorDoubleFree::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n",
      scariness.GetDescription(), addr_description.addr,
      AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  scariness.Print();
  GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
                        second_free_stack->top_frame_bp);
  stack.Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), &stack);
}

void ErrorNewDeleteTypeMismatch::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: %s on %p in thread %s:\n",
      scariness.GetDescription(), addr_description.addr,
      AsanThreadIdAndName(tid).c_str());
  Printf("%s  object passed to delete has wrong type:\n", d.Default());
  if (delete_size != 0) {
    Printf(
        "  size of the allocated type:   %zd bytes;\n"
        "  size of the deallocated type: %zd bytes.\n",
        addr_description.chunk_access.chunk_size, delete_size);
  }
  const uptr user_alignment =
      addr_description.chunk_access.user_requested_alignment;
  if (delete_alignment != user_alignment) {
    char user_alignment_str[32];
    char delete_alignment_str[32];
    internal_snprintf(user_alignment_str, sizeof(user_alignment_str),
                      "%zd bytes", user_alignment);
    internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str),
                      "%zd bytes", delete_alignment);
    static const char *kDefaultAlignment = "default-aligned";
    Printf(
        "  alignment of the allocated type:   %s;\n"
        "  alignment of the deallocated type: %s.\n",
        user_alignment > 0 ? user_alignment_str : kDefaultAlignment,
        delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment);
  }
  CHECK_GT(free_stack->size, 0);
  scariness.Print();
  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
  stack.Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), &stack);
  Report(
      "HINT: if you don't care about these errors you may set "
      "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
}

void ErrorFreeNotMalloced::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: attempting free on address "
      "which was not malloc()-ed: %p in thread %s\n",
      addr_description.Address(), AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  CHECK_GT(free_stack->size, 0);
  scariness.Print();
  GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
  stack.Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), &stack);
}

void ErrorAllocTypeMismatch::Print() {
  static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
                                      "operator new []"};
  static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
                                        "operator delete []"};
  CHECK_NE(alloc_type, dealloc_type);
  Decorator d;
  Printf("%s", d.Error());
  Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
         scariness.GetDescription(), alloc_names[alloc_type],
         dealloc_names[dealloc_type], addr_description.Address());
  Printf("%s", d.Default());
  CHECK_GT(dealloc_stack->size, 0);
  scariness.Print();
  GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
  stack.Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), &stack);
  Report(
      "HINT: if you don't care about these errors you may set "
      "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
}

void ErrorMallocUsableSizeNotOwned::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
      "pointer which is not owned: %p\n",
      addr_description.Address());
  Printf("%s", d.Default());
  stack->Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: attempting to call "
      "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
      addr_description.Address());
  Printf("%s", d.Default());
  stack->Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorCallocOverflow::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: calloc parameters overflow: count * size "
      "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
      count, size, AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorReallocArrayOverflow::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size "
      "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
      count, size, AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorPvallocOverflow::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx "
      "rounded up to system page size 0x%zx cannot be represented in type "
      "size_t (thread %s)\n",
      size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorInvalidAllocationAlignment::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: invalid allocation alignment: %zd, "
      "alignment must be a power of two (thread %s)\n",
      alignment, AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorInvalidAlignedAllocAlignment::Print() {
  Decorator d;
  Printf("%s", d.Error());
#if SANITIZER_POSIX
  Report("ERROR: AddressSanitizer: invalid alignment requested in "
         "aligned_alloc: %zd, alignment must be a power of two and the "
         "requested size 0x%zx must be a multiple of alignment "
         "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str());
#else
  Report("ERROR: AddressSanitizer: invalid alignment requested in "
         "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of "
         "alignment (thread %s)\n", alignment, size,
         AsanThreadIdAndName(tid).c_str());
#endif
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorInvalidPosixMemalignAlignment::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: "
      "%zd, alignment must be a power of two and a multiple of sizeof(void*) "
      "== %zd (thread %s)\n",
      alignment, sizeof(void *), AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorAllocationSizeTooBig::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after "
      "adjustments for alignment, red zones etc.) exceeds maximum supported "
      "size of 0x%zx (thread %s)\n",
      user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str());
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorRssLimitExceeded::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to "
      "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb);
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorOutOfMemory::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: allocator is out of memory trying to allocate "
      "0x%zx bytes\n", requested_size);
  Printf("%s", d.Default());
  stack->Print();
  PrintHintAllocatorCannotReturnNull();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorStringFunctionMemoryRangesOverlap::Print() {
  Decorator d;
  char bug_type[100];
  internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
  Printf("%s", d.Error());
  Report(
      "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
      "overlap\n",
      bug_type, addr1_description.Address(),
      addr1_description.Address() + length1, addr2_description.Address(),
      addr2_description.Address() + length2);
  Printf("%s", d.Default());
  scariness.Print();
  stack->Print();
  addr1_description.Print();
  addr2_description.Print();
  ReportErrorSummary(bug_type, stack);
}

void ErrorStringFunctionSizeOverflow::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
         scariness.GetDescription(), size);
  Printf("%s", d.Default());
  scariness.Print();
  stack->Print();
  addr_description.Print();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorBadParamsToAnnotateContiguousContainer::Print() {
  Report(
      "ERROR: AddressSanitizer: bad parameters to "
      "__sanitizer_annotate_contiguous_container:\n"
      "      beg     : %p\n"
      "      end     : %p\n"
      "      old_mid : %p\n"
      "      new_mid : %p\n",
      beg, end, old_mid, new_mid);
  uptr granularity = SHADOW_GRANULARITY;
  if (!IsAligned(beg, granularity))
    Report("ERROR: beg is not aligned by %d\n", granularity);
  stack->Print();
  ReportErrorSummary(scariness.GetDescription(), stack);
}

void ErrorODRViolation::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
         global1.beg);
  Printf("%s", d.Default());
  InternalScopedString g1_loc;
  InternalScopedString g2_loc;
  PrintGlobalLocation(&g1_loc, global1);
  PrintGlobalLocation(&g2_loc, global2);
  Printf("  [1] size=%zd '%s' %s\n", global1.size,
         MaybeDemangleGlobalName(global1.name), g1_loc.data());
  Printf("  [2] size=%zd '%s' %s\n", global2.size,
         MaybeDemangleGlobalName(global2.name), g2_loc.data());
  if (stack_id1 && stack_id2) {
    Printf("These globals were registered at these points:\n");
    Printf("  [1]:\n");
    StackDepotGet(stack_id1).Print();
    Printf("  [2]:\n");
    StackDepotGet(stack_id2).Print();
  }
  Report(
      "HINT: if you don't care about these errors you may set "
      "ASAN_OPTIONS=detect_odr_violation=0\n");
  InternalScopedString error_msg;
  error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
                   MaybeDemangleGlobalName(global1.name), g1_loc.data());
  ReportErrorSummary(error_msg.data());
}

void ErrorInvalidPointerPair::Print() {
  Decorator d;
  Printf("%s", d.Error());
  Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
         addr1_description.Address(), addr2_description.Address());
  Printf("%s", d.Default());
  GET_STACK_TRACE_FATAL(pc, bp);
  stack.Print();
  addr1_description.Print();
  addr2_description.Print();
  ReportErrorSummary(scariness.GetDescription(), &stack);
}

static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
  return s[-1] > 127 && s[1] > 127;
}

ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
                           bool is_write_, uptr access_size_)
    : ErrorBase(tid),
      addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
      pc(pc_),
      bp(bp_),
      sp(sp_),
      access_size(access_size_),
      is_write(is_write_),
      shadow_val(0) {
  scariness.Clear();
  if (access_size) {
    if (access_size <= 9) {
      char desr[] = "?-byte";
      desr[0] = '0' + access_size;
      scariness.Scare(access_size + access_size / 2, desr);
    } else if (access_size >= 10) {
      scariness.Scare(15, "multi-byte");
    }
    is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");

    // Determine the error type.
    bug_descr = "unknown-crash";
    if (AddrIsInMem(addr)) {
      u8 *shadow_addr = (u8 *)MemToShadow(addr);
      // If we are accessing 16 bytes, look at the second shadow byte.
      if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) shadow_addr++;
      // If we are in the partial right redzone, look at the next shadow byte.
      if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;
      bool far_from_bounds = false;
      shadow_val = *shadow_addr;
      int bug_type_score = 0;
      // For use-after-frees reads are almost as bad as writes.
      int read_after_free_bonus = 0;
      switch (shadow_val) {
        case kAsanHeapLeftRedzoneMagic:
        case kAsanArrayCookieMagic:
          bug_descr = "heap-buffer-overflow";
          bug_type_score = 10;
          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
          break;
        case kAsanHeapFreeMagic:
          bug_descr = "heap-use-after-free";
          bug_type_score = 20;
          if (!is_write) read_after_free_bonus = 18;
          break;
        case kAsanStackLeftRedzoneMagic:
          bug_descr = "stack-buffer-underflow";
          bug_type_score = 25;
          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
          break;
        case kAsanInitializationOrderMagic:
          bug_descr = "initialization-order-fiasco";
          bug_type_score = 1;
          break;
        case kAsanStackMidRedzoneMagic:
        case kAsanStackRightRedzoneMagic:
          bug_descr = "stack-buffer-overflow";
          bug_type_score = 25;
          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
          break;
        case kAsanStackAfterReturnMagic:
          bug_descr = "stack-use-after-return";
          bug_type_score = 30;
          if (!is_write) read_after_free_bonus = 18;
          break;
        case kAsanUserPoisonedMemoryMagic:
          bug_descr = "use-after-poison";
          bug_type_score = 20;
          break;
        case kAsanContiguousContainerOOBMagic:
          bug_descr = "container-overflow";
          bug_type_score = 10;
          break;
        case kAsanStackUseAfterScopeMagic:
          bug_descr = "stack-use-after-scope";
          bug_type_score = 10;
          break;
        case kAsanGlobalRedzoneMagic:
          bug_descr = "global-buffer-overflow";
          bug_type_score = 10;
          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
          break;
        case kAsanIntraObjectRedzone:
          bug_descr = "intra-object-overflow";
          bug_type_score = 10;
          break;
        case kAsanAllocaLeftMagic:
        case kAsanAllocaRightMagic:
          bug_descr = "dynamic-stack-buffer-overflow";
          bug_type_score = 25;
          far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
          break;
      }
      scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
      if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
    }
  }
}

static void PrintContainerOverflowHint() {
  Printf("HINT: if you don't care about these errors you may set "
         "ASAN_OPTIONS=detect_container_overflow=0.\n"
         "If you suspect a false positive see also: "
         "https://github.com/google/sanitizers/wiki/"
         "AddressSanitizerContainerOverflow.\n");
}

static void PrintShadowByte(InternalScopedString *str, const char *before,
    u8 byte, const char *after = "\n") {
  PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
}

static void PrintLegend(InternalScopedString *str) {
  str->append(
      "Shadow byte legend (one shadow byte represents %d "
      "application bytes):\n",
      (int)SHADOW_GRANULARITY);
  PrintShadowByte(str, "  Addressable:           ", 0);
  str->append("  Partially addressable: ");
  for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " ");
  str->append("\n");
  PrintShadowByte(str, "  Heap left redzone:       ",
                  kAsanHeapLeftRedzoneMagic);
  PrintShadowByte(str, "  Freed heap region:       ", kAsanHeapFreeMagic);
  PrintShadowByte(str, "  Stack left redzone:      ",
                  kAsanStackLeftRedzoneMagic);
  PrintShadowByte(str, "  Stack mid redzone:       ",
                  kAsanStackMidRedzoneMagic);
  PrintShadowByte(str, "  Stack right redzone:     ",
                  kAsanStackRightRedzoneMagic);
  PrintShadowByte(str, "  Stack after return:      ",
                  kAsanStackAfterReturnMagic);
  PrintShadowByte(str, "  Stack use after scope:   ",
                  kAsanStackUseAfterScopeMagic);
  PrintShadowByte(str, "  Global redzone:          ", kAsanGlobalRedzoneMagic);
  PrintShadowByte(str, "  Global init order:       ",
                  kAsanInitializationOrderMagic);
  PrintShadowByte(str, "  Poisoned by user:        ",
                  kAsanUserPoisonedMemoryMagic);
  PrintShadowByte(str, "  Container overflow:      ",
                  kAsanContiguousContainerOOBMagic);
  PrintShadowByte(str, "  Array cookie:            ",
                  kAsanArrayCookieMagic);
  PrintShadowByte(str, "  Intra object redzone:    ",
                  kAsanIntraObjectRedzone);
  PrintShadowByte(str, "  ASan internal:           ", kAsanInternalHeapMagic);
  PrintShadowByte(str, "  Left alloca redzone:     ", kAsanAllocaLeftMagic);
  PrintShadowByte(str, "  Right alloca redzone:    ", kAsanAllocaRightMagic);
  PrintShadowByte(str, "  Shadow gap:              ", kAsanShadowGap);
}

static void PrintShadowBytes(InternalScopedString *str, const char *before,
                             u8 *bytes, u8 *guilty, uptr n) {
  Decorator d;
  if (before) str->append("%s%p:", before, bytes);
  for (uptr i = 0; i < n; i++) {
    u8 *p = bytes + i;
    const char *before =
        p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
    const char *after = p == guilty ? "]" : "";
    PrintShadowByte(str, before, *p, after);
  }
  str->append("\n");
}

static void PrintShadowMemoryForAddress(uptr addr) {
  if (!AddrIsInMem(addr)) return;
  uptr shadow_addr = MemToShadow(addr);
  const uptr n_bytes_per_row = 16;
  uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
  InternalScopedString str;
  str.append("Shadow bytes around the buggy address:\n");
  for (int i = -5; i <= 5; i++) {
    uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;
    // Skip rows that would be outside the shadow range. This can happen when
    // the user address is near the bottom, top, or shadow gap of the address
    // space.
    if (!AddrIsInShadow(row_shadow_addr)) continue;
    const char *prefix = (i == 0) ? "=>" : "  ";
    PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,
                     n_bytes_per_row);
  }
  if (flags()->print_legend) PrintLegend(&str);
  Printf("%s", str.data());
}

void ErrorGeneric::Print() {
  Decorator d;
  Printf("%s", d.Error());
  uptr addr = addr_description.Address();
  Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
         bug_descr, (void *)addr, pc, bp, sp);
  Printf("%s", d.Default());

  Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),
         access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
         (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());

  scariness.Print();
  GET_STACK_TRACE_FATAL(pc, bp);
  stack.Print();

  // Pass bug_descr because we have a special case for
  // initialization-order-fiasco
  addr_description.Print(bug_descr);
  if (shadow_val == kAsanContiguousContainerOOBMagic)
    PrintContainerOverflowHint();
  ReportErrorSummary(bug_descr, &stack);
  PrintShadowMemoryForAddress(addr);
}

}  // namespace __asan
