llvm-project
165 строк · 5.5 Кб
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_THUNK18#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# endif65
66INTERCEPT_LIBRARY_FUNCTION(atoi);67INTERCEPT_LIBRARY_FUNCTION(atol);68INTERCEPT_LIBRARY_FUNCTION(atoll);69INTERCEPT_LIBRARY_FUNCTION(frexp);70INTERCEPT_LIBRARY_FUNCTION(longjmp);71#if SANITIZER_INTERCEPT_MEMCHR72INTERCEPT_LIBRARY_FUNCTION(memchr);73#endif74INTERCEPT_LIBRARY_FUNCTION(memcmp);75INTERCEPT_LIBRARY_FUNCTION(memcpy);76INTERCEPT_LIBRARY_FUNCTION(memmove);77INTERCEPT_LIBRARY_FUNCTION(memset);78INTERCEPT_LIBRARY_FUNCTION(strcat);79INTERCEPT_LIBRARY_FUNCTION(strchr);80INTERCEPT_LIBRARY_FUNCTION(strcmp);81INTERCEPT_LIBRARY_FUNCTION(strcpy);82INTERCEPT_LIBRARY_FUNCTION(strcspn);83INTERCEPT_LIBRARY_FUNCTION(_strdup);84INTERCEPT_LIBRARY_FUNCTION(strlen);85INTERCEPT_LIBRARY_FUNCTION(strncat);86INTERCEPT_LIBRARY_FUNCTION(strncmp);87INTERCEPT_LIBRARY_FUNCTION(strncpy);88INTERCEPT_LIBRARY_FUNCTION(strnlen);89INTERCEPT_LIBRARY_FUNCTION(strpbrk);90INTERCEPT_LIBRARY_FUNCTION(strrchr);91INTERCEPT_LIBRARY_FUNCTION(strspn);92INTERCEPT_LIBRARY_FUNCTION(strstr);93INTERCEPT_LIBRARY_FUNCTION(strtok);94INTERCEPT_LIBRARY_FUNCTION(strtol);95INTERCEPT_LIBRARY_FUNCTION(strtoll);96INTERCEPT_LIBRARY_FUNCTION(wcslen);97INTERCEPT_LIBRARY_FUNCTION(wcsnlen);98
99# if defined(_MSC_VER) && !defined(__clang__)100# pragma warning(pop)101# endif102
103#ifdef _WIN64104INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);105#else106INTERCEPT_LIBRARY_FUNCTION(_except_handler3);107// _except_handler4 checks -GS cookie which is different for each module, so we
108// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
109INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {110__asan_handle_no_return();111return REAL(_except_handler4)(a, b, c, d);112}
113#endif114
115// Windows specific functions not included in asan_interface.inc.
116INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)117INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)118INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)119
120using namespace __sanitizer;121
122extern "C" {123int __asan_option_detect_stack_use_after_return;124uptr __asan_shadow_memory_dynamic_address;125} // extern "C"126
127static int asan_dll_thunk_init() {128typedef void (*fntype)();129static fntype fn = 0;130// asan_dll_thunk_init is expected to be called by only one thread.131if (fn) return 0;132
133// Ensure all interception was executed.134__dll_thunk_init();135
136fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");137fn();138__asan_option_detect_stack_use_after_return =139(__asan_should_detect_stack_use_after_return() != 0);140__asan_shadow_memory_dynamic_address =141(uptr)__asan_get_shadow_memory_dynamic_address();142
143#ifndef _WIN64144INTERCEPT_FUNCTION(_except_handler4);145#endif146// In DLLs, the callbacks are expected to return 0,147// otherwise CRT initialization fails.148return 0;149}
150
151#pragma section(".CRT$XIB", long, read)152__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;153
154static void WINAPI asan_thread_init(void *mod, unsigned long reason,155void *reserved) {156if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();157}
158
159#pragma section(".CRT$XLAB", long, read)160__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,161unsigned long, void *) = asan_thread_init;162
163WIN_FORCE_LINK(__asan_dso_reg_hook)164
165#endif // SANITIZER_DLL_THUNK166