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 #include "asan_interceptors.h" 15 16 #include "asan_allocator.h" 17 #include "asan_intercepted_functions.h" 18 #include "asan_internal.h" 19 #include "asan_mapping.h" 20 #include "asan_poisoning.h" 21 #include "asan_report.h" 22 #include "asan_stack.h" 23 #include "asan_stats.h" 24 #include "interception/interception.h" 25 #include "sanitizer_common/sanitizer_libc.h" 26 27 namespace __asan { 28 29 // Return true if we can quickly decide that the region is unpoisoned. 30 static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { 31 if (size == 0) return true; 32 if (size <= 32) 33 return !AddressIsPoisoned(beg) && 34 !AddressIsPoisoned(beg + size - 1) && 35 !AddressIsPoisoned(beg + size / 2); 36 return false; 37 } 38 39 // We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 40 // and ASAN_WRITE_RANGE as macro instead of function so 41 // that no extra frames are created, and stack trace contains 42 // relevant information only. 43 // We check all shadow bytes. 44 #define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 45 uptr __offset = (uptr)(offset); \ 46 uptr __size = (uptr)(size); \ 47 uptr __bad = 0; \ 48 if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \ 49 (__bad = __asan_region_is_poisoned(__offset, __size))) { \ 50 GET_CURRENT_PC_BP_SP; \ 51 __asan_report_error(pc, bp, sp, __bad, isWrite, __size); \ 52 } \ 53 } while (0) 54 55 #define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false) 56 #define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true) 57 58 // Behavior of functions like "memcpy" or "strcpy" is undefined 59 // if memory intervals overlap. We report error in this case. 60 // Macro is used to avoid creation of new frames. 61 static inline bool RangesOverlap(const char *offset1, uptr length1, 62 const char *offset2, uptr length2) { 63 return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 64 } 65 #define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 66 const char *offset1 = (const char*)_offset1; \ 67 const char *offset2 = (const char*)_offset2; \ 68 if (RangesOverlap(offset1, length1, offset2, length2)) { \ 69 GET_STACK_TRACE_FATAL_HERE; \ 70 ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ 71 offset2, length2, &stack); \ 72 } \ 73 } while (0) 74 75 #define ENSURE_ASAN_INITED() do { \ 76 CHECK(!asan_init_is_running); \ 77 if (!asan_inited) { \ 78 __asan_init(); \ 79 } \ 80 } while (0) 81 82 static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) { 83 #if ASAN_INTERCEPT_STRNLEN 84 if (REAL(strnlen) != 0) { 85 return REAL(strnlen)(s, maxlen); 86 } 87 #endif 88 return internal_strnlen(s, maxlen); 89 } 90 91 void SetThreadName(const char *name) { 92 AsanThread *t = GetCurrentThread(); 93 if (t) 94 asanThreadRegistry().SetThreadName(t->tid(), name); 95 } 96 97 } // namespace __asan 98 99 // ---------------------- Wrappers ---------------- {{{1 100 using namespace __asan; // NOLINT 101 102 DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) 103 DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) 104 105 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \ 106 do { \ 107 } while (false) 108 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 109 ASAN_WRITE_RANGE(ptr, size) 110 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size) 111 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 112 do { \ 113 if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \ 114 ctx = 0; \ 115 (void) ctx; \ 116 ENSURE_ASAN_INITED(); \ 117 } while (false) 118 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 119 do { \ 120 } while (false) 121 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 122 do { \ 123 } while (false) 124 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 125 do { \ 126 } while (false) 127 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name) 128 #include "sanitizer_common/sanitizer_common_interceptors.inc" 129 130 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s) 131 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s) 132 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 133 do { \ 134 } while (false) 135 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \ 136 do { \ 137 } while (false) 138 #include "sanitizer_common/sanitizer_common_syscalls.inc" 139 140 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 141 AsanThread *t = (AsanThread*)arg; 142 SetCurrentThread(t); 143 return t->ThreadStart(GetTid()); 144 } 145 146 #if ASAN_INTERCEPT_PTHREAD_CREATE 147 extern "C" int pthread_attr_getdetachstate(void *attr, int *v); 148 149 INTERCEPTOR(int, pthread_create, void *thread, 150 void *attr, void *(*start_routine)(void*), void *arg) { 151 EnsureMainThreadIDIsCorrect(); 152 // Strict init-order checking in thread-hostile. 153 if (flags()->strict_init_order) 154 StopInitOrderChecking(); 155 GET_STACK_TRACE_THREAD; 156 int detached = 0; 157 if (attr != 0) 158 pthread_attr_getdetachstate(attr, &detached); 159 160 u32 current_tid = GetCurrentTidOrInvalid(); 161 AsanThread *t = AsanThread::Create(start_routine, arg); 162 CreateThreadContextArgs args = { t, &stack }; 163 asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 164 return REAL(pthread_create)(thread, attr, asan_thread_start, t); 165 } 166 #endif // ASAN_INTERCEPT_PTHREAD_CREATE 167 168 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 169 INTERCEPTOR(void*, signal, int signum, void *handler) { 170 if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 171 return REAL(signal)(signum, handler); 172 } 173 return 0; 174 } 175 176 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 177 struct sigaction *oldact) { 178 if (!AsanInterceptsSignal(signum) || flags()->allow_user_segv_handler) { 179 return REAL(sigaction)(signum, act, oldact); 180 } 181 return 0; 182 } 183 #elif SANITIZER_POSIX 184 // We need to have defined REAL(sigaction) on posix systems. 185 DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 186 struct sigaction *oldact) 187 #endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 188 189 #if ASAN_INTERCEPT_SWAPCONTEXT 190 static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) { 191 // Align to page size. 192 uptr PageSize = GetPageSizeCached(); 193 uptr bottom = stack & ~(PageSize - 1); 194 ssize += stack - bottom; 195 ssize = RoundUpTo(ssize, PageSize); 196 static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb 197 if (ssize && ssize <= kMaxSaneContextStackSize) { 198 PoisonShadow(bottom, ssize, 0); 199 } 200 } 201 202 INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp, 203 struct ucontext_t *ucp) { 204 static bool reported_warning = false; 205 if (!reported_warning) { 206 Report("WARNING: ASan doesn't fully support makecontext/swapcontext " 207 "functions and may produce false positives in some cases!\n"); 208 reported_warning = true; 209 } 210 // Clear shadow memory for new context (it may share stack 211 // with current context). 212 uptr stack, ssize; 213 ReadContextStack(ucp, &stack, &ssize); 214 ClearShadowMemoryForContextStack(stack, ssize); 215 int res = REAL(swapcontext)(oucp, ucp); 216 // swapcontext technically does not return, but program may swap context to 217 // "oucp" later, that would look as if swapcontext() returned 0. 218 // We need to clear shadow for ucp once again, as it may be in arbitrary 219 // state. 220 ClearShadowMemoryForContextStack(stack, ssize); 221 return res; 222 } 223 #endif // ASAN_INTERCEPT_SWAPCONTEXT 224 225 INTERCEPTOR(void, longjmp, void *env, int val) { 226 __asan_handle_no_return(); 227 REAL(longjmp)(env, val); 228 } 229 230 #if ASAN_INTERCEPT__LONGJMP 231 INTERCEPTOR(void, _longjmp, void *env, int val) { 232 __asan_handle_no_return(); 233 REAL(_longjmp)(env, val); 234 } 235 #endif 236 237 #if ASAN_INTERCEPT_SIGLONGJMP 238 INTERCEPTOR(void, siglongjmp, void *env, int val) { 239 __asan_handle_no_return(); 240 REAL(siglongjmp)(env, val); 241 } 242 #endif 243 244 #if ASAN_INTERCEPT___CXA_THROW 245 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 246 CHECK(REAL(__cxa_throw)); 247 __asan_handle_no_return(); 248 REAL(__cxa_throw)(a, b, c); 249 } 250 #endif 251 252 // intercept mlock and friends. 253 // Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 254 // All functions return 0 (success). 255 static void MlockIsUnsupported() { 256 static bool printed = false; 257 if (printed) return; 258 printed = true; 259 if (flags()->verbosity > 0) { 260 Printf("INFO: AddressSanitizer ignores " 261 "mlock/mlockall/munlock/munlockall\n"); 262 } 263 } 264 265 INTERCEPTOR(int, mlock, const void *addr, uptr len) { 266 MlockIsUnsupported(); 267 return 0; 268 } 269 270 INTERCEPTOR(int, munlock, const void *addr, uptr len) { 271 MlockIsUnsupported(); 272 return 0; 273 } 274 275 INTERCEPTOR(int, mlockall, int flags) { 276 MlockIsUnsupported(); 277 return 0; 278 } 279 280 INTERCEPTOR(int, munlockall, void) { 281 MlockIsUnsupported(); 282 return 0; 283 } 284 285 static inline int CharCmp(unsigned char c1, unsigned char c2) { 286 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 287 } 288 289 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 290 if (!asan_inited) return internal_memcmp(a1, a2, size); 291 ENSURE_ASAN_INITED(); 292 if (flags()->replace_intrin) { 293 if (flags()->strict_memcmp) { 294 // Check the entire regions even if the first bytes of the buffers are 295 // different. 296 ASAN_READ_RANGE(a1, size); 297 ASAN_READ_RANGE(a2, size); 298 // Fallthrough to REAL(memcmp) below. 299 } else { 300 unsigned char c1 = 0, c2 = 0; 301 const unsigned char *s1 = (const unsigned char*)a1; 302 const unsigned char *s2 = (const unsigned char*)a2; 303 uptr i; 304 for (i = 0; i < size; i++) { 305 c1 = s1[i]; 306 c2 = s2[i]; 307 if (c1 != c2) break; 308 } 309 ASAN_READ_RANGE(s1, Min(i + 1, size)); 310 ASAN_READ_RANGE(s2, Min(i + 1, size)); 311 return CharCmp(c1, c2); 312 } 313 } 314 return REAL(memcmp(a1, a2, size)); 315 } 316 317 INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { 318 if (!asan_inited) return internal_memcpy(to, from, size); 319 // memcpy is called during __asan_init() from the internals 320 // of printf(...). 321 if (asan_init_is_running) { 322 return REAL(memcpy)(to, from, size); 323 } 324 ENSURE_ASAN_INITED(); 325 if (flags()->replace_intrin) { 326 if (to != from) { 327 // We do not treat memcpy with to==from as a bug. 328 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 329 CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 330 } 331 ASAN_READ_RANGE(from, size); 332 ASAN_WRITE_RANGE(to, size); 333 } 334 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. 335 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 336 return internal_memcpy(to, from, size); 337 } 338 339 INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { 340 if (!asan_inited) return internal_memmove(to, from, size); 341 if (asan_init_is_running) { 342 return REAL(memmove)(to, from, size); 343 } 344 ENSURE_ASAN_INITED(); 345 if (flags()->replace_intrin) { 346 ASAN_READ_RANGE(from, size); 347 ASAN_WRITE_RANGE(to, size); 348 } 349 // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. 350 // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. 351 return internal_memmove(to, from, size); 352 } 353 354 INTERCEPTOR(void*, memset, void *block, int c, uptr size) { 355 if (!asan_inited) return internal_memset(block, c, size); 356 // memset is called inside Printf. 357 if (asan_init_is_running) { 358 return REAL(memset)(block, c, size); 359 } 360 ENSURE_ASAN_INITED(); 361 if (flags()->replace_intrin) { 362 ASAN_WRITE_RANGE(block, size); 363 } 364 return REAL(memset)(block, c, size); 365 } 366 367 INTERCEPTOR(char*, strchr, const char *str, int c) { 368 if (!asan_inited) return internal_strchr(str, c); 369 // strchr is called inside create_purgeable_zone() when MallocGuardEdges=1 is 370 // used. 371 if (asan_init_is_running) { 372 return REAL(strchr)(str, c); 373 } 374 ENSURE_ASAN_INITED(); 375 char *result = REAL(strchr)(str, c); 376 if (flags()->replace_str) { 377 uptr bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 378 ASAN_READ_RANGE(str, bytes_read); 379 } 380 return result; 381 } 382 383 #if ASAN_INTERCEPT_INDEX 384 # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 385 INTERCEPTOR(char*, index, const char *string, int c) 386 ALIAS(WRAPPER_NAME(strchr)); 387 # else 388 # if SANITIZER_MAC 389 DECLARE_REAL(char*, index, const char *string, int c) 390 OVERRIDE_FUNCTION(index, strchr); 391 # else 392 DEFINE_REAL(char*, index, const char *string, int c) 393 # endif 394 # endif 395 #endif // ASAN_INTERCEPT_INDEX 396 397 // For both strcat() and strncat() we need to check the validity of |to| 398 // argument irrespective of the |from| length. 399 INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 400 ENSURE_ASAN_INITED(); 401 if (flags()->replace_str) { 402 uptr from_length = REAL(strlen)(from); 403 ASAN_READ_RANGE(from, from_length + 1); 404 uptr to_length = REAL(strlen)(to); 405 ASAN_READ_RANGE(to, to_length); 406 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 407 // If the copying actually happens, the |from| string should not overlap 408 // with the resulting string starting at |to|, which has a length of 409 // to_length + from_length + 1. 410 if (from_length > 0) { 411 CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, 412 from, from_length + 1); 413 } 414 } 415 return REAL(strcat)(to, from); // NOLINT 416 } 417 418 INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { 419 ENSURE_ASAN_INITED(); 420 if (flags()->replace_str) { 421 uptr from_length = MaybeRealStrnlen(from, size); 422 uptr copy_length = Min(size, from_length + 1); 423 ASAN_READ_RANGE(from, copy_length); 424 uptr to_length = REAL(strlen)(to); 425 ASAN_READ_RANGE(to, to_length); 426 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 427 if (from_length > 0) { 428 CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1, 429 from, copy_length); 430 } 431 } 432 return REAL(strncat)(to, from, size); 433 } 434 435 INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 436 #if SANITIZER_MAC 437 if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT 438 #endif 439 // strcpy is called from malloc_default_purgeable_zone() 440 // in __asan::ReplaceSystemAlloc() on Mac. 441 if (asan_init_is_running) { 442 return REAL(strcpy)(to, from); // NOLINT 443 } 444 ENSURE_ASAN_INITED(); 445 if (flags()->replace_str) { 446 uptr from_size = REAL(strlen)(from) + 1; 447 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 448 ASAN_READ_RANGE(from, from_size); 449 ASAN_WRITE_RANGE(to, from_size); 450 } 451 return REAL(strcpy)(to, from); // NOLINT 452 } 453 454 #if ASAN_INTERCEPT_STRDUP 455 INTERCEPTOR(char*, strdup, const char *s) { 456 if (!asan_inited) return internal_strdup(s); 457 ENSURE_ASAN_INITED(); 458 uptr length = REAL(strlen)(s); 459 if (flags()->replace_str) { 460 ASAN_READ_RANGE(s, length + 1); 461 } 462 GET_STACK_TRACE_MALLOC; 463 void *new_mem = asan_malloc(length + 1, &stack); 464 REAL(memcpy)(new_mem, s, length + 1); 465 return reinterpret_cast<char*>(new_mem); 466 } 467 #endif 468 469 INTERCEPTOR(uptr, strlen, const char *s) { 470 if (!asan_inited) return internal_strlen(s); 471 // strlen is called from malloc_default_purgeable_zone() 472 // in __asan::ReplaceSystemAlloc() on Mac. 473 if (asan_init_is_running) { 474 return REAL(strlen)(s); 475 } 476 ENSURE_ASAN_INITED(); 477 uptr length = REAL(strlen)(s); 478 if (flags()->replace_str) { 479 ASAN_READ_RANGE(s, length + 1); 480 } 481 return length; 482 } 483 484 INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { 485 ENSURE_ASAN_INITED(); 486 if (flags()->replace_str) { 487 uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1); 488 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 489 ASAN_READ_RANGE(from, from_size); 490 ASAN_WRITE_RANGE(to, size); 491 } 492 return REAL(strncpy)(to, from, size); 493 } 494 495 #if ASAN_INTERCEPT_STRNLEN 496 INTERCEPTOR(uptr, strnlen, const char *s, uptr maxlen) { 497 ENSURE_ASAN_INITED(); 498 uptr length = REAL(strnlen)(s, maxlen); 499 if (flags()->replace_str) { 500 ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 501 } 502 return length; 503 } 504 #endif // ASAN_INTERCEPT_STRNLEN 505 506 static inline bool IsValidStrtolBase(int base) { 507 return (base == 0) || (2 <= base && base <= 36); 508 } 509 510 static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 511 CHECK(endptr); 512 if (nptr == *endptr) { 513 // No digits were found at strtol call, we need to find out the last 514 // symbol accessed by strtoll on our own. 515 // We get this symbol by skipping leading blanks and optional +/- sign. 516 while (IsSpace(*nptr)) nptr++; 517 if (*nptr == '+' || *nptr == '-') nptr++; 518 *endptr = (char*)nptr; 519 } 520 CHECK(*endptr >= nptr); 521 } 522 523 INTERCEPTOR(long, strtol, const char *nptr, // NOLINT 524 char **endptr, int base) { 525 ENSURE_ASAN_INITED(); 526 if (!flags()->replace_str) { 527 return REAL(strtol)(nptr, endptr, base); 528 } 529 char *real_endptr; 530 long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT 531 if (endptr != 0) { 532 *endptr = real_endptr; 533 } 534 if (IsValidStrtolBase(base)) { 535 FixRealStrtolEndptr(nptr, &real_endptr); 536 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 537 } 538 return result; 539 } 540 541 INTERCEPTOR(int, atoi, const char *nptr) { 542 #if SANITIZER_MAC 543 if (!asan_inited) return REAL(atoi)(nptr); 544 #endif 545 ENSURE_ASAN_INITED(); 546 if (!flags()->replace_str) { 547 return REAL(atoi)(nptr); 548 } 549 char *real_endptr; 550 // "man atoi" tells that behavior of atoi(nptr) is the same as 551 // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the 552 // parsed integer can't be stored in *long* type (even if it's 553 // different from int). So, we just imitate this behavior. 554 int result = REAL(strtol)(nptr, &real_endptr, 10); 555 FixRealStrtolEndptr(nptr, &real_endptr); 556 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 557 return result; 558 } 559 560 INTERCEPTOR(long, atol, const char *nptr) { // NOLINT 561 #if SANITIZER_MAC 562 if (!asan_inited) return REAL(atol)(nptr); 563 #endif 564 ENSURE_ASAN_INITED(); 565 if (!flags()->replace_str) { 566 return REAL(atol)(nptr); 567 } 568 char *real_endptr; 569 long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT 570 FixRealStrtolEndptr(nptr, &real_endptr); 571 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 572 return result; 573 } 574 575 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 576 INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT 577 char **endptr, int base) { 578 ENSURE_ASAN_INITED(); 579 if (!flags()->replace_str) { 580 return REAL(strtoll)(nptr, endptr, base); 581 } 582 char *real_endptr; 583 long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT 584 if (endptr != 0) { 585 *endptr = real_endptr; 586 } 587 // If base has unsupported value, strtoll can exit with EINVAL 588 // without reading any characters. So do additional checks only 589 // if base is valid. 590 if (IsValidStrtolBase(base)) { 591 FixRealStrtolEndptr(nptr, &real_endptr); 592 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 593 } 594 return result; 595 } 596 597 INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT 598 ENSURE_ASAN_INITED(); 599 if (!flags()->replace_str) { 600 return REAL(atoll)(nptr); 601 } 602 char *real_endptr; 603 long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT 604 FixRealStrtolEndptr(nptr, &real_endptr); 605 ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1); 606 return result; 607 } 608 #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL 609 610 static void AtCxaAtexit(void *unused) { 611 (void)unused; 612 StopInitOrderChecking(); 613 } 614 615 #if ASAN_INTERCEPT___CXA_ATEXIT 616 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 617 void *dso_handle) { 618 ENSURE_ASAN_INITED(); 619 int res = REAL(__cxa_atexit)(func, arg, dso_handle); 620 REAL(__cxa_atexit)(AtCxaAtexit, 0, 0); 621 return res; 622 } 623 #endif // ASAN_INTERCEPT___CXA_ATEXIT 624 625 #if !SANITIZER_MAC 626 #define ASAN_INTERCEPT_FUNC(name) do { \ 627 if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ 628 Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ 629 } while (0) 630 #else 631 // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. 632 #define ASAN_INTERCEPT_FUNC(name) 633 #endif // SANITIZER_MAC 634 635 #if SANITIZER_WINDOWS 636 INTERCEPTOR_WINAPI(DWORD, CreateThread, 637 void* security, uptr stack_size, 638 DWORD (__stdcall *start_routine)(void*), void* arg, 639 DWORD thr_flags, void* tid) { 640 // Strict init-order checking in thread-hostile. 641 if (flags()->strict_init_order) 642 StopInitOrderChecking(); 643 GET_STACK_TRACE_THREAD; 644 u32 current_tid = GetCurrentTidOrInvalid(); 645 AsanThread *t = AsanThread::Create(start_routine, arg); 646 CreateThreadContextArgs args = { t, &stack }; 647 bool detached = false; // FIXME: how can we determine it on Windows? 648 asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); 649 return REAL(CreateThread)(security, stack_size, 650 asan_thread_start, t, thr_flags, tid); 651 } 652 653 namespace __asan { 654 void InitializeWindowsInterceptors() { 655 ASAN_INTERCEPT_FUNC(CreateThread); 656 } 657 658 } // namespace __asan 659 #endif 660 661 // ---------------------- InitializeAsanInterceptors ---------------- {{{1 662 namespace __asan { 663 void InitializeAsanInterceptors() { 664 static bool was_called_once; 665 CHECK(was_called_once == false); 666 was_called_once = true; 667 SANITIZER_COMMON_INTERCEPTORS_INIT; 668 669 // Intercept mem* functions. 670 ASAN_INTERCEPT_FUNC(memcmp); 671 ASAN_INTERCEPT_FUNC(memmove); 672 ASAN_INTERCEPT_FUNC(memset); 673 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 674 ASAN_INTERCEPT_FUNC(memcpy); 675 } 676 677 // Intercept str* functions. 678 ASAN_INTERCEPT_FUNC(strcat); // NOLINT 679 ASAN_INTERCEPT_FUNC(strchr); 680 ASAN_INTERCEPT_FUNC(strcpy); // NOLINT 681 ASAN_INTERCEPT_FUNC(strlen); 682 ASAN_INTERCEPT_FUNC(strncat); 683 ASAN_INTERCEPT_FUNC(strncpy); 684 #if ASAN_INTERCEPT_STRDUP 685 ASAN_INTERCEPT_FUNC(strdup); 686 #endif 687 #if ASAN_INTERCEPT_STRNLEN 688 ASAN_INTERCEPT_FUNC(strnlen); 689 #endif 690 #if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 691 ASAN_INTERCEPT_FUNC(index); 692 #endif 693 694 ASAN_INTERCEPT_FUNC(atoi); 695 ASAN_INTERCEPT_FUNC(atol); 696 ASAN_INTERCEPT_FUNC(strtol); 697 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL 698 ASAN_INTERCEPT_FUNC(atoll); 699 ASAN_INTERCEPT_FUNC(strtoll); 700 #endif 701 702 #if ASAN_INTERCEPT_MLOCKX 703 // Intercept mlock/munlock. 704 ASAN_INTERCEPT_FUNC(mlock); 705 ASAN_INTERCEPT_FUNC(munlock); 706 ASAN_INTERCEPT_FUNC(mlockall); 707 ASAN_INTERCEPT_FUNC(munlockall); 708 #endif 709 710 // Intecept signal- and jump-related functions. 711 ASAN_INTERCEPT_FUNC(longjmp); 712 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 713 ASAN_INTERCEPT_FUNC(sigaction); 714 ASAN_INTERCEPT_FUNC(signal); 715 #endif 716 #if ASAN_INTERCEPT_SWAPCONTEXT 717 ASAN_INTERCEPT_FUNC(swapcontext); 718 #endif 719 #if ASAN_INTERCEPT__LONGJMP 720 ASAN_INTERCEPT_FUNC(_longjmp); 721 #endif 722 #if ASAN_INTERCEPT_SIGLONGJMP 723 ASAN_INTERCEPT_FUNC(siglongjmp); 724 #endif 725 726 // Intercept exception handling functions. 727 #if ASAN_INTERCEPT___CXA_THROW 728 INTERCEPT_FUNCTION(__cxa_throw); 729 #endif 730 731 // Intercept threading-related functions 732 #if ASAN_INTERCEPT_PTHREAD_CREATE 733 ASAN_INTERCEPT_FUNC(pthread_create); 734 #endif 735 736 // Intercept atexit function. 737 #if ASAN_INTERCEPT___CXA_ATEXIT 738 ASAN_INTERCEPT_FUNC(__cxa_atexit); 739 #endif 740 741 // Some Windows-specific interceptors. 742 #if SANITIZER_WINDOWS 743 InitializeWindowsInterceptors(); 744 #endif 745 746 if (flags()->verbosity > 0) { 747 Report("AddressSanitizer: libc interceptors initialized\n"); 748 } 749 } 750 751 } // namespace __asan 752