Home | History | Annotate | Line # | Download | only in asan
      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