asan_interceptors.cc revision 73fe35fa6b4c437c9a723eb7bbad4863c7edbe1e
1//===-- asan_interceptors.cc ------------------------------------*- C++ -*-===// 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_interface.h" 18#include "asan_internal.h" 19#include "asan_mapping.h" 20#include "asan_stack.h" 21#include "asan_stats.h" 22#include "asan_thread_registry.h" 23#include "interception/interception.h" 24 25#include <new> 26 27#if defined(__APPLE__) 28// FIXME(samsonov): Gradually replace system headers with declarations of 29// intercepted functions. 30#include <pthread.h> 31#include <string.h> 32#include <strings.h> 33#endif // __APPLE__ 34 35#if defined(__APPLE__) 36extern "C" { 37// signal.h 38struct sigaction; 39int sigaction(int sig, const struct sigaction *act, 40 struct sigaction *oldact); 41void *signal(int signum, void *handler); 42// setjmp.h 43void longjmp(void* env, int val); 44void _longjmp(void *env, int val); 45} // extern "C" 46#endif // __APPLE__ 47 48#if defined(_WIN32) && !defined(_DLL) 49// FIXME: We might want to use these on Mac too. 50extern "C" { 51int memcmp(const void *b1, const void *b2, size_t sz); 52void* memmove(void *d, const void *s, size_t sz); 53void* memcpy(void *d, const void *s, size_t sz); 54void* memset(void *b, int c, size_t sz); 55 56char* strchr(const char *s, char c); 57char* strcat(char *d, const char* s); // NOLINT 58char* strncat(char *d, const char* s, size_t sz); 59char* strcpy(char *d, const char* s); // NOLINT 60char* strncpy(char *d, const char* s, size_t sz); 61int strcmp(const char *s1, const char* s2); 62int strncmp(const char *s1, const char* s2, size_t sz); 63size_t strnlen(const char *s1, size_t sz); 64 65void longjmp(void* env, int value); 66 67__declspec(dllimport) 68void* __stdcall CreateThread(void *sec, size_t st, void* start, 69 void *arg, DWORD fl, DWORD *id); 70} // extern "C" 71#endif 72 73namespace __asan { 74 75// Instruments read/write access to a single byte in memory. 76// On error calls __asan_report_error, which aborts the program. 77#define ACCESS_ADDRESS(address, isWrite) do { \ 78 if (AddressIsPoisoned(address)) { \ 79 GET_CURRENT_PC_BP_SP; \ 80 __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \ 81 } \ 82} while (0) 83 84// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE, 85// and ASAN_WRITE_RANGE as macro instead of function so 86// that no extra frames are created, and stack trace contains 87// relevant information only. 88 89// Instruments read/write access to a memory range. 90// More complex implementation is possible, for now just 91// checking the first and the last byte of a range. 92#define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \ 93 if (size > 0) { \ 94 uintptr_t ptr = (uintptr_t)(offset); \ 95 ACCESS_ADDRESS(ptr, isWrite); \ 96 ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \ 97 } \ 98} while (0) 99 100#define ASAN_READ_RANGE(offset, size) do { \ 101 ACCESS_MEMORY_RANGE(offset, size, false); \ 102} while (0) 103 104#define ASAN_WRITE_RANGE(offset, size) do { \ 105 ACCESS_MEMORY_RANGE(offset, size, true); \ 106} while (0) 107 108// Behavior of functions like "memcpy" or "strcpy" is undefined 109// if memory intervals overlap. We report error in this case. 110// Macro is used to avoid creation of new frames. 111static inline bool RangesOverlap(const char *offset1, size_t length1, 112 const char *offset2, size_t length2) { 113 return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); 114} 115#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ 116 const char *offset1 = (const char*)_offset1; \ 117 const char *offset2 = (const char*)_offset2; \ 118 if (RangesOverlap(offset1, length1, offset2, length2)) { \ 119 Report("ERROR: AddressSanitizer %s-param-overlap: " \ 120 "memory ranges [%p,%p) and [%p, %p) overlap\n", \ 121 name, offset1, offset1 + length1, offset2, offset2 + length2); \ 122 PRINT_CURRENT_STACK(); \ 123 ShowStatsAndAbort(); \ 124 } \ 125} while (0) 126 127#define ENSURE_ASAN_INITED() do { \ 128 CHECK(!asan_init_is_running); \ 129 if (!asan_inited) { \ 130 __asan_init(); \ 131 } \ 132} while (0) 133 134static inline bool IsSpace(int c) { 135 return (c == ' ') || (c == '\n') || (c == '\t') || 136 (c == '\f') || (c == '\r') || (c == '\v'); 137} 138 139static inline bool IsDigit(int c) { 140 return (c >= '0') && (c <= '9'); 141} 142 143static inline int ToLower(int c) { 144 return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c; 145} 146 147// ---------------------- Internal string functions ---------------- {{{1 148 149int64_t internal_simple_strtoll(const char *nptr, char **endptr, int base) { 150 CHECK(base == 10); 151 while (IsSpace(*nptr)) nptr++; 152 int sgn = 1; 153 uint64_t res = 0; 154 bool have_digits = false; 155 char *old_nptr = (char*)nptr; 156 if (*nptr == '+') { 157 sgn = 1; 158 nptr++; 159 } else if (*nptr == '-') { 160 sgn = -1; 161 nptr++; 162 } 163 while (IsDigit(*nptr)) { 164 res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX; 165 int digit = ((*nptr) - '0'); 166 res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX; 167 have_digits = true; 168 nptr++; 169 } 170 if (endptr != NULL) { 171 *endptr = (have_digits) ? (char*)nptr : old_nptr; 172 } 173 if (sgn > 0) { 174 return (int64_t)(Min((uint64_t)INT64_MAX, res)); 175 } else { 176 return (res > INT64_MAX) ? INT64_MIN : ((int64_t)res * -1); 177 } 178} 179 180int64_t internal_atoll(const char *nptr) { 181 return internal_simple_strtoll(nptr, (char**)NULL, 10); 182} 183 184size_t internal_strlen(const char *s) { 185 size_t i = 0; 186 while (s[i]) i++; 187 return i; 188} 189 190size_t internal_strnlen(const char *s, size_t maxlen) { 191#ifndef __APPLE__ 192 if (REAL(strnlen) != NULL) { 193 return REAL(strnlen)(s, maxlen); 194 } 195#endif 196 size_t i = 0; 197 while (i < maxlen && s[i]) i++; 198 return i; 199} 200 201char* internal_strchr(const char *s, int c) { 202 while (true) { 203 if (*s == (char)c) 204 return (char*)s; 205 if (*s == 0) 206 return NULL; 207 s++; 208 } 209} 210 211void* internal_memchr(const void* s, int c, size_t n) { 212 const char* t = (char*)s; 213 for (size_t i = 0; i < n; ++i, ++t) 214 if (*t == c) 215 return (void*)t; 216 return NULL; 217} 218 219int internal_memcmp(const void* s1, const void* s2, size_t n) { 220 const char* t1 = (char*)s1; 221 const char* t2 = (char*)s2; 222 for (size_t i = 0; i < n; ++i, ++t1, ++t2) 223 if (*t1 != *t2) 224 return *t1 < *t2 ? -1 : 1; 225 return 0; 226} 227 228char *internal_strstr(const char *haystack, const char *needle) { 229 // This is O(N^2), but we are not using it in hot places. 230 size_t len1 = internal_strlen(haystack); 231 size_t len2 = internal_strlen(needle); 232 if (len1 < len2) return 0; 233 for (size_t pos = 0; pos <= len1 - len2; pos++) { 234 if (internal_memcmp(haystack + pos, needle, len2) == 0) 235 return (char*)haystack + pos; 236 } 237 return 0; 238} 239 240char *internal_strncat(char *dst, const char *src, size_t n) { 241 size_t len = internal_strlen(dst); 242 size_t i; 243 for (i = 0; i < n && src[i]; i++) 244 dst[len + i] = src[i]; 245 dst[len + i] = 0; 246 return dst; 247} 248 249int internal_strcmp(const char *s1, const char *s2) { 250 while (true) { 251 unsigned c1 = *s1; 252 unsigned c2 = *s2; 253 if (c1 != c2) return (c1 < c2) ? -1 : 1; 254 if (c1 == 0) break; 255 s1++; 256 s2++; 257 } 258 return 0; 259} 260 261char *internal_strncpy(char *dst, const char *src, size_t n) { 262 size_t i; 263 for (i = 0; i < n && src[i]; i++) 264 dst[i] = src[i]; 265 return dst; 266} 267 268} // namespace __asan 269 270// ---------------------- Wrappers ---------------- {{{1 271using namespace __asan; // NOLINT 272 273#define OPERATOR_NEW_BODY \ 274 GET_STACK_TRACE_HERE_FOR_MALLOC;\ 275 return asan_memalign(0, size, &stack); 276 277#ifdef ANDROID 278void *operator new(size_t size) { OPERATOR_NEW_BODY; } 279void *operator new[](size_t size) { OPERATOR_NEW_BODY; } 280#else 281void *operator new(size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 282void *operator new[](size_t size) throw(std::bad_alloc) { OPERATOR_NEW_BODY; } 283void *operator new(size_t size, std::nothrow_t const&) throw() 284{ OPERATOR_NEW_BODY; } 285void *operator new[](size_t size, std::nothrow_t const&) throw() 286{ OPERATOR_NEW_BODY; } 287#endif 288 289#define OPERATOR_DELETE_BODY \ 290 GET_STACK_TRACE_HERE_FOR_FREE(ptr);\ 291 asan_free(ptr, &stack); 292 293void operator delete(void *ptr) throw() { OPERATOR_DELETE_BODY; } 294void operator delete[](void *ptr) throw() { OPERATOR_DELETE_BODY; } 295void operator delete(void *ptr, std::nothrow_t const&) throw() 296{ OPERATOR_DELETE_BODY; } 297void operator delete[](void *ptr, std::nothrow_t const&) throw() 298{ OPERATOR_DELETE_BODY;} 299 300static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { 301 AsanThread *t = (AsanThread*)arg; 302 asanThreadRegistry().SetCurrent(t); 303 return t->ThreadStart(); 304} 305 306#ifndef _WIN32 307INTERCEPTOR(int, pthread_create, void *thread, 308 void *attr, void *(*start_routine)(void*), void *arg) { 309 GET_STACK_TRACE_HERE(kStackTraceMax); 310 int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 311 AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 312 asanThreadRegistry().RegisterThread(t); 313 return REAL(pthread_create)(thread, attr, asan_thread_start, t); 314} 315#endif // !_WIN32 316 317#if !defined(ANDROID) && !defined(_WIN32) 318INTERCEPTOR(void*, signal, int signum, void *handler) { 319 if (!AsanInterceptsSignal(signum)) { 320 return REAL(signal)(signum, handler); 321 } 322 return NULL; 323} 324 325INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, 326 struct sigaction *oldact) { 327 if (!AsanInterceptsSignal(signum)) { 328 return REAL(sigaction)(signum, act, oldact); 329 } 330 return 0; 331} 332#endif // !ANDROID && !_WIN32 333 334INTERCEPTOR(void, longjmp, void *env, int val) { 335 __asan_handle_no_return(); 336 REAL(longjmp)(env, val); 337} 338 339#if !defined(_WIN32) 340INTERCEPTOR(void, _longjmp, void *env, int val) { 341 __asan_handle_no_return(); 342 REAL(_longjmp)(env, val); 343} 344 345INTERCEPTOR(void, siglongjmp, void *env, int val) { 346 __asan_handle_no_return(); 347 REAL(siglongjmp)(env, val); 348} 349#endif 350 351#if ASAN_HAS_EXCEPTIONS == 1 352#ifdef __APPLE__ 353extern "C" void __cxa_throw(void *a, void *b, void *c); 354#endif // __APPLE__ 355 356INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { 357 CHECK(REAL(__cxa_throw)); 358 __asan_handle_no_return(); 359 REAL(__cxa_throw)(a, b, c); 360} 361#endif 362 363// intercept mlock and friends. 364// Since asan maps 16T of RAM, mlock is completely unfriendly to asan. 365// All functions return 0 (success). 366static void MlockIsUnsupported() { 367 static bool printed = 0; 368 if (printed) return; 369 printed = true; 370 Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); 371} 372 373extern "C" { 374INTERCEPTOR_ATTRIBUTE 375int mlock(const void *addr, size_t len) { 376 MlockIsUnsupported(); 377 return 0; 378} 379 380INTERCEPTOR_ATTRIBUTE 381int munlock(const void *addr, size_t len) { 382 MlockIsUnsupported(); 383 return 0; 384} 385 386INTERCEPTOR_ATTRIBUTE 387int mlockall(int flags) { 388 MlockIsUnsupported(); 389 return 0; 390} 391 392INTERCEPTOR_ATTRIBUTE 393int munlockall(void) { 394 MlockIsUnsupported(); 395 return 0; 396} 397} // extern "C" 398 399static inline int CharCmp(unsigned char c1, unsigned char c2) { 400 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 401} 402 403static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 404 int c1_low = ToLower(c1); 405 int c2_low = ToLower(c2); 406 return c1_low - c2_low; 407} 408 409INTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) { 410 ENSURE_ASAN_INITED(); 411 unsigned char c1 = 0, c2 = 0; 412 const unsigned char *s1 = (const unsigned char*)a1; 413 const unsigned char *s2 = (const unsigned char*)a2; 414 size_t i; 415 for (i = 0; i < size; i++) { 416 c1 = s1[i]; 417 c2 = s2[i]; 418 if (c1 != c2) break; 419 } 420 ASAN_READ_RANGE(s1, Min(i + 1, size)); 421 ASAN_READ_RANGE(s2, Min(i + 1, size)); 422 return CharCmp(c1, c2); 423} 424 425INTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) { 426 // memcpy is called during __asan_init() from the internals 427 // of printf(...). 428 if (asan_init_is_running) { 429 return REAL(memcpy)(to, from, size); 430 } 431 ENSURE_ASAN_INITED(); 432 if (FLAG_replace_intrin) { 433 if (to != from) { 434 // We do not treat memcpy with to==from as a bug. 435 // See http://llvm.org/bugs/show_bug.cgi?id=11763. 436 CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); 437 } 438 ASAN_WRITE_RANGE(from, size); 439 ASAN_READ_RANGE(to, size); 440 } 441 return REAL(memcpy)(to, from, size); 442} 443 444INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) { 445 ENSURE_ASAN_INITED(); 446 if (FLAG_replace_intrin) { 447 ASAN_WRITE_RANGE(from, size); 448 ASAN_READ_RANGE(to, size); 449 } 450 return REAL(memmove)(to, from, size); 451} 452 453INTERCEPTOR(void*, memset, void *block, int c, size_t size) { 454 // memset is called inside INTERCEPT_FUNCTION on Mac. 455 if (asan_init_is_running) { 456 return REAL(memset)(block, c, size); 457 } 458 ENSURE_ASAN_INITED(); 459 if (FLAG_replace_intrin) { 460 ASAN_WRITE_RANGE(block, size); 461 } 462 return REAL(memset)(block, c, size); 463} 464 465INTERCEPTOR(char*, strchr, const char *str, int c) { 466 ENSURE_ASAN_INITED(); 467 char *result = REAL(strchr)(str, c); 468 if (FLAG_replace_str) { 469 size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1; 470 ASAN_READ_RANGE(str, bytes_read); 471 } 472 return result; 473} 474 475#ifdef __linux__ 476INTERCEPTOR(char*, index, const char *string, int c) 477 ALIAS(WRAPPER_NAME(strchr)); 478#else 479DEFINE_REAL(char*, index, const char *string, int c); 480#endif 481 482#ifdef ANDROID 483DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, 484 struct sigaction *oldact); 485#endif 486 487INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 488 ENSURE_ASAN_INITED(); 489 unsigned char c1, c2; 490 size_t i; 491 for (i = 0; ; i++) { 492 c1 = (unsigned char)s1[i]; 493 c2 = (unsigned char)s2[i]; 494 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 495 } 496 ASAN_READ_RANGE(s1, i + 1); 497 ASAN_READ_RANGE(s2, i + 1); 498 return CharCaseCmp(c1, c2); 499} 500 501INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT 502 ENSURE_ASAN_INITED(); 503 if (FLAG_replace_str) { 504 size_t from_length = REAL(strlen)(from); 505 ASAN_READ_RANGE(from, from_length + 1); 506 if (from_length > 0) { 507 size_t to_length = REAL(strlen)(to); 508 ASAN_READ_RANGE(to, to_length); 509 ASAN_WRITE_RANGE(to + to_length, from_length + 1); 510 CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1); 511 } 512 } 513 return REAL(strcat)(to, from); // NOLINT 514} 515 516INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 517 if (!asan_inited) { 518 return internal_strcmp(s1, s2); 519 } 520 unsigned char c1, c2; 521 size_t i; 522 for (i = 0; ; i++) { 523 c1 = (unsigned char)s1[i]; 524 c2 = (unsigned char)s2[i]; 525 if (c1 != c2 || c1 == '\0') break; 526 } 527 ASAN_READ_RANGE(s1, i + 1); 528 ASAN_READ_RANGE(s2, i + 1); 529 return CharCmp(c1, c2); 530} 531 532INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT 533 // strcpy is called from malloc_default_purgeable_zone() 534 // in __asan::ReplaceSystemAlloc() on Mac. 535 if (asan_init_is_running) { 536 return REAL(strcpy)(to, from); // NOLINT 537 } 538 ENSURE_ASAN_INITED(); 539 if (FLAG_replace_str) { 540 size_t from_size = REAL(strlen)(from) + 1; 541 CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size); 542 ASAN_READ_RANGE(from, from_size); 543 ASAN_WRITE_RANGE(to, from_size); 544 } 545 return REAL(strcpy)(to, from); // NOLINT 546} 547 548INTERCEPTOR(char*, strdup, const char *s) { 549 ENSURE_ASAN_INITED(); 550 if (FLAG_replace_str) { 551 size_t length = REAL(strlen)(s); 552 ASAN_READ_RANGE(s, length + 1); 553 } 554 return REAL(strdup)(s); 555} 556 557INTERCEPTOR(size_t, strlen, const char *s) { 558 // strlen is called from malloc_default_purgeable_zone() 559 // in __asan::ReplaceSystemAlloc() on Mac. 560 if (asan_init_is_running) { 561 return REAL(strlen)(s); 562 } 563 ENSURE_ASAN_INITED(); 564 size_t length = REAL(strlen)(s); 565 if (FLAG_replace_str) { 566 ASAN_READ_RANGE(s, length + 1); 567 } 568 return length; 569} 570 571INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) { 572 ENSURE_ASAN_INITED(); 573 unsigned char c1 = 0, c2 = 0; 574 size_t i; 575 for (i = 0; i < n; i++) { 576 c1 = (unsigned char)s1[i]; 577 c2 = (unsigned char)s2[i]; 578 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 579 } 580 ASAN_READ_RANGE(s1, Min(i + 1, n)); 581 ASAN_READ_RANGE(s2, Min(i + 1, n)); 582 return CharCaseCmp(c1, c2); 583} 584 585INTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) { 586 // strncmp is called from malloc_default_purgeable_zone() 587 // in __asan::ReplaceSystemAlloc() on Mac. 588 if (asan_init_is_running) { 589 return REAL(strncmp)(s1, s2, size); 590 } 591 unsigned char c1 = 0, c2 = 0; 592 size_t i; 593 for (i = 0; i < size; i++) { 594 c1 = (unsigned char)s1[i]; 595 c2 = (unsigned char)s2[i]; 596 if (c1 != c2 || c1 == '\0') break; 597 } 598 ASAN_READ_RANGE(s1, Min(i + 1, size)); 599 ASAN_READ_RANGE(s2, Min(i + 1, size)); 600 return CharCmp(c1, c2); 601} 602 603INTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) { 604 ENSURE_ASAN_INITED(); 605 if (FLAG_replace_str) { 606 size_t from_size = Min(size, internal_strnlen(from, size) + 1); 607 CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size); 608 ASAN_READ_RANGE(from, from_size); 609 ASAN_WRITE_RANGE(to, size); 610 } 611 return REAL(strncpy)(to, from, size); 612} 613 614#ifndef __APPLE__ 615INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) { 616 ENSURE_ASAN_INITED(); 617 size_t length = REAL(strnlen)(s, maxlen); 618 if (FLAG_replace_str) { 619 ASAN_READ_RANGE(s, Min(length + 1, maxlen)); 620 } 621 return length; 622} 623#endif 624 625#if defined(_WIN32) 626INTERCEPTOR_WINAPI(DWORD, CreateThread, 627 void* security, size_t stack_size, 628 DWORD (__stdcall *start_routine)(void*), void* arg, 629 DWORD flags, void* tid) { 630 GET_STACK_TRACE_HERE(kStackTraceMax); 631 int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne(); 632 AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack); 633 asanThreadRegistry().RegisterThread(t); 634 return REAL(CreateThread)(security, stack_size, 635 asan_thread_start, t, flags, tid); 636} 637 638namespace __asan { 639void InitializeWindowsInterceptors() { 640 CHECK(INTERCEPT_FUNCTION(CreateThread)); 641} 642 643} // namespace __asan 644#endif 645 646// ---------------------- InitializeAsanInterceptors ---------------- {{{1 647namespace __asan { 648void InitializeAsanInterceptors() { 649 static bool was_called_once; 650 CHECK(was_called_once == false); 651 was_called_once = true; 652 // Intercept mem* functions. 653 CHECK(INTERCEPT_FUNCTION(memcmp)); 654 CHECK(INTERCEPT_FUNCTION(memmove)); 655 CHECK(INTERCEPT_FUNCTION(memset)); 656 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 657 CHECK(INTERCEPT_FUNCTION(memcpy)); 658 } else { 659 REAL(memcpy) = REAL(memmove); 660 } 661 662 // Intercept str* functions. 663 CHECK(INTERCEPT_FUNCTION(strcat)); // NOLINT 664 CHECK(INTERCEPT_FUNCTION(strchr)); 665 CHECK(INTERCEPT_FUNCTION(strcmp)); 666 CHECK(INTERCEPT_FUNCTION(strcpy)); // NOLINT 667 CHECK(INTERCEPT_FUNCTION(strlen)); 668 CHECK(INTERCEPT_FUNCTION(strncmp)); 669 CHECK(INTERCEPT_FUNCTION(strncpy)); 670#if !defined(_WIN32) 671 CHECK(INTERCEPT_FUNCTION(strcasecmp)); 672 CHECK(INTERCEPT_FUNCTION(strdup)); 673 CHECK(INTERCEPT_FUNCTION(strncasecmp)); 674# ifndef __APPLE__ 675 CHECK(INTERCEPT_FUNCTION(index)); 676# else 677 CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr))); 678# endif 679#endif 680#if !defined(__APPLE__) 681 CHECK(INTERCEPT_FUNCTION(strnlen)); 682#endif 683 684 // Intecept signal- and jump-related functions. 685 CHECK(INTERCEPT_FUNCTION(longjmp)); 686#if !defined(ANDROID) && !defined(_WIN32) 687 CHECK(INTERCEPT_FUNCTION(sigaction)); 688 CHECK(INTERCEPT_FUNCTION(signal)); 689#endif 690 691#if !defined(_WIN32) 692 CHECK(INTERCEPT_FUNCTION(_longjmp)); 693 INTERCEPT_FUNCTION(__cxa_throw); 694# if !defined(__APPLE__) 695 // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it 696 // there. 697 CHECK(INTERCEPT_FUNCTION(siglongjmp)); 698# endif 699#endif 700 701 // Intercept threading-related functions 702#if !defined(_WIN32) 703 CHECK(INTERCEPT_FUNCTION(pthread_create)); 704#endif 705 706 // Some Windows-specific interceptors. 707#if defined(_WIN32) 708 InitializeWindowsInterceptors(); 709#endif 710 711 // Some Mac-specific interceptors. 712#if defined(__APPLE__) 713 InitializeMacInterceptors(); 714#endif 715 716 if (FLAG_v > 0) { 717 Report("AddressSanitizer: libc interceptors initialized\n"); 718 } 719} 720 721} // namespace __asan 722