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