1*673dc3d4SNico Weber #include "sanitizer\allocator_interface.h"
2*673dc3d4SNico Weber #include <cassert>
3*673dc3d4SNico Weber #include <stdio.h>
4*673dc3d4SNico Weber #include <windows.h>
5*673dc3d4SNico Weber
6*673dc3d4SNico Weber // RUN: %clang_cl_asan %s -o%t
7*673dc3d4SNico Weber // RUN: %env_asan_opts=windows_hook_rtl_allocators=true %run %t 2>&1 | FileCheck %s
8*673dc3d4SNico Weber // UNSUPPORTED: asan-64-bits
9*673dc3d4SNico Weber
10*673dc3d4SNico Weber using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T);
11*673dc3d4SNico Weber using ReAllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID, SIZE_T);
12*673dc3d4SNico Weber
13*673dc3d4SNico Weber using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID);
14*673dc3d4SNico Weber
main()15*673dc3d4SNico Weber int main() {
16*673dc3d4SNico Weber HMODULE NtDllHandle = GetModuleHandle("ntdll.dll");
17*673dc3d4SNico Weber if (!NtDllHandle) {
18*673dc3d4SNico Weber puts("Couldn't load ntdll??");
19*673dc3d4SNico Weber return -1;
20*673dc3d4SNico Weber }
21*673dc3d4SNico Weber
22*673dc3d4SNico Weber auto RtlAllocateHeap_ptr = (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap");
23*673dc3d4SNico Weber if (RtlAllocateHeap_ptr == 0) {
24*673dc3d4SNico Weber puts("Couldn't find RtlAllocateHeap");
25*673dc3d4SNico Weber return -1;
26*673dc3d4SNico Weber }
27*673dc3d4SNico Weber
28*673dc3d4SNico Weber auto RtlReAllocateHeap_ptr = (ReAllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlReAllocateHeap");
29*673dc3d4SNico Weber if (RtlReAllocateHeap_ptr == 0) {
30*673dc3d4SNico Weber puts("Couldn't find RtlReAllocateHeap");
31*673dc3d4SNico Weber return -1;
32*673dc3d4SNico Weber }
33*673dc3d4SNico Weber
34*673dc3d4SNico Weber //owned by rtl
35*673dc3d4SNico Weber void *alloc = RtlAllocateHeap_ptr(GetProcessHeap(),
36*673dc3d4SNico Weber HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, 100);
37*673dc3d4SNico Weber assert(alloc);
38*673dc3d4SNico Weber for (int i = 0; i < 100; i++) {
39*673dc3d4SNico Weber assert(((char *)alloc)[i] == 0);
40*673dc3d4SNico Weber ((char *)alloc)[i] = '\xcc';
41*673dc3d4SNico Weber }
42*673dc3d4SNico Weber
43*673dc3d4SNico Weber // still owned by rtl
44*673dc3d4SNico Weber alloc = RtlReAllocateHeap_ptr(GetProcessHeap(),
45*673dc3d4SNico Weber HEAP_GENERATE_EXCEPTIONS | HEAP_ZERO_MEMORY, alloc, 500);
46*673dc3d4SNico Weber assert(alloc && !__sanitizer_get_ownership(alloc) && HeapValidate(GetProcessHeap(), 0, alloc));
47*673dc3d4SNico Weber for (int i = 0; i < 100; i++) {
48*673dc3d4SNico Weber assert(((char *)alloc)[i] == '\xcc');
49*673dc3d4SNico Weber }
50*673dc3d4SNico Weber for (int i = 100; i < 500; i++) {
51*673dc3d4SNico Weber assert(((char *)alloc)[i] == 0);
52*673dc3d4SNico Weber ((char *)alloc)[i] = '\xcc';
53*673dc3d4SNico Weber }
54*673dc3d4SNico Weber
55*673dc3d4SNico Weber //convert to asan owned
56*673dc3d4SNico Weber void *realloc = RtlReAllocateHeap_ptr(GetProcessHeap(),
57*673dc3d4SNico Weber HEAP_ZERO_MEMORY, alloc, 600);
58*673dc3d4SNico Weber alloc = nullptr;
59*673dc3d4SNico Weber assert(realloc && __sanitizer_get_ownership(realloc));
60*673dc3d4SNico Weber
61*673dc3d4SNico Weber for (int i = 0; i < 500; i++) {
62*673dc3d4SNico Weber assert(((char *)realloc)[i] == '\xcc');
63*673dc3d4SNico Weber }
64*673dc3d4SNico Weber for (int i = 500; i < 600; i++) {
65*673dc3d4SNico Weber assert(((char *)realloc)[i] == 0);
66*673dc3d4SNico Weber ((char *)realloc)[i] = '\xcc';
67*673dc3d4SNico Weber }
68*673dc3d4SNico Weber realloc = RtlReAllocateHeap_ptr(GetProcessHeap(),
69*673dc3d4SNico Weber HEAP_ZERO_MEMORY, realloc, 2048);
70*673dc3d4SNico Weber assert(realloc && __sanitizer_get_ownership(realloc));
71*673dc3d4SNico Weber
72*673dc3d4SNico Weber for (int i = 0; i < 600; i++) {
73*673dc3d4SNico Weber assert(((char *)realloc)[i] == '\xcc');
74*673dc3d4SNico Weber }
75*673dc3d4SNico Weber for (int i = 600; i < 2048; i++) {
76*673dc3d4SNico Weber assert(((char *)realloc)[i] == 0);
77*673dc3d4SNico Weber ((char *)realloc)[i] = '\xcc';
78*673dc3d4SNico Weber }
79*673dc3d4SNico Weber //convert back to rtl owned;
80*673dc3d4SNico Weber alloc = RtlReAllocateHeap_ptr(GetProcessHeap(),
81*673dc3d4SNico Weber HEAP_ZERO_MEMORY | HEAP_GENERATE_EXCEPTIONS, realloc, 100);
82*673dc3d4SNico Weber assert(alloc && !__sanitizer_get_ownership(alloc) && HeapValidate(GetProcessHeap(), 0, alloc));
83*673dc3d4SNico Weber for (int i = 0; i < 100; i++) {
84*673dc3d4SNico Weber assert(((char *)alloc)[i] == '\xcc');
85*673dc3d4SNico Weber ((char *)alloc)[i] = 0;
86*673dc3d4SNico Weber }
87*673dc3d4SNico Weber
88*673dc3d4SNico Weber auto usable_size = HeapSize(GetProcessHeap(), 0, alloc);
89*673dc3d4SNico Weber for (int i = 100; i < usable_size; i++) {
90*673dc3d4SNico Weber assert(((char *)alloc)[i] == 0);
91*673dc3d4SNico Weber }
92*673dc3d4SNico Weber
93*673dc3d4SNico Weber printf("Success\n");
94*673dc3d4SNico Weber }
95*673dc3d4SNico Weber
96*673dc3d4SNico Weber // CHECK-NOT: Assertion failed:
97*673dc3d4SNico Weber // CHECK-NOT: AddressSanitizer
98*673dc3d4SNico Weber // CHECK: Success