1 //===-- asan_win_static_runtime_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 // modules that are statically linked with the C Runtime in order to delegate 13 // the calls to the ASAN runtime DLL. 14 // See https://github.com/google/sanitizers/issues/209 for the details. 15 //===----------------------------------------------------------------------===// 16 17 #ifdef SANITIZER_STATIC_RUNTIME_THUNK 18 # include "asan_init_version.h" 19 # include "asan_interface_internal.h" 20 # include "asan_win_common_runtime_thunk.h" 21 # include "sanitizer_common/sanitizer_platform_interceptors.h" 22 # include "sanitizer_common/sanitizer_win_defs.h" 23 # include "sanitizer_common/sanitizer_win_thunk_interception.h" 24 25 # if defined(_MSC_VER) && !defined(__clang__) 26 // Disable warnings such as: 'void memchr(void)': incorrect number of arguments 27 // for intrinsic function, expected '3' arguments. 28 # pragma warning(push) 29 # pragma warning(disable : 4392) 30 # endif 31 32 # define INTERCEPT_LIBRARY_FUNCTION_ASAN(X) \ 33 INTERCEPT_LIBRARY_FUNCTION(X, "__asan_wrap_" #X) 34 35 INTERCEPT_LIBRARY_FUNCTION_ASAN(atoi); 36 INTERCEPT_LIBRARY_FUNCTION_ASAN(atol); 37 INTERCEPT_LIBRARY_FUNCTION_ASAN(atoll); 38 INTERCEPT_LIBRARY_FUNCTION_ASAN(frexp); 39 INTERCEPT_LIBRARY_FUNCTION_ASAN(longjmp); 40 # if SANITIZER_INTERCEPT_MEMCHR 41 INTERCEPT_LIBRARY_FUNCTION_ASAN(memchr); 42 # endif 43 INTERCEPT_LIBRARY_FUNCTION_ASAN(memcmp); 44 INTERCEPT_LIBRARY_FUNCTION_ASAN(memcpy); 45 # ifndef _WIN64 46 // memmove and memcpy share an implementation on amd64 47 INTERCEPT_LIBRARY_FUNCTION_ASAN(memmove); 48 # endif 49 INTERCEPT_LIBRARY_FUNCTION_ASAN(memset); 50 INTERCEPT_LIBRARY_FUNCTION_ASAN(strcat); 51 INTERCEPT_LIBRARY_FUNCTION_ASAN(strchr); 52 INTERCEPT_LIBRARY_FUNCTION_ASAN(strcmp); 53 INTERCEPT_LIBRARY_FUNCTION_ASAN(strcpy); 54 INTERCEPT_LIBRARY_FUNCTION_ASAN(strcspn); 55 INTERCEPT_LIBRARY_FUNCTION_ASAN(_strdup); 56 INTERCEPT_LIBRARY_FUNCTION_ASAN(strlen); 57 INTERCEPT_LIBRARY_FUNCTION_ASAN(strncat); 58 INTERCEPT_LIBRARY_FUNCTION_ASAN(strncmp); 59 INTERCEPT_LIBRARY_FUNCTION_ASAN(strncpy); 60 INTERCEPT_LIBRARY_FUNCTION_ASAN(strnlen); 61 INTERCEPT_LIBRARY_FUNCTION_ASAN(strpbrk); 62 // INTERCEPT_LIBRARY_FUNCTION_ASAN(strrchr); 63 INTERCEPT_LIBRARY_FUNCTION_ASAN(strspn); 64 INTERCEPT_LIBRARY_FUNCTION_ASAN(strstr); 65 INTERCEPT_LIBRARY_FUNCTION_ASAN(strtok); 66 INTERCEPT_LIBRARY_FUNCTION_ASAN(wcslen); 67 INTERCEPT_LIBRARY_FUNCTION_ASAN(wcsnlen); 68 69 // Note: Don't intercept strtol(l). They are supposed to set errno for out-of- 70 // range values, but since the ASan runtime is linked against the dynamic CRT, 71 // its errno is different from the one in the current module. 72 73 # if defined(_MSC_VER) && !defined(__clang__) 74 # pragma warning(pop) 75 # endif 76 77 # ifdef _WIN64 78 INTERCEPT_LIBRARY_FUNCTION_ASAN(__C_specific_handler); 79 # else 80 extern "C" void abort(); 81 INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler3); 82 // _except_handler4 checks -GS cookie which is different for each module, so we 83 // can't use INTERCEPT_LIBRARY_FUNCTION_ASAN(_except_handler4), need to apply 84 // manually 85 extern "C" int _except_handler4(void *, void *, void *, void *); 86 static int (*real_except_handler4)(void *, void *, void *, 87 void *) = &_except_handler4; 88 static int intercept_except_handler4(void *a, void *b, void *c, void *d) { 89 __asan_handle_no_return(); 90 return real_except_handler4(a, b, c, d); 91 } 92 # endif 93 94 // Windows specific functions not included in asan_interface.inc. 95 // INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return) 96 // INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address) 97 // INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter) 98 99 extern "C" void __asan_initialize_static_thunk() { 100 # ifndef _WIN64 101 if (real_except_handler4 == &_except_handler4) { 102 // Single threaded, no need for synchronization. 103 if (!__sanitizer_override_function_by_addr( 104 reinterpret_cast<__sanitizer::uptr>(&intercept_except_handler4), 105 reinterpret_cast<__sanitizer::uptr>(&_except_handler4), 106 reinterpret_cast<__sanitizer::uptr*>(&real_except_handler4))) { 107 abort(); 108 } 109 } 110 # endif 111 } 112 113 #endif // SANITIZER_DLL_THUNK 114