1//===-- asan_win_dll_thunk.cpp --------------------------------------------===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// This file is a part of AddressSanitizer, an address sanity checker. 10// 11// This file defines a family of thunks that should be statically linked into 12// the DLLs that have ASan instrumentation in order to delegate the calls to the 13// shared runtime that lives in the main binary. 14// See https://github.com/google/sanitizers/issues/209 for the details. 15//===----------------------------------------------------------------------===// 16 17#ifdef SANITIZER_DLL_THUNK 18#include "asan_init_version.h" 19#include "interception/interception.h" 20#include "sanitizer_common/sanitizer_win_defs.h" 21#include "sanitizer_common/sanitizer_win_dll_thunk.h" 22#include "sanitizer_common/sanitizer_platform_interceptors.h" 23 24// ASan own interface functions. 25#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name) 26#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) 27#include "asan_interface.inc" 28 29// Memory allocation functions. 30INTERCEPT_WRAP_V_W(free) 31INTERCEPT_WRAP_V_W(_free_base) 32INTERCEPT_WRAP_V_WW(_free_dbg) 33 34INTERCEPT_WRAP_W_W(malloc) 35INTERCEPT_WRAP_W_W(_malloc_base) 36INTERCEPT_WRAP_W_WWWW(_malloc_dbg) 37 38INTERCEPT_WRAP_W_WW(calloc) 39INTERCEPT_WRAP_W_WW(_calloc_base) 40INTERCEPT_WRAP_W_WWWWW(_calloc_dbg) 41INTERCEPT_WRAP_W_WWW(_calloc_impl) 42 43INTERCEPT_WRAP_W_WW(realloc) 44INTERCEPT_WRAP_W_WW(_realloc_base) 45INTERCEPT_WRAP_W_WWW(_realloc_dbg) 46INTERCEPT_WRAP_W_WWW(_recalloc) 47INTERCEPT_WRAP_W_WWW(_recalloc_base) 48 49INTERCEPT_WRAP_W_W(_msize) 50INTERCEPT_WRAP_W_W(_msize_base) 51INTERCEPT_WRAP_W_W(_expand) 52INTERCEPT_WRAP_W_W(_expand_dbg) 53 54// TODO(timurrrr): Might want to add support for _aligned_* allocation 55// functions to detect a bit more bugs. Those functions seem to wrap malloc(). 56 57// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp) 58 59# if defined(_MSC_VER) && !defined(__clang__) 60// Disable warnings such as: 'void memchr(void)': incorrect number of arguments 61// for intrinsic function, expected '3' arguments. 62# pragma warning(push) 63# pragma warning(disable : 4392) 64# endif 65 66INTERCEPT_LIBRARY_FUNCTION(atoi); 67INTERCEPT_LIBRARY_FUNCTION(atol); 68INTERCEPT_LIBRARY_FUNCTION(frexp); 69INTERCEPT_LIBRARY_FUNCTION(longjmp); 70#if SANITIZER_INTERCEPT_MEMCHR 71INTERCEPT_LIBRARY_FUNCTION(memchr); 72#endif 73INTERCEPT_LIBRARY_FUNCTION(memcmp); 74INTERCEPT_LIBRARY_FUNCTION(memcpy); 75INTERCEPT_LIBRARY_FUNCTION(memmove); 76INTERCEPT_LIBRARY_FUNCTION(memset); 77INTERCEPT_LIBRARY_FUNCTION(strcat); 78INTERCEPT_LIBRARY_FUNCTION(strchr); 79INTERCEPT_LIBRARY_FUNCTION(strcmp); 80INTERCEPT_LIBRARY_FUNCTION(strcpy); 81INTERCEPT_LIBRARY_FUNCTION(strcspn); 82INTERCEPT_LIBRARY_FUNCTION(strdup); 83INTERCEPT_LIBRARY_FUNCTION(strlen); 84INTERCEPT_LIBRARY_FUNCTION(strncat); 85INTERCEPT_LIBRARY_FUNCTION(strncmp); 86INTERCEPT_LIBRARY_FUNCTION(strncpy); 87INTERCEPT_LIBRARY_FUNCTION(strnlen); 88INTERCEPT_LIBRARY_FUNCTION(strpbrk); 89INTERCEPT_LIBRARY_FUNCTION(strrchr); 90INTERCEPT_LIBRARY_FUNCTION(strspn); 91INTERCEPT_LIBRARY_FUNCTION(strstr); 92INTERCEPT_LIBRARY_FUNCTION(strtok); 93INTERCEPT_LIBRARY_FUNCTION(strtol); 94INTERCEPT_LIBRARY_FUNCTION(wcslen); 95INTERCEPT_LIBRARY_FUNCTION(wcsnlen); 96 97# if defined(_MSC_VER) && !defined(__clang__) 98# pragma warning(pop) 99# endif 100 101#ifdef _WIN64 102INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler); 103#else 104INTERCEPT_LIBRARY_FUNCTION(_except_handler3); 105// _except_handler4 checks -GS cookie which is different for each module, so we 106// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4). 107INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) { 108 __asan_handle_no_return(); 109 return REAL(_except_handler4)(a, b, c, d); 110} 111#endif 112 113// Windows specific functions not included in asan_interface.inc. 114INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return) 115INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address) 116INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter) 117 118using namespace __sanitizer; 119 120extern "C" { 121int __asan_option_detect_stack_use_after_return; 122uptr __asan_shadow_memory_dynamic_address; 123} // extern "C" 124 125static int asan_dll_thunk_init() { 126 typedef void (*fntype)(); 127 static fntype fn = 0; 128 // asan_dll_thunk_init is expected to be called by only one thread. 129 if (fn) return 0; 130 131 // Ensure all interception was executed. 132 __dll_thunk_init(); 133 134 fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init"); 135 fn(); 136 __asan_option_detect_stack_use_after_return = 137 (__asan_should_detect_stack_use_after_return() != 0); 138 __asan_shadow_memory_dynamic_address = 139 (uptr)__asan_get_shadow_memory_dynamic_address(); 140 141#ifndef _WIN64 142 INTERCEPT_FUNCTION(_except_handler4); 143#endif 144 // In DLLs, the callbacks are expected to return 0, 145 // otherwise CRT initialization fails. 146 return 0; 147} 148 149#pragma section(".CRT$XIB", long, read) 150__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init; 151 152static void WINAPI asan_thread_init(void *mod, unsigned long reason, 153 void *reserved) { 154 if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init(); 155} 156 157#pragma section(".CRT$XLAB", long, read) 158__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *, 159 unsigned long, void *) = asan_thread_init; 160 161WIN_FORCE_LINK(__asan_dso_reg_hook) 162 163#endif // SANITIZER_DLL_THUNK 164