//===-- hwasan_report.cpp -------------------------------------------------===//
//
// 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 HWAddressSanitizer.
//
// Error reporting.
//===----------------------------------------------------------------------===//

#include "hwasan.h"
#include "hwasan_allocator.h"
#include "hwasan_mapping.h"
#include "hwasan_report.h"
#include "hwasan_thread.h"
#include "hwasan_thread_list.h"
#include "sanitizer_common/sanitizer_allocator_internal.h"
#include "sanitizer_common/sanitizer_common.h"
#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_mutex.h"
#include "sanitizer_common/sanitizer_report_decorator.h"
#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_stacktrace_printer.h"
#include "sanitizer_common/sanitizer_symbolizer.h"

using namespace __sanitizer;

namespace __hwasan {

class ScopedReport {
 public:
  ScopedReport(bool fatal = false) : error_message_(1), fatal(fatal) {
    BlockingMutexLock lock(&error_message_lock_);
    error_message_ptr_ = fatal ? &error_message_ : nullptr;
    ++hwasan_report_count;
  }

  ~ScopedReport() {
    {
      BlockingMutexLock lock(&error_message_lock_);
      if (fatal)
        SetAbortMessage(error_message_.data());
      error_message_ptr_ = nullptr;
    }
    if (common_flags()->print_module_map >= 2 ||
        (fatal && common_flags()->print_module_map))
      DumpProcessMap();
    if (fatal)
      Die();
  }

  static void MaybeAppendToErrorMessage(const char *msg) {
    BlockingMutexLock lock(&error_message_lock_);
    if (!error_message_ptr_)
      return;
    uptr len = internal_strlen(msg);
    uptr old_size = error_message_ptr_->size();
    error_message_ptr_->resize(old_size + len);
    // overwrite old trailing '\0', keep new trailing '\0' untouched.
    internal_memcpy(&(*error_message_ptr_)[old_size - 1], msg, len);
  }
 private:
  ScopedErrorReportLock error_report_lock_;
  InternalMmapVector<char> error_message_;
  bool fatal;

  static InternalMmapVector<char> *error_message_ptr_;
  static BlockingMutex error_message_lock_;
};

InternalMmapVector<char> *ScopedReport::error_message_ptr_;
BlockingMutex ScopedReport::error_message_lock_;

// If there is an active ScopedReport, append to its error message.
void AppendToErrorMessageBuffer(const char *buffer) {
  ScopedReport::MaybeAppendToErrorMessage(buffer);
}

static StackTrace GetStackTraceFromId(u32 id) {
  CHECK(id);
  StackTrace res = StackDepotGet(id);
  CHECK(res.trace);
  return res;
}

// A RAII object that holds a copy of the current thread stack ring buffer.
// The actual stack buffer may change while we are iterating over it (for
// example, Printf may call syslog() which can itself be built with hwasan).
class SavedStackAllocations {
 public:
  SavedStackAllocations(StackAllocationsRingBuffer *rb) {
    uptr size = rb->size() * sizeof(uptr);
    void *storage =
        MmapAlignedOrDieOnFatalError(size, size * 2, "saved stack allocations");
    new (&rb_) StackAllocationsRingBuffer(*rb, storage);
  }

  ~SavedStackAllocations() {
    StackAllocationsRingBuffer *rb = get();
    UnmapOrDie(rb->StartOfStorage(), rb->size() * sizeof(uptr));
  }

  StackAllocationsRingBuffer *get() {
    return (StackAllocationsRingBuffer *)&rb_;
  }

 private:
  uptr rb_;
};

class Decorator: public __sanitizer::SanitizerCommonDecorator {
 public:
  Decorator() : SanitizerCommonDecorator() { }
  const char *Access() { return Blue(); }
  const char *Allocation() const { return Magenta(); }
  const char *Origin() const { return Magenta(); }
  const char *Name() const { return Green(); }
  const char *Location() { return Green(); }
  const char *Thread() { return Green(); }
};

// Returns the index of the rb element that matches tagged_addr (plus one),
// or zero if found nothing.
uptr FindHeapAllocation(HeapAllocationsRingBuffer *rb,
                        uptr tagged_addr,
                        HeapAllocationRecord *har) {
  if (!rb) return 0;
  for (uptr i = 0, size = rb->size(); i < size; i++) {
    auto h = (*rb)[i];
    if (h.tagged_addr <= tagged_addr &&
        h.tagged_addr + h.requested_size > tagged_addr) {
      *har = h;
      return i + 1;
    }
  }
  return 0;
}

static void PrintStackAllocations(StackAllocationsRingBuffer *sa,
                                  tag_t addr_tag, uptr untagged_addr) {
  uptr frames = Min((uptr)flags()->stack_history_size, sa->size());
  bool found_local = false;
  for (uptr i = 0; i < frames; i++) {
    const uptr *record_addr = &(*sa)[i];
    uptr record = *record_addr;
    if (!record)
      break;
    tag_t base_tag =
        reinterpret_cast<uptr>(record_addr) >> kRecordAddrBaseTagShift;
    uptr fp = (record >> kRecordFPShift) << kRecordFPLShift;
    uptr pc_mask = (1ULL << kRecordFPShift) - 1;
    uptr pc = record & pc_mask;
    FrameInfo frame;
    if (Symbolizer::GetOrInit()->SymbolizeFrame(pc, &frame)) {
      for (LocalInfo &local : frame.locals) {
        if (!local.has_frame_offset || !local.has_size || !local.has_tag_offset)
          continue;
        tag_t obj_tag = base_tag ^ local.tag_offset;
        if (obj_tag != addr_tag)
          continue;
        // Calculate the offset from the object address to the faulting
        // address. Because we only store bits 4-19 of FP (bits 0-3 are
        // guaranteed to be zero), the calculation is performed mod 2^20 and may
        // harmlessly underflow if the address mod 2^20 is below the object
        // address.
        uptr obj_offset =
            (untagged_addr - fp - local.frame_offset) & (kRecordFPModulus - 1);
        if (obj_offset >= local.size)
          continue;
        if (!found_local) {
          Printf("Potentially referenced stack objects:\n");
          found_local = true;
        }
        Printf("  %s in %s %s:%d\n", local.name, local.function_name,
               local.decl_file, local.decl_line);
      }
      frame.Clear();
    }
  }

  if (found_local)
    return;

  // We didn't find any locals. Most likely we don't have symbols, so dump
  // the information that we have for offline analysis.
  InternalScopedString frame_desc(GetPageSizeCached() * 2);
  Printf("Previously allocated frames:\n");
  for (uptr i = 0; i < frames; i++) {
    const uptr *record_addr = &(*sa)[i];
    uptr record = *record_addr;
    if (!record)
      break;
    uptr pc_mask = (1ULL << 48) - 1;
    uptr pc = record & pc_mask;
    frame_desc.append("  record_addr:0x%zx record:0x%zx",
                      reinterpret_cast<uptr>(record_addr), record);
    if (SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc)) {
      RenderFrame(&frame_desc, " %F %L\n", 0, frame->info,
                  common_flags()->symbolize_vs_style,
                  common_flags()->strip_path_prefix);
      frame->ClearAll();
    }
    Printf("%s", frame_desc.data());
    frame_desc.clear();
  }
}

// Returns true if tag == *tag_ptr, reading tags from short granules if
// necessary. This may return a false positive if tags 1-15 are used as a
// regular tag rather than a short granule marker.
static bool TagsEqual(tag_t tag, tag_t *tag_ptr) {
  if (tag == *tag_ptr)
    return true;
  if (*tag_ptr == 0 || *tag_ptr > kShadowAlignment - 1)
    return false;
  uptr mem = ShadowToMem(reinterpret_cast<uptr>(tag_ptr));
  tag_t inline_tag = *reinterpret_cast<tag_t *>(mem + kShadowAlignment - 1);
  return tag == inline_tag;
}

void PrintAddressDescription(
    uptr tagged_addr, uptr access_size,
    StackAllocationsRingBuffer *current_stack_allocations) {
  Decorator d;
  int num_descriptions_printed = 0;
  uptr untagged_addr = UntagAddr(tagged_addr);

  // Print some very basic information about the address, if it's a heap.
  HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
  if (uptr beg = chunk.Beg()) {
    uptr size = chunk.ActualSize();
    Printf("%s[%p,%p) is a %s %s heap chunk; "
           "size: %zd offset: %zd\n%s",
           d.Location(),
           beg, beg + size,
           chunk.FromSmallHeap() ? "small" : "large",
           chunk.IsAllocated() ? "allocated" : "unallocated",
           size, untagged_addr - beg,
           d.Default());
  }

  // Check if this looks like a heap buffer overflow by scanning
  // the shadow left and right and looking for the first adjacent
  // object with a different memory tag. If that tag matches addr_tag,
  // check the allocator if it has a live chunk there.
  tag_t addr_tag = GetTagFromPointer(tagged_addr);
  tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
  tag_t *candidate = nullptr, *left = tag_ptr, *right = tag_ptr;
  for (int i = 0; i < 1000; i++) {
    if (TagsEqual(addr_tag, left)) {
      candidate = left;
      break;
    }
    --left;
    if (TagsEqual(addr_tag, right)) {
      candidate = right;
      break;
    }
    ++right;
  }

  if (candidate) {
    uptr mem = ShadowToMem(reinterpret_cast<uptr>(candidate));
    HwasanChunkView chunk = FindHeapChunkByAddress(mem);
    if (chunk.IsAllocated()) {
      Printf("%s", d.Location());
      Printf("%p is located %zd bytes to the %s of %zd-byte region [%p,%p)\n",
             untagged_addr,
             candidate == left ? untagged_addr - chunk.End()
                               : chunk.Beg() - untagged_addr,
             candidate == left ? "right" : "left", chunk.UsedSize(),
             chunk.Beg(), chunk.End());
      Printf("%s", d.Allocation());
      Printf("allocated here:\n");
      Printf("%s", d.Default());
      GetStackTraceFromId(chunk.GetAllocStackId()).Print();
      num_descriptions_printed++;
    } else {
      // Check whether the address points into a loaded library. If so, this is
      // most likely a global variable.
      const char *module_name;
      uptr module_address;
      Symbolizer *sym = Symbolizer::GetOrInit();
      if (sym->GetModuleNameAndOffsetForPC(mem, &module_name,
                                           &module_address)) {
        DataInfo info;
        if (sym->SymbolizeData(mem, &info) && info.start) {
          Printf(
              "%p is located %zd bytes to the %s of %zd-byte global variable "
              "%s [%p,%p) in %s\n",
              untagged_addr,
              candidate == left ? untagged_addr - (info.start + info.size)
                                : info.start - untagged_addr,
              candidate == left ? "right" : "left", info.size, info.name,
              info.start, info.start + info.size, module_name);
        } else {
          Printf("%p is located to the %s of a global variable in (%s+0x%x)\n",
                 untagged_addr, candidate == left ? "right" : "left",
                 module_name, module_address);
        }
        num_descriptions_printed++;
      }
    }
  }

  hwasanThreadList().VisitAllLiveThreads([&](Thread *t) {
    // Scan all threads' ring buffers to find if it's a heap-use-after-free.
    HeapAllocationRecord har;
    if (uptr D = FindHeapAllocation(t->heap_allocations(), tagged_addr, &har)) {
      Printf("%s", d.Location());
      Printf("%p is located %zd bytes inside of %zd-byte region [%p,%p)\n",
             untagged_addr, untagged_addr - UntagAddr(har.tagged_addr),
             har.requested_size, UntagAddr(har.tagged_addr),
             UntagAddr(har.tagged_addr) + har.requested_size);
      Printf("%s", d.Allocation());
      Printf("freed by thread T%zd here:\n", t->unique_id());
      Printf("%s", d.Default());
      GetStackTraceFromId(har.free_context_id).Print();

      Printf("%s", d.Allocation());
      Printf("previously allocated here:\n", t);
      Printf("%s", d.Default());
      GetStackTraceFromId(har.alloc_context_id).Print();

      // Print a developer note: the index of this heap object
      // in the thread's deallocation ring buffer.
      Printf("hwasan_dev_note_heap_rb_distance: %zd %zd\n", D,
             flags()->heap_history_size);

      t->Announce();
      num_descriptions_printed++;
    }

    // Very basic check for stack memory.
    if (t->AddrIsInStack(untagged_addr)) {
      Printf("%s", d.Location());
      Printf("Address %p is located in stack of thread T%zd\n", untagged_addr,
             t->unique_id());
      Printf("%s", d.Default());
      t->Announce();

      auto *sa = (t == GetCurrentThread() && current_stack_allocations)
                     ? current_stack_allocations
                     : t->stack_allocations();
      PrintStackAllocations(sa, addr_tag, untagged_addr);
      num_descriptions_printed++;
    }
  });

  // Print the remaining threads, as an extra information, 1 line per thread.
  hwasanThreadList().VisitAllLiveThreads([&](Thread *t) { t->Announce(); });

  if (!num_descriptions_printed)
    // We exhausted our possibilities. Bail out.
    Printf("HWAddressSanitizer can not describe address in more detail.\n");
}

void ReportStats() {}

static void PrintTagInfoAroundAddr(tag_t *tag_ptr, uptr num_rows,
                                   void (*print_tag)(InternalScopedString &s,
                                                     tag_t *tag)) {
  const uptr row_len = 16;  // better be power of two.
  tag_t *center_row_beg = reinterpret_cast<tag_t *>(
      RoundDownTo(reinterpret_cast<uptr>(tag_ptr), row_len));
  tag_t *beg_row = center_row_beg - row_len * (num_rows / 2);
  tag_t *end_row = center_row_beg + row_len * ((num_rows + 1) / 2);
  InternalScopedString s(GetPageSizeCached() * 8);
  for (tag_t *row = beg_row; row < end_row; row += row_len) {
    s.append("%s", row == center_row_beg ? "=>" : "  ");
    for (uptr i = 0; i < row_len; i++) {
      s.append("%s", row + i == tag_ptr ? "[" : " ");
      print_tag(s, &row[i]);
      s.append("%s", row + i == tag_ptr ? "]" : " ");
    }
    s.append("%s\n", row == center_row_beg ? "<=" : "  ");
  }
  Printf("%s", s.data());
}

static void PrintTagsAroundAddr(tag_t *tag_ptr) {
  Printf(
      "Memory tags around the buggy address (one tag corresponds to %zd "
      "bytes):\n", kShadowAlignment);
  PrintTagInfoAroundAddr(tag_ptr, 17, [](InternalScopedString &s, tag_t *tag) {
    s.append("%02x", *tag);
  });

  Printf(
      "Tags for short granules around the buggy address (one tag corresponds "
      "to %zd bytes):\n",
      kShadowAlignment);
  PrintTagInfoAroundAddr(tag_ptr, 3, [](InternalScopedString &s, tag_t *tag) {
    if (*tag >= 1 && *tag <= kShadowAlignment) {
      uptr granule_addr = ShadowToMem(reinterpret_cast<uptr>(tag));
      s.append("%02x",
               *reinterpret_cast<u8 *>(granule_addr + kShadowAlignment - 1));
    } else {
      s.append("..");
    }
  });
  Printf(
      "See "
      "https://clang.llvm.org/docs/"
      "HardwareAssistedAddressSanitizerDesign.html#short-granules for a "
      "description of short granule tags\n");
}

void ReportInvalidFree(StackTrace *stack, uptr tagged_addr) {
  ScopedReport R(flags()->halt_on_error);

  uptr untagged_addr = UntagAddr(tagged_addr);
  tag_t ptr_tag = GetTagFromPointer(tagged_addr);
  tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
  tag_t mem_tag = *tag_ptr;
  Decorator d;
  Printf("%s", d.Error());
  uptr pc = stack->size ? stack->trace[0] : 0;
  const char *bug_type = "invalid-free";
  Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
         untagged_addr, pc);
  Printf("%s", d.Access());
  Printf("tags: %02x/%02x (ptr/mem)\n", ptr_tag, mem_tag);
  Printf("%s", d.Default());

  stack->Print();

  PrintAddressDescription(tagged_addr, 0, nullptr);

  PrintTagsAroundAddr(tag_ptr);

  ReportErrorSummary(bug_type, stack);
}

void ReportTailOverwritten(StackTrace *stack, uptr tagged_addr, uptr orig_size,
                           const u8 *expected) {
  uptr tail_size = kShadowAlignment - (orig_size % kShadowAlignment);
  ScopedReport R(flags()->halt_on_error);
  Decorator d;
  uptr untagged_addr = UntagAddr(tagged_addr);
  Printf("%s", d.Error());
  const char *bug_type = "alocation-tail-overwritten";
  Report("ERROR: %s: %s; heap object [%p,%p) of size %zd\n", SanitizerToolName,
         bug_type, untagged_addr, untagged_addr + orig_size, orig_size);
  Printf("\n%s", d.Default());
  stack->Print();
  HwasanChunkView chunk = FindHeapChunkByAddress(untagged_addr);
  if (chunk.Beg()) {
    Printf("%s", d.Allocation());
    Printf("allocated here:\n");
    Printf("%s", d.Default());
    GetStackTraceFromId(chunk.GetAllocStackId()).Print();
  }

  InternalScopedString s(GetPageSizeCached() * 8);
  CHECK_GT(tail_size, 0U);
  CHECK_LT(tail_size, kShadowAlignment);
  u8 *tail = reinterpret_cast<u8*>(untagged_addr + orig_size);
  s.append("Tail contains: ");
  for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
    s.append(".. ");
  for (uptr i = 0; i < tail_size; i++)
    s.append("%02x ", tail[i]);
  s.append("\n");
  s.append("Expected:      ");
  for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
    s.append(".. ");
  for (uptr i = 0; i < tail_size; i++)
    s.append("%02x ", expected[i]);
  s.append("\n");
  s.append("               ");
  for (uptr i = 0; i < kShadowAlignment - tail_size; i++)
    s.append("   ");
  for (uptr i = 0; i < tail_size; i++)
    s.append("%s ", expected[i] != tail[i] ? "^^" : "  ");

  s.append("\nThis error occurs when a buffer overflow overwrites memory\n"
    "to the right of a heap object, but within the %zd-byte granule, e.g.\n"
    "   char *x = new char[20];\n"
    "   x[25] = 42;\n"
    "%s does not detect such bugs in uninstrumented code at the time of write,"
    "\nbut can detect them at the time of free/delete.\n"
    "To disable this feature set HWASAN_OPTIONS=free_checks_tail_magic=0\n",
    kShadowAlignment, SanitizerToolName);
  Printf("%s", s.data());
  GetCurrentThread()->Announce();

  tag_t *tag_ptr = reinterpret_cast<tag_t*>(MemToShadow(untagged_addr));
  PrintTagsAroundAddr(tag_ptr);

  ReportErrorSummary(bug_type, stack);
}

void ReportTagMismatch(StackTrace *stack, uptr tagged_addr, uptr access_size,
                       bool is_store, bool fatal, uptr *registers_frame) {
  ScopedReport R(fatal);
  SavedStackAllocations current_stack_allocations(
      GetCurrentThread()->stack_allocations());

  Decorator d;
  Printf("%s", d.Error());
  uptr untagged_addr = UntagAddr(tagged_addr);
  // TODO: when possible, try to print heap-use-after-free, etc.
  const char *bug_type = "tag-mismatch";
  uptr pc = stack->size ? stack->trace[0] : 0;
  Report("ERROR: %s: %s on address %p at pc %p\n", SanitizerToolName, bug_type,
         untagged_addr, pc);

  Thread *t = GetCurrentThread();

  sptr offset =
      __hwasan_test_shadow(reinterpret_cast<void *>(tagged_addr), access_size);
  CHECK(offset >= 0 && offset < static_cast<sptr>(access_size));
  tag_t ptr_tag = GetTagFromPointer(tagged_addr);
  tag_t *tag_ptr =
      reinterpret_cast<tag_t *>(MemToShadow(untagged_addr + offset));
  tag_t mem_tag = *tag_ptr;

  Printf("%s", d.Access());
  Printf("%s of size %zu at %p tags: %02x/%02x (ptr/mem) in thread T%zd\n",
         is_store ? "WRITE" : "READ", access_size, untagged_addr, ptr_tag,
         mem_tag, t->unique_id());
  if (offset != 0)
    Printf("Invalid access starting at offset [%zu, %zu)\n", offset,
           Min(access_size, static_cast<uptr>(offset) + (1 << kShadowScale)));
  Printf("%s", d.Default());

  stack->Print();

  PrintAddressDescription(tagged_addr, access_size,
                          current_stack_allocations.get());
  t->Announce();

  PrintTagsAroundAddr(tag_ptr);

  if (registers_frame)
    ReportRegisters(registers_frame, pc);

  ReportErrorSummary(bug_type, stack);
}

// See the frame breakdown defined in __hwasan_tag_mismatch (from
// hwasan_tag_mismatch_aarch64.S).
void ReportRegisters(uptr *frame, uptr pc) {
  Printf("Registers where the failure occurred (pc %p):\n", pc);

  // We explicitly print a single line (4 registers/line) each iteration to
  // reduce the amount of logcat error messages printed. Each Printf() will
  // result in a new logcat line, irrespective of whether a newline is present,
  // and so we wish to reduce the number of Printf() calls we have to make.
  Printf("    x0  %016llx  x1  %016llx  x2  %016llx  x3  %016llx\n",
       frame[0], frame[1], frame[2], frame[3]);
  Printf("    x4  %016llx  x5  %016llx  x6  %016llx  x7  %016llx\n",
       frame[4], frame[5], frame[6], frame[7]);
  Printf("    x8  %016llx  x9  %016llx  x10 %016llx  x11 %016llx\n",
       frame[8], frame[9], frame[10], frame[11]);
  Printf("    x12 %016llx  x13 %016llx  x14 %016llx  x15 %016llx\n",
       frame[12], frame[13], frame[14], frame[15]);
  Printf("    x16 %016llx  x17 %016llx  x18 %016llx  x19 %016llx\n",
       frame[16], frame[17], frame[18], frame[19]);
  Printf("    x20 %016llx  x21 %016llx  x22 %016llx  x23 %016llx\n",
       frame[20], frame[21], frame[22], frame[23]);
  Printf("    x24 %016llx  x25 %016llx  x26 %016llx  x27 %016llx\n",
       frame[24], frame[25], frame[26], frame[27]);
  Printf("    x28 %016llx  x29 %016llx  x30 %016llx\n",
       frame[28], frame[29], frame[30]);
}

}  // namespace __hwasan
