diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -162,8 +162,11 @@ internal_memset(allocated, flags()->malloc_fill_byte, fill_size); } if (size != orig_size) { - internal_memcpy(reinterpret_cast(allocated) + orig_size, tail_magic, - size - orig_size - 1); + u8 *tail = reinterpret_cast(allocated) + orig_size; + uptr tail_length = size - orig_size; + internal_memcpy(tail, tail_magic, tail_length - 1); + // Short granule is excluded from magic tail, so we explicitly untag. + tail[tail_length - 1] = 0; } void *user_ptr = allocated; diff --git a/compiler-rt/test/hwasan/TestCases/short-granule-disabled.cpp b/compiler-rt/test/hwasan/TestCases/short-granule-disabled.cpp new file mode 100644 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/short-granule-disabled.cpp @@ -0,0 +1,21 @@ +// RUN: %clangxx_hwasan %s -o %t && %run %t 2>&1 + +#include +#include +#include +#include + +// Regression test for https://reviews.llvm.org/D107938#2961070, where, on +// reusing an allocation, we forgot to reset the short granule tag if the +// allocator was disabled. This lead to a false positive magic-string mismatch. + +int main() { + void *p = malloc(16); + memset(p, 0xff, 16); + free(p); + + // Relies on the LRU cache immediately recycling the allocation above. + p = malloc(8); + free(p); // Regression was here, in the magic-string check in the runtime. + return 0; +}