Home | History | Annotate | Download | only in asan
      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