reference, declarationdefinition
definition → references, declarations, derived classes, virtual overrides
reference to multiple definitions → definitions
unreferenced
    1
    2
    3
    4
    5
    6
    7
    8
    9
   10
   11
   12
   13
   14
   15
   16
   17
   18
   19
   20
   21
   22
   23
   24
   25
   26
   27
   28
   29
   30
   31
   32
   33
   34
   35
   36
   37
   38
   39
   40
   41
   42
   43
   44
   45
   46
   47
   48
   49
   50
   51
   52
   53
   54
   55
   56
   57
   58
   59
   60
   61
   62
   63
   64
   65
   66
   67
   68
   69
   70
   71
   72
   73
   74
   75
   76
   77
   78
   79
   80
   81
   82
   83
   84
   85
   86
   87
   88
   89
   90
   91
   92
   93
   94
   95
   96
   97
   98
   99
  100
  101
  102
  103
  104
  105
  106
  107
  108
  109
  110
  111
  112
  113
  114
  115
  116
  117
  118
  119
  120
  121
  122
  123
  124
  125
  126
  127
  128
  129
  130
  131
  132
  133
  134
  135
  136
  137
  138
  139
  140
  141
  142
  143
  144
  145
  146
  147
  148
  149
  150
  151
  152
//===-- asan_win_dll_thunk.cpp --------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This file is a part of AddressSanitizer, an address sanity checker.
//
// This file defines a family of thunks that should be statically linked into
// the DLLs that have ASan instrumentation in order to delegate the calls to the
// shared runtime that lives in the main binary.
// See https://github.com/google/sanitizers/issues/209 for the details.
//===----------------------------------------------------------------------===//

#ifdef SANITIZER_DLL_THUNK
#include "asan_init_version.h"
#include "interception/interception.h"
#include "sanitizer_common/sanitizer_win_defs.h"
#include "sanitizer_common/sanitizer_win_dll_thunk.h"
#include "sanitizer_common/sanitizer_platform_interceptors.h"

// ASan own interface functions.
#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
#include "asan_interface.inc"

// Memory allocation functions.
INTERCEPT_WRAP_V_W(free)
INTERCEPT_WRAP_V_W(_free_base)
INTERCEPT_WRAP_V_WW(_free_dbg)

INTERCEPT_WRAP_W_W(malloc)
INTERCEPT_WRAP_W_W(_malloc_base)
INTERCEPT_WRAP_W_WWWW(_malloc_dbg)

INTERCEPT_WRAP_W_WW(calloc)
INTERCEPT_WRAP_W_WW(_calloc_base)
INTERCEPT_WRAP_W_WWWWW(_calloc_dbg)
INTERCEPT_WRAP_W_WWW(_calloc_impl)

INTERCEPT_WRAP_W_WW(realloc)
INTERCEPT_WRAP_W_WW(_realloc_base)
INTERCEPT_WRAP_W_WWW(_realloc_dbg)
INTERCEPT_WRAP_W_WWW(_recalloc)
INTERCEPT_WRAP_W_WWW(_recalloc_base)

INTERCEPT_WRAP_W_W(_msize)
INTERCEPT_WRAP_W_W(_msize_base)
INTERCEPT_WRAP_W_W(_expand)
INTERCEPT_WRAP_W_W(_expand_dbg)

// TODO(timurrrr): Might want to add support for _aligned_* allocation
// functions to detect a bit more bugs.  Those functions seem to wrap malloc().

// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp)

INTERCEPT_LIBRARY_FUNCTION(atoi);
INTERCEPT_LIBRARY_FUNCTION(atol);
INTERCEPT_LIBRARY_FUNCTION(frexp);
INTERCEPT_LIBRARY_FUNCTION(longjmp);
#if SANITIZER_INTERCEPT_MEMCHR
INTERCEPT_LIBRARY_FUNCTION(memchr);
#endif
INTERCEPT_LIBRARY_FUNCTION(memcmp);
INTERCEPT_LIBRARY_FUNCTION(memcpy);
INTERCEPT_LIBRARY_FUNCTION(memmove);
INTERCEPT_LIBRARY_FUNCTION(memset);
INTERCEPT_LIBRARY_FUNCTION(strcat);
INTERCEPT_LIBRARY_FUNCTION(strchr);
INTERCEPT_LIBRARY_FUNCTION(strcmp);
INTERCEPT_LIBRARY_FUNCTION(strcpy);
INTERCEPT_LIBRARY_FUNCTION(strcspn);
INTERCEPT_LIBRARY_FUNCTION(strdup);
INTERCEPT_LIBRARY_FUNCTION(strlen);
INTERCEPT_LIBRARY_FUNCTION(strncat);
INTERCEPT_LIBRARY_FUNCTION(strncmp);
INTERCEPT_LIBRARY_FUNCTION(strncpy);
INTERCEPT_LIBRARY_FUNCTION(strnlen);
INTERCEPT_LIBRARY_FUNCTION(strpbrk);
INTERCEPT_LIBRARY_FUNCTION(strrchr);
INTERCEPT_LIBRARY_FUNCTION(strspn);
INTERCEPT_LIBRARY_FUNCTION(strstr);
INTERCEPT_LIBRARY_FUNCTION(strtok);
INTERCEPT_LIBRARY_FUNCTION(strtol);
INTERCEPT_LIBRARY_FUNCTION(wcslen);
INTERCEPT_LIBRARY_FUNCTION(wcsnlen);

#ifdef _WIN64
INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);
#else
INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
// _except_handler4 checks -GS cookie which is different for each module, so we
// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
  __asan_handle_no_return();
  return REAL(_except_handler4)(a, b, c, d);
}
#endif

// Windows specific functions not included in asan_interface.inc.
INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)

using namespace __sanitizer;

extern "C" {
int __asan_option_detect_stack_use_after_return;
uptr __asan_shadow_memory_dynamic_address;
} // extern "C"

static int asan_dll_thunk_init() {
  typedef void (*fntype)();
  static fntype fn = 0;
  // asan_dll_thunk_init is expected to be called by only one thread.
  if (fn) return 0;

  // Ensure all interception was executed.
  __dll_thunk_init();

  fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");
  fn();
  __asan_option_detect_stack_use_after_return =
      (__asan_should_detect_stack_use_after_return() != 0);
  __asan_shadow_memory_dynamic_address =
      (uptr)__asan_get_shadow_memory_dynamic_address();

#ifndef _WIN64
  INTERCEPT_FUNCTION(_except_handler4);
#endif
  // In DLLs, the callbacks are expected to return 0,
  // otherwise CRT initialization fails.
  return 0;
}

#pragma section(".CRT$XIB", long, read)
__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;

static void WINAPI asan_thread_init(void *mod, unsigned long reason,
                                    void *reserved) {
  if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
}

#pragma section(".CRT$XLAB", long, read)
__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
    unsigned long, void *) = asan_thread_init;

WIN_FORCE_LINK(__asan_dso_reg_hook)

#endif // SANITIZER_DLL_THUNK