diff --git a/compiler-rt/lib/hwasan/hwasan_allocator.cpp b/compiler-rt/lib/hwasan/hwasan_allocator.cpp index c99d730e059faa..d21ba024a20e12 100644 --- a/compiler-rt/lib/hwasan/hwasan_allocator.cpp +++ b/compiler-rt/lib/hwasan/hwasan_allocator.cpp @@ -234,28 +234,23 @@ static void *HwasanAllocate(StackTrace *stack, uptr orig_size, uptr alignment, } void *user_ptr = allocated; - // Tagging can only be skipped when both tag_in_malloc and tag_in_free are - // false. When tag_in_malloc = false and tag_in_free = true malloc needs to - // retag to 0. if (InTaggableRegion(reinterpret_cast(user_ptr)) && - (flags()->tag_in_malloc || flags()->tag_in_free) && - atomic_load_relaxed(&hwasan_allocator_tagging_enabled)) { - if (flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) { - tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag; - uptr tag_size = orig_size ? orig_size : 1; - uptr full_granule_size = RoundDownTo(tag_size, kShadowAlignment); - user_ptr = - (void *)TagMemoryAligned((uptr)user_ptr, full_granule_size, tag); - if (full_granule_size != tag_size) { - u8 *short_granule = - reinterpret_cast(allocated) + full_granule_size; - TagMemoryAligned((uptr)short_granule, kShadowAlignment, - tag_size % kShadowAlignment); - short_granule[kShadowAlignment - 1] = tag; - } - } else { - user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, 0); + atomic_load_relaxed(&hwasan_allocator_tagging_enabled) && + flags()->tag_in_malloc && malloc_bisect(stack, orig_size)) { + tag_t tag = t ? t->GenerateRandomTag() : kFallbackAllocTag; + uptr tag_size = orig_size ? orig_size : 1; + uptr full_granule_size = RoundDownTo(tag_size, kShadowAlignment); + user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, full_granule_size, tag); + if (full_granule_size != tag_size) { + u8 *short_granule = reinterpret_cast(allocated) + full_granule_size; + TagMemoryAligned((uptr)short_granule, kShadowAlignment, + tag_size % kShadowAlignment); + short_granule[kShadowAlignment - 1] = tag; } + } else { + // Tagging can not be completely skipped. If it's disabled, we need to tag + // with zeros. + user_ptr = (void *)TagMemoryAligned((uptr)user_ptr, size, 0); } Metadata *meta = diff --git a/compiler-rt/test/hwasan/TestCases/enable-disable.c b/compiler-rt/test/hwasan/TestCases/enable-disable.c new file mode 100644 index 00000000000000..290ce07656a608 --- /dev/null +++ b/compiler-rt/test/hwasan/TestCases/enable-disable.c @@ -0,0 +1,42 @@ +// Test that disabling/enabling tagging does not trigger false reports on +// allocations happened in a different state. + +// RUN: %clang_hwasan -O1 %s -o %t && %run %t 2>&1 + +#include +#include +#include + +enum { + COUNT = 5, + SZ = 10, +}; +void *x[COUNT]; + +int main() { + __hwasan_enable_allocator_tagging(); + for (unsigned i = 0; i < COUNT; ++i) { + x[i] = malloc(SZ); + assert(__hwasan_test_shadow(x[i], SZ) == -1); + } + for (unsigned i = 0; i < COUNT; ++i) + free(x[i]); + + __hwasan_disable_allocator_tagging(); + for (unsigned i = 0; i < COUNT; ++i) { + x[i] = malloc(SZ); + assert(__hwasan_tag_pointer(x[i], 0) == x[i]); + assert(__hwasan_test_shadow(x[i], SZ) == -1); + } + for (unsigned i = 0; i < COUNT; ++i) + free(x[i]); + + __hwasan_enable_allocator_tagging(); + for (unsigned i = 0; i < COUNT; ++i) { + x[i] = malloc(SZ); + assert(__hwasan_test_shadow(x[i], SZ) == -1); + } + for (unsigned i = 0; i < COUNT; ++i) + free(x[i]); + return 0; +}