1 //===-- asan_interceptors.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 // Intercept various libc functions. 12 //===----------------------------------------------------------------------===// 13 14 #include "asan_interceptors.h" 15 #include "asan_allocator.h" 16 #include "asan_internal.h" 17 #include "asan_mapping.h" 18 #include "asan_poisoning.h" 19 #include "asan_report.h" 20 #include "asan_stack.h" 21 #include "asan_stats.h" 22 #include "asan_suppressions.h" 23 #include "lsan/lsan_common.h" 24 #include "sanitizer_common/sanitizer_libc.h" 25 26 // There is no general interception at all on Fuchsia and RTEMS. 27 // Only the functions in asan_interceptors_memintrinsics.cpp are 28 // really defined to replace libc functions. 29 #if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS 30 31 #if SANITIZER_POSIX 32 #include "sanitizer_common/sanitizer_posix.h" 33 #endif 34 35 #if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION || \ 36 ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION 37 #include <unwind.h> 38 #endif 39 40 #if defined(__i386) && SANITIZER_LINUX 41 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" 42 #elif defined(__mips__) && SANITIZER_LINUX 43 #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2" 44 #endif 45 46 namespace __asan { 47 48 #define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \ 49 ASAN_READ_RANGE((ctx), (s), \ 50 common_flags()->strict_string_checks ? (len) + 1 : (n)) 51 52 #define ASAN_READ_STRING(ctx, s, n) \ 53 ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n)) 54 55 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 56 #if SANITIZER_INTERCEPT_STRNLEN 57 if (REAL(strnlen)) { 58 return REAL(strnlen)(s, maxlen); 59 } 60 #endif 61 return internal_strnlen(s, maxlen); 62 } 63 64 void SetThreadName(const char *name) { 65 AsanThread *t = GetCurrentThread(); 66 if (t) 67 asanThreadRegistry().SetThreadName(t->tid(), name); 68 } 69 70 int OnExit() { 71 if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks && 72 __lsan::HasReportedLeaks()) { 73 return common_flags()->exitcode; 74 } 75 // FIXME: ask frontend whether we need to return failure. 76 return 0; 77 } 78 79 } // namespace __asan 80 81 // ---------------------- Wrappers ---------------- {{{1 82 using namespace __asan; 83 84 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) 85 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) 86 87 #define ASAN_INTERCEPTOR_ENTER(ctx, func) \ 88 AsanInterceptorContext _ctx = {#func}; \ 89 ctx = (void *)&_ctx; \ 90 (void) ctx; \ 91 92 #define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name) 93 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ 94 ASAN_INTERCEPT_FUNC_VER(name, ver) 95 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 96 ASAN_WRITE_RANGE(ctx, ptr, size) 97 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 98 ASAN_READ_RANGE(ctx, ptr, size) 99 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 100 ASAN_INTERCEPTOR_ENTER(ctx, func); \ 101 do { \ 102 if (asan_init_is_running) \ 103 return REAL(func)(__VA_ARGS__); \ 104 if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \ 105 return REAL(func)(__VA_ARGS__); \ 106 ENSURE_ASAN_INITED(); \ 107 } while (false) 108 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \ 109 do { \ 110 } while (false) 111 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 112 do { \ 113 } while (false) 114 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 115 do { \ 116 } while (false) 117 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 118 do { \ 119 } while (false) 120 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 121 // Should be asanThreadRegistry().SetThreadNameByUserId(thread, name) 122 // But asan does not remember UserId's for threads (pthread_t); 123 // and remembers all ever existed threads, so the linear search by UserId 124 // can be slow. 125 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \ 126 do { \ 127 } while (false) 128 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) 129 // Strict init-order checking is dlopen-hostile: 130 // https://github.com/google/sanitizers/issues/178 131 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ 132 do { \ 133 if (flags()->strict_init_order) \ 134 StopInitOrderChecking(); \ 135 CheckNoDeepBind(filename, flag); \ 136 } while (false) 137 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() 138 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) 139 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() 140 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited) 141 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ 142 if (AsanThread *t = GetCurrentThread()) { \ 143 *begin = t->tls_begin(); \ 144 *end = t->tls_end(); \ 145 } else { \ 146 *begin = *end = 0; \ 147 } 148 149 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \ 150 do { \ 151 ASAN_INTERCEPTOR_ENTER(ctx, memmove); \ 152 ASAN_MEMMOVE_IMPL(ctx, to, from, size); \ 153 } while (false) 154 155 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \ 156 do { \ 157 ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \ 158 ASAN_MEMCPY_IMPL(ctx, to, from, size); \ 159 } while (false) 160 161 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \ 162 do { \ 163 ASAN_INTERCEPTOR_ENTER(ctx, memset); \ 164 ASAN_MEMSET_IMPL(ctx, block, c, size); \ 165 } while (false) 166 167 #if CAN_SANITIZE_LEAKS 168 #define COMMON_INTERCEPTOR_STRERROR() \ 169 __lsan::ScopedInterceptorDisabler disabler 170 #endif 171 172 #include "sanitizer_common/sanitizer_common_interceptors.inc" 173 #include "sanitizer_common/sanitizer_signal_interceptors.inc" 174 175 // Syscall interceptors don't have contexts, we don't support suppressions 176 // for them. 177 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s) 178 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s) 179 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 180 do { \ 181 (void)(p); \ 182 (void)(s); \ 183 } while (false) 184 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ 185 do { \ 186 (void)(p); \ 187 (void)(s); \ 188 } while (false) 189 #include "sanitizer_common/sanitizer_common_syscalls.inc" 190 #include "sanitizer_common/sanitizer_syscalls_netbsd.inc" 191 192 struct ThreadStartParam { 193 atomic_uintptr_t t; 194 atomic_uintptr_t is_registered; 195 }; 196 197 #if ASAN_INTERCEPT_PTHREAD_CREATE 198 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 199 ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg); 200 AsanThread *t = nullptr; 201 while ((t = reinterpret_cast<AsanThread *>( 202 atomic_load(¶m->t, memory_order_acquire))) == nullptr) 203 internal_sched_yield(); 204 SetCurrentThread(t); 205 return t->ThreadStart(GetTid(), ¶m->is_registered); 206 } 207 208 INTERCEPTOR(int, pthread_create, void *thread, 209 void *attr, void *(*start_routine)(void*), void *arg) { 210 EnsureMainThreadIDIsCorrect(); 211 // Strict init-order checking is thread-hostile. 212 if (flags()->strict_init_order) 213 StopInitOrderChecking(); 214 GET_STACK_TRACE_THREAD; 215 int detached = 0; 216 if (attr) 217 REAL(pthread_attr_getdetachstate)(attr, &detached); 218 ThreadStartParam param; 219 atomic_store(¶m.t, 0, memory_order_relaxed); 220 atomic_store(¶m.is_registered, 0, memory_order_relaxed); 221 int result; 222 { 223 // Ignore all allocations made by pthread_create: thread stack/TLS may be 224 // stored by pthread for future reuse even after thread destruction, and 225 // the linked list it's stored in doesn't even hold valid pointers to the 226 // objects, the latter are calculated by obscure pointer arithmetic. 227 #if CAN_SANITIZE_LEAKS 228 __lsan::ScopedInterceptorDisabler disabler; 229 #endif 230 result = REAL(pthread_create)(thread, attr, asan_thread_start, ¶m); 231 } 232 if (result == 0) { 233 u32 current_tid = GetCurrentTidOrInvalid(); 234 AsanThread *t = 235 AsanThread::Create(start_routine, arg, current_tid, &stack, detached); 236 atomic_store(¶m.t, reinterpret_cast<uptr>(t), memory_order_release); 237 // Wait until the AsanThread object is initialized and the ThreadRegistry 238 // entry is in "started" state. One reason for this is that after this 239 // interceptor exits, the child thread's stack may be the only thing holding 240 // the |arg| pointer. This may cause LSan to report a leak if leak checking 241 // happens at a point when the interceptor has already exited, but the stack 242 // range for the child thread is not yet known. 243 while (atomic_load(¶m.is_registered, memory_order_acquire) == 0) 244 internal_sched_yield(); 245 } 246 return result; 247 } 248 249 INTERCEPTOR(int, pthread_join, void *t, void **arg) { 250 return real_pthread_join(t, arg); 251 } 252 253 DEFINE_REAL_PTHREAD_FUNCTIONS 254 #endif // ASAN_INTERCEPT_PTHREAD_CREATE 255 256 #if ASAN_INTERCEPT_SWAPCONTEXT 257 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 258 // Align to page size. 259 uptr PageSize = GetPageSizeCached(); 260 uptr bottom = stack & ~(PageSize - 1); 261 ssize += stack - bottom; 262 ssize = RoundUpTo(ssize, PageSize); 263 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 264 if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) { 265 PoisonShadow(bottom, ssize, 0); 266 } 267 } 268 269 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 270 struct ucontext_t *ucp) { 271 static bool reported_warning = false; 272 if (!reported_warning) { 273 Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 274 "functions and may produce false positives in some cases!\n"); 275 reported_warning = true; 276 } 277 // Clear shadow memory for new context (it may share stack 278 // with current context). 279 uptr stack, ssize; 280 ReadContextStack(ucp, &stack, &ssize); 281 ClearShadowMemoryForContextStack(stack, ssize); 282 #if __has_attribute(__indirect_return__) && \ 283 (defined(__x86_64__) || defined(__i386__)) 284 int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *) 285 __attribute__((__indirect_return__)) 286 = REAL(swapcontext); 287 int res = real_swapcontext(oucp, ucp); 288 #else 289 int res = REAL(swapcontext)(oucp, ucp); 290 #endif 291 // swapcontext technically does not return, but program may swap context to 292 // "oucp" later, that would look as if swapcontext() returned 0. 293 // We need to clear shadow for ucp once again, as it may be in arbitrary 294 // state. 295 ClearShadowMemoryForContextStack(stack, ssize); 296 return res; 297 } 298 #endif // ASAN_INTERCEPT_SWAPCONTEXT 299 300 #if SANITIZER_NETBSD 301 #define longjmp __longjmp14 302 #define siglongjmp __siglongjmp14 303 #endif 304 305 INTERCEPTOR(void, longjmp, void *env, int val) { 306 __asan_handle_no_return(); 307 REAL(longjmp)(env, val); 308 } 309 310 #if ASAN_INTERCEPT__LONGJMP 311 INTERCEPTOR(void, _longjmp, void *env, int val) { 312 __asan_handle_no_return(); 313 REAL(_longjmp)(env, val); 314 } 315 #endif 316 317 #if ASAN_INTERCEPT___LONGJMP_CHK 318 INTERCEPTOR(void, __longjmp_chk, void *env, int val) { 319 __asan_handle_no_return(); 320 REAL(__longjmp_chk)(env, val); 321 } 322 #endif 323 324 #if ASAN_INTERCEPT_SIGLONGJMP 325 INTERCEPTOR(void, siglongjmp, void *env, int val) { 326 __asan_handle_no_return(); 327 REAL(siglongjmp)(env, val); 328 } 329 #endif 330 331 #if ASAN_INTERCEPT___CXA_THROW 332 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 333 CHECK(REAL(__cxa_throw)); 334 __asan_handle_no_return(); 335 REAL(__cxa_throw)(a, b, c); 336 } 337 #endif 338 339 #if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 340 INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) { 341 CHECK(REAL(__cxa_rethrow_primary_exception)); 342 __asan_handle_no_return(); 343 REAL(__cxa_rethrow_primary_exception)(a); 344 } 345 #endif 346 347 #if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 348 INTERCEPTOR(_Unwind_Reason_Code, _Unwind_RaiseException, 349 _Unwind_Exception *object) { 350 CHECK(REAL(_Unwind_RaiseException)); 351 __asan_handle_no_return(); 352 return REAL(_Unwind_RaiseException)(object); 353 } 354 #endif 355 356 #if ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION 357 INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException, 358 _Unwind_Exception *object) { 359 CHECK(REAL(_Unwind_SjLj_RaiseException)); 360 __asan_handle_no_return(); 361 return REAL(_Unwind_SjLj_RaiseException)(object); 362 } 363 #endif 364 365 #if ASAN_INTERCEPT_INDEX 366 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 367 INTERCEPTOR(char*, index, const char *string, int c) 368 ALIAS(WRAPPER_NAME(strchr)); 369 # else 370 # if SANITIZER_MAC 371 DECLARE_REAL(char*, index, const char *string, int c) 372 OVERRIDE_FUNCTION(index, strchr); 373 # else 374 DEFINE_REAL(char*, index, const char *string, int c) 375 # endif 376 # endif 377 #endif // ASAN_INTERCEPT_INDEX 378 379 // For both strcat() and strncat() we need to check the validity of |to| 380 // argument irrespective of the |from| length. 381 INTERCEPTOR(char *, strcat, char *to, const char *from) { 382 void *ctx; 383 ASAN_INTERCEPTOR_ENTER(ctx, strcat); 384 ENSURE_ASAN_INITED(); 385 if (flags()->replace_str) { 386 uptr from_length = REAL(strlen)(from); 387 ASAN_READ_RANGE(ctx, from, from_length + 1); 388 uptr to_length = REAL(strlen)(to); 389 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); 390 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); 391 // If the copying actually happens, the |from| string should not overlap 392 // with the resulting string starting at |to|, which has a length of 393 // to_length + from_length + 1. 394 if (from_length > 0) { 395 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, from, 396 from_length + 1); 397 } 398 } 399 return REAL(strcat)(to, from); 400 } 401 402 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 403 void *ctx; 404 ASAN_INTERCEPTOR_ENTER(ctx, strncat); 405 ENSURE_ASAN_INITED(); 406 if (flags()->replace_str) { 407 uptr from_length = MaybeRealStrnlen(from, size); 408 uptr copy_length = Min(size, from_length + 1); 409 ASAN_READ_RANGE(ctx, from, copy_length); 410 uptr to_length = REAL(strlen)(to); 411 ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); 412 ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); 413 if (from_length > 0) { 414 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 415 from, copy_length); 416 } 417 } 418 return REAL(strncat)(to, from, size); 419 } 420 421 INTERCEPTOR(char *, strcpy, char *to, const char *from) { 422 void *ctx; 423 ASAN_INTERCEPTOR_ENTER(ctx, strcpy); 424 #if SANITIZER_MAC 425 if (UNLIKELY(!asan_inited)) 426 return REAL(strcpy)(to, from); 427 #endif 428 // strcpy is called from malloc_default_purgeable_zone() 429 // in __asan::ReplaceSystemAlloc() on Mac. 430 if (asan_init_is_running) { 431 return REAL(strcpy)(to, from); 432 } 433 ENSURE_ASAN_INITED(); 434 if (flags()->replace_str) { 435 uptr from_size = REAL(strlen)(from) + 1; 436 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 437 ASAN_READ_RANGE(ctx, from, from_size); 438 ASAN_WRITE_RANGE(ctx, to, from_size); 439 } 440 return REAL(strcpy)(to, from); 441 } 442 443 INTERCEPTOR(char*, strdup, const char *s) { 444 void *ctx; 445 ASAN_INTERCEPTOR_ENTER(ctx, strdup); 446 if (UNLIKELY(!asan_inited)) return internal_strdup(s); 447 ENSURE_ASAN_INITED(); 448 uptr length = REAL(strlen)(s); 449 if (flags()->replace_str) { 450 ASAN_READ_RANGE(ctx, s, length + 1); 451 } 452 GET_STACK_TRACE_MALLOC; 453 void *new_mem = asan_malloc(length + 1, &stack); 454 REAL(memcpy)(new_mem, s, length + 1); 455 return reinterpret_cast<char*>(new_mem); 456 } 457 458 #if ASAN_INTERCEPT___STRDUP 459 INTERCEPTOR(char*, __strdup, const char *s) { 460 void *ctx; 461 ASAN_INTERCEPTOR_ENTER(ctx, strdup); 462 if (UNLIKELY(!asan_inited)) return internal_strdup(s); 463 ENSURE_ASAN_INITED(); 464 uptr length = REAL(strlen)(s); 465 if (flags()->replace_str) { 466 ASAN_READ_RANGE(ctx, s, length + 1); 467 } 468 GET_STACK_TRACE_MALLOC; 469 void *new_mem = asan_malloc(length + 1, &stack); 470 REAL(memcpy)(new_mem, s, length + 1); 471 return reinterpret_cast<char*>(new_mem); 472 } 473 #endif // ASAN_INTERCEPT___STRDUP 474 475 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 476 void *ctx; 477 ASAN_INTERCEPTOR_ENTER(ctx, strncpy); 478 ENSURE_ASAN_INITED(); 479 if (flags()->replace_str) { 480 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 481 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 482 ASAN_READ_RANGE(ctx, from, from_size); 483 ASAN_WRITE_RANGE(ctx, to, size); 484 } 485 return REAL(strncpy)(to, from, size); 486 } 487 488 INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) { 489 void *ctx; 490 ASAN_INTERCEPTOR_ENTER(ctx, strtol); 491 ENSURE_ASAN_INITED(); 492 if (!flags()->replace_str) { 493 return REAL(strtol)(nptr, endptr, base); 494 } 495 char *real_endptr; 496 long result = REAL(strtol)(nptr, &real_endptr, base); 497 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 498 return result; 499 } 500 501 INTERCEPTOR(int, atoi, const char *nptr) { 502 void *ctx; 503 ASAN_INTERCEPTOR_ENTER(ctx, atoi); 504 #if SANITIZER_MAC 505 if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr); 506 #endif 507 ENSURE_ASAN_INITED(); 508 if (!flags()->replace_str) { 509 return REAL(atoi)(nptr); 510 } 511 char *real_endptr; 512 // "man atoi" tells that behavior of atoi(nptr) is the same as 513 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 514 // parsed integer can't be stored in *long* type (even if it's 515 // different from int). So, we just imitate this behavior. 516 int result = REAL(strtol)(nptr, &real_endptr, 10); 517 FixRealStrtolEndptr(nptr, &real_endptr); 518 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 519 return result; 520 } 521 522 INTERCEPTOR(long, atol, const char *nptr) { 523 void *ctx; 524 ASAN_INTERCEPTOR_ENTER(ctx, atol); 525 #if SANITIZER_MAC 526 if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr); 527 #endif 528 ENSURE_ASAN_INITED(); 529 if (!flags()->replace_str) { 530 return REAL(atol)(nptr); 531 } 532 char *real_endptr; 533 long result = REAL(strtol)(nptr, &real_endptr, 10); 534 FixRealStrtolEndptr(nptr, &real_endptr); 535 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 536 return result; 537 } 538 539 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 540 INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, int base) { 541 void *ctx; 542 ASAN_INTERCEPTOR_ENTER(ctx, strtoll); 543 ENSURE_ASAN_INITED(); 544 if (!flags()->replace_str) { 545 return REAL(strtoll)(nptr, endptr, base); 546 } 547 char *real_endptr; 548 long long result = REAL(strtoll)(nptr, &real_endptr, base); 549 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 550 return result; 551 } 552 553 INTERCEPTOR(long long, atoll, const char *nptr) { 554 void *ctx; 555 ASAN_INTERCEPTOR_ENTER(ctx, atoll); 556 ENSURE_ASAN_INITED(); 557 if (!flags()->replace_str) { 558 return REAL(atoll)(nptr); 559 } 560 char *real_endptr; 561 long long result = REAL(strtoll)(nptr, &real_endptr, 10); 562 FixRealStrtolEndptr(nptr, &real_endptr); 563 ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); 564 return result; 565 } 566 #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 567 568 #if ASAN_INTERCEPT___CXA_ATEXIT || ASAN_INTERCEPT_ATEXIT 569 static void AtCxaAtexit(void *unused) { 570 (void)unused; 571 StopInitOrderChecking(); 572 } 573 #endif 574 575 #if ASAN_INTERCEPT___CXA_ATEXIT 576 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 577 void *dso_handle) { 578 #if SANITIZER_MAC 579 if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle); 580 #endif 581 ENSURE_ASAN_INITED(); 582 #if CAN_SANITIZE_LEAKS 583 __lsan::ScopedInterceptorDisabler disabler; 584 #endif 585 int res = REAL(__cxa_atexit)(func, arg, dso_handle); 586 REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr); 587 return res; 588 } 589 #endif // ASAN_INTERCEPT___CXA_ATEXIT 590 591 #if ASAN_INTERCEPT_ATEXIT 592 INTERCEPTOR(int, atexit, void (*func)()) { 593 ENSURE_ASAN_INITED(); 594 #if CAN_SANITIZE_LEAKS 595 __lsan::ScopedInterceptorDisabler disabler; 596 #endif 597 // Avoid calling real atexit as it is unrechable on at least on Linux. 598 int res = REAL(__cxa_atexit)((void (*)(void *a))func, nullptr, nullptr); 599 REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr); 600 return res; 601 } 602 #endif 603 604 #if ASAN_INTERCEPT_PTHREAD_ATFORK 605 extern "C" { 606 extern int _pthread_atfork(void (*prepare)(), void (*parent)(), 607 void (*child)()); 608 }; 609 610 INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(), 611 void (*child)()) { 612 #if CAN_SANITIZE_LEAKS 613 __lsan::ScopedInterceptorDisabler disabler; 614 #endif 615 // REAL(pthread_atfork) cannot be called due to symbol indirections at least 616 // on NetBSD 617 return _pthread_atfork(prepare, parent, child); 618 } 619 #endif 620 621 #if ASAN_INTERCEPT_VFORK 622 DEFINE_REAL(int, vfork) 623 DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) 624 #endif 625 626 // ---------------------- InitializeAsanInterceptors ---------------- {{{1 627 namespace __asan { 628 void InitializeAsanInterceptors() { 629 static bool was_called_once; 630 CHECK(!was_called_once); 631 was_called_once = true; 632 InitializeCommonInterceptors(); 633 InitializeSignalInterceptors(); 634 635 // Intercept str* functions. 636 ASAN_INTERCEPT_FUNC(strcat); 637 ASAN_INTERCEPT_FUNC(strcpy); 638 ASAN_INTERCEPT_FUNC(strncat); 639 ASAN_INTERCEPT_FUNC(strncpy); 640 ASAN_INTERCEPT_FUNC(strdup); 641 #if ASAN_INTERCEPT___STRDUP 642 ASAN_INTERCEPT_FUNC(__strdup); 643 #endif 644 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 645 ASAN_INTERCEPT_FUNC(index); 646 #endif 647 648 ASAN_INTERCEPT_FUNC(atoi); 649 ASAN_INTERCEPT_FUNC(atol); 650 ASAN_INTERCEPT_FUNC(strtol); 651 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 652 ASAN_INTERCEPT_FUNC(atoll); 653 ASAN_INTERCEPT_FUNC(strtoll); 654 #endif 655 656 // Intecept jump-related functions. 657 ASAN_INTERCEPT_FUNC(longjmp); 658 659 #if ASAN_INTERCEPT_SWAPCONTEXT 660 ASAN_INTERCEPT_FUNC(swapcontext); 661 #endif 662 #if ASAN_INTERCEPT__LONGJMP 663 ASAN_INTERCEPT_FUNC(_longjmp); 664 #endif 665 #if ASAN_INTERCEPT___LONGJMP_CHK 666 ASAN_INTERCEPT_FUNC(__longjmp_chk); 667 #endif 668 #if ASAN_INTERCEPT_SIGLONGJMP 669 ASAN_INTERCEPT_FUNC(siglongjmp); 670 #endif 671 672 // Intercept exception handling functions. 673 #if ASAN_INTERCEPT___CXA_THROW 674 ASAN_INTERCEPT_FUNC(__cxa_throw); 675 #endif 676 #if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 677 ASAN_INTERCEPT_FUNC(__cxa_rethrow_primary_exception); 678 #endif 679 // Indirectly intercept std::rethrow_exception. 680 #if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 681 INTERCEPT_FUNCTION(_Unwind_RaiseException); 682 #endif 683 // Indirectly intercept std::rethrow_exception. 684 #if ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 685 INTERCEPT_FUNCTION(_Unwind_SjLj_RaiseException); 686 #endif 687 688 // Intercept threading-related functions 689 #if ASAN_INTERCEPT_PTHREAD_CREATE 690 #if defined(ASAN_PTHREAD_CREATE_VERSION) 691 ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION); 692 #else 693 ASAN_INTERCEPT_FUNC(pthread_create); 694 #endif 695 ASAN_INTERCEPT_FUNC(pthread_join); 696 #endif 697 698 // Intercept atexit function. 699 #if ASAN_INTERCEPT___CXA_ATEXIT 700 ASAN_INTERCEPT_FUNC(__cxa_atexit); 701 #endif 702 703 #if ASAN_INTERCEPT_ATEXIT 704 ASAN_INTERCEPT_FUNC(atexit); 705 #endif 706 707 #if ASAN_INTERCEPT_PTHREAD_ATFORK 708 ASAN_INTERCEPT_FUNC(pthread_atfork); 709 #endif 710 711 #if ASAN_INTERCEPT_VFORK 712 ASAN_INTERCEPT_FUNC(vfork); 713 #endif 714 715 InitializePlatformInterceptors(); 716 717 VReport(1, "AddressSanitizer: libc interceptors initialized\n"); 718 } 719 720 } // namespace __asan 721 722 #endif // !SANITIZER_FUCHSIA 723