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
11extern "C" {
12#if defined(EXE)
13using AllocateFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, SIZE_T);
14using FreeFunctionPtr = PVOID(__stdcall *)(PVOID, ULONG, PVOID);
15
16int main(int argc, char **argv) {
17 HMODULE NtDllHandle = GetModuleHandle("ntdll.dll");
18 if (!NtDllHandle) {
19 puts("Couldn't load ntdll??");
20 return -1;
21 }
22
23 auto RtlAllocateHeap_ptr =
24 (AllocateFunctionPtr)GetProcAddress(NtDllHandle, "RtlAllocateHeap");
25 if (RtlAllocateHeap_ptr == 0) {
26 puts("Couldn't RtlAllocateHeap");
27 return -1;
28 }
29
30 auto RtlFreeHeap_ptr =
31 (FreeFunctionPtr)GetProcAddress(NtDllHandle, "RtlFreeHeap");
32 if (RtlFreeHeap_ptr == 0) {
33 puts("Couldn't get RtlFreeHeap");
34 return -1;
35 }
36
37 char *buffer;
38 buffer = (char *)RtlAllocateHeap_ptr(GetProcessHeap(), 0, 32);
39
40 HMODULE lib = LoadLibraryA(argv[1]);
41 assert(lib != INVALID_HANDLE_VALUE);
42 assert(0 != FreeLibrary(lib));
43
44 if (!RtlFreeHeap_ptr(GetProcessHeap(), 0, buffer)) {
45 puts("Couldn't RtlFreeHeap");
46 return -1;
47 }
48 // Because this pointer was allocated pre-hooking,
49 // this will dump as a nested bug. Asan attempts to free
50 // the pointer and AV's, so the ASAN exception handler
51 // will dump as a 'nested bug'.
52 RtlFreeHeap_ptr(GetProcessHeap(), 0, buffer);
53}
54
55#elif defined(DLL)
56// This global is registered at startup.
57
58BOOL WINAPI DllMain(HMODULE, DWORD reason, LPVOID) {
59 fprintf(stderr, "in DLL(reason=%d)\n", (int)reason);
60 fflush(0);
61 return TRUE;
62}
63
64// CHECK: in DLL(reason=1)
65// CHECK: in DLL(reason=0)
66// CHECK: AddressSanitizer: nested bug in the same thread, aborting.
67
68#else
69#error oops!
70#endif
71}
72

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