Index: lib/hwasan/hwasan.h =================================================================== --- lib/hwasan/hwasan.h +++ lib/hwasan/hwasan.h @@ -1,4 +1,4 @@ -//===-- hwasan.h --------------------------------------------------*- C++ -*-===// +//===-- hwasan.h ------------------------------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -97,15 +97,6 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_s, uptr pc, uptr bp, void *context, bool request_fast_unwind); -void ReportInvalidAccess(StackTrace *stack, u32 origin); -void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size, - bool is_store); -void ReportStats(); -void ReportAtExitStatistics(); -void DescribeMemoryRange(const void *x, uptr size); -void ReportInvalidAccessInsideAddressRange(const char *what, const void *start, uptr size, - uptr offset); - // Returns a "chained" origin id, pointing to the given stack trace followed by // the previous origin id. u32 ChainOrigin(u32 id, StackTrace *stack); Index: lib/hwasan/hwasan.cc =================================================================== --- lib/hwasan/hwasan.cc +++ lib/hwasan/hwasan.cc @@ -1,4 +1,4 @@ -//===-- hwasan.cc -----------------------------------------------------------===// +//===-- hwasan.cc ---------------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -14,8 +14,9 @@ #include "hwasan.h" #include "hwasan_mapping.h" -#include "hwasan_thread.h" #include "hwasan_poisoning.h" +#include "hwasan_report.h" +#include "hwasan_thread.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" Index: lib/hwasan/hwasan_allocator.cc =================================================================== --- lib/hwasan/hwasan_allocator.cc +++ lib/hwasan/hwasan_allocator.cc @@ -1,4 +1,4 @@ -//===-- hwasan_allocator.cc --------------------------- ---------------------===// +//===-- hwasan_allocator.cc ------------------------- ---------------------===// // // The LLVM Compiler Infrastructure // @@ -15,6 +15,7 @@ #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_checks.h" #include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -127,9 +128,12 @@ size = RoundUpTo(size, kShadowAlignment); if (size > kMaxAllowedMallocSize) { - Report("WARNING: HWAddressSanitizer failed to allocate %p bytes\n", - (void *)size); - return ReturnNullOrDieOnFailure::OnBadRequest(); + if (AllocatorMayReturnNull()) { + Report("WARNING: HWAddressSanitizer failed to allocate 0x%zx bytes\n", + size); + return nullptr; + } + ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, stack); } HwasanThread *t = GetCurrentThread(); void *allocated; @@ -141,8 +145,12 @@ AllocatorCache *cache = &fallback_allocator_cache; allocated = allocator.Allocate(cache, size, alignment); } - if (UNLIKELY(!allocated)) - return ReturnNullOrDieOnFailure::OnOOM(); + if (UNLIKELY(!allocated)) { + SetAllocatorOutOfMemory(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportOutOfMemory(size, stack); + } Metadata *meta = reinterpret_cast(allocator.GetMetaData(allocated)); meta->state = CHUNK_ALLOCATED; @@ -224,6 +232,15 @@ return new_p; } +void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) { + if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { + if (AllocatorMayReturnNull()) + return nullptr; + ReportCallocOverflow(nmemb, size, stack); + } + return HwasanAllocate(stack, nmemb * size, sizeof(u64), true); +} + HwasanChunkView FindHeapChunkByAddress(uptr address) { void *block = allocator.GetBlockBegin(reinterpret_cast(address)); if (!block) @@ -247,9 +264,7 @@ } void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) { - if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) - return SetErrnoOnNull(ReturnNullOrDieOnFailure::OnBadRequest()); - return SetErrnoOnNull(HwasanAllocate(stack, nmemb * size, sizeof(u64), true)); + return SetErrnoOnNull(HwasanCalloc(stack, nmemb, size)); } void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack) { @@ -263,14 +278,17 @@ } void *hwasan_valloc(uptr size, StackTrace *stack) { - return SetErrnoOnNull(HwasanAllocate(stack, size, GetPageSizeCached(), false)); + return SetErrnoOnNull( + HwasanAllocate(stack, size, GetPageSizeCached(), false)); } void *hwasan_pvalloc(uptr size, StackTrace *stack) { uptr PageSize = GetPageSizeCached(); if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { errno = errno_ENOMEM; - return ReturnNullOrDieOnFailure::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportPvallocOverflow(size, stack); } // pvalloc(0) should allocate one page. size = size ? RoundUpTo(size, PageSize) : PageSize; @@ -280,7 +298,9 @@ void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack) { if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) { errno = errno_EINVAL; - return ReturnNullOrDieOnFailure::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAlignedAllocAlignment(size, alignment, stack); } return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false)); } @@ -288,7 +308,9 @@ void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack) { if (UNLIKELY(!IsPowerOfTwo(alignment))) { errno = errno_EINVAL; - return ReturnNullOrDieOnFailure::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAllocationAlignment(alignment, stack); } return SetErrnoOnNull(HwasanAllocate(stack, size, alignment, false)); } @@ -296,18 +318,20 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size, StackTrace *stack) { if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { - ReturnNullOrDieOnFailure::OnBadRequest(); - return errno_EINVAL; + if (AllocatorMayReturnNull()) + return errno_EINVAL; + ReportInvalidPosixMemalignAlignment(alignment, stack); } void *ptr = HwasanAllocate(stack, size, alignment, false); if (UNLIKELY(!ptr)) + // OOM error is already taken care of by HwasanAllocate. return errno_ENOMEM; CHECK(IsAligned((uptr)ptr, alignment)); *memptr = ptr; return 0; } -} // namespace __hwasan +} // namespace __hwasan using namespace __hwasan; Index: lib/hwasan/hwasan_interceptors.cc =================================================================== --- lib/hwasan/hwasan_interceptors.cc +++ lib/hwasan/hwasan_interceptors.cc @@ -20,6 +20,7 @@ #include "hwasan_mapping.h" #include "hwasan_thread.h" #include "hwasan_poisoning.h" +#include "hwasan_report.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_interface.h" Index: lib/hwasan/hwasan_linux.cc =================================================================== --- lib/hwasan/hwasan_linux.cc +++ lib/hwasan/hwasan_linux.cc @@ -20,6 +20,7 @@ #include "hwasan_dynamic_shadow.h" #include "hwasan_interface_internal.h" #include "hwasan_mapping.h" +#include "hwasan_report.h" #include "hwasan_thread.h" #include Index: lib/hwasan/hwasan_new_delete.cc =================================================================== --- lib/hwasan/hwasan_new_delete.cc +++ lib/hwasan/hwasan_new_delete.cc @@ -1,4 +1,4 @@ -//===-- hwasan_new_delete.cc ------------------------------------------------===// +//===-- hwasan_new_delete.cc ----------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -15,6 +15,7 @@ #include "hwasan.h" #include "interception/interception.h" #include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #if HWASAN_REPLACE_OPERATORS_NEW_AND_DELETE @@ -32,7 +33,7 @@ #define OPERATOR_NEW_BODY(nothrow) \ GET_MALLOC_STACK_TRACE; \ void *res = hwasan_malloc(size, &stack);\ - if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM();\ + if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ return res INTERCEPTOR_ATTRIBUTE Index: lib/hwasan/hwasan_report.h =================================================================== --- /dev/null +++ lib/hwasan/hwasan_report.h @@ -0,0 +1,36 @@ +//===-- hwasan_report.h -----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// This file is a part of HWAddressSanitizer. HWASan-private header for error +/// reporting functions. +/// +//===----------------------------------------------------------------------===// + +#ifndef HWASAN_REPORT_H +#define HWASAN_REPORT_H + +#include "sanitizer_common/sanitizer_internal_defs.h" +#include "sanitizer_common/sanitizer_stacktrace.h" + +namespace __hwasan { + +void ReportInvalidAccess(StackTrace *stack, u32 origin); +void ReportStats(); +void ReportInvalidAccessInsideAddressRange(const char *what, const void *start, + uptr size, uptr offset); +void ReportTagMismatch(StackTrace *stack, uptr addr, uptr access_size, + bool is_store); + +void ReportAtExitStatistics(); + + +} // namespace __hwasan + +#endif // HWASAN_REPORT_H Index: lib/hwasan/hwasan_report.cc =================================================================== --- lib/hwasan/hwasan_report.cc +++ lib/hwasan/hwasan_report.cc @@ -1,4 +1,4 @@ -//===-- hwasan_report.cc ----------------------------------------------------===// +//===-- hwasan_report.cc --------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -37,9 +37,9 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { public: Decorator() : SanitizerCommonDecorator() { } - const char *Allocation() { return Magenta(); } - const char *Origin() { return Magenta(); } - const char *Name() { return Green(); } + const char *Allocation() const { return Magenta(); } + const char *Origin() const { return Magenta(); } + const char *Name() const { return Green(); } }; struct HeapAddressDescription { @@ -130,5 +130,4 @@ ReportErrorSummary("tag-mismatch", stack); } - } // namespace __hwasan