1*673dc3d4SNico Weber // RUN: %clang_cl_asan /Od /MT -o %t %s
2*673dc3d4SNico Weber // RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
3*673dc3d4SNico Weber // UNSUPPORTED: asan-64-bits
4*673dc3d4SNico Weber #include <cassert>
5*673dc3d4SNico Weber #include <iostream>
6*673dc3d4SNico Weber #include <windows.h>
7*673dc3d4SNico Weber
main()8*673dc3d4SNico Weber int main() {
9*673dc3d4SNico Weber void *ptr = malloc(0);
10*673dc3d4SNico Weber if (ptr)
11*673dc3d4SNico Weber std::cerr << "allocated!\n";
12*673dc3d4SNico Weber ((char *)ptr)[0] = '\xff'; //check this 'allocate 1 instead of 0' hack hasn't changed
13*673dc3d4SNico Weber
14*673dc3d4SNico Weber free(ptr);
15*673dc3d4SNico Weber
16*673dc3d4SNico Weber /*
17*673dc3d4SNico Weber HeapAlloc hack for our asan interceptor is to change 0
18*673dc3d4SNico Weber sized allocations to size 1 to avoid weird inconsistencies
19*673dc3d4SNico Weber between how realloc and heaprealloc handle 0 size allocations.
20*673dc3d4SNico Weber
21*673dc3d4SNico Weber Note this test relies on these instructions being intercepted.
22*673dc3d4SNico Weber Without ASAN HeapRealloc on line 27 would return a ptr whose
23*673dc3d4SNico Weber HeapSize would be 0. This test makes sure that the underlying behavior
24*673dc3d4SNico Weber of our hack hasn't changed underneath us.
25*673dc3d4SNico Weber
26*673dc3d4SNico Weber We can get rid of the test (or change it to test for the correct
27*673dc3d4SNico Weber behavior) once we fix the interceptor or write a different allocator
28*673dc3d4SNico Weber to handle 0 sized allocations properly by default.
29*673dc3d4SNico Weber
30*673dc3d4SNico Weber */
31*673dc3d4SNico Weber ptr = HeapAlloc(GetProcessHeap(), 0, 0);
32*673dc3d4SNico Weber if (!ptr)
33*673dc3d4SNico Weber return 1;
34*673dc3d4SNico Weber void *ptr2 = HeapReAlloc(GetProcessHeap(), 0, ptr, 0);
35*673dc3d4SNico Weber if (!ptr2)
36*673dc3d4SNico Weber return 1;
37*673dc3d4SNico Weber size_t heapsize = HeapSize(GetProcessHeap(), 0, ptr2);
38*673dc3d4SNico Weber if (heapsize != 1) { // will be 0 without ASAN turned on
39*673dc3d4SNico Weber std::cerr << "HeapAlloc size failure! " << heapsize << " != 1\n";
40*673dc3d4SNico Weber return 1;
41*673dc3d4SNico Weber }
42*673dc3d4SNico Weber void *ptr3 = HeapReAlloc(GetProcessHeap(), 0, ptr2, 3);
43*673dc3d4SNico Weber if (!ptr3)
44*673dc3d4SNico Weber return 1;
45*673dc3d4SNico Weber heapsize = HeapSize(GetProcessHeap(), 0, ptr3);
46*673dc3d4SNico Weber
47*673dc3d4SNico Weber if (heapsize != 3) {
48*673dc3d4SNico Weber std::cerr << "HeapAlloc size failure! " << heapsize << " != 3\n";
49*673dc3d4SNico Weber return 1;
50*673dc3d4SNico Weber }
51*673dc3d4SNico Weber HeapFree(GetProcessHeap(), 0, ptr3);
52*673dc3d4SNico Weber return 0;
53*673dc3d4SNico Weber }
54*673dc3d4SNico Weber
55*673dc3d4SNico Weber // CHECK: allocated!
56*673dc3d4SNico Weber // CHECK-NOT: heap-buffer-overflow
57*673dc3d4SNico Weber // CHECK-NOT: AddressSanitizer
58*673dc3d4SNico Weber // CHECK-NOT: HeapAlloc size failure!