diff --git a/compiler-rt/lib/asan/asan_allocator2.cc b/compiler-rt/lib/asan/asan_allocator2.cc index bc953969af6d7345addcf45254575b92ef83854e..42d8b29afd6b10fd74d9670463392662d12e605b 100644 --- a/compiler-rt/lib/asan/asan_allocator2.cc +++ b/compiler-rt/lib/asan/asan_allocator2.cc @@ -675,16 +675,18 @@ uptr __asan_get_estimated_allocated_size(uptr size) { } bool __asan_get_ownership(const void *p) { - return AllocationSize(reinterpret_cast(p)) > 0; + uptr ptr = reinterpret_cast(p); + return (ptr == kReturnOnZeroMalloc) || (AllocationSize(ptr) > 0); } uptr __asan_get_allocated_size(const void *p) { if (p == 0) return 0; - uptr allocated_size = AllocationSize(reinterpret_cast(p)); + uptr ptr = reinterpret_cast(p); + uptr allocated_size = AllocationSize(ptr); // Die if p is not malloced or if it is already freed. - if (allocated_size == 0) { + if (allocated_size == 0 && ptr != kReturnOnZeroMalloc) { GET_STACK_TRACE_FATAL_HERE; - ReportAsanGetAllocatedSizeNotOwned(reinterpret_cast(p), &stack); + ReportAsanGetAllocatedSizeNotOwned(ptr, &stack); } return allocated_size; } diff --git a/compiler-rt/lib/asan/tests/asan_noinst_test.cc b/compiler-rt/lib/asan/tests/asan_noinst_test.cc index fc4a3d1f5f0c8458c7a486f928bbff8e3db7a2fd..8a7f77455a59170b49323b1a933f07d0d94c8d7e 100644 --- a/compiler-rt/lib/asan/tests/asan_noinst_test.cc +++ b/compiler-rt/lib/asan/tests/asan_noinst_test.cc @@ -382,8 +382,16 @@ TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) { free(array); EXPECT_FALSE(__asan_get_ownership(array)); EXPECT_DEATH(__asan_get_allocated_size(array), kGetAllocatedSizeErrorMsg); - delete int_ptr; + + void *zero_alloc = Ident(malloc(0)); + if (zero_alloc != 0) { + // If malloc(0) is not null, this pointer is owned and should have valid + // allocated size. + EXPECT_TRUE(__asan_get_ownership(zero_alloc)); + EXPECT_EQ(0U, __asan_get_allocated_size(zero_alloc)); + } + free(zero_alloc); } TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {