[compiler-rt] r334248 - [HWASan] Report proper error on allocator failures instead of CHECK(0)-ing

Alex Shlyapnikov via llvm-commits llvm-commits at lists.llvm.org
Thu Jun 7 16:33:34 PDT 2018


Author: alekseyshl
Date: Thu Jun  7 16:33:33 2018
New Revision: 334248

URL: http://llvm.org/viewvc/llvm-project?rev=334248&view=rev
Log:
[HWASan] Report proper error on allocator failures instead of CHECK(0)-ing

Summary:
Currently many allocator specific errors (OOM, for example) are reported as
a text message and CHECK(0) termination, not stack, no details, not too
helpful nor informative. To improve the situation, detailed and
structured errors were defined and reported under the appropriate conditions.

Reviewers: eugenis

Subscribers: kubamracek, delcypher, llvm-commits, #sanitizers

Differential Revision: https://reviews.llvm.org/D47798

Added:
    compiler-rt/trunk/lib/hwasan/hwasan_report.h
    compiler-rt/trunk/test/hwasan/TestCases/Linux/
    compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc
    compiler-rt/trunk/test/hwasan/TestCases/Linux/lit.local.cfg
    compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cc
    compiler-rt/trunk/test/hwasan/TestCases/Posix/
    compiler-rt/trunk/test/hwasan/TestCases/Posix/lit.local.cfg
    compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc
    compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cc
Modified:
    compiler-rt/trunk/lib/hwasan/hwasan.cc
    compiler-rt/trunk/lib/hwasan/hwasan.h
    compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
    compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
    compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
    compiler-rt/trunk/lib/hwasan/hwasan_new_delete.cc
    compiler-rt/trunk/lib/hwasan/hwasan_report.cc

Modified: compiler-rt/trunk/lib/hwasan/hwasan.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.cc Thu Jun  7 16:33:33 2018
@@ -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"

Modified: compiler-rt/trunk/lib/hwasan/hwasan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.h?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.h Thu Jun  7 16:33:33 2018
@@ -1,4 +1,4 @@
-//===-- hwasan.h --------------------------------------------------*- C++ -*-===//
+//===-- hwasan.h ------------------------------------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -97,15 +97,6 @@ void PrintWarning(uptr pc, uptr bp);
 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);

Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cc Thu Jun  7 16:33:33 2018
@@ -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 @@ static void *HwasanAllocate(StackTrace *
   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 @@ static void *HwasanAllocate(StackTrace *
     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<Metadata *>(allocator.GetMetaData(allocated));
   meta->state = CHUNK_ALLOCATED;
@@ -224,6 +232,15 @@ void *HwasanReallocate(StackTrace *stack
   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<void*>(address));
   if (!block)
@@ -247,9 +264,7 @@ void *hwasan_malloc(uptr size, StackTrac
 }
 
 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_realloc(void *ptr, uptr siz
 }
 
 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_pvalloc(uptr size, StackTra
 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_aligned_alloc(uptr alignmen
 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 @@ void *hwasan_memalign(uptr alignment, up
 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;
 

Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cc Thu Jun  7 16:33:33 2018
@@ -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"

Modified: compiler-rt/trunk/lib/hwasan/hwasan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_linux.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_linux.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_linux.cc Thu Jun  7 16:33:33 2018
@@ -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 <elf.h>

Modified: compiler-rt/trunk/lib/hwasan/hwasan_new_delete.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_new_delete.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_new_delete.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_new_delete.cc Thu Jun  7 16:33:33 2018
@@ -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 @@ namespace std {
 #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

Modified: compiler-rt/trunk/lib/hwasan/hwasan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.cc?rev=334248&r1=334247&r2=334248&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.cc (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.cc Thu Jun  7 16:33:33 2018
@@ -1,4 +1,4 @@
-//===-- hwasan_report.cc ----------------------------------------------------===//
+//===-- hwasan_report.cc --------------------------------------------------===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -37,9 +37,9 @@ static StackTrace GetStackTraceFromId(u3
 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 @@ void ReportTagMismatch(StackTrace *stack
   ReportErrorSummary("tag-mismatch", stack);
 }
 
-
 }  // namespace __hwasan

Added: compiler-rt/trunk/lib/hwasan/hwasan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_report.h?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_report.h (added)
+++ compiler-rt/trunk/lib/hwasan/hwasan_report.h Thu Jun  7 16:33:33 2018
@@ -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

Added: compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/Linux/aligned_alloc-alignment.cc Thu Jun  7 16:33:33 2018
@@ -0,0 +1,25 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// UNSUPPORTED: android
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+extern void *aligned_alloc(size_t alignment, size_t size);
+
+int main() {
+  void *p = aligned_alloc(17, 100);
+  // CHECK: ERROR: HWAddressSanitizer: invalid alignment requested in aligned_alloc: 17
+  // CHECK: {{#0 0x.* in .*}}{{aligned_alloc|memalign}}
+  // CHECK: {{#1 0x.* in main .*aligned_alloc-alignment.cc:}}[[@LINE-3]]
+  // CHECK: SUMMARY: HWAddressSanitizer: invalid-aligned-alloc-alignment
+
+  printf("pointer after failed aligned_alloc: %zd\n", (size_t)p);
+  // CHECK-NULL: pointer after failed aligned_alloc: 0
+
+  return 0;
+}

Added: compiler-rt/trunk/test/hwasan/TestCases/Linux/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/Linux/lit.local.cfg?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/Linux/lit.local.cfg (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/Linux/lit.local.cfg Thu Jun  7 16:33:33 2018
@@ -0,0 +1,9 @@
+def getRoot(config):
+  if not config.parent:
+    return config
+  return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Linux']:
+  config.unsupported = True

Added: compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cc?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cc (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/Linux/pvalloc-overflow.cc Thu Jun  7 16:33:33 2018
@@ -0,0 +1,46 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t m1 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t m1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t psm1 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t psm1 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// UNSUPPORTED: android
+
+// REQUIRES: stable-runtime
+
+// Checks that pvalloc overflows are caught. If the allocator is allowed to
+// return null, the errno should be set to ENOMEM.
+
+#include <assert.h>
+#include <errno.h>
+#include <malloc.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+
+int main(int argc, char *argv[]) {
+  assert(argc == 2);
+  const char *action = argv[1];
+
+  const size_t page_size = sysconf(_SC_PAGESIZE);
+
+  void *p = nullptr;
+  if (!strcmp(action, "m1")) {
+    p = pvalloc((uintptr_t)-1);
+  } else if (!strcmp(action, "psm1")) {
+    p = pvalloc((uintptr_t)-(page_size - 1));
+  } else {
+    assert(0);
+  }
+
+  fprintf(stderr, "errno: %d\n", errno);
+
+  return p != nullptr;
+}
+
+// CHECK: {{ERROR: HWAddressSanitizer: pvalloc parameters overflow: size .* rounded up to system page size .* cannot be represented in type size_t}}
+// CHECK: {{#0 0x.* in .*pvalloc}}
+// CHECK: {{#1 0x.* in main .*pvalloc-overflow.cc:}}
+// CHECK: SUMMARY: HWAddressSanitizer: pvalloc-overflow
+
+// CHECK-NULL: errno: 12

Added: compiler-rt/trunk/test/hwasan/TestCases/Posix/lit.local.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/Posix/lit.local.cfg?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/Posix/lit.local.cfg (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/Posix/lit.local.cfg Thu Jun  7 16:33:33 2018
@@ -0,0 +1,9 @@
+def getRoot(config):
+  if not config.parent:
+    return config
+  return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os in ['Windows']:
+  config.unsupported = True

Added: compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/Posix/posix_memalign-alignment.cc Thu Jun  7 16:33:33 2018
@@ -0,0 +1,22 @@
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int main() {
+  void *p = reinterpret_cast<void*>(42);
+  int res = posix_memalign(&p, 17, 100);
+  // CHECK: ERROR: HWAddressSanitizer: invalid alignment requested in posix_memalign: 17
+  // CHECK: {{#0 0x.* in .*posix_memalign}}
+  // CHECK: {{#1 0x.* in main .*posix_memalign-alignment.cc:}}[[@LINE-3]]
+  // CHECK: SUMMARY: HWAddressSanitizer: invalid-posix-memalign-alignment
+
+  printf("pointer after failed posix_memalign: %zd\n", (size_t)p);
+  // CHECK-NULL: pointer after failed posix_memalign: 42
+
+  return 0;
+}

Added: compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cc?rev=334248&view=auto
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cc (added)
+++ compiler-rt/trunk/test/hwasan/TestCases/allocator_returns_null.cc Thu Jun  7 16:33:33 2018
@@ -0,0 +1,115 @@
+// Test the behavior of malloc/calloc/realloc/new when the allocation size
+// exceeds the HWASan allocator's max allowed one.
+// By default (allocator_may_return_null=0) the process should crash. With
+// allocator_may_return_null=1 the allocator should return 0 and set errno to
+// the appropriate error code.
+//
+// RUN: %clangxx_hwasan -O0 %s -o %t
+// RUN: not %run %t malloc 2>&1 | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t malloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-mCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t malloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-mNULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-cCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t calloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-cNULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc-overflow 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-coCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t calloc-overflow 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-coNULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-rCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t realloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-rNULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t realloc-after-malloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-mrCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t realloc-after-malloc 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-mrNULL
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-nCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 not %run %t new 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-nCRASH-OOM
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new-nothrow 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-nnCRASH
+// RUN: %env_hwasan_opts=allocator_may_return_null=1     %run %t new-nothrow 2>&1 \
+// RUN:   | FileCheck %s --check-prefix=CHECK-nnNULL
+
+// REQUIRES: stable-runtime
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <limits>
+#include <new>
+
+int main(int argc, char **argv) {
+  assert(argc == 2);
+  const char *action = argv[1];
+  fprintf(stderr, "%s:\n", action);
+
+  static const size_t kMaxAllowedMallocSizePlusOne = (2UL << 30) + 1;
+
+  void *x = nullptr;
+  if (!strcmp(action, "malloc")) {
+    x = malloc(kMaxAllowedMallocSizePlusOne);
+  } else if (!strcmp(action, "calloc")) {
+    x = calloc((kMaxAllowedMallocSizePlusOne / 4) + 1, 4);
+  } else if (!strcmp(action, "calloc-overflow")) {
+    volatile size_t kMaxSizeT = std::numeric_limits<size_t>::max();
+    size_t kArraySize = 4096;
+    volatile size_t kArraySize2 = kMaxSizeT / kArraySize + 10;
+    x = calloc(kArraySize, kArraySize2);
+  } else if (!strcmp(action, "realloc")) {
+    x = realloc(0, kMaxAllowedMallocSizePlusOne);
+  } else if (!strcmp(action, "realloc-after-malloc")) {
+    char *t = (char*)malloc(100);
+    *t = 42;
+    x = realloc(t, kMaxAllowedMallocSizePlusOne);
+    assert(*t == 42);
+    free(t);
+  } else if (!strcmp(action, "new")) {
+    x = operator new(kMaxAllowedMallocSizePlusOne);
+  } else if (!strcmp(action, "new-nothrow")) {
+    x = operator new(kMaxAllowedMallocSizePlusOne, std::nothrow);
+  } else {
+    assert(0);
+  }
+
+  fprintf(stderr, "errno: %d\n", errno);
+
+  free(x);
+
+  return x != nullptr;
+}
+
+// CHECK-mCRASH: malloc:
+// CHECK-mCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-cCRASH: calloc:
+// CHECK-cCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-coCRASH: calloc-overflow:
+// CHECK-coCRASH: SUMMARY: HWAddressSanitizer: calloc-overflow
+// CHECK-rCRASH: realloc:
+// CHECK-rCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-mrCRASH: realloc-after-malloc:
+// CHECK-mrCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-nCRASH: new:
+// CHECK-nCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+// CHECK-nCRASH-OOM: new:
+// CHECK-nCRASH-OOM: SUMMARY: HWAddressSanitizer: out-of-memory
+// CHECK-nnCRASH: new-nothrow:
+// CHECK-nnCRASH: SUMMARY: HWAddressSanitizer: allocation-size-too-big
+
+// CHECK-mNULL: malloc:
+// CHECK-mNULL: errno: 12
+// CHECK-cNULL: calloc:
+// CHECK-cNULL: errno: 12
+// CHECK-coNULL: calloc-overflow:
+// CHECK-coNULL: errno: 12
+// CHECK-rNULL: realloc:
+// CHECK-rNULL: errno: 12
+// CHECK-mrNULL: realloc-after-malloc:
+// CHECK-mrNULL: errno: 12
+// CHECK-nnNULL: new-nothrow:




More information about the llvm-commits mailing list