Home | History | Annotate | Download | only in asan
      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 // Use macro to describe if specific function should be
     26 // intercepted on a given platform.
     27 #if !defined(_WIN32)
     28 # define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1
     29 #else
     30 # define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
     31 #endif
     32 
     33 #if !defined(__APPLE__)
     34 # define ASAN_INTERCEPT_STRNLEN 1
     35 #else
     36 # define ASAN_INTERCEPT_STRNLEN 0
     37 #endif
     38 
     39 #if defined(ANDROID) || defined(_WIN32)
     40 # define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 0
     41 #else
     42 # define ASAN_INTERCEPT_SIGNAL_AND_SIGACTION 1
     43 #endif
     44 
     45 // Use extern declarations of intercepted functions on Mac and Windows
     46 // to avoid including system headers.
     47 #if defined(__APPLE__) || (defined(_WIN32) && !defined(_DLL))
     48 extern "C" {
     49 // signal.h
     50 # if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
     51 struct sigaction;
     52 int sigaction(int sig, const struct sigaction *act,
     53               struct sigaction *oldact);
     54 void *signal(int signum, void *handler);
     55 # endif
     56 
     57 // setjmp.h
     58 void longjmp(void* env, int value);
     59 # if !defined(_WIN32)
     60 void _longjmp(void *env, int value);
     61 # endif
     62 
     63 // string.h / strings.h
     64 int memcmp(const void *a1, const void *a2, size_t size);
     65 void* memmove(void *to, const void *from, size_t size);
     66 void* memcpy(void *to, const void *from, size_t size);
     67 void* memset(void *block, int c, size_t size);
     68 char* strchr(const char *str, int c);
     69 # if defined(__APPLE__)
     70 char* index(const char *string, int c);
     71 # endif
     72 char* strcat(char *to, const char* from);  // NOLINT
     73 char* strcpy(char *to, const char* from);  // NOLINT
     74 char* strncpy(char *to, const char* from, size_t size);
     75 int strcmp(const char *s1, const char* s2);
     76 int strncmp(const char *s1, const char* s2, size_t size);
     77 # if !defined(_WIN32)
     78 int strcasecmp(const char *s1, const char *s2);
     79 int strncasecmp(const char *s1, const char *s2, size_t n);
     80 char* strdup(const char *s);
     81 # endif
     82 size_t strlen(const char *s);
     83 # if ASAN_INTERCEPT_STRNLEN
     84 size_t strnlen(const char *s, size_t maxlen);
     85 # endif
     86 
     87 // stdlib.h
     88 int atoi(const char *nptr);
     89 long atol(const char *nptr);  // NOLINT
     90 long strtol(const char *nptr, char **endptr, int base);  // NOLINT
     91 # if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
     92 long long atoll(const char *nptr);  // NOLINT
     93 long long strtoll(const char *nptr, char **endptr, int base);  // NOLINT
     94 # endif
     95 
     96 // Windows threads.
     97 # if defined(_WIN32)
     98 __declspec(dllimport)
     99 void* __stdcall CreateThread(void *sec, size_t st, void* start,
    100                              void *arg, DWORD fl, DWORD *id);
    101 # endif
    102 
    103 // Posix threads.
    104 # if !defined(_WIN32)
    105 int pthread_create(void *thread, void *attr, void *(*start_routine)(void*),
    106                    void *arg);
    107 # endif
    108 }  // extern "C"
    109 #endif
    110 
    111 namespace __asan {
    112 
    113 // Instruments read/write access to a single byte in memory.
    114 // On error calls __asan_report_error, which aborts the program.
    115 #define ACCESS_ADDRESS(address, isWrite)   do {         \
    116   if (AddressIsPoisoned(address)) {                     \
    117     GET_CURRENT_PC_BP_SP;                               \
    118     __asan_report_error(pc, bp, sp, address, isWrite, /* access_size */ 1); \
    119   } \
    120 } while (0)
    121 
    122 // We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
    123 // and ASAN_WRITE_RANGE as macro instead of function so
    124 // that no extra frames are created, and stack trace contains
    125 // relevant information only.
    126 
    127 // Instruments read/write access to a memory range.
    128 // More complex implementation is possible, for now just
    129 // checking the first and the last byte of a range.
    130 #define ACCESS_MEMORY_RANGE(offset, size, isWrite) do { \
    131   if (size > 0) { \
    132     uintptr_t ptr = (uintptr_t)(offset); \
    133     ACCESS_ADDRESS(ptr, isWrite); \
    134     ACCESS_ADDRESS(ptr + (size) - 1, isWrite); \
    135   } \
    136 } while (0)
    137 
    138 #define ASAN_READ_RANGE(offset, size) do { \
    139   ACCESS_MEMORY_RANGE(offset, size, false); \
    140 } while (0)
    141 
    142 #define ASAN_WRITE_RANGE(offset, size) do { \
    143   ACCESS_MEMORY_RANGE(offset, size, true); \
    144 } while (0)
    145 
    146 // Behavior of functions like "memcpy" or "strcpy" is undefined
    147 // if memory intervals overlap. We report error in this case.
    148 // Macro is used to avoid creation of new frames.
    149 static inline bool RangesOverlap(const char *offset1, size_t length1,
    150                                  const char *offset2, size_t length2) {
    151   return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
    152 }
    153 #define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \
    154   const char *offset1 = (const char*)_offset1; \
    155   const char *offset2 = (const char*)_offset2; \
    156   if (RangesOverlap(offset1, length1, offset2, length2)) { \
    157     Report("ERROR: AddressSanitizer %s-param-overlap: " \
    158            "memory ranges [%p,%p) and [%p, %p) overlap\n", \
    159            name, offset1, offset1 + length1, offset2, offset2 + length2); \
    160     PRINT_CURRENT_STACK(); \
    161     ShowStatsAndAbort(); \
    162   } \
    163 } while (0)
    164 
    165 #define ENSURE_ASAN_INITED() do { \
    166   CHECK(!asan_init_is_running); \
    167   if (!asan_inited) { \
    168     __asan_init(); \
    169   } \
    170 } while (0)
    171 
    172 static inline bool IsSpace(int c) {
    173   return (c == ' ') || (c == '\n') || (c == '\t') ||
    174          (c == '\f') || (c == '\r') || (c == '\v');
    175 }
    176 
    177 static inline bool IsDigit(int c) {
    178   return (c >= '0') && (c <= '9');
    179 }
    180 
    181 static inline int ToLower(int c) {
    182   return (c >= 'A' && c <= 'Z') ? (c + 'a' - 'A') : c;
    183 }
    184 
    185 // ---------------------- Internal string functions ---------------- {{{1
    186 
    187 int64_t internal_simple_strtoll(const char *nptr, char **endptr, int base) {
    188   CHECK(base == 10);
    189   while (IsSpace(*nptr)) nptr++;
    190   int sgn = 1;
    191   uint64_t res = 0;
    192   bool have_digits = false;
    193   char *old_nptr = (char*)nptr;
    194   if (*nptr == '+') {
    195     sgn = 1;
    196     nptr++;
    197   } else if (*nptr == '-') {
    198     sgn = -1;
    199     nptr++;
    200   }
    201   while (IsDigit(*nptr)) {
    202     res = (res <= UINT64_MAX / 10) ? res * 10 : UINT64_MAX;
    203     int digit = ((*nptr) - '0');
    204     res = (res <= UINT64_MAX - digit) ? res + digit : UINT64_MAX;
    205     have_digits = true;
    206     nptr++;
    207   }
    208   if (endptr != NULL) {
    209     *endptr = (have_digits) ? (char*)nptr : old_nptr;
    210   }
    211   if (sgn > 0) {
    212     return (int64_t)(Min((uint64_t)INT64_MAX, res));
    213   } else {
    214     return (res > INT64_MAX) ? INT64_MIN : ((int64_t)res * -1);
    215   }
    216 }
    217 
    218 int64_t internal_atoll(const char *nptr) {
    219   return internal_simple_strtoll(nptr, (char**)NULL, 10);
    220 }
    221 
    222 size_t internal_strlen(const char *s) {
    223   size_t i = 0;
    224   while (s[i]) i++;
    225   return i;
    226 }
    227 
    228 size_t internal_strnlen(const char *s, size_t maxlen) {
    229 #if ASAN_INTERCEPT_STRNLEN
    230   if (REAL(strnlen) != NULL) {
    231     return REAL(strnlen)(s, maxlen);
    232   }
    233 #endif
    234   size_t i = 0;
    235   while (i < maxlen && s[i]) i++;
    236   return i;
    237 }
    238 
    239 char* internal_strchr(const char *s, int c) {
    240   while (true) {
    241     if (*s == (char)c)
    242       return (char*)s;
    243     if (*s == 0)
    244       return NULL;
    245     s++;
    246   }
    247 }
    248 
    249 void* internal_memchr(const void* s, int c, size_t n) {
    250   const char* t = (char*)s;
    251   for (size_t i = 0; i < n; ++i, ++t)
    252     if (*t == c)
    253       return (void*)t;
    254   return NULL;
    255 }
    256 
    257 int internal_memcmp(const void* s1, const void* s2, size_t n) {
    258   const char* t1 = (char*)s1;
    259   const char* t2 = (char*)s2;
    260   for (size_t i = 0; i < n; ++i, ++t1, ++t2)
    261     if (*t1 != *t2)
    262       return *t1 < *t2 ? -1 : 1;
    263   return 0;
    264 }
    265 
    266 // Should not be used in performance-critical places.
    267 void* internal_memset(void* s, int c, size_t n) {
    268   // The next line prevents Clang from making a call to memset() instead of the
    269   // loop below.
    270   // FIXME: building the runtime with -ffreestanding is a better idea. However
    271   // there currently are linktime problems due to PR12396.
    272   char volatile *t = (char*)s;
    273   for (size_t i = 0; i < n; ++i, ++t) {
    274     *t = c;
    275   }
    276   return s;
    277 }
    278 
    279 char *internal_strstr(const char *haystack, const char *needle) {
    280   // This is O(N^2), but we are not using it in hot places.
    281   size_t len1 = internal_strlen(haystack);
    282   size_t len2 = internal_strlen(needle);
    283   if (len1 < len2) return 0;
    284   for (size_t pos = 0; pos <= len1 - len2; pos++) {
    285     if (internal_memcmp(haystack + pos, needle, len2) == 0)
    286       return (char*)haystack + pos;
    287   }
    288   return 0;
    289 }
    290 
    291 char *internal_strncat(char *dst, const char *src, size_t n) {
    292   size_t len = internal_strlen(dst);
    293   size_t i;
    294   for (i = 0; i < n && src[i]; i++)
    295     dst[len + i] = src[i];
    296   dst[len + i] = 0;
    297   return dst;
    298 }
    299 
    300 int internal_strcmp(const char *s1, const char *s2) {
    301   while (true) {
    302     unsigned c1 = *s1;
    303     unsigned c2 = *s2;
    304     if (c1 != c2) return (c1 < c2) ? -1 : 1;
    305     if (c1 == 0) break;
    306     s1++;
    307     s2++;
    308   }
    309   return 0;
    310 }
    311 
    312 char *internal_strncpy(char *dst, const char *src, size_t n) {
    313   size_t i;
    314   for (i = 0; i < n && src[i]; i++)
    315     dst[i] = src[i];
    316   return dst;
    317 }
    318 
    319 }  // namespace __asan
    320 
    321 // ---------------------- Wrappers ---------------- {{{1
    322 using namespace __asan;  // NOLINT
    323 
    324 static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
    325   AsanThread *t = (AsanThread*)arg;
    326   asanThreadRegistry().SetCurrent(t);
    327   return t->ThreadStart();
    328 }
    329 
    330 #ifndef _WIN32
    331 INTERCEPTOR(int, pthread_create, void *thread,
    332     void *attr, void *(*start_routine)(void*), void *arg) {
    333   GET_STACK_TRACE_HERE(kStackTraceMax);
    334   int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
    335   AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
    336   asanThreadRegistry().RegisterThread(t);
    337   return REAL(pthread_create)(thread, attr, asan_thread_start, t);
    338 }
    339 #endif  // !_WIN32
    340 
    341 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
    342 INTERCEPTOR(void*, signal, int signum, void *handler) {
    343   if (!AsanInterceptsSignal(signum)) {
    344     return REAL(signal)(signum, handler);
    345   }
    346   return NULL;
    347 }
    348 
    349 INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act,
    350                             struct sigaction *oldact) {
    351   if (!AsanInterceptsSignal(signum)) {
    352     return REAL(sigaction)(signum, act, oldact);
    353   }
    354   return 0;
    355 }
    356 #elif ASAN_POSIX
    357 // We need to have defined REAL(sigaction) on posix systems.
    358 DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act,
    359     struct sigaction *oldact);
    360 #endif  // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
    361 
    362 INTERCEPTOR(void, longjmp, void *env, int val) {
    363   __asan_handle_no_return();
    364   REAL(longjmp)(env, val);
    365 }
    366 
    367 #if !defined(_WIN32)
    368 INTERCEPTOR(void, _longjmp, void *env, int val) {
    369   __asan_handle_no_return();
    370   REAL(_longjmp)(env, val);
    371 }
    372 
    373 INTERCEPTOR(void, siglongjmp, void *env, int val) {
    374   __asan_handle_no_return();
    375   REAL(siglongjmp)(env, val);
    376 }
    377 #endif
    378 
    379 #if ASAN_HAS_EXCEPTIONS == 1
    380 #ifdef __APPLE__
    381 extern "C" void __cxa_throw(void *a, void *b, void *c);
    382 #endif  // __APPLE__
    383 
    384 INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
    385   CHECK(REAL(__cxa_throw));
    386   __asan_handle_no_return();
    387   REAL(__cxa_throw)(a, b, c);
    388 }
    389 #endif
    390 
    391 // intercept mlock and friends.
    392 // Since asan maps 16T of RAM, mlock is completely unfriendly to asan.
    393 // All functions return 0 (success).
    394 static void MlockIsUnsupported() {
    395   static bool printed = 0;
    396   if (printed) return;
    397   printed = true;
    398   Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n");
    399 }
    400 
    401 extern "C" {
    402 INTERCEPTOR_ATTRIBUTE
    403 int mlock(const void *addr, size_t len) {
    404   MlockIsUnsupported();
    405   return 0;
    406 }
    407 
    408 INTERCEPTOR_ATTRIBUTE
    409 int munlock(const void *addr, size_t len) {
    410   MlockIsUnsupported();
    411   return 0;
    412 }
    413 
    414 INTERCEPTOR_ATTRIBUTE
    415 int mlockall(int flags) {
    416   MlockIsUnsupported();
    417   return 0;
    418 }
    419 
    420 INTERCEPTOR_ATTRIBUTE
    421 int munlockall(void) {
    422   MlockIsUnsupported();
    423   return 0;
    424 }
    425 }  // extern "C"
    426 
    427 static inline int CharCmp(unsigned char c1, unsigned char c2) {
    428   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
    429 }
    430 
    431 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
    432   int c1_low = ToLower(c1);
    433   int c2_low = ToLower(c2);
    434   return c1_low - c2_low;
    435 }
    436 
    437 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, size_t size) {
    438   ENSURE_ASAN_INITED();
    439   unsigned char c1 = 0, c2 = 0;
    440   const unsigned char *s1 = (const unsigned char*)a1;
    441   const unsigned char *s2 = (const unsigned char*)a2;
    442   size_t i;
    443   for (i = 0; i < size; i++) {
    444     c1 = s1[i];
    445     c2 = s2[i];
    446     if (c1 != c2) break;
    447   }
    448   ASAN_READ_RANGE(s1, Min(i + 1, size));
    449   ASAN_READ_RANGE(s2, Min(i + 1, size));
    450   return CharCmp(c1, c2);
    451 }
    452 
    453 INTERCEPTOR(void*, memcpy, void *to, const void *from, size_t size) {
    454   // memcpy is called during __asan_init() from the internals
    455   // of printf(...).
    456   if (asan_init_is_running) {
    457     return REAL(memcpy)(to, from, size);
    458   }
    459   ENSURE_ASAN_INITED();
    460   if (FLAG_replace_intrin) {
    461     if (to != from) {
    462       // We do not treat memcpy with to==from as a bug.
    463       // See http://llvm.org/bugs/show_bug.cgi?id=11763.
    464       CHECK_RANGES_OVERLAP("memcpy", to, size, from, size);
    465     }
    466     ASAN_WRITE_RANGE(from, size);
    467     ASAN_READ_RANGE(to, size);
    468   }
    469   return REAL(memcpy)(to, from, size);
    470 }
    471 
    472 INTERCEPTOR(void*, memmove, void *to, const void *from, size_t size) {
    473   ENSURE_ASAN_INITED();
    474   if (FLAG_replace_intrin) {
    475     ASAN_WRITE_RANGE(from, size);
    476     ASAN_READ_RANGE(to, size);
    477   }
    478   return REAL(memmove)(to, from, size);
    479 }
    480 
    481 INTERCEPTOR(void*, memset, void *block, int c, size_t size) {
    482   // memset is called inside Printf.
    483   if (asan_init_is_running) {
    484     return REAL(memset)(block, c, size);
    485   }
    486   ENSURE_ASAN_INITED();
    487   if (FLAG_replace_intrin) {
    488     ASAN_WRITE_RANGE(block, size);
    489   }
    490   return REAL(memset)(block, c, size);
    491 }
    492 
    493 INTERCEPTOR(char*, strchr, const char *str, int c) {
    494   ENSURE_ASAN_INITED();
    495   char *result = REAL(strchr)(str, c);
    496   if (FLAG_replace_str) {
    497     size_t bytes_read = (result ? result - str : REAL(strlen)(str)) + 1;
    498     ASAN_READ_RANGE(str, bytes_read);
    499   }
    500   return result;
    501 }
    502 
    503 #ifdef __linux__
    504 INTERCEPTOR(char*, index, const char *string, int c)
    505   ALIAS(WRAPPER_NAME(strchr));
    506 #else
    507 DEFINE_REAL(char*, index, const char *string, int c);
    508 #endif
    509 
    510 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
    511   ENSURE_ASAN_INITED();
    512   unsigned char c1, c2;
    513   size_t i;
    514   for (i = 0; ; i++) {
    515     c1 = (unsigned char)s1[i];
    516     c2 = (unsigned char)s2[i];
    517     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    518   }
    519   ASAN_READ_RANGE(s1, i + 1);
    520   ASAN_READ_RANGE(s2, i + 1);
    521   return CharCaseCmp(c1, c2);
    522 }
    523 
    524 INTERCEPTOR(char*, strcat, char *to, const char *from) {  // NOLINT
    525   ENSURE_ASAN_INITED();
    526   if (FLAG_replace_str) {
    527     size_t from_length = REAL(strlen)(from);
    528     ASAN_READ_RANGE(from, from_length + 1);
    529     if (from_length > 0) {
    530       size_t to_length = REAL(strlen)(to);
    531       ASAN_READ_RANGE(to, to_length);
    532       ASAN_WRITE_RANGE(to + to_length, from_length + 1);
    533       CHECK_RANGES_OVERLAP("strcat", to, to_length + 1, from, from_length + 1);
    534     }
    535   }
    536   return REAL(strcat)(to, from);  // NOLINT
    537 }
    538 
    539 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
    540   if (!asan_inited) {
    541     return internal_strcmp(s1, s2);
    542   }
    543   unsigned char c1, c2;
    544   size_t i;
    545   for (i = 0; ; i++) {
    546     c1 = (unsigned char)s1[i];
    547     c2 = (unsigned char)s2[i];
    548     if (c1 != c2 || c1 == '\0') break;
    549   }
    550   ASAN_READ_RANGE(s1, i + 1);
    551   ASAN_READ_RANGE(s2, i + 1);
    552   return CharCmp(c1, c2);
    553 }
    554 
    555 INTERCEPTOR(char*, strcpy, char *to, const char *from) {  // NOLINT
    556   // strcpy is called from malloc_default_purgeable_zone()
    557   // in __asan::ReplaceSystemAlloc() on Mac.
    558   if (asan_init_is_running) {
    559     return REAL(strcpy)(to, from);  // NOLINT
    560   }
    561   ENSURE_ASAN_INITED();
    562   if (FLAG_replace_str) {
    563     size_t from_size = REAL(strlen)(from) + 1;
    564     CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
    565     ASAN_READ_RANGE(from, from_size);
    566     ASAN_WRITE_RANGE(to, from_size);
    567   }
    568   return REAL(strcpy)(to, from);  // NOLINT
    569 }
    570 
    571 INTERCEPTOR(char*, strdup, const char *s) {
    572   ENSURE_ASAN_INITED();
    573   if (FLAG_replace_str) {
    574     size_t length = REAL(strlen)(s);
    575     ASAN_READ_RANGE(s, length + 1);
    576   }
    577   return REAL(strdup)(s);
    578 }
    579 
    580 INTERCEPTOR(size_t, strlen, const char *s) {
    581   // strlen is called from malloc_default_purgeable_zone()
    582   // in __asan::ReplaceSystemAlloc() on Mac.
    583   if (asan_init_is_running) {
    584     return REAL(strlen)(s);
    585   }
    586   ENSURE_ASAN_INITED();
    587   size_t length = REAL(strlen)(s);
    588   if (FLAG_replace_str) {
    589     ASAN_READ_RANGE(s, length + 1);
    590   }
    591   return length;
    592 }
    593 
    594 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, size_t n) {
    595   ENSURE_ASAN_INITED();
    596   unsigned char c1 = 0, c2 = 0;
    597   size_t i;
    598   for (i = 0; i < n; i++) {
    599     c1 = (unsigned char)s1[i];
    600     c2 = (unsigned char)s2[i];
    601     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    602   }
    603   ASAN_READ_RANGE(s1, Min(i + 1, n));
    604   ASAN_READ_RANGE(s2, Min(i + 1, n));
    605   return CharCaseCmp(c1, c2);
    606 }
    607 
    608 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, size_t size) {
    609   // strncmp is called from malloc_default_purgeable_zone()
    610   // in __asan::ReplaceSystemAlloc() on Mac.
    611   if (asan_init_is_running) {
    612     return REAL(strncmp)(s1, s2, size);
    613   }
    614   unsigned char c1 = 0, c2 = 0;
    615   size_t i;
    616   for (i = 0; i < size; i++) {
    617     c1 = (unsigned char)s1[i];
    618     c2 = (unsigned char)s2[i];
    619     if (c1 != c2 || c1 == '\0') break;
    620   }
    621   ASAN_READ_RANGE(s1, Min(i + 1, size));
    622   ASAN_READ_RANGE(s2, Min(i + 1, size));
    623   return CharCmp(c1, c2);
    624 }
    625 
    626 INTERCEPTOR(char*, strncpy, char *to, const char *from, size_t size) {
    627   ENSURE_ASAN_INITED();
    628   if (FLAG_replace_str) {
    629     size_t from_size = Min(size, internal_strnlen(from, size) + 1);
    630     CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
    631     ASAN_READ_RANGE(from, from_size);
    632     ASAN_WRITE_RANGE(to, size);
    633   }
    634   return REAL(strncpy)(to, from, size);
    635 }
    636 
    637 #if ASAN_INTERCEPT_STRNLEN
    638 INTERCEPTOR(size_t, strnlen, const char *s, size_t maxlen) {
    639   ENSURE_ASAN_INITED();
    640   size_t length = REAL(strnlen)(s, maxlen);
    641   if (FLAG_replace_str) {
    642     ASAN_READ_RANGE(s, Min(length + 1, maxlen));
    643   }
    644   return length;
    645 }
    646 #endif  // ASAN_INTERCEPT_STRNLEN
    647 
    648 static inline bool IsValidStrtolBase(int base) {
    649   return (base == 0) || (2 <= base && base <= 36);
    650 }
    651 
    652 static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
    653   CHECK(endptr != NULL);
    654   if (nptr == *endptr) {
    655     // No digits were found at strtol call, we need to find out the last
    656     // symbol accessed by strtoll on our own.
    657     // We get this symbol by skipping leading blanks and optional +/- sign.
    658     while (IsSpace(*nptr)) nptr++;
    659     if (*nptr == '+' || *nptr == '-') nptr++;
    660     *endptr = (char*)nptr;
    661   }
    662   CHECK(*endptr >= nptr);
    663 }
    664 
    665 INTERCEPTOR(long, strtol, const char *nptr,  // NOLINT
    666             char **endptr, int base) {
    667   ENSURE_ASAN_INITED();
    668   if (!FLAG_replace_str) {
    669     return REAL(strtol)(nptr, endptr, base);
    670   }
    671   char *real_endptr;
    672   long result = REAL(strtol)(nptr, &real_endptr, base);  // NOLINT
    673   if (endptr != NULL) {
    674     *endptr = real_endptr;
    675   }
    676   if (IsValidStrtolBase(base)) {
    677     FixRealStrtolEndptr(nptr, &real_endptr);
    678     ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
    679   }
    680   return result;
    681 }
    682 
    683 INTERCEPTOR(int, atoi, const char *nptr) {
    684   ENSURE_ASAN_INITED();
    685   if (!FLAG_replace_str) {
    686     return REAL(atoi)(nptr);
    687   }
    688   char *real_endptr;
    689   // "man atoi" tells that behavior of atoi(nptr) is the same as
    690   // strtol(nptr, NULL, 10), i.e. it sets errno to ERANGE if the
    691   // parsed integer can't be stored in *long* type (even if it's
    692   // different from int). So, we just imitate this behavior.
    693   int result = REAL(strtol)(nptr, &real_endptr, 10);
    694   FixRealStrtolEndptr(nptr, &real_endptr);
    695   ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
    696   return result;
    697 }
    698 
    699 INTERCEPTOR(long, atol, const char *nptr) {  // NOLINT
    700   ENSURE_ASAN_INITED();
    701   if (!FLAG_replace_str) {
    702     return REAL(atol)(nptr);
    703   }
    704   char *real_endptr;
    705   long result = REAL(strtol)(nptr, &real_endptr, 10);  // NOLINT
    706   FixRealStrtolEndptr(nptr, &real_endptr);
    707   ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
    708   return result;
    709 }
    710 
    711 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
    712 INTERCEPTOR(long long, strtoll, const char *nptr,  // NOLINT
    713             char **endptr, int base) {
    714   ENSURE_ASAN_INITED();
    715   if (!FLAG_replace_str) {
    716     return REAL(strtoll)(nptr, endptr, base);
    717   }
    718   char *real_endptr;
    719   long long result = REAL(strtoll)(nptr, &real_endptr, base);  // NOLINT
    720   if (endptr != NULL) {
    721     *endptr = real_endptr;
    722   }
    723   // If base has unsupported value, strtoll can exit with EINVAL
    724   // without reading any characters. So do additional checks only
    725   // if base is valid.
    726   if (IsValidStrtolBase(base)) {
    727     FixRealStrtolEndptr(nptr, &real_endptr);
    728     ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
    729   }
    730   return result;
    731 }
    732 
    733 INTERCEPTOR(long long, atoll, const char *nptr) {  // NOLINT
    734   ENSURE_ASAN_INITED();
    735   if (!FLAG_replace_str) {
    736     return REAL(atoll)(nptr);
    737   }
    738   char *real_endptr;
    739   long long result = REAL(strtoll)(nptr, &real_endptr, 10);  // NOLINT
    740   FixRealStrtolEndptr(nptr, &real_endptr);
    741   ASAN_READ_RANGE(nptr, (real_endptr - nptr) + 1);
    742   return result;
    743 }
    744 #endif  // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
    745 
    746 #if defined(_WIN32)
    747 INTERCEPTOR_WINAPI(DWORD, CreateThread,
    748                    void* security, size_t stack_size,
    749                    DWORD (__stdcall *start_routine)(void*), void* arg,
    750                    DWORD flags, void* tid) {
    751   GET_STACK_TRACE_HERE(kStackTraceMax);
    752   int current_tid = asanThreadRegistry().GetCurrentTidOrMinusOne();
    753   AsanThread *t = AsanThread::Create(current_tid, start_routine, arg, &stack);
    754   asanThreadRegistry().RegisterThread(t);
    755   return REAL(CreateThread)(security, stack_size,
    756                             asan_thread_start, t, flags, tid);
    757 }
    758 
    759 namespace __asan {
    760 void InitializeWindowsInterceptors() {
    761   CHECK(INTERCEPT_FUNCTION(CreateThread));
    762 }
    763 
    764 }  // namespace __asan
    765 #endif
    766 
    767 // ---------------------- InitializeAsanInterceptors ---------------- {{{1
    768 namespace __asan {
    769 void InitializeAsanInterceptors() {
    770   static bool was_called_once;
    771   CHECK(was_called_once == false);
    772   was_called_once = true;
    773   // Intercept mem* functions.
    774   CHECK(INTERCEPT_FUNCTION(memcmp));
    775   CHECK(INTERCEPT_FUNCTION(memmove));
    776   CHECK(INTERCEPT_FUNCTION(memset));
    777   if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
    778     CHECK(INTERCEPT_FUNCTION(memcpy));
    779   } else {
    780     REAL(memcpy) = REAL(memmove);
    781   }
    782 
    783   // Intercept str* functions.
    784   CHECK(INTERCEPT_FUNCTION(strcat));  // NOLINT
    785   CHECK(INTERCEPT_FUNCTION(strchr));
    786   CHECK(INTERCEPT_FUNCTION(strcmp));
    787   CHECK(INTERCEPT_FUNCTION(strcpy));  // NOLINT
    788   CHECK(INTERCEPT_FUNCTION(strlen));
    789   CHECK(INTERCEPT_FUNCTION(strncmp));
    790   CHECK(INTERCEPT_FUNCTION(strncpy));
    791 #if !defined(_WIN32)
    792   CHECK(INTERCEPT_FUNCTION(strcasecmp));
    793   CHECK(INTERCEPT_FUNCTION(strdup));
    794   CHECK(INTERCEPT_FUNCTION(strncasecmp));
    795 # ifndef __APPLE__
    796   CHECK(INTERCEPT_FUNCTION(index));
    797 # else
    798   CHECK(OVERRIDE_FUNCTION(index, WRAP(strchr)));
    799 # endif
    800 #endif
    801 #if ASAN_INTERCEPT_STRNLEN
    802   CHECK(INTERCEPT_FUNCTION(strnlen));
    803 #endif
    804 
    805   CHECK(INTERCEPT_FUNCTION(atoi));
    806   CHECK(INTERCEPT_FUNCTION(atol));
    807   CHECK(INTERCEPT_FUNCTION(strtol));
    808 #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
    809   CHECK(INTERCEPT_FUNCTION(atoll));
    810   CHECK(INTERCEPT_FUNCTION(strtoll));
    811 #endif
    812 
    813   // Intecept signal- and jump-related functions.
    814   CHECK(INTERCEPT_FUNCTION(longjmp));
    815 #if ASAN_INTERCEPT_SIGNAL_AND_SIGACTION
    816   CHECK(INTERCEPT_FUNCTION(sigaction));
    817   CHECK(INTERCEPT_FUNCTION(signal));
    818 #endif
    819 
    820 #if !defined(_WIN32)
    821   CHECK(INTERCEPT_FUNCTION(_longjmp));
    822   INTERCEPT_FUNCTION(__cxa_throw);
    823 # if !defined(__APPLE__)
    824   // On Darwin siglongjmp tailcalls longjmp, so we don't want to intercept it
    825   // there.
    826   CHECK(INTERCEPT_FUNCTION(siglongjmp));
    827 # endif
    828 #endif
    829 
    830   // Intercept threading-related functions
    831 #if !defined(_WIN32)
    832   CHECK(INTERCEPT_FUNCTION(pthread_create));
    833 #endif
    834 
    835   // Some Windows-specific interceptors.
    836 #if defined(_WIN32)
    837   InitializeWindowsInterceptors();
    838 #endif
    839 
    840   // Some Mac-specific interceptors.
    841 #if defined(__APPLE__)
    842   InitializeMacInterceptors();
    843 #endif
    844 
    845   if (FLAG_v > 0) {
    846     Report("AddressSanitizer: libc interceptors initialized\n");
    847   }
    848 }
    849 
    850 }  // namespace __asan
    851