Index: lib/asan/asan_allocator.cc =================================================================== --- lib/asan/asan_allocator.cc +++ lib/asan/asan_allocator.cc @@ -554,7 +554,16 @@ uptr chunk_beg = p - kChunkHeaderSize; AsanChunk *m = reinterpret_cast(chunk_beg); + // On windows, some DLL may allocate memory before HeapAlloc is hooked. + if (SANITIZER_WINDOWS && + !get_allocator().PointerIsMine(ptr)) { + if (!PlatformIsValidAddress(p)) + ReportFreeNotMalloced(p, stack); + return; + } + ASAN_FREE_HOOK(ptr); + // Must mark the chunk as quarantined before any changes to its metadata. // Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag. if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack)) return; Index: lib/asan/asan_internal.h =================================================================== --- lib/asan/asan_internal.h +++ lib/asan/asan_internal.h @@ -64,6 +64,7 @@ // asan_win.cc void InitializePlatformExceptionHandlers(); +bool PlatformIsValidAddress(uptr addr); // asan_rtl.cc void NORETURN ShowStatsAndAbort(); Index: lib/asan/asan_linux.cc =================================================================== --- lib/asan/asan_linux.cc +++ lib/asan/asan_linux.cc @@ -70,6 +70,7 @@ void InitializePlatformInterceptors() {} void InitializePlatformExceptionHandlers() {} +bool PlatformIsValidAddress(uptr addr) { return false; } void *AsanDoesNotSupportStaticLinkage() { // This will fail to link with -static. Index: lib/asan/asan_mac.cc =================================================================== --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -48,6 +48,7 @@ void InitializePlatformInterceptors() {} void InitializePlatformExceptionHandlers() {} +bool PlatformIsValidAddress(uptr addr) { return false; } // No-op. Mac does not support static linkage anyway. void *AsanDoesNotSupportStaticLinkage() { Index: lib/asan/asan_win.cc =================================================================== --- lib/asan/asan_win.cc +++ lib/asan/asan_win.cc @@ -277,6 +277,16 @@ #endif } +bool PlatformIsValidAddress(uptr addr) { + MEMORY_BASIC_INFORMATION mem_info = {}; + if (::VirtualQuery((LPVOID)addr, &mem_info, sizeof(mem_info)) == 0 || + mem_info.State == MEM_FREE) { + return false; + } + + return true; +} + // We want to install our own exception handler (EH) to print helpful reports // on access violations and whatnot. Unfortunately, the CRT initializers assume // they are run before any user code and drop any previously-installed EHs on Index: test/asan/TestCases/Windows/virtual_memory.cc =================================================================== --- /dev/null +++ test/asan/TestCases/Windows/virtual_memory.cc @@ -0,0 +1,14 @@ +// RUN: %clang_cl_asan -O0 %s -Fe%t +// RUN: not %run %t 2>&1 | FileCheck %s + +#include + +int main() { + + char* buffer = (char*)VirtualAlloc(NULL, 1024, MEM_COMMIT, PAGE_READWRITE); + buffer[42] = 42; + VirtualFree(buffer, 0, MEM_RELEASE); + free(buffer); + +// CHECK: AddressSanitizer: attempting free on address which was not malloc()-ed: [[ADDR:0x[0-9a-f]+]] in thread T0 +}