1 // RUN: %clang_cl_asan %LD %Od -DDLL %s %Fe%t.dll
2 // RUN: %clang_cl %Od -DEXE %s %Fe%te.exe
3 // RUN: %env_asan_opts=windows_hook_rtl_allocators=true not %run %te.exe %t.dll 2>&1 | FileCheck %s
4 // REQUIRES: asan-dynamic-runtime
5 // REQUIRES: asan-32-bits
6
7 #include <cassert>
8 #include <stdio.h>
9 #include <windows.h>
10
11 extern "C" {
12 #if defined(EXE)
13 using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T);
14 using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID);
15 using RtlReAllocateHeapPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID, SIZE_T);
16
main(int argc,char ** argv)17 int main(int argc, char **argv) {
18 HMODULE NtDllHandle = GetModuleHandle("ntdll.dll");
19 if (!NtDllHandle) {
20 puts("Couldn't load ntdll??");
21 return -1;
22 }
23
24 auto RtlAllocateHeap_ptr =
25 (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap");
26 if (RtlAllocateHeap_ptr == 0) {
27 puts("Couldn't RtlAllocateHeap");
28 return -1;
29 }
30
31 auto RtlFreeHeap_ptr =
32 (FreeFunctionPtr)GetProcAddress(NtDllHandle, "RtlFreeHeap");
33 if (RtlFreeHeap_ptr == 0) {
34 puts("Couldn't get RtlFreeHeap");
35 return -1;
36 }
37
38 auto RtlReAllocateHeap_ptr =
39 (RtlReAllocateHeapPtr)GetProcAddress(NtDllHandle, "RtlReAllocateHeap");
40 if (RtlReAllocateHeap_ptr == 0) {
41 puts("Couldn't get rtlreallocateheap\n");
42 return -1;
43 }
44
45 char *buffer;
46 buffer = (char *)RtlAllocateHeap_ptr(GetProcessHeap(), 0, 32);
47
48 HMODULE lib = LoadLibraryA(argv[1]);
49 assert(lib != INVALID_HANDLE_VALUE);
50 assert(0 != FreeLibrary(lib));
51
52 if (!RtlFreeHeap_ptr(GetProcessHeap(), 0, buffer)) {
53 puts("Couldn't RtlFreeHeap");
54 return -1;
55 }
56 RtlReAllocateHeap_ptr(GetProcessHeap(), 0, buffer, 100); // should dump
57 }
58
59 #elif defined(DLL)
60 // This global is registered at startup.
61
62 BOOL WINAPI DllMain(HMODULE, DWORD reason, LPVOID) {
63 fprintf(stderr, "in DLL(reason=%d)\n", (int)reason);
64 fflush(0);
65 return TRUE;
66 }
67
68 // CHECK: in DLL(reason=1)
69 // CHECK: in DLL(reason=0)
70 // CHECK: AddressSanitizer: nested bug in the same thread, aborting.
71
72 #else
73 #error oops!
74 #endif
75 }
76