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.
64 lines
2.0 KiB
C++
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!
|