diff options
Diffstat (limited to 'lib/hwasan/hwasan_report.cc')
-rw-r--r-- | lib/hwasan/hwasan_report.cc | 133 |
1 files changed, 133 insertions, 0 deletions
diff --git a/lib/hwasan/hwasan_report.cc b/lib/hwasan/hwasan_report.cc new file mode 100644 index 000000000..a3c670949 --- /dev/null +++ b/lib/hwasan/hwasan_report.cc @@ -0,0 +1,133 @@ +//===-- hwasan_report.cc ----------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +// Error reporting. +//===----------------------------------------------------------------------===// + +#include "hwasan.h" +#include "hwasan_allocator.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_symbolizer.h" + +using namespace __sanitizer; + +namespace __hwasan { + +static StackTrace GetStackTraceFromId(u32 id) { + CHECK(id); + StackTrace res = StackDepotGet(id); + CHECK(res.trace); + return res; +} + +class Decorator: public __sanitizer::SanitizerCommonDecorator { + public: + Decorator() : SanitizerCommonDecorator() { } + const char *Allocation() { return Magenta(); } + const char *Origin() { return Magenta(); } + const char *Name() { return Green(); } +}; + +struct HeapAddressDescription { + uptr addr; + u32 alloc_stack_id; + u32 free_stack_id; + + void Print() const { + Decorator d; + if (free_stack_id) { + Printf("%sfreed here:%s\n", d.Allocation(), d.Default()); + GetStackTraceFromId(free_stack_id).Print(); + Printf("%spreviously allocated here:%s\n", d.Allocation(), d.Default()); + } else { + Printf("%sallocated here:%s\n", d.Allocation(), d.Default()); + } + GetStackTraceFromId(alloc_stack_id).Print(); + } +}; + +bool GetHeapAddressInformation(uptr addr, uptr access_size, + HeapAddressDescription *description) { + HwasanChunkView chunk = FindHeapChunkByAddress(addr); + if (!chunk.IsValid()) + return false; + description->addr = addr; + description->alloc_stack_id = chunk.GetAllocStackId(); + description->free_stack_id = chunk.GetFreeStackId(); + return true; +} + +void PrintAddressDescription(uptr addr, uptr access_size) { + HeapAddressDescription heap_description; + if (GetHeapAddressInformation(addr, access_size, &heap_description)) { + heap_description.Print(); + return; + } + // We exhausted our possibilities. Bail out. + Printf("HWAddressSanitizer can not describe address in more detail.\n"); +} + +void ReportInvalidAccess(StackTrace *stack, u32 origin) { + ScopedErrorReportLock l; + + Decorator d; + Printf("%s", d.Warning()); + Report("WARNING: HWAddressSanitizer: invalid access\n"); + Printf("%s", d.Default()); + stack->Print(); + ReportErrorSummary("invalid-access", stack); +} + +void ReportStats() {} + +void ReportInvalidAccessInsideAddressRange(const char *what, const void *start, + uptr size, uptr offset) { + ScopedErrorReportLock l; + + Decorator d; + Printf("%s", d.Warning()); + Printf("%sTag mismatch in %s%s%s at offset %zu inside [%p, %zu)%s\n", + d.Warning(), d.Name(), what, d.Warning(), offset, start, size, + d.Default()); + PrintAddressDescription((uptr)start + offset, 1); + // if (__sanitizer::Verbosity()) + // DescribeMemoryRange(start, size); +} + +void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size, + bool is_store) { + ScopedErrorReportLock l; + + Decorator d; + Printf("%s", d.Warning()); + uptr address = GetAddressFromPointer(addr); + Printf("%s of size %zu at %p\n", is_store ? "WRITE" : "READ", access_size, + address); + + tag_t ptr_tag = GetTagFromPointer(addr); + tag_t mem_tag = *(tag_t *)MEM_TO_SHADOW(address); + Printf("pointer tag 0x%x\nmemory tag 0x%x\n", ptr_tag, mem_tag); + Printf("%s", d.Default()); + + stack->Print(); + + PrintAddressDescription(address, access_size); + + ReportErrorSummary("tag-mismatch", stack); +} + + +} // namespace __hwasan |