llvm-project/compiler-rt/test/asan/TestCases/Windows/heaprealloc_alloc_zero.cpp
Thurston Dang 6dfd8d0ab4
[asan] Rewrite Windows/heaprealloc_alloc_zero check to avoid dereference (#156211)
The test currently checks that 1-byte is allocated when malloc(0) is
called, by dereferencing the pointer.
https://github.com/llvm/llvm-project/pull/155943 changed ASan to
consider the dereference to be a heap buffer overflow. This patch
changes the test to check the allocated size is still 1-byte, but not
dereference the pointer.

This aims to fix the breakage reported in
https://github.com/llvm/llvm-project/pull/155943#issuecomment-3239543505

It also enables the test for 64-bit Windows.
2025-08-30 15:43:51 -07:00

64 lines
2.0 KiB
C++

// RUN: %clang_cl_asan %Od %MT -o %t %s
// RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
#include <cassert>
#include <iostream>
#include <sanitizer/allocator_interface.h>
#include <windows.h>
int main() {
void *ptr = malloc(0);
if (ptr)
std::cerr << "allocated!\n";
// Check the 'allocate 1 instead of 0' hack hasn't changed
// Note that as of b3452d90b043a398639e62b0ab01aa339cc649de, dereferencing
// the pointer will be detected as a heap-buffer-overflow.
if (__sanitizer_get_allocated_size(ptr) != 1)
return 1;
free(ptr);
/*
HeapAlloc hack for our asan interceptor is to change 0
sized allocations to size 1 to avoid weird inconsistencies
between how realloc and heaprealloc handle 0 size allocations.
Note this test relies on these instructions being intercepted.
Without ASAN HeapRealloc on line 27 would return a ptr whose
HeapSize would be 0. This test makes sure that the underlying behavior
of our hack hasn't changed underneath us.
We can get rid of the test (or change it to test for the correct
behavior) once we fix the interceptor or write a different allocator
to handle 0 sized allocations properly by default.
*/
ptr = HeapAlloc(GetProcessHeap(), 0, 0);
if (!ptr)
return 1;
void *ptr2 = HeapReAlloc(GetProcessHeap(), 0, ptr, 0);
if (!ptr2)
return 1;
size_t heapsize = HeapSize(GetProcessHeap(), 0, ptr2);
if (heapsize != 1) { // will be 0 without ASAN turned on
std::cerr << "HeapAlloc size failure! " << heapsize << " != 1\n";
return 1;
}
void *ptr3 = HeapReAlloc(GetProcessHeap(), 0, ptr2, 3);
if (!ptr3)
return 1;
heapsize = HeapSize(GetProcessHeap(), 0, ptr3);
if (heapsize != 3) {
std::cerr << "HeapAlloc size failure! " << heapsize << " != 3\n";
return 1;
}
HeapFree(GetProcessHeap(), 0, ptr3);
return 0;
}
// CHECK: allocated!
// CHECK-NOT: heap-buffer-overflow
// CHECK-NOT: AddressSanitizer
// CHECK-NOT: HeapAlloc size failure!