#include "asan_interceptors.h"
#include "asan_allocator.h"
#include "asan_internal.h"
#include "asan_mapping.h"
#include "asan_poisoning.h"
#include "asan_report.h"
#include "asan_stack.h"
#include "asan_stats.h"
#include "asan_suppressions.h"
#include "asan_thread.h"
#include "lsan/lsan_common.h"
#include "sanitizer_common/sanitizer_errno.h"
#include "sanitizer_common/sanitizer_internal_defs.h"
#include "sanitizer_common/sanitizer_libc.h"
#if !SANITIZER_FUCHSIA
# if SANITIZER_POSIX
# include "sanitizer_common/sanitizer_posix.h"
# endif
# if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION || \
ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
# include <unwind.h>
# endif
# if defined(__i386) && SANITIZER_LINUX
#define ASAN_PTHREAD_CREATE_VERSION …
# elif defined(__mips__) && SANITIZER_LINUX
#define ASAN_PTHREAD_CREATE_VERSION …
# endif
namespace __asan {
#define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) …
#define ASAN_READ_STRING(ctx, s, n) …
static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { … }
void SetThreadName(const char *name) { … }
int OnExit() { … }
}
usingnamespace__asan;
DECLARE_REAL_AND_INTERCEPTOR(…)
DECLARE_REAL_AND_INTERCEPTOR(…)
#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) …
#define COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(name, ver) …
#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) …
#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) …
#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) …
#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) …
#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) …
#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) …
#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) …
#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) …
#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) …
#define COMMON_INTERCEPTOR_BLOCK_REAL(name) …
#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) …
#define COMMON_INTERCEPTOR_ON_EXIT(ctx) …
#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) …
#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() …
#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED …
#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) …
template <class Mmap>
static void* mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length,
int prot, int flags, int fd, OFF64_T offset) { … }
template <class Munmap>
static int munmap_interceptor(Munmap real_munmap, void *addr, SIZE_T length) { … }
#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, \
fd, offset) …
#define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, length) …
#if CAN_SANITIZE_LEAKS
#define COMMON_INTERCEPTOR_STRERROR() …
#endif
#define SIGNAL_INTERCEPTOR_ENTER() …
# include "sanitizer_common/sanitizer_common_interceptors.inc"
# include "sanitizer_common/sanitizer_signal_interceptors.inc"
#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) …
#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) …
#define COMMON_SYSCALL_POST_READ_RANGE(p, s) …
#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) …
#include "sanitizer_common/sanitizer_common_syscalls.inc"
#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
#if ASAN_INTERCEPT_PTHREAD_CREATE
static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { … }
INTERCEPTOR(int, pthread_create, void *thread, void *attr,
void *(*start_routine)(void *), void *arg) { … }
INTERCEPTOR(int, pthread_join, void *thread, void **retval) { … }
INTERCEPTOR(int, pthread_detach, void *thread) { … }
INTERCEPTOR(void, pthread_exit, void *retval) { … }
# if ASAN_INTERCEPT_TRYJOIN
INTERCEPTOR(int, pthread_tryjoin_np, void *thread, void **ret) { … }
# endif
# if ASAN_INTERCEPT_TIMEDJOIN
INTERCEPTOR(int, pthread_timedjoin_np, void *thread, void **ret,
const struct timespec *abstime) { … }
# endif
DEFINE_INTERNAL_PTHREAD_FUNCTIONS
#endif
#if ASAN_INTERCEPT_SWAPCONTEXT
static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { … }
# if SANITIZER_SOLARIS && defined(__sparc__)
INTERCEPTOR(void, __makecontext_v2, struct ucontext_t *ucp, void (*func)(),
int argc, ...) {
# else
INTERCEPTOR(void, makecontext, struct ucontext_t *ucp, void (*func)(), int argc,
...) { … }
INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
struct ucontext_t *ucp) { … }
#endif
#if SANITIZER_NETBSD
#define longjmp …
#define siglongjmp …
#endif
INTERCEPTOR(void, longjmp, void *env, int val) { … }
#if ASAN_INTERCEPT__LONGJMP
INTERCEPTOR(void, _longjmp, void *env, int val) { … }
#endif
#if ASAN_INTERCEPT___LONGJMP_CHK
INTERCEPTOR(void, __longjmp_chk, void *env, int val) { … }
#endif
#if ASAN_INTERCEPT_SIGLONGJMP
INTERCEPTOR(void, siglongjmp, void *env, int val) { … }
#endif
#if ASAN_INTERCEPT___CXA_THROW
INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { … }
#endif
#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) { … }
#endif
#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION
INTERCEPTOR(_Unwind_Reason_Code, _Unwind_RaiseException,
_Unwind_Exception *object) { … }
#endif
#if ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException,
_Unwind_Exception *object) {
CHECK(REAL(_Unwind_SjLj_RaiseException));
__asan_handle_no_return();
return REAL(_Unwind_SjLj_RaiseException)(object);
}
#endif
#if ASAN_INTERCEPT_INDEX
# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
INTERCEPTOR(char*, index, const char *string, int c)
ALIAS(WRAP(strchr));
# else
# if SANITIZER_APPLE
DECLARE_REAL(char*, index, const char *string, int c)
OVERRIDE_FUNCTION(index, strchr);
# else
DEFINE_REAL(char*, index, const char *string, int c)
# endif
# endif
#endif
INTERCEPTOR(char *, strcat, char *to, const char *from) { … }
INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { … }
INTERCEPTOR(char *, strcpy, char *to, const char *from) { … }
# if SANITIZER_WINDOWS
# pragma push_macro("strdup")
# undef strdup
#define strdup …
# endif
INTERCEPTOR(char*, strdup, const char *s) { … }
# if ASAN_INTERCEPT___STRDUP
INTERCEPTOR(char*, __strdup, const char *s) { … }
#endif
INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { … }
template <typename Fn>
static ALWAYS_INLINE auto StrtolImpl(void *ctx, Fn real, const char *nptr,
char **endptr, int base)
-> decltype(real(nullptr, nullptr, 0)) { … }
#define INTERCEPTOR_STRTO_BASE(ret_type, func) …
INTERCEPTOR_STRTO_BASE(…)
# if SANITIZER_WINDOWS
INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) {
COMPILER_CHECK(sizeof(long) == sizeof(u32));
void *ctx;
ASAN_INTERCEPTOR_ENTER(ctx, strtol);
AsanInitFromRtl();
long long result = StrtolImpl(ctx, REAL(strtoll), nptr, endptr, base);
if (result > INT32_MAX) {
errno = errno_ERANGE;
return INT32_MAX;
}
if (result < INT32_MIN) {
errno = errno_ERANGE;
return INT32_MIN;
}
return (long)result;
}
# else
INTERCEPTOR_STRTO_BASE(…)
# endif
# if SANITIZER_GLIBC
INTERCEPTOR_STRTO_BASE(…)
INTERCEPTOR_STRTO_BASE(…)
# endif
INTERCEPTOR(int, atoi, const char *nptr) { … }
INTERCEPTOR(long, atol, const char *nptr) { … }
INTERCEPTOR(long long, atoll, const char *nptr) { … }
#if ASAN_INTERCEPT___CXA_ATEXIT || ASAN_INTERCEPT_ATEXIT
static void AtCxaAtexit(void *unused) { … }
#endif
#if ASAN_INTERCEPT___CXA_ATEXIT
INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
void *dso_handle) { … }
#endif
#if ASAN_INTERCEPT_ATEXIT
INTERCEPTOR(int, atexit, void (*func)()) {
AsanInitFromRtl();
# if CAN_SANITIZE_LEAKS
__lsan::ScopedInterceptorDisabler disabler;
#endif
int res = REAL(__cxa_atexit)((void (*)(void *a))func, nullptr, nullptr);
REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
return res;
}
#endif
#if ASAN_INTERCEPT_PTHREAD_ATFORK
extern "C" {
extern int _pthread_atfork(void (*prepare)(), void (*parent)(),
void (*child)());
}
INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(),
void (*child)()) {
#if CAN_SANITIZE_LEAKS
__lsan::ScopedInterceptorDisabler disabler;
#endif
return _pthread_atfork(prepare, parent, child);
}
#endif
#if ASAN_INTERCEPT_VFORK
DEFINE_REAL(…)
DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(…)
#endif
namespace __asan {
void InitializeAsanInterceptors() { … }
# if SANITIZER_WINDOWS
# pragma pop_macro("strdup")
# endif
}
#endif