[compiler-rt] r359708 - [sanitizer] Implement reallocarray.
Evgeniy Stepanov via llvm-commits
llvm-commits at lists.llvm.org
Wed May 1 10:33:02 PDT 2019
Author: eugenis
Date: Wed May 1 10:33:01 2019
New Revision: 359708
URL: http://llvm.org/viewvc/llvm-project?rev=359708&view=rev
Log:
[sanitizer] Implement reallocarray.
Summary:
It's a cross of calloc and realloc. Sanitizers implement calloc-like check for size
overflow.
Reviewers: vitalybuka, kcc
Subscribers: kubamracek, #sanitizers, llvm-commits
Tags: #sanitizers, #llvm
Differential Revision: https://reviews.llvm.org/D61108
Added:
compiler-rt/trunk/test/sanitizer_common/TestCases/reallocarray-overflow.cc
Modified:
compiler-rt/trunk/include/sanitizer/hwasan_interface.h
compiler-rt/trunk/lib/asan/asan_allocator.cc
compiler-rt/trunk/lib/asan/asan_allocator.h
compiler-rt/trunk/lib/asan/asan_errors.cc
compiler-rt/trunk/lib/asan/asan_errors.h
compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
compiler-rt/trunk/lib/asan/asan_report.cc
compiler-rt/trunk/lib/asan/asan_report.h
compiler-rt/trunk/lib/hwasan/hwasan.h
compiler-rt/trunk/lib/hwasan/hwasan_allocator.cpp
compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cpp
compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h
compiler-rt/trunk/lib/lsan/lsan_allocator.cc
compiler-rt/trunk/lib/lsan/lsan_allocator.h
compiler-rt/trunk/lib/lsan/lsan_interceptors.cc
compiler-rt/trunk/lib/msan/msan.h
compiler-rt/trunk/lib/msan/msan_allocator.cc
compiler-rt/trunk/lib/msan/msan_interceptors.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc
compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.h
compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
compiler-rt/trunk/test/hwasan/TestCases/realloc-test.cc
compiler-rt/trunk/test/hwasan/TestCases/sanitizer_malloc.cc
compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp
Modified: compiler-rt/trunk/include/sanitizer/hwasan_interface.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/include/sanitizer/hwasan_interface.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/include/sanitizer/hwasan_interface.h (original)
+++ compiler-rt/trunk/include/sanitizer/hwasan_interface.h Wed May 1 10:33:01 2019
@@ -87,6 +87,7 @@ extern "C" {
void __sanitizer_malloc_stats(void);
void * __sanitizer_calloc(size_t nmemb, size_t size);
void * __sanitizer_realloc(void *ptr, size_t size);
+ void * __sanitizer_reallocarray(void *ptr, size_t nmemb, size_t size);
void * __sanitizer_malloc(size_t size);
#ifdef __cplusplus
} // extern "C"
Modified: compiler-rt/trunk/lib/asan/asan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.cc Wed May 1 10:33:01 2019
@@ -879,6 +879,17 @@ void *asan_calloc(uptr nmemb, uptr size,
return SetErrnoOnNull(instance.Calloc(nmemb, size, stack));
}
+void *asan_reallocarray(void *p, uptr nmemb, uptr size,
+ BufferedStackTrace *stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, stack);
+ }
+ return asan_realloc(p, nmemb * size, stack);
+}
+
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
if (!p)
return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
Modified: compiler-rt/trunk/lib/asan/asan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_allocator.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_allocator.h (original)
+++ compiler-rt/trunk/lib/asan/asan_allocator.h Wed May 1 10:33:01 2019
@@ -219,6 +219,8 @@ void asan_delete(void *ptr, uptr size, u
void *asan_malloc(uptr size, BufferedStackTrace *stack);
void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);
+void *asan_reallocarray(void *p, uptr nmemb, uptr size,
+ BufferedStackTrace *stack);
void *asan_valloc(uptr size, BufferedStackTrace *stack);
void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
Modified: compiler-rt/trunk/lib/asan/asan_errors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_errors.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_errors.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_errors.cc Wed May 1 10:33:01 2019
@@ -177,6 +177,19 @@ void ErrorCallocOverflow::Print() {
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());
Modified: compiler-rt/trunk/lib/asan/asan_errors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_errors.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_errors.h (original)
+++ compiler-rt/trunk/lib/asan/asan_errors.h Wed May 1 10:33:01 2019
@@ -163,6 +163,21 @@ struct ErrorCallocOverflow : ErrorBase {
void Print();
};
+struct ErrorReallocArrayOverflow : ErrorBase {
+ const BufferedStackTrace *stack;
+ uptr count;
+ uptr size;
+
+ ErrorReallocArrayOverflow() = default; // (*)
+ ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
+ uptr size_)
+ : ErrorBase(tid, 10, "reallocarray-overflow"),
+ stack(stack_),
+ count(count_),
+ size(size_) {}
+ void Print();
+};
+
struct ErrorPvallocOverflow : ErrorBase {
const BufferedStackTrace *stack;
uptr size;
@@ -371,6 +386,7 @@ struct ErrorGeneric : ErrorBase {
macro(MallocUsableSizeNotOwned) \
macro(SanitizerGetAllocatedSizeNotOwned) \
macro(CallocOverflow) \
+ macro(ReallocArrayOverflow) \
macro(PvallocOverflow) \
macro(InvalidAllocationAlignment) \
macro(InvalidAlignedAllocAlignment) \
Modified: compiler-rt/trunk/lib/asan/asan_malloc_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_malloc_linux.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_malloc_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_malloc_linux.cc Wed May 1 10:33:01 2019
@@ -165,6 +165,14 @@ INTERCEPTOR(void*, realloc, void *ptr, u
return asan_realloc(ptr, size, &stack);
}
+#if SANITIZER_INTERCEPT_REALLOCARRAY
+INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) {
+ ENSURE_ASAN_INITED();
+ GET_STACK_TRACE_MALLOC;
+ return asan_reallocarray(ptr, nmemb, size, &stack);
+}
+#endif // SANITIZER_INTERCEPT_REALLOCARRAY
+
#if SANITIZER_INTERCEPT_MEMALIGN
INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
GET_STACK_TRACE_MALLOC;
Modified: compiler-rt/trunk/lib/asan/asan_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_report.cc Wed May 1 10:33:01 2019
@@ -263,6 +263,13 @@ void ReportCallocOverflow(uptr count, up
in_report.ReportError(error);
}
+void ReportReallocArrayOverflow(uptr count, uptr size,
+ BufferedStackTrace *stack) {
+ ScopedInErrorReport in_report(/*fatal*/ true);
+ ErrorReallocArrayOverflow error(GetCurrentTidOrInvalid(), stack, count, size);
+ in_report.ReportError(error);
+}
+
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack) {
ScopedInErrorReport in_report(/*fatal*/ true);
ErrorPvallocOverflow error(GetCurrentTidOrInvalid(), stack, size);
Modified: compiler-rt/trunk/lib/asan/asan_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_report.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_report.h (original)
+++ compiler-rt/trunk/lib/asan/asan_report.h Wed May 1 10:33:01 2019
@@ -61,6 +61,8 @@ void ReportMallocUsableSizeNotOwned(uptr
void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
BufferedStackTrace *stack);
void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack);
+void ReportReallocArrayOverflow(uptr count, uptr size,
+ BufferedStackTrace *stack);
void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack);
void ReportInvalidAllocationAlignment(uptr alignment,
BufferedStackTrace *stack);
Modified: compiler-rt/trunk/lib/hwasan/hwasan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan.h Wed May 1 10:33:01 2019
@@ -81,6 +81,7 @@ void HwasanAllocatorThreadFinish();
void *hwasan_malloc(uptr size, StackTrace *stack);
void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack);
void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack);
+void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack);
void *hwasan_valloc(uptr size, StackTrace *stack);
void *hwasan_pvalloc(uptr size, StackTrace *stack);
void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
Modified: compiler-rt/trunk/lib/hwasan/hwasan_allocator.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_allocator.cpp?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_allocator.cpp (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_allocator.cpp Wed May 1 10:33:01 2019
@@ -341,6 +341,16 @@ void *hwasan_realloc(void *ptr, uptr siz
return SetErrnoOnNull(HwasanReallocate(stack, ptr, size, sizeof(u64)));
}
+void *hwasan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, stack);
+ }
+ return hwasan_realloc(ptr, nmemb * size, stack);
+}
+
void *hwasan_valloc(uptr size, StackTrace *stack) {
return SetErrnoOnNull(
HwasanAllocate(stack, size, GetPageSizeCached(), false));
Modified: compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cpp?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cpp (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interceptors.cpp Wed May 1 10:33:01 2019
@@ -178,6 +178,11 @@ void * __sanitizer_realloc(void *ptr, up
return hwasan_realloc(ptr, size, &stack);
}
+void * __sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size) {
+ GET_MALLOC_STACK_TRACE;
+ return hwasan_reallocarray(ptr, nmemb, size, &stack);
+}
+
void * __sanitizer_malloc(uptr size) {
GET_MALLOC_STACK_TRACE;
if (UNLIKELY(!hwasan_init_is_running))
@@ -204,6 +209,7 @@ INTERCEPTOR_ALIAS(void, free, void *ptr)
INTERCEPTOR_ALIAS(uptr, malloc_usable_size, const void *ptr);
INTERCEPTOR_ALIAS(void *, calloc, SIZE_T nmemb, SIZE_T size);
INTERCEPTOR_ALIAS(void *, realloc, void *ptr, SIZE_T size);
+INTERCEPTOR_ALIAS(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size);
INTERCEPTOR_ALIAS(void *, malloc, SIZE_T size);
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
Modified: compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h (original)
+++ compiler-rt/trunk/lib/hwasan/hwasan_interface_internal.h Wed May 1 10:33:01 2019
@@ -198,6 +198,9 @@ SANITIZER_INTERFACE_ATTRIBUTE
void * __sanitizer_realloc(void *ptr, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE
+void * __sanitizer_reallocarray(void *ptr, uptr nmemb, uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
void * __sanitizer_malloc(uptr size);
SANITIZER_INTERFACE_ATTRIBUTE
Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.cc Wed May 1 10:33:01 2019
@@ -185,6 +185,17 @@ void *lsan_realloc(void *p, uptr size, c
return SetErrnoOnNull(Reallocate(stack, p, size, 1));
}
+void *lsan_reallocarray(void *ptr, uptr nmemb, uptr size,
+ const StackTrace &stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, &stack);
+ }
+ return lsan_realloc(ptr, nmemb * size, stack);
+}
+
void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack) {
return SetErrnoOnNull(Calloc(nmemb, size, stack));
}
Modified: compiler-rt/trunk/lib/lsan/lsan_allocator.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_allocator.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_allocator.h (original)
+++ compiler-rt/trunk/lib/lsan/lsan_allocator.h Wed May 1 10:33:01 2019
@@ -116,6 +116,8 @@ void *lsan_memalign(uptr alignment, uptr
void *lsan_malloc(uptr size, const StackTrace &stack);
void lsan_free(void *p);
void *lsan_realloc(void *p, uptr size, const StackTrace &stack);
+void *lsan_reallocarray(void *p, uptr nmemb, uptr size,
+ const StackTrace &stack);
void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack);
void *lsan_valloc(uptr size, const StackTrace &stack);
void *lsan_pvalloc(uptr size, const StackTrace &stack);
Modified: compiler-rt/trunk/lib/lsan/lsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/lsan/lsan_interceptors.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/lsan/lsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/lsan/lsan_interceptors.cc Wed May 1 10:33:01 2019
@@ -83,6 +83,12 @@ INTERCEPTOR(void*, realloc, void *q, upt
return lsan_realloc(q, size, stack);
}
+INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) {
+ ENSURE_LSAN_INITED;
+ GET_STACK_TRACE_MALLOC;
+ return lsan_reallocarray(q, nmemb, size, stack);
+}
+
INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
ENSURE_LSAN_INITED;
GET_STACK_TRACE_MALLOC;
Modified: compiler-rt/trunk/lib/msan/msan.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan.h (original)
+++ compiler-rt/trunk/lib/msan/msan.h Wed May 1 10:33:01 2019
@@ -288,6 +288,7 @@ void MsanDeallocate(StackTrace *stack, v
void *msan_malloc(uptr size, StackTrace *stack);
void *msan_calloc(uptr nmemb, uptr size, StackTrace *stack);
void *msan_realloc(void *ptr, uptr size, StackTrace *stack);
+void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack);
void *msan_valloc(uptr size, StackTrace *stack);
void *msan_pvalloc(uptr size, StackTrace *stack);
void *msan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
Modified: compiler-rt/trunk/lib/msan/msan_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_allocator.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_allocator.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_allocator.cc Wed May 1 10:33:01 2019
@@ -261,6 +261,16 @@ void *msan_realloc(void *ptr, uptr size,
return SetErrnoOnNull(MsanReallocate(stack, ptr, size, sizeof(u64)));
}
+void *msan_reallocarray(void *ptr, uptr nmemb, uptr size, StackTrace *stack) {
+ if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
+ errno = errno_ENOMEM;
+ if (AllocatorMayReturnNull())
+ return nullptr;
+ ReportReallocArrayOverflow(nmemb, size, stack);
+ }
+ return msan_realloc(ptr, nmemb * size, stack);
+}
+
void *msan_valloc(uptr size, StackTrace *stack) {
return SetErrnoOnNull(MsanAllocate(stack, size, GetPageSizeCached(), false));
}
Modified: compiler-rt/trunk/lib/msan/msan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/msan/msan_interceptors.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/msan/msan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/msan/msan_interceptors.cc Wed May 1 10:33:01 2019
@@ -907,6 +907,11 @@ INTERCEPTOR(void *, realloc, void *ptr,
return msan_realloc(ptr, size, &stack);
}
+INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) {
+ GET_MALLOC_STACK_TRACE;
+ return msan_reallocarray(ptr, nmemb, size, &stack);
+}
+
INTERCEPTOR(void *, malloc, SIZE_T size) {
GET_MALLOC_STACK_TRACE;
if (UNLIKELY(!msan_inited))
@@ -1597,6 +1602,7 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(malloc);
INTERCEPT_FUNCTION(calloc);
INTERCEPT_FUNCTION(realloc);
+ INTERCEPT_FUNCTION(reallocarray);
INTERCEPT_FUNCTION(free);
MSAN_MAYBE_INTERCEPT_CFREE;
MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE;
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator.cc Wed May 1 10:33:01 2019
@@ -170,6 +170,18 @@ void *InternalRealloc(void *addr, uptr s
return (char*)p + sizeof(u64);
}
+void *InternalReallocArray(void *addr, uptr count, uptr size,
+ InternalAllocatorCache *cache) {
+ if (UNLIKELY(CheckForCallocOverflow(count, size))) {
+ Report(
+ "FATAL: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
+ "cannot be represented in type size_t\n",
+ SanitizerToolName, count, size);
+ Die();
+ }
+ return InternalRealloc(addr, count * size, cache);
+}
+
void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) {
if (UNLIKELY(CheckForCallocOverflow(count, size))) {
Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) "
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_internal.h Wed May 1 10:33:01 2019
@@ -48,7 +48,9 @@ void *InternalAlloc(uptr size, InternalA
uptr alignment = 0);
void *InternalRealloc(void *p, uptr size,
InternalAllocatorCache *cache = nullptr);
-void *InternalCalloc(uptr countr, uptr size,
+void *InternalReallocArray(void *p, uptr count, uptr size,
+ InternalAllocatorCache *cache = nullptr);
+void *InternalCalloc(uptr count, uptr size,
InternalAllocatorCache *cache = nullptr);
void InternalFree(void *p, InternalAllocatorCache *cache = nullptr);
InternalAllocator *internal_allocator();
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.cc Wed May 1 10:33:01 2019
@@ -51,6 +51,18 @@ void NORETURN ReportCallocOverflow(uptr
Die();
}
+void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
+ const StackTrace *stack) {
+ {
+ ScopedAllocatorErrorReport report("reallocarray-overflow", stack);
+ Report(
+ "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) "
+ "cannot be represented in type size_t\n",
+ SanitizerToolName, count, size);
+ }
+ Die();
+}
+
void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) {
{
ScopedAllocatorErrorReport report("pvalloc-overflow", stack);
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_allocator_report.h Wed May 1 10:33:01 2019
@@ -21,6 +21,8 @@ namespace __sanitizer {
void NORETURN ReportCallocOverflow(uptr count, uptr size,
const StackTrace *stack);
+void NORETURN ReportReallocArrayOverflow(uptr count, uptr size,
+ const StackTrace *stack);
void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack);
void NORETURN ReportInvalidAllocationAlignment(uptr alignment,
const StackTrace *stack);
Modified: compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h (original)
+++ compiler-rt/trunk/lib/sanitizer_common/sanitizer_platform_interceptors.h Wed May 1 10:33:01 2019
@@ -487,6 +487,7 @@
#define SANITIZER_INTERCEPT_CFREE \
(!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \
SI_NOT_RTEMS)
+#define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX
#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS)
#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_OPENBSD)
#define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_interceptors.cc Wed May 1 10:33:01 2019
@@ -706,6 +706,19 @@ TSAN_INTERCEPTOR(void*, realloc, void *p
return p;
}
+TSAN_INTERCEPTOR(void*, reallocarray, void *p, uptr size, uptr n) {
+ if (in_symbolizer())
+ return InternalReallocArray(p, size, n);
+ if (p)
+ invoke_free_hook(p);
+ {
+ SCOPED_INTERCEPTOR_RAW(reallocarray, p, size, n);
+ p = user_reallocarray(thr, pc, p, size, n);
+ }
+ invoke_malloc_hook(p, size);
+ return p;
+}
+
TSAN_INTERCEPTOR(void, free, void *p) {
if (p == 0)
return;
@@ -2667,6 +2680,7 @@ void InitializeInterceptors() {
TSAN_INTERCEPT(__libc_memalign);
TSAN_INTERCEPT(calloc);
TSAN_INTERCEPT(realloc);
+ TSAN_INTERCEPT(reallocarray);
TSAN_INTERCEPT(free);
TSAN_INTERCEPT(cfree);
TSAN_INTERCEPT(munmap);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.cc Wed May 1 10:33:01 2019
@@ -201,6 +201,16 @@ void *user_calloc(ThreadState *thr, uptr
return SetErrnoOnNull(p);
}
+void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr size, uptr n) {
+ if (UNLIKELY(CheckForCallocOverflow(size, n))) {
+ if (AllocatorMayReturnNull())
+ return SetErrnoOnNull(nullptr);
+ GET_STACK_TRACE_FATAL(thr, pc);
+ ReportReallocArrayOverflow(size, n, &stack);
+ }
+ return user_realloc(thr, pc, p, size * n);
+}
+
void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) {
DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p);
ctx->metamap.AllocBlock(thr, pc, p, sz);
Modified: compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h (original)
+++ compiler-rt/trunk/lib/tsan/rtl/tsan_mman.h Wed May 1 10:33:01 2019
@@ -34,6 +34,7 @@ void user_free(ThreadState *thr, uptr pc
void *user_alloc(ThreadState *thr, uptr pc, uptr sz);
void *user_calloc(ThreadState *thr, uptr pc, uptr sz, uptr n);
void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz);
+void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr sz, uptr n);
void *user_memalign(ThreadState *thr, uptr pc, uptr align, uptr sz);
int user_posix_memalign(ThreadState *thr, uptr pc, void **memptr, uptr align,
uptr sz);
Modified: compiler-rt/trunk/test/hwasan/TestCases/realloc-test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/realloc-test.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/realloc-test.cc (original)
+++ compiler-rt/trunk/test/hwasan/TestCases/realloc-test.cc Wed May 1 10:33:01 2019
@@ -1,36 +1,43 @@
// Test basic realloc functionality.
-// RUN: %clang_hwasan %s -o %t
-// RUN: %run %t
+// RUN: %clang_hwasan %s -o %t && %run %t
+// RUN: %clang_hwasan %s -DREALLOCARRAY -o %t && %run %t
-#include <stdlib.h>
#include <assert.h>
#include <sanitizer/hwasan_interface.h>
+#ifdef REALLOCARRAY
+extern "C" void *reallocarray(void *, size_t nmemb, size_t size);
+#define REALLOC(p, s) reallocarray(p, 1, s)
+#else
+#include <stdlib.h>
+#define REALLOC(p, s) realloc(p, s)
+#endif
+
int main() {
__hwasan_enable_allocator_tagging();
- char *x = (char*)realloc(nullptr, 4);
+ char *x = (char*)REALLOC(nullptr, 4);
x[0] = 10;
x[1] = 20;
x[2] = 30;
x[3] = 40;
- char *x1 = (char*)realloc(x, 5);
+ char *x1 = (char*)REALLOC(x, 5);
assert(x1 != x); // not necessary true for C,
// but true today for hwasan.
assert(x1[0] == 10 && x1[1] == 20 && x1[2] == 30 && x1[3] == 40);
x1[4] = 50;
- char *x2 = (char*)realloc(x1, 6);
+ char *x2 = (char*)REALLOC(x1, 6);
x2[5] = 60;
assert(x2 != x1);
assert(x2[0] == 10 && x2[1] == 20 && x2[2] == 30 && x2[3] == 40 &&
x2[4] == 50 && x2[5] == 60);
- char *x3 = (char*)realloc(x2, 6);
+ char *x3 = (char*)REALLOC(x2, 6);
assert(x3 != x2);
assert(x3[0] == 10 && x3[1] == 20 && x3[2] == 30 && x3[3] == 40 &&
x3[4] == 50 && x3[5] == 60);
- char *x4 = (char*)realloc(x3, 5);
+ char *x4 = (char*)REALLOC(x3, 5);
assert(x4 != x3);
assert(x4[0] == 10 && x4[1] == 20 && x4[2] == 30 && x4[3] == 40 &&
x4[4] == 50);
Modified: compiler-rt/trunk/test/hwasan/TestCases/sanitizer_malloc.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/sanitizer_malloc.cc?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/sanitizer_malloc.cc (original)
+++ compiler-rt/trunk/test/hwasan/TestCases/sanitizer_malloc.cc Wed May 1 10:33:01 2019
@@ -20,6 +20,7 @@ int main() {
sink = (void *)&__sanitizer_malloc_stats;
sink = (void *)&__sanitizer_calloc;
sink = (void *)&__sanitizer_realloc;
+ sink = (void *)&__sanitizer_reallocarray;
sink = (void *)&__sanitizer_malloc;
// sanity check
Modified: compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp?rev=359708&r1=359707&r2=359708&view=diff
==============================================================================
--- compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp (original)
+++ compiler-rt/trunk/test/hwasan/TestCases/sizes.cpp Wed May 1 10:33:01 2019
@@ -7,6 +7,8 @@
// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t malloc max 2>&1
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t calloc 2>&1 | FileCheck %s --check-prefix=CHECK-calloc
// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t calloc 2>&1
+// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t reallocarray 2>&1 | FileCheck %s --check-prefix=CHECK-reallocarray
+// RUN: %env_hwasan_opts=allocator_may_return_null=1 %run %t reallocarray 2>&1
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-max
// RUN: %env_hwasan_opts=allocator_may_return_null=1 not %run %t new 2>&1 | FileCheck %s --check-prefix=CHECK-oom
// RUN: %env_hwasan_opts=allocator_may_return_null=0 not %run %t new max 2>&1 | FileCheck %s --check-prefix=CHECK-max
@@ -30,6 +32,7 @@
#include <new>
#include <sanitizer/allocator_interface.h>
+#include <sanitizer/hwasan_interface.h>
int main(int argc, char **argv) {
assert(argc <= 3);
@@ -51,6 +54,11 @@ int main(int argc, char **argv) {
size_t size = std::numeric_limits<size_t>::max();
void *p = calloc((size / 0x1000) + 1, 0x1000);
assert(!p);
+ } else if (!strcmp(argv[1], "reallocarray")) {
+ // Trigger an overflow in reallocarray.
+ size_t size = std::numeric_limits<size_t>::max();
+ void *p = __sanitizer_reallocarray(nullptr, (size / 0x1000) + 1, 0x1000);
+ assert(!p);
} else if (!strcmp(argv[1], "new")) {
void *p = operator new(MallocSize);
assert(!p);
@@ -80,3 +88,4 @@ int main(int argc, char **argv) {
// CHECK-max: {{ERROR: HWAddressSanitizer: requested allocation size .* exceeds maximum supported size}}
// CHECK-oom: ERROR: HWAddressSanitizer: allocator is out of memory
// CHECK-calloc: ERROR: HWAddressSanitizer: calloc parameters overflow
+// CHECK-reallocarray: ERROR: HWAddressSanitizer: reallocarray parameters overflow
Added: compiler-rt/trunk/test/sanitizer_common/TestCases/reallocarray-overflow.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/sanitizer_common/TestCases/reallocarray-overflow.cc?rev=359708&view=auto
==============================================================================
--- compiler-rt/trunk/test/sanitizer_common/TestCases/reallocarray-overflow.cc (added)
+++ compiler-rt/trunk/test/sanitizer_common/TestCases/reallocarray-overflow.cc Wed May 1 10:33:01 2019
@@ -0,0 +1,19 @@
+// RUN: %clangxx -O0 %s -o %t
+// RUN: %env_tool_opts=allocator_may_return_null=0 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tool_opts=allocator_may_return_null=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NULL
+
+// REQUIRES: stable-runtime && !ubsan && !darwin
+
+#include <stdio.h>
+
+extern "C" void *reallocarray(void *, size_t, size_t);
+
+int main() {
+ void *p = reallocarray(nullptr, -1, 1000);
+ // CHECK: {{ERROR: .*Sanitizer: reallocarray parameters overflow: count \* size \(.* \* 1000\) cannot be represented in type size_t}}
+
+ printf("reallocarray returned: %zu\n", (size_t)p);
+ // CHECK-NULL: reallocarray returned: 0
+
+ return 0;
+}
More information about the llvm-commits
mailing list