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