| 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 | |