From: Evgeniy Stepanov Date: Fri, 31 Aug 2018 17:49:49 +0000 (+0000) Subject: [hwasan] Fix new[] with zero size. X-Git-Tag: llvmorg-8.0.0-rc1~9640 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=5abf7d90ace56e96ebf7b4d72de5a56c8c368d80;p=platform%2Fupstream%2Fllvm.git [hwasan] Fix new[] with zero size. Fixes "allocator is out of memory trying to allocate 0x0 bytes" by always allocating at least one byte. llvm-svn: 341229 --- diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cc b/compiler-rt/lib/hwasan/hwasan_allocator.cc index 374cd70..a380d8d 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cc +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cc @@ -64,11 +64,15 @@ void HwasanThreadLocalMallocStorage::CommitBack() { allocator.SwallowCache(GetAllocatorCache(this)); } +static uptr TaggedSize(uptr size) { + if (!size) size = 1; + return RoundUpTo(size, kShadowAlignment); +} + static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, bool zeroise) { - if (!orig_size) return nullptr; alignment = Max(alignment, kShadowAlignment); - uptr size = RoundUpTo(orig_size, kShadowAlignment); + uptr size = TaggedSize(orig_size); if (size > kMaxAllowedMallocSize) { if (AllocatorMayReturnNull()) { @@ -134,7 +138,7 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { void *untagged_ptr = UntagPtr(tagged_ptr); Metadata *meta = reinterpret_cast(allocator.GetMetaData(untagged_ptr)); - uptr size = meta->requested_size; + uptr orig_size = meta->requested_size; u32 free_context_id = StackDepotPut(*stack); u32 alloc_context_id = meta->alloc_context_id; meta->requested_size = 0; @@ -143,19 +147,19 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { // poisoned. Thread *t = GetCurrentThread(); if (flags()->max_free_fill_size > 0) { - uptr fill_size = Min(size, (uptr)flags()->max_free_fill_size); + uptr fill_size = Min(orig_size, (uptr)flags()->max_free_fill_size); internal_memset(untagged_ptr, flags()->free_fill_byte, fill_size); } if (flags()->tag_in_free && atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) - TagMemoryAligned((uptr)untagged_ptr, RoundUpTo(size, kShadowAlignment), + TagMemoryAligned((uptr)untagged_ptr, TaggedSize(orig_size), t ? t->GenerateRandomTag() : kFallbackFreeTag); if (t) { AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage()); allocator.Deallocate(cache, untagged_ptr); if (auto *ha = t->heap_allocations()) ha->push({reinterpret_cast(tagged_ptr), alloc_context_id, - free_context_id, static_cast(size)}); + free_context_id, static_cast(orig_size)}); } else { SpinMutexLock l(&fallback_mutex); AllocatorCache *cache = &fallback_allocator_cache; @@ -165,9 +169,6 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) { void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, uptr new_size, uptr alignment) { - alignment = Max(alignment, kShadowAlignment); - new_size = RoundUpTo(new_size, kShadowAlignment); - if (!PointerAndMemoryTagsMatch(tagged_ptr_old)) ReportInvalidFree(stack, reinterpret_cast(tagged_ptr_old)); diff --git a/compiler-rt/test/hwasan/TestCases/malloc-test.c b/compiler-rt/test/hwasan/TestCases/malloc-test.c index 13d04e6..199464b 100644 --- a/compiler-rt/test/hwasan/TestCases/malloc-test.c +++ b/compiler-rt/test/hwasan/TestCases/malloc-test.c @@ -5,9 +5,12 @@ #include #include #include +#include int main() { __hwasan_enable_allocator_tagging(); char *a1 = (char*)malloc(0); - assert(a1 == NULL); // may not be true for other malloc. + assert(a1 != 0); + assert(__sanitizer_get_allocated_size(a1) == 0); + free(a1); } diff --git a/compiler-rt/test/hwasan/TestCases/new-test.cc b/compiler-rt/test/hwasan/TestCases/new-test.cc new file mode 100644 index 0000000..3b1991e --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/new-test.cc @@ -0,0 +1,18 @@ +// Test basic new functionality. +// RUN: %clangxx_hwasan %s -o %t +// RUN: %run %t + +#include +#include +#include +#include + +int main() { + __hwasan_enable_allocator_tagging(); + + size_t volatile n = 0; + char *a1 = new char[n]; + assert(a1 != nullptr); + assert(__sanitizer_get_allocated_size(a1) == 0); + delete[] a1; +}