From fd48b7d5586189173f3d45d0b98952ab59d301cd Mon Sep 17 00:00:00 2001 From: Kostya Serebryany Date: Wed, 29 Aug 2018 21:28:14 +0000 Subject: [PATCH] [hwasan] simplify the realloc implementation: always allocate/deallocate on realloc. This may slowdown some realloc-heavy code, but at least at this point a want simpler code. Also added a test llvm-svn: 340973 --- compiler-rt/lib/hwasan/hwasan_allocator.cc | 34 +++++----------------- compiler-rt/lib/hwasan/hwasan_flags.inc | 1 - compiler-rt/test/hwasan/TestCases/realloc-test.cc | 35 +++++++++++++++++++++++ 3 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 compiler-rt/test/hwasan/TestCases/realloc-test.cc diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cc b/compiler-rt/lib/hwasan/hwasan_allocator.cc index 5d3595b..ba5bf0e1 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cc +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cc @@ -228,35 +228,15 @@ void *HwasanReallocate(StackTrace *stack, void *user_old_p, uptr new_size, if (!PointerAndMemoryTagsMatch(user_old_p)) ReportInvalidFree(stack, reinterpret_cast(user_old_p)); - void *old_p = GetAddressFromPointer(user_old_p); - Metadata *meta = reinterpret_cast(allocator.GetMetaData(old_p)); - uptr old_size = meta->requested_size; - uptr actually_allocated_size = allocator.GetActuallyAllocatedSize(old_p); - if (new_size <= actually_allocated_size) { - // We are not reallocating here. - // FIXME: update stack trace for the allocation? - meta->requested_size = new_size; - if (!atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) - return user_old_p; - if (flags()->retag_in_realloc) { - HwasanThread *t = GetCurrentThread(); - return (void *)TagMemoryAligned( - (uptr)old_p, new_size, - t ? t->GenerateRandomTag() : kFallbackAllocTag); - } - if (new_size > old_size) { - tag_t tag = GetTagFromPointer(reinterpret_cast(user_old_p)); - TagMemoryAligned((uptr)old_p + old_size, new_size - old_size, tag); - } - return user_old_p; - } - uptr memcpy_size = Min(new_size, old_size); void *new_p = HwasanAllocate(stack, new_size, alignment, false /*zeroise*/); - if (new_p) { - internal_memcpy(new_p, old_p, memcpy_size); - HwasanDeallocate(stack, old_p); + if (user_old_p && new_p) { + void *untagged_ptr_old = GetAddressFromPointer(user_old_p); + Metadata *meta = + reinterpret_cast(allocator.GetMetaData(untagged_ptr_old)); + internal_memcpy(GetAddressFromPointer(new_p), untagged_ptr_old, + Min(new_size, static_cast(meta->requested_size))); + HwasanDeallocate(stack, user_old_p); } - // FIXME: update t->heap_allocations or simplify HwasanReallocate. return new_p; } diff --git a/compiler-rt/lib/hwasan/hwasan_flags.inc b/compiler-rt/lib/hwasan/hwasan_flags.inc index 7a474ae..cd04f53 100644 --- a/compiler-rt/lib/hwasan/hwasan_flags.inc +++ b/compiler-rt/lib/hwasan/hwasan_flags.inc @@ -19,7 +19,6 @@ HWASAN_FLAG(bool, tag_in_malloc, true, "") HWASAN_FLAG(bool, tag_in_free, true, "") -HWASAN_FLAG(bool, retag_in_realloc, true, "") HWASAN_FLAG(bool, print_stats, false, "") HWASAN_FLAG(bool, halt_on_error, true, "") HWASAN_FLAG(bool, atexit, false, "") diff --git a/compiler-rt/test/hwasan/TestCases/realloc-test.cc b/compiler-rt/test/hwasan/TestCases/realloc-test.cc new file mode 100644 index 0000000..23bc619 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/realloc-test.cc @@ -0,0 +1,35 @@ +// Test basic realloc functionality. +// RUN: %clang_hwasan %s -o %t +// RUN: %run %t + +#include +#include + +int main() { + char *x = (char*)realloc(nullptr, 4); + x[0] = 10; + x[1] = 20; + x[2] = 30; + x[3] = 40; + 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); + 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); + 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); + assert(x4 != x3); + assert(x4[0] == 10 && x4[1] == 20 && x4[2] == 30 && x4[3] == 40 && + x4[4] == 50); +} -- 2.7.4