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