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