forked from OSchip/llvm-project
[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
This commit is contained in:
parent
e12dcf124b
commit
fd48b7d558
|
@ -228,35 +228,15 @@ void *HwasanReallocate(StackTrace *stack, void *user_old_p, uptr new_size,
|
|||
if (!PointerAndMemoryTagsMatch(user_old_p))
|
||||
ReportInvalidFree(stack, reinterpret_cast<uptr>(user_old_p));
|
||||
|
||||
void *old_p = GetAddressFromPointer(user_old_p);
|
||||
Metadata *meta = reinterpret_cast<Metadata*>(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<uptr>(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<Metadata *>(allocator.GetMetaData(untagged_ptr_old));
|
||||
internal_memcpy(GetAddressFromPointer(new_p), untagged_ptr_old,
|
||||
Min(new_size, static_cast<uptr>(meta->requested_size)));
|
||||
HwasanDeallocate(stack, user_old_p);
|
||||
}
|
||||
// FIXME: update t->heap_allocations or simplify HwasanReallocate.
|
||||
return new_p;
|
||||
}
|
||||
|
||||
|
|
|
@ -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, "")
|
||||
|
|
|
@ -0,0 +1,35 @@
|
|||
// Test basic realloc functionality.
|
||||
// RUN: %clang_hwasan %s -o %t
|
||||
// RUN: %run %t
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <assert.h>
|
||||
|
||||
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);
|
||||
}
|
Loading…
Reference in New Issue