1// RUN: %clang_cl_asan %Od %s %Fe%t %MD
2// RUN: %env_asan_opts=windows_hook_rtl_allocators=true not %run %t 2>&1 | FileCheck %s
3// UNSUPPORTED: asan-64-bits
4
5#include <assert.h>
6#include <stdio.h>
7#include <windows.h>
8
9using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T);
10using ReAllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID, SIZE_T);
11using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID);
12
13int main() {
14 HMODULE NtDllHandle = GetModuleHandle("ntdll.dll");
15 if (!NtDllHandle) {
16 puts(s: "Couldn't load ntdll??");
17 return -1;
18 }
19
20 auto RtlAllocateHeap_ptr = (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap");
21 if (RtlAllocateHeap_ptr == 0) {
22 puts(s: "Couldn't find RtlAllocateHeap");
23 return -1;
24 }
25
26 auto RtlReAllocateHeap_ptr = (ReAllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlReAllocateHeap");
27 if (RtlReAllocateHeap_ptr == 0) {
28 puts(s: "Couldn't find RtlReAllocateHeap");
29 return -1;
30 }
31
32 char *buffer;
33 SIZE_T buffer_size = 32;
34 SIZE_T new_buffer_size = buffer_size * 2;
35
36 buffer = (char *)RtlAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer_size);
37 assert(buffer != nullptr);
38 // Check that the buffer is zeroed.
39 for (SIZE_T i = 0; i < buffer_size; ++i) {
40 assert(buffer[i] == 0);
41 }
42 memset(buffer, 0xcc, buffer_size);
43
44 // Zero the newly allocated memory.
45 buffer = (char *)RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, new_buffer_size);
46 assert(buffer != nullptr);
47 // Check that the first part of the buffer still has the old contents.
48 for (SIZE_T i = 0; i < buffer_size; ++i) {
49 assert(buffer[i] == (char)0xcc);
50 }
51 // Check that the new part of the buffer is zeroed.
52 for (SIZE_T i = buffer_size; i < new_buffer_size; ++i) {
53 assert(buffer[i] == 0x0);
54 }
55
56 // Shrink the buffer back down.
57 buffer = (char *)RtlReAllocateHeap_ptr(GetProcessHeap(), HEAP_ZERO_MEMORY, buffer, buffer_size);
58 assert(buffer != nullptr);
59 // Check that the first part of the buffer still has the old contents.
60 for (SIZE_T i = 0; i < buffer_size; ++i) {
61 assert(buffer[i] == (char)0xcc);
62 }
63
64 buffer[buffer_size + 1] = 'a';
65 // CHECK: AddressSanitizer: heap-buffer-overflow on address [[ADDR:0x[0-9a-f]+]]
66 // CHECK: WRITE of size 1 at [[ADDR]] thread T0
67}
68

source code of compiler-rt/test/asan/TestCases/Windows/rtlallocateheap_zero.cpp