Home | History | Annotate | Download | only in msan
      1 //===-- msan_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 MemorySanitizer.
     11 //
     12 // Interceptors for standard library functions.
     13 //
     14 // FIXME: move as many interceptors as possible into
     15 // sanitizer_common/sanitizer_common_interceptors.h
     16 //===----------------------------------------------------------------------===//
     17 
     18 #include "interception/interception.h"
     19 #include "msan.h"
     20 #include "msan_chained_origin_depot.h"
     21 #include "msan_origin.h"
     22 #include "msan_thread.h"
     23 #include "msan_poisoning.h"
     24 #include "sanitizer_common/sanitizer_platform_limits_posix.h"
     25 #include "sanitizer_common/sanitizer_allocator.h"
     26 #include "sanitizer_common/sanitizer_allocator_interface.h"
     27 #include "sanitizer_common/sanitizer_allocator_internal.h"
     28 #include "sanitizer_common/sanitizer_atomic.h"
     29 #include "sanitizer_common/sanitizer_common.h"
     30 #include "sanitizer_common/sanitizer_stackdepot.h"
     31 #include "sanitizer_common/sanitizer_libc.h"
     32 #include "sanitizer_common/sanitizer_linux.h"
     33 #include "sanitizer_common/sanitizer_tls_get_addr.h"
     34 
     35 #include <stdarg.h>
     36 // ACHTUNG! No other system header includes in this file.
     37 // Ideally, we should get rid of stdarg.h as well.
     38 
     39 using namespace __msan;
     40 
     41 using __sanitizer::memory_order;
     42 using __sanitizer::atomic_load;
     43 using __sanitizer::atomic_store;
     44 using __sanitizer::atomic_uintptr_t;
     45 
     46 DECLARE_REAL(SIZE_T, strlen, const char *s)
     47 DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
     48 
     49 #if SANITIZER_FREEBSD
     50 #define __errno_location __error
     51 #endif
     52 
     53 // True if this is a nested interceptor.
     54 static THREADLOCAL int in_interceptor_scope;
     55 
     56 extern "C" int *__errno_location(void);
     57 
     58 struct InterceptorScope {
     59   InterceptorScope() { ++in_interceptor_scope; }
     60   ~InterceptorScope() { --in_interceptor_scope; }
     61 };
     62 
     63 bool IsInInterceptorScope() {
     64   return in_interceptor_scope;
     65 }
     66 
     67 #define ENSURE_MSAN_INITED() do { \
     68   CHECK(!msan_init_is_running); \
     69   if (!msan_inited) { \
     70     __msan_init(); \
     71   } \
     72 } while (0)
     73 
     74 // Check that [x, x+n) range is unpoisoned.
     75 #define CHECK_UNPOISONED_0(x, n)                                               \
     76   do {                                                                         \
     77     sptr offset = __msan_test_shadow(x, n);                                    \
     78     if (__msan::IsInSymbolizer())                                              \
     79       break;                                                                   \
     80     if (offset >= 0 && __msan::flags()->report_umrs) {                         \
     81       GET_CALLER_PC_BP_SP;                                                     \
     82       (void) sp;                                                               \
     83       ReportUMRInsideAddressRange(__func__, x, n, offset);                     \
     84       __msan::PrintWarningWithOrigin(                                          \
     85           pc, bp, __msan_get_origin((const char *)x + offset));                \
     86       if (__msan::flags()->halt_on_error) {                                    \
     87         Printf("Exiting\n");                                                   \
     88         Die();                                                                 \
     89       }                                                                        \
     90     }                                                                          \
     91   } while (0)
     92 
     93 // Check that [x, x+n) range is unpoisoned unless we are in a nested
     94 // interceptor.
     95 #define CHECK_UNPOISONED(x, n)                             \
     96   do {                                                     \
     97     if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \
     98   } while (0);
     99 
    100 #define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n)               \
    101   CHECK_UNPOISONED((x),                                         \
    102     common_flags()->strict_string_checks ? (len) + 1 : (n) )
    103 
    104 #define CHECK_UNPOISONED_STRING(x, n)                           \
    105     CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
    106 
    107 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
    108   ENSURE_MSAN_INITED();
    109   SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
    110   if (res > 0)
    111     __msan_unpoison(ptr, res *size);
    112   return res;
    113 }
    114 
    115 #if !SANITIZER_FREEBSD
    116 INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
    117             void *file) {
    118   ENSURE_MSAN_INITED();
    119   SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file);
    120   if (res > 0)
    121     __msan_unpoison(ptr, res *size);
    122   return res;
    123 }
    124 #define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked)
    125 #else
    126 #define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED
    127 #endif
    128 
    129 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
    130   ENSURE_MSAN_INITED();
    131   CHECK_UNPOISONED_STRING(path, 0)
    132   SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
    133   if (res > 0)
    134     __msan_unpoison(buf, res);
    135   return res;
    136 }
    137 
    138 INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) {
    139   return __msan_memcpy(dest, src, n);
    140 }
    141 
    142 INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) {
    143   return (char *)__msan_memcpy(dest, src, n) + n;
    144 }
    145 
    146 INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) {
    147   ENSURE_MSAN_INITED();
    148   void *res = REAL(memccpy)(dest, src, c, n);
    149   CHECK(!res || (res >= dest && res <= (char *)dest + n));
    150   SIZE_T sz = res ? (char *)res - (char *)dest : n;
    151   CHECK_UNPOISONED(src, sz);
    152   __msan_unpoison(dest, sz);
    153   return res;
    154 }
    155 
    156 INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) {
    157   return __msan_memmove(dest, src, n);
    158 }
    159 
    160 INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) {
    161   return __msan_memset(s, c, n);
    162 }
    163 
    164 INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) {
    165   return __msan_memmove(dest, src, n);
    166 }
    167 
    168 INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
    169   GET_MALLOC_STACK_TRACE;
    170   CHECK_EQ(alignment & (alignment - 1), 0);
    171   CHECK_NE(memptr, 0);
    172   *memptr = MsanReallocate(&stack, nullptr, size, alignment, false);
    173   CHECK_NE(*memptr, 0);
    174   __msan_unpoison(memptr, sizeof(*memptr));
    175   return 0;
    176 }
    177 
    178 #if !SANITIZER_FREEBSD
    179 INTERCEPTOR(void *, memalign, SIZE_T boundary, SIZE_T size) {
    180   GET_MALLOC_STACK_TRACE;
    181   CHECK_EQ(boundary & (boundary - 1), 0);
    182   void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
    183   return ptr;
    184 }
    185 #define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign)
    186 #else
    187 #define MSAN_MAYBE_INTERCEPT_MEMALIGN
    188 #endif
    189 
    190 INTERCEPTOR(void *, aligned_alloc, SIZE_T boundary, SIZE_T size) {
    191   GET_MALLOC_STACK_TRACE;
    192   CHECK_EQ(boundary & (boundary - 1), 0);
    193   void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
    194   return ptr;
    195 }
    196 
    197 INTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) {
    198   GET_MALLOC_STACK_TRACE;
    199   CHECK_EQ(boundary & (boundary - 1), 0);
    200   void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false);
    201   DTLS_on_libc_memalign(ptr, size);
    202   return ptr;
    203 }
    204 
    205 INTERCEPTOR(void *, valloc, SIZE_T size) {
    206   GET_MALLOC_STACK_TRACE;
    207   void *ptr = MsanReallocate(&stack, nullptr, size, GetPageSizeCached(), false);
    208   return ptr;
    209 }
    210 
    211 #if !SANITIZER_FREEBSD
    212 INTERCEPTOR(void *, pvalloc, SIZE_T size) {
    213   GET_MALLOC_STACK_TRACE;
    214   uptr PageSize = GetPageSizeCached();
    215   size = RoundUpTo(size, PageSize);
    216   if (size == 0) {
    217     // pvalloc(0) should allocate one page.
    218     size = PageSize;
    219   }
    220   void *ptr = MsanReallocate(&stack, nullptr, size, PageSize, false);
    221   return ptr;
    222 }
    223 #define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc)
    224 #else
    225 #define MSAN_MAYBE_INTERCEPT_PVALLOC
    226 #endif
    227 
    228 INTERCEPTOR(void, free, void *ptr) {
    229   GET_MALLOC_STACK_TRACE;
    230   if (!ptr) return;
    231   MsanDeallocate(&stack, ptr);
    232 }
    233 
    234 #if !SANITIZER_FREEBSD
    235 INTERCEPTOR(void, cfree, void *ptr) {
    236   GET_MALLOC_STACK_TRACE;
    237   if (!ptr) return;
    238   MsanDeallocate(&stack, ptr);
    239 }
    240 #define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree)
    241 #else
    242 #define MSAN_MAYBE_INTERCEPT_CFREE
    243 #endif
    244 
    245 INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
    246   return __sanitizer_get_allocated_size(ptr);
    247 }
    248 
    249 #if !SANITIZER_FREEBSD
    250 // This function actually returns a struct by value, but we can't unpoison a
    251 // temporary! The following is equivalent on all supported platforms but
    252 // aarch64 (which uses a different register for sret value).  We have a test
    253 // to confirm that.
    254 INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
    255 #ifdef __aarch64__
    256   uptr r8;
    257   asm volatile("mov %0,x8" : "=r" (r8));
    258   sret = reinterpret_cast<__sanitizer_mallinfo*>(r8);
    259 #endif
    260   REAL(memset)(sret, 0, sizeof(*sret));
    261   __msan_unpoison(sret, sizeof(*sret));
    262 }
    263 #define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo)
    264 #else
    265 #define MSAN_MAYBE_INTERCEPT_MALLINFO
    266 #endif
    267 
    268 #if !SANITIZER_FREEBSD
    269 INTERCEPTOR(int, mallopt, int cmd, int value) {
    270   return -1;
    271 }
    272 #define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt)
    273 #else
    274 #define MSAN_MAYBE_INTERCEPT_MALLOPT
    275 #endif
    276 
    277 #if !SANITIZER_FREEBSD
    278 INTERCEPTOR(void, malloc_stats, void) {
    279   // FIXME: implement, but don't call REAL(malloc_stats)!
    280 }
    281 #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats)
    282 #else
    283 #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS
    284 #endif
    285 
    286 INTERCEPTOR(char *, strcpy, char *dest, const char *src) {  // NOLINT
    287   ENSURE_MSAN_INITED();
    288   GET_STORE_STACK_TRACE;
    289   SIZE_T n = REAL(strlen)(src);
    290   CHECK_UNPOISONED_STRING(src + n, 0);
    291   char *res = REAL(strcpy)(dest, src);  // NOLINT
    292   CopyShadowAndOrigin(dest, src, n + 1, &stack);
    293   return res;
    294 }
    295 
    296 INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) {  // NOLINT
    297   ENSURE_MSAN_INITED();
    298   GET_STORE_STACK_TRACE;
    299   SIZE_T copy_size = REAL(strnlen)(src, n);
    300   if (copy_size < n)
    301     copy_size++;  // trailing \0
    302   char *res = REAL(strncpy)(dest, src, n);  // NOLINT
    303   CopyShadowAndOrigin(dest, src, copy_size, &stack);
    304   __msan_unpoison(dest + copy_size, n - copy_size);
    305   return res;
    306 }
    307 
    308 INTERCEPTOR(char *, stpcpy, char *dest, const char *src) {  // NOLINT
    309   ENSURE_MSAN_INITED();
    310   GET_STORE_STACK_TRACE;
    311   SIZE_T n = REAL(strlen)(src);
    312   CHECK_UNPOISONED_STRING(src + n, 0);
    313   char *res = REAL(stpcpy)(dest, src);  // NOLINT
    314   CopyShadowAndOrigin(dest, src, n + 1, &stack);
    315   return res;
    316 }
    317 
    318 INTERCEPTOR(char *, strdup, char *src) {
    319   ENSURE_MSAN_INITED();
    320   GET_STORE_STACK_TRACE;
    321   // On FreeBSD strdup() leverages strlen().
    322   InterceptorScope interceptor_scope;
    323   SIZE_T n = REAL(strlen)(src);
    324   CHECK_UNPOISONED_STRING(src + n, 0);
    325   char *res = REAL(strdup)(src);
    326   CopyShadowAndOrigin(res, src, n + 1, &stack);
    327   return res;
    328 }
    329 
    330 #if !SANITIZER_FREEBSD
    331 INTERCEPTOR(char *, __strdup, char *src) {
    332   ENSURE_MSAN_INITED();
    333   GET_STORE_STACK_TRACE;
    334   SIZE_T n = REAL(strlen)(src);
    335   CHECK_UNPOISONED_STRING(src + n, 0);
    336   char *res = REAL(__strdup)(src);
    337   CopyShadowAndOrigin(res, src, n + 1, &stack);
    338   return res;
    339 }
    340 #define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup)
    341 #else
    342 #define MSAN_MAYBE_INTERCEPT___STRDUP
    343 #endif
    344 
    345 INTERCEPTOR(char *, strndup, char *src, SIZE_T n) {
    346   ENSURE_MSAN_INITED();
    347   GET_STORE_STACK_TRACE;
    348   // On FreeBSD strndup() leverages strnlen().
    349   InterceptorScope interceptor_scope;
    350   SIZE_T copy_size = REAL(strnlen)(src, n);
    351   char *res = REAL(strndup)(src, n);
    352   CopyShadowAndOrigin(res, src, copy_size, &stack);
    353   __msan_unpoison(res + copy_size, 1); // \0
    354   return res;
    355 }
    356 
    357 #if !SANITIZER_FREEBSD
    358 INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) {
    359   ENSURE_MSAN_INITED();
    360   GET_STORE_STACK_TRACE;
    361   SIZE_T copy_size = REAL(strnlen)(src, n);
    362   char *res = REAL(__strndup)(src, n);
    363   CopyShadowAndOrigin(res, src, copy_size, &stack);
    364   __msan_unpoison(res + copy_size, 1); // \0
    365   return res;
    366 }
    367 #define MSAN_MAYBE_INTERCEPT___STRNDUP INTERCEPT_FUNCTION(__strndup)
    368 #else
    369 #define MSAN_MAYBE_INTERCEPT___STRNDUP
    370 #endif
    371 
    372 INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) {
    373   ENSURE_MSAN_INITED();
    374   char *res = REAL(gcvt)(number, ndigit, buf);
    375   SIZE_T n = REAL(strlen)(buf);
    376   __msan_unpoison(buf, n + 1);
    377   return res;
    378 }
    379 
    380 INTERCEPTOR(char *, strcat, char *dest, const char *src) {  // NOLINT
    381   ENSURE_MSAN_INITED();
    382   GET_STORE_STACK_TRACE;
    383   SIZE_T src_size = REAL(strlen)(src);
    384   SIZE_T dest_size = REAL(strlen)(dest);
    385   CHECK_UNPOISONED_STRING(src + src_size, 0);
    386   CHECK_UNPOISONED_STRING(dest + dest_size, 0);
    387   char *res = REAL(strcat)(dest, src);  // NOLINT
    388   CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack);
    389   return res;
    390 }
    391 
    392 INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) {  // NOLINT
    393   ENSURE_MSAN_INITED();
    394   GET_STORE_STACK_TRACE;
    395   SIZE_T dest_size = REAL(strlen)(dest);
    396   SIZE_T copy_size = REAL(strnlen)(src, n);
    397   CHECK_UNPOISONED_STRING(dest + dest_size, 0);
    398   char *res = REAL(strncat)(dest, src, n);  // NOLINT
    399   CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack);
    400   __msan_unpoison(dest + dest_size + copy_size, 1); // \0
    401   return res;
    402 }
    403 
    404 // Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to
    405 // deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO.
    406 #define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \
    407   ENSURE_MSAN_INITED();                             \
    408   ret_type res = REAL(func)(__VA_ARGS__);           \
    409   __msan_unpoison(endptr, sizeof(*endptr));         \
    410   return res;
    411 
    412 #define INTERCEPTOR_STRTO(ret_type, func, char_type)                       \
    413   INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \
    414     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr);                  \
    415   }
    416 
    417 #define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)                \
    418   INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
    419               int base) {                                                \
    420     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base);          \
    421   }
    422 
    423 #define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type)                 \
    424   INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
    425               void *loc) {                                               \
    426     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc);           \
    427   }
    428 
    429 #define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type)            \
    430   INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \
    431               int base, void *loc) {                                     \
    432     INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc);     \
    433   }
    434 
    435 #define INTERCEPTORS_STRTO(ret_type, func, char_type)      \
    436   INTERCEPTOR_STRTO(ret_type, func, char_type)             \
    437   INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type)     \
    438   INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \
    439   INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type)
    440 
    441 #define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type)      \
    442   INTERCEPTOR_STRTO_BASE(ret_type, func, char_type)             \
    443   INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type)     \
    444   INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \
    445   INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type)
    446 
    447 INTERCEPTORS_STRTO(double, strtod, char)                     // NOLINT
    448 INTERCEPTORS_STRTO(float, strtof, char)                      // NOLINT
    449 INTERCEPTORS_STRTO(long double, strtold, char)               // NOLINT
    450 INTERCEPTORS_STRTO_BASE(long, strtol, char)                  // NOLINT
    451 INTERCEPTORS_STRTO_BASE(long long, strtoll, char)            // NOLINT
    452 INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char)        // NOLINT
    453 INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char)  // NOLINT
    454 
    455 INTERCEPTORS_STRTO(double, wcstod, wchar_t)                     // NOLINT
    456 INTERCEPTORS_STRTO(float, wcstof, wchar_t)                      // NOLINT
    457 INTERCEPTORS_STRTO(long double, wcstold, wchar_t)               // NOLINT
    458 INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t)                  // NOLINT
    459 INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t)            // NOLINT
    460 INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t)        // NOLINT
    461 INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t)  // NOLINT
    462 
    463 #define INTERCEPT_STRTO(func) \
    464   INTERCEPT_FUNCTION(func); \
    465   INTERCEPT_FUNCTION(func##_l); \
    466   INTERCEPT_FUNCTION(__##func##_l); \
    467   INTERCEPT_FUNCTION(__##func##_internal);
    468 
    469 
    470 // FIXME: support *wprintf in common format interceptors.
    471 INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) {
    472   ENSURE_MSAN_INITED();
    473   int res = REAL(vswprintf)(str, size, format, ap);
    474   if (res >= 0) {
    475     __msan_unpoison(str, 4 * (res + 1));
    476   }
    477   return res;
    478 }
    479 
    480 INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) {
    481   ENSURE_MSAN_INITED();
    482   va_list ap;
    483   va_start(ap, format);
    484   int res = vswprintf(str, size, format, ap);
    485   va_end(ap);
    486   return res;
    487 }
    488 
    489 INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T n) {
    490   ENSURE_MSAN_INITED();
    491   CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
    492   SIZE_T res = REAL(strxfrm)(dest, src, n);
    493   if (res < n) __msan_unpoison(dest, res + 1);
    494   return res;
    495 }
    496 
    497 INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T n,
    498             void *loc) {
    499   ENSURE_MSAN_INITED();
    500   CHECK_UNPOISONED(src, REAL(strlen)(src) + 1);
    501   SIZE_T res = REAL(strxfrm_l)(dest, src, n, loc);
    502   if (res < n) __msan_unpoison(dest, res + 1);
    503   return res;
    504 }
    505 
    506 #define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \
    507   ENSURE_MSAN_INITED();                                              \
    508   ret_type res = REAL(func)(s, __VA_ARGS__);                         \
    509   if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1));          \
    510   return res;
    511 
    512 INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format,
    513             __sanitizer_tm *tm) {
    514   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm);
    515 }
    516 
    517 INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
    518             __sanitizer_tm *tm, void *loc) {
    519   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
    520 }
    521 
    522 #if !SANITIZER_FREEBSD
    523 INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
    524             __sanitizer_tm *tm, void *loc) {
    525   INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
    526                             loc);
    527 }
    528 #define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l)
    529 #else
    530 #define MSAN_MAYBE_INTERCEPT___STRFTIME_L
    531 #endif
    532 
    533 INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format,
    534             __sanitizer_tm *tm) {
    535   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm);
    536 }
    537 
    538 INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
    539             __sanitizer_tm *tm, void *loc) {
    540   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm,
    541                             loc);
    542 }
    543 
    544 #if !SANITIZER_FREEBSD
    545 INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
    546             __sanitizer_tm *tm, void *loc) {
    547   INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
    548                             loc);
    549 }
    550 #define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l)
    551 #else
    552 #define MSAN_MAYBE_INTERCEPT___WCSFTIME_L
    553 #endif
    554 
    555 INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) {
    556   ENSURE_MSAN_INITED();
    557   int res = REAL(mbtowc)(dest, src, n);
    558   if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
    559   return res;
    560 }
    561 
    562 INTERCEPTOR(int, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, void *ps) {
    563   ENSURE_MSAN_INITED();
    564   SIZE_T res = REAL(mbrtowc)(dest, src, n, ps);
    565   if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t));
    566   return res;
    567 }
    568 
    569 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
    570   ENSURE_MSAN_INITED();
    571   SIZE_T res = REAL(wcslen)(s);
    572   CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1));
    573   return res;
    574 }
    575 
    576 // wchar_t *wcschr(const wchar_t *wcs, wchar_t wc);
    577 INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) {
    578   ENSURE_MSAN_INITED();
    579   wchar_t *res = REAL(wcschr)(s, wc, ps);
    580   return res;
    581 }
    582 
    583 // wchar_t *wcscpy(wchar_t *dest, const wchar_t *src);
    584 INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) {
    585   ENSURE_MSAN_INITED();
    586   GET_STORE_STACK_TRACE;
    587   wchar_t *res = REAL(wcscpy)(dest, src);
    588   CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1),
    589                       &stack);
    590   return res;
    591 }
    592 
    593 // wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n);
    594 INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    595   ENSURE_MSAN_INITED();
    596   GET_STORE_STACK_TRACE;
    597   wchar_t *res = REAL(wmemcpy)(dest, src, n);
    598   CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
    599   return res;
    600 }
    601 
    602 INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    603   ENSURE_MSAN_INITED();
    604   GET_STORE_STACK_TRACE;
    605   wchar_t *res = REAL(wmempcpy)(dest, src, n);
    606   CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
    607   return res;
    608 }
    609 
    610 INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) {
    611   CHECK(MEM_IS_APP(s));
    612   ENSURE_MSAN_INITED();
    613   wchar_t *res = REAL(wmemset)(s, c, n);
    614   __msan_unpoison(s, n * sizeof(wchar_t));
    615   return res;
    616 }
    617 
    618 INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) {
    619   ENSURE_MSAN_INITED();
    620   GET_STORE_STACK_TRACE;
    621   wchar_t *res = REAL(wmemmove)(dest, src, n);
    622   MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack);
    623   return res;
    624 }
    625 
    626 INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) {
    627   ENSURE_MSAN_INITED();
    628   int res = REAL(wcscmp)(s1, s2);
    629   return res;
    630 }
    631 
    632 INTERCEPTOR(int, gettimeofday, void *tv, void *tz) {
    633   ENSURE_MSAN_INITED();
    634   int res = REAL(gettimeofday)(tv, tz);
    635   if (tv)
    636     __msan_unpoison(tv, 16);
    637   if (tz)
    638     __msan_unpoison(tz, 8);
    639   return res;
    640 }
    641 
    642 INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) {
    643   ENSURE_MSAN_INITED();
    644   char *res = REAL(fcvt)(x, a, b, c);
    645   __msan_unpoison(b, sizeof(*b));
    646   __msan_unpoison(c, sizeof(*c));
    647   if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
    648   return res;
    649 }
    650 
    651 INTERCEPTOR(char *, getenv, char *name) {
    652   if (msan_init_is_running)
    653     return REAL(getenv)(name);
    654   ENSURE_MSAN_INITED();
    655   char *res = REAL(getenv)(name);
    656   if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
    657   return res;
    658 }
    659 
    660 extern char **environ;
    661 
    662 static void UnpoisonEnviron() {
    663   char **envp = environ;
    664   for (; *envp; ++envp) {
    665     __msan_unpoison(envp, sizeof(*envp));
    666     __msan_unpoison(*envp, REAL(strlen)(*envp) + 1);
    667   }
    668   // Trailing NULL pointer.
    669   __msan_unpoison(envp, sizeof(*envp));
    670 }
    671 
    672 INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) {
    673   ENSURE_MSAN_INITED();
    674   CHECK_UNPOISONED_STRING(name, 0)
    675   int res = REAL(setenv)(name, value, overwrite);
    676   if (!res) UnpoisonEnviron();
    677   return res;
    678 }
    679 
    680 INTERCEPTOR(int, putenv, char *string) {
    681   ENSURE_MSAN_INITED();
    682   int res = REAL(putenv)(string);
    683   if (!res) UnpoisonEnviron();
    684   return res;
    685 }
    686 
    687 #if !SANITIZER_FREEBSD
    688 INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
    689   ENSURE_MSAN_INITED();
    690   int res = REAL(__fxstat)(magic, fd, buf);
    691   if (!res)
    692     __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    693   return res;
    694 }
    695 #define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat)
    696 #else
    697 #define MSAN_MAYBE_INTERCEPT___FXSTAT
    698 #endif
    699 
    700 #if !SANITIZER_FREEBSD
    701 INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
    702   ENSURE_MSAN_INITED();
    703   int res = REAL(__fxstat64)(magic, fd, buf);
    704   if (!res)
    705     __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    706   return res;
    707 }
    708 #define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64)
    709 #else
    710 #define MSAN_MAYBE_INTERCEPT___FXSTAT64
    711 #endif
    712 
    713 #if SANITIZER_FREEBSD
    714 INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
    715   ENSURE_MSAN_INITED();
    716   int res = REAL(fstatat)(fd, pathname, buf, flags);
    717   if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    718   return res;
    719 }
    720 # define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat)
    721 #else
    722 INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
    723             int flags) {
    724   ENSURE_MSAN_INITED();
    725   int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags);
    726   if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz);
    727   return res;
    728 }
    729 # define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
    730 #endif
    731 
    732 #if !SANITIZER_FREEBSD
    733 INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
    734             int flags) {
    735   ENSURE_MSAN_INITED();
    736   int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags);
    737   if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz);
    738   return res;
    739 }
    740 #define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64)
    741 #else
    742 #define MSAN_MAYBE_INTERCEPT___FXSTATAT64
    743 #endif
    744 
    745 INTERCEPTOR(int, pipe, int pipefd[2]) {
    746   if (msan_init_is_running)
    747     return REAL(pipe)(pipefd);
    748   ENSURE_MSAN_INITED();
    749   int res = REAL(pipe)(pipefd);
    750   if (!res)
    751     __msan_unpoison(pipefd, sizeof(int[2]));
    752   return res;
    753 }
    754 
    755 INTERCEPTOR(int, pipe2, int pipefd[2], int flags) {
    756   ENSURE_MSAN_INITED();
    757   int res = REAL(pipe2)(pipefd, flags);
    758   if (!res)
    759     __msan_unpoison(pipefd, sizeof(int[2]));
    760   return res;
    761 }
    762 
    763 INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) {
    764   ENSURE_MSAN_INITED();
    765   int res = REAL(socketpair)(domain, type, protocol, sv);
    766   if (!res)
    767     __msan_unpoison(sv, sizeof(int[2]));
    768   return res;
    769 }
    770 
    771 INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
    772   ENSURE_MSAN_INITED();
    773   char *res = REAL(fgets)(s, size, stream);
    774   if (res)
    775     __msan_unpoison(s, REAL(strlen)(s) + 1);
    776   return res;
    777 }
    778 
    779 #if !SANITIZER_FREEBSD
    780 INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
    781   ENSURE_MSAN_INITED();
    782   char *res = REAL(fgets_unlocked)(s, size, stream);
    783   if (res)
    784     __msan_unpoison(s, REAL(strlen)(s) + 1);
    785   return res;
    786 }
    787 #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked)
    788 #else
    789 #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED
    790 #endif
    791 
    792 INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
    793   if (msan_init_is_running)
    794     return REAL(getrlimit)(resource, rlim);
    795   ENSURE_MSAN_INITED();
    796   int res = REAL(getrlimit)(resource, rlim);
    797   if (!res)
    798     __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz);
    799   return res;
    800 }
    801 
    802 #if !SANITIZER_FREEBSD
    803 INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
    804   if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
    805   ENSURE_MSAN_INITED();
    806   int res = REAL(getrlimit64)(resource, rlim);
    807   if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz);
    808   return res;
    809 }
    810 
    811 INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit,
    812             void *old_rlimit) {
    813   if (msan_init_is_running)
    814     return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
    815   ENSURE_MSAN_INITED();
    816   CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz);
    817   int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit);
    818   if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz);
    819   return res;
    820 }
    821 
    822 INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit,
    823             void *old_rlimit) {
    824   if (msan_init_is_running)
    825     return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
    826   ENSURE_MSAN_INITED();
    827   CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz);
    828   int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit);
    829   if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz);
    830   return res;
    831 }
    832 
    833 #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64)
    834 #define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit)
    835 #define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64)
    836 #else
    837 #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64
    838 #define MSAN_MAYBE_INTERCEPT_PRLIMIT
    839 #define MSAN_MAYBE_INTERCEPT_PRLIMIT64
    840 #endif
    841 
    842 #if SANITIZER_FREEBSD
    843 // FreeBSD's <sys/utsname.h> define uname() as
    844 // static __inline int uname(struct utsname *name) {
    845 //   return __xuname(SYS_NMLN, (void*)name);
    846 // }
    847 INTERCEPTOR(int, __xuname, int size, void *utsname) {
    848   ENSURE_MSAN_INITED();
    849   int res = REAL(__xuname)(size, utsname);
    850   if (!res)
    851     __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
    852   return res;
    853 }
    854 #define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname)
    855 #else
    856 INTERCEPTOR(int, uname, struct utsname *utsname) {
    857   ENSURE_MSAN_INITED();
    858   int res = REAL(uname)(utsname);
    859   if (!res)
    860     __msan_unpoison(utsname, __sanitizer::struct_utsname_sz);
    861   return res;
    862 }
    863 #define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname)
    864 #endif
    865 
    866 INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
    867   ENSURE_MSAN_INITED();
    868   int res = REAL(gethostname)(name, len);
    869   if (!res) {
    870     SIZE_T real_len = REAL(strnlen)(name, len);
    871     if (real_len < len)
    872       ++real_len;
    873     __msan_unpoison(name, real_len);
    874   }
    875   return res;
    876 }
    877 
    878 #if !SANITIZER_FREEBSD
    879 INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
    880     int timeout) {
    881   ENSURE_MSAN_INITED();
    882   int res = REAL(epoll_wait)(epfd, events, maxevents, timeout);
    883   if (res > 0) {
    884     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
    885   }
    886   return res;
    887 }
    888 #define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait)
    889 #else
    890 #define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
    891 #endif
    892 
    893 #if !SANITIZER_FREEBSD
    894 INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
    895     int timeout, void *sigmask) {
    896   ENSURE_MSAN_INITED();
    897   int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask);
    898   if (res > 0) {
    899     __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res);
    900   }
    901   return res;
    902 }
    903 #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait)
    904 #else
    905 #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT
    906 #endif
    907 
    908 INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) {
    909   GET_MALLOC_STACK_TRACE;
    910   if (UNLIKELY(!msan_inited)) {
    911     // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
    912     const SIZE_T kCallocPoolSize = 1024;
    913     static uptr calloc_memory_for_dlsym[kCallocPoolSize];
    914     static SIZE_T allocated;
    915     SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize;
    916     void *mem = (void*)&calloc_memory_for_dlsym[allocated];
    917     allocated += size_in_words;
    918     CHECK(allocated < kCallocPoolSize);
    919     return mem;
    920   }
    921   return MsanCalloc(&stack, nmemb, size);
    922 }
    923 
    924 INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) {
    925   GET_MALLOC_STACK_TRACE;
    926   return MsanReallocate(&stack, ptr, size, sizeof(u64), false);
    927 }
    928 
    929 INTERCEPTOR(void *, malloc, SIZE_T size) {
    930   GET_MALLOC_STACK_TRACE;
    931   return MsanReallocate(&stack, nullptr, size, sizeof(u64), false);
    932 }
    933 
    934 void __msan_allocated_memory(const void *data, uptr size) {
    935   GET_MALLOC_STACK_TRACE;
    936   if (flags()->poison_in_malloc) {
    937     stack.tag = STACK_TRACE_TAG_POISON;
    938     PoisonMemory(data, size, &stack);
    939   }
    940 }
    941 
    942 void __msan_copy_shadow(void *dest, const void *src, uptr n) {
    943   GET_STORE_STACK_TRACE;
    944   MoveShadowAndOrigin(dest, src, n, &stack);
    945 }
    946 
    947 void __sanitizer_dtor_callback(const void *data, uptr size) {
    948   GET_MALLOC_STACK_TRACE;
    949   if (flags()->poison_in_dtor) {
    950     stack.tag = STACK_TRACE_TAG_POISON;
    951     PoisonMemory(data, size, &stack);
    952   }
    953 }
    954 
    955 INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
    956             int fd, OFF_T offset) {
    957   if (msan_init_is_running)
    958     return REAL(mmap)(addr, length, prot, flags, fd, offset);
    959   ENSURE_MSAN_INITED();
    960   if (addr && !MEM_IS_APP(addr)) {
    961     if (flags & map_fixed) {
    962       *__errno_location() = errno_EINVAL;
    963       return (void *)-1;
    964     } else {
    965       addr = nullptr;
    966     }
    967   }
    968   void *res = REAL(mmap)(addr, length, prot, flags, fd, offset);
    969   if (res != (void*)-1)
    970     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
    971   return res;
    972 }
    973 
    974 #if !SANITIZER_FREEBSD
    975 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
    976             int fd, OFF64_T offset) {
    977   ENSURE_MSAN_INITED();
    978   if (addr && !MEM_IS_APP(addr)) {
    979     if (flags & map_fixed) {
    980       *__errno_location() = errno_EINVAL;
    981       return (void *)-1;
    982     } else {
    983       addr = nullptr;
    984     }
    985   }
    986   void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset);
    987   if (res != (void*)-1)
    988     __msan_unpoison(res, RoundUpTo(length, GetPageSize()));
    989   return res;
    990 }
    991 #define MSAN_MAYBE_INTERCEPT_MMAP64 INTERCEPT_FUNCTION(mmap64)
    992 #else
    993 #define MSAN_MAYBE_INTERCEPT_MMAP64
    994 #endif
    995 
    996 INTERCEPTOR(int, getrusage, int who, void *usage) {
    997   ENSURE_MSAN_INITED();
    998   int res = REAL(getrusage)(who, usage);
    999   if (res == 0) {
   1000     __msan_unpoison(usage, __sanitizer::struct_rusage_sz);
   1001   }
   1002   return res;
   1003 }
   1004 
   1005 class SignalHandlerScope {
   1006  public:
   1007   SignalHandlerScope() {
   1008     if (MsanThread *t = GetCurrentThread())
   1009       t->EnterSignalHandler();
   1010   }
   1011   ~SignalHandlerScope() {
   1012     if (MsanThread *t = GetCurrentThread())
   1013       t->LeaveSignalHandler();
   1014   }
   1015 };
   1016 
   1017 // sigactions_mu guarantees atomicity of sigaction() and signal() calls.
   1018 // Access to sigactions[] is gone with relaxed atomics to avoid data race with
   1019 // the signal handler.
   1020 const int kMaxSignals = 1024;
   1021 static atomic_uintptr_t sigactions[kMaxSignals];
   1022 static StaticSpinMutex sigactions_mu;
   1023 
   1024 static void SignalHandler(int signo) {
   1025   SignalHandlerScope signal_handler_scope;
   1026   ScopedThreadLocalStateBackup stlsb;
   1027   UnpoisonParam(1);
   1028 
   1029   typedef void (*signal_cb)(int x);
   1030   signal_cb cb =
   1031       (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   1032   cb(signo);
   1033 }
   1034 
   1035 static void SignalAction(int signo, void *si, void *uc) {
   1036   SignalHandlerScope signal_handler_scope;
   1037   ScopedThreadLocalStateBackup stlsb;
   1038   UnpoisonParam(3);
   1039   __msan_unpoison(si, sizeof(__sanitizer_sigaction));
   1040   __msan_unpoison(uc, __sanitizer::ucontext_t_sz);
   1041 
   1042   typedef void (*sigaction_cb)(int, void *, void *);
   1043   sigaction_cb cb =
   1044       (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed);
   1045   cb(signo, si, uc);
   1046 }
   1047 
   1048 INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act,
   1049             __sanitizer_sigaction *oldact) {
   1050   ENSURE_MSAN_INITED();
   1051   // FIXME: check that *act is unpoisoned.
   1052   // That requires intercepting all of sigemptyset, sigfillset, etc.
   1053   int res;
   1054   if (flags()->wrap_signals) {
   1055     SpinMutexLock lock(&sigactions_mu);
   1056     CHECK_LT(signo, kMaxSignals);
   1057     uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed);
   1058     __sanitizer_sigaction new_act;
   1059     __sanitizer_sigaction *pnew_act = act ? &new_act : nullptr;
   1060     if (act) {
   1061       REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction));
   1062       uptr cb = (uptr)pnew_act->sigaction;
   1063       uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo)
   1064                         ? (uptr)SignalAction
   1065                         : (uptr)SignalHandler;
   1066       if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1067         atomic_store(&sigactions[signo], cb, memory_order_relaxed);
   1068         pnew_act->sigaction = (void (*)(int, void *, void *))new_cb;
   1069       }
   1070     }
   1071     res = REAL(sigaction)(signo, pnew_act, oldact);
   1072     if (res == 0 && oldact) {
   1073       uptr cb = (uptr)oldact->sigaction;
   1074       if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1075         oldact->sigaction = (void (*)(int, void *, void *))old_cb;
   1076       }
   1077     }
   1078   } else {
   1079     res = REAL(sigaction)(signo, act, oldact);
   1080   }
   1081 
   1082   if (res == 0 && oldact) {
   1083     __msan_unpoison(oldact, sizeof(__sanitizer_sigaction));
   1084   }
   1085   return res;
   1086 }
   1087 
   1088 INTERCEPTOR(int, signal, int signo, uptr cb) {
   1089   ENSURE_MSAN_INITED();
   1090   if (flags()->wrap_signals) {
   1091     CHECK_LT(signo, kMaxSignals);
   1092     SpinMutexLock lock(&sigactions_mu);
   1093     if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) {
   1094       atomic_store(&sigactions[signo], cb, memory_order_relaxed);
   1095       cb = (uptr) SignalHandler;
   1096     }
   1097     return REAL(signal)(signo, cb);
   1098   } else {
   1099     return REAL(signal)(signo, cb);
   1100   }
   1101 }
   1102 
   1103 extern "C" int pthread_attr_init(void *attr);
   1104 extern "C" int pthread_attr_destroy(void *attr);
   1105 
   1106 static void *MsanThreadStartFunc(void *arg) {
   1107   MsanThread *t = (MsanThread *)arg;
   1108   SetCurrentThread(t);
   1109   return t->ThreadStart();
   1110 }
   1111 
   1112 INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
   1113             void * param) {
   1114   ENSURE_MSAN_INITED(); // for GetTlsSize()
   1115   __sanitizer_pthread_attr_t myattr;
   1116   if (!attr) {
   1117     pthread_attr_init(&myattr);
   1118     attr = &myattr;
   1119   }
   1120 
   1121   AdjustStackSize(attr);
   1122 
   1123   MsanThread *t = MsanThread::Create(callback, param);
   1124 
   1125   int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t);
   1126 
   1127   if (attr == &myattr)
   1128     pthread_attr_destroy(&myattr);
   1129   if (!res) {
   1130     __msan_unpoison(th, __sanitizer::pthread_t_sz);
   1131   }
   1132   return res;
   1133 }
   1134 
   1135 INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key,
   1136             void (*dtor)(void *value)) {
   1137   if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor);
   1138   ENSURE_MSAN_INITED();
   1139   int res = REAL(pthread_key_create)(key, dtor);
   1140   if (!res && key)
   1141     __msan_unpoison(key, sizeof(*key));
   1142   return res;
   1143 }
   1144 
   1145 INTERCEPTOR(int, pthread_join, void *th, void **retval) {
   1146   ENSURE_MSAN_INITED();
   1147   int res = REAL(pthread_join)(th, retval);
   1148   if (!res && retval)
   1149     __msan_unpoison(retval, sizeof(*retval));
   1150   return res;
   1151 }
   1152 
   1153 extern char *tzname[2];
   1154 
   1155 INTERCEPTOR(void, tzset, int fake) {
   1156   ENSURE_MSAN_INITED();
   1157   REAL(tzset)(fake);
   1158   if (tzname[0])
   1159     __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1);
   1160   if (tzname[1])
   1161     __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1);
   1162   return;
   1163 }
   1164 
   1165 struct MSanAtExitRecord {
   1166   void (*func)(void *arg);
   1167   void *arg;
   1168 };
   1169 
   1170 void MSanAtExitWrapper(void *arg) {
   1171   UnpoisonParam(1);
   1172   MSanAtExitRecord *r = (MSanAtExitRecord *)arg;
   1173   r->func(r->arg);
   1174   InternalFree(r);
   1175 }
   1176 
   1177 // Unpoison argument shadow for C++ module destructors.
   1178 INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
   1179             void *dso_handle) {
   1180   if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle);
   1181   ENSURE_MSAN_INITED();
   1182   MSanAtExitRecord *r =
   1183       (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord));
   1184   r->func = func;
   1185   r->arg = arg;
   1186   return REAL(__cxa_atexit)(MSanAtExitWrapper, r, dso_handle);
   1187 }
   1188 
   1189 DECLARE_REAL(int, shmctl, int shmid, int cmd, void *buf)
   1190 
   1191 INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) {
   1192   ENSURE_MSAN_INITED();
   1193   void *p = REAL(shmat)(shmid, shmaddr, shmflg);
   1194   if (p != (void *)-1) {
   1195     __sanitizer_shmid_ds ds;
   1196     int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds);
   1197     if (!res) {
   1198       __msan_unpoison(p, ds.shm_segsz);
   1199     }
   1200   }
   1201   return p;
   1202 }
   1203 
   1204 static void BeforeFork() {
   1205   StackDepotLockAll();
   1206   ChainedOriginDepotLockAll();
   1207 }
   1208 
   1209 static void AfterFork() {
   1210   ChainedOriginDepotUnlockAll();
   1211   StackDepotUnlockAll();
   1212 }
   1213 
   1214 INTERCEPTOR(int, fork, void) {
   1215   ENSURE_MSAN_INITED();
   1216   BeforeFork();
   1217   int pid = REAL(fork)();
   1218   AfterFork();
   1219   return pid;
   1220 }
   1221 
   1222 INTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name,
   1223             const void *termp, const void *winp) {
   1224   ENSURE_MSAN_INITED();
   1225   InterceptorScope interceptor_scope;
   1226   int res = REAL(openpty)(amaster, aslave, name, termp, winp);
   1227   if (!res) {
   1228     __msan_unpoison(amaster, sizeof(*amaster));
   1229     __msan_unpoison(aslave, sizeof(*aslave));
   1230   }
   1231   return res;
   1232 }
   1233 
   1234 INTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp,
   1235             const void *winp) {
   1236   ENSURE_MSAN_INITED();
   1237   InterceptorScope interceptor_scope;
   1238   int res = REAL(forkpty)(amaster, name, termp, winp);
   1239   if (res != -1)
   1240     __msan_unpoison(amaster, sizeof(*amaster));
   1241   return res;
   1242 }
   1243 
   1244 struct MSanInterceptorContext {
   1245   bool in_interceptor_scope;
   1246 };
   1247 
   1248 namespace __msan {
   1249 
   1250 int OnExit() {
   1251   // FIXME: ask frontend whether we need to return failure.
   1252   return 0;
   1253 }
   1254 
   1255 } // namespace __msan
   1256 
   1257 // A version of CHECK_UNPOISONED using a saved scope value. Used in common
   1258 // interceptors.
   1259 #define CHECK_UNPOISONED_CTX(ctx, x, n)                         \
   1260   do {                                                          \
   1261     if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \
   1262       CHECK_UNPOISONED_0(x, n);                                 \
   1263   } while (0)
   1264 
   1265 #define MSAN_INTERCEPT_FUNC(name)                                       \
   1266   do {                                                                  \
   1267     if ((!INTERCEPT_FUNCTION(name) || !REAL(name)))                     \
   1268       VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \
   1269   } while (0)
   1270 
   1271 #define MSAN_INTERCEPT_FUNC_VER(name, ver)                                    \
   1272   do {                                                                        \
   1273     if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name)))                  \
   1274       VReport(                                                                \
   1275           1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
   1276   } while (0)
   1277 
   1278 #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name)
   1279 #define COMMON_INTERCEPT_FUNCTION_VER(name, ver)                          \
   1280   MSAN_INTERCEPT_FUNC_VER(name, ver)
   1281 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count)  \
   1282   UnpoisonParam(count)
   1283 #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
   1284   __msan_unpoison(ptr, size)
   1285 #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
   1286   CHECK_UNPOISONED_CTX(ctx, ptr, size)
   1287 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \
   1288   __msan_unpoison(ptr, size)
   1289 #define COMMON_INTERCEPTOR_ENTER(ctx, func, ...)                  \
   1290   if (msan_init_is_running) return REAL(func)(__VA_ARGS__);       \
   1291   ENSURE_MSAN_INITED();                                           \
   1292   MSanInterceptorContext msan_ctx = {IsInInterceptorScope()};     \
   1293   ctx = (void *)&msan_ctx;                                        \
   1294   (void)ctx;                                                      \
   1295   InterceptorScope interceptor_scope;                             \
   1296   __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */
   1297 #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
   1298   do {                                            \
   1299   } while (false)
   1300 #define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
   1301   do {                                         \
   1302   } while (false)
   1303 #define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
   1304   do {                                         \
   1305   } while (false)
   1306 #define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
   1307   do {                                                      \
   1308   } while (false)
   1309 #define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \
   1310   do {                                                \
   1311   } while (false)  // FIXME
   1312 #define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
   1313   do {                                                         \
   1314   } while (false)  // FIXME
   1315 #define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
   1316 #define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
   1317 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)                    \
   1318   do {                                                                         \
   1319     link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle));                   \
   1320     if (filename && map)                                                       \
   1321       ForEachMappedRegion(map, __msan_unpoison);                               \
   1322   } while (false)
   1323 
   1324 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end)                           \
   1325   if (MsanThread *t = GetCurrentThread()) {                                    \
   1326     *begin = t->tls_begin();                                                   \
   1327     *end = t->tls_end();                                                       \
   1328   } else {                                                                     \
   1329     *begin = *end = 0;                                                         \
   1330   }
   1331 
   1332 #include "sanitizer_common/sanitizer_platform_interceptors.h"
   1333 // Msan needs custom handling of these:
   1334 #undef SANITIZER_INTERCEPT_MEMSET
   1335 #undef SANITIZER_INTERCEPT_MEMMOVE
   1336 #undef SANITIZER_INTERCEPT_MEMCPY
   1337 #include "sanitizer_common/sanitizer_common_interceptors.inc"
   1338 
   1339 #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s)
   1340 #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \
   1341   do {                                       \
   1342   } while (false)
   1343 #define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
   1344   do {                                       \
   1345   } while (false)
   1346 #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s)
   1347 #include "sanitizer_common/sanitizer_common_syscalls.inc"
   1348 
   1349 struct dlinfo {
   1350   char *dli_fname;
   1351   void *dli_fbase;
   1352   char *dli_sname;
   1353   void *dli_saddr;
   1354 };
   1355 
   1356 INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) {
   1357   void *ctx;
   1358   COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info);
   1359   int res = REAL(dladdr)(addr, info);
   1360   if (res != 0) {
   1361     __msan_unpoison(info, sizeof(*info));
   1362     if (info->dli_fname)
   1363       __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1);
   1364     if (info->dli_sname)
   1365       __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1);
   1366   }
   1367   return res;
   1368 }
   1369 
   1370 INTERCEPTOR(char *, dlerror, int fake) {
   1371   void *ctx;
   1372   COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake);
   1373   char *res = REAL(dlerror)(fake);
   1374   if (res) __msan_unpoison(res, REAL(strlen)(res) + 1);
   1375   return res;
   1376 }
   1377 
   1378 typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size,
   1379                                   void *data);
   1380 struct dl_iterate_phdr_data {
   1381   dl_iterate_phdr_cb callback;
   1382   void *data;
   1383 };
   1384 
   1385 static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size,
   1386                                    void *data) {
   1387   if (info) {
   1388     __msan_unpoison(info, size);
   1389     if (info->dlpi_phdr && info->dlpi_phnum)
   1390       __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum);
   1391     if (info->dlpi_name)
   1392       __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1);
   1393   }
   1394   dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data;
   1395   UnpoisonParam(3);
   1396   return cbdata->callback(info, size, cbdata->data);
   1397 }
   1398 
   1399 INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) {
   1400   void *ctx;
   1401   COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data);
   1402   dl_iterate_phdr_data cbdata;
   1403   cbdata.callback = callback;
   1404   cbdata.data = data;
   1405   int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata);
   1406   return res;
   1407 }
   1408 
   1409 // These interface functions reside here so that they can use
   1410 // REAL(memset), etc.
   1411 void __msan_unpoison(const void *a, uptr size) {
   1412   if (!MEM_IS_APP(a)) return;
   1413   SetShadow(a, size, 0);
   1414 }
   1415 
   1416 void __msan_poison(const void *a, uptr size) {
   1417   if (!MEM_IS_APP(a)) return;
   1418   SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1);
   1419 }
   1420 
   1421 void __msan_poison_stack(void *a, uptr size) {
   1422   if (!MEM_IS_APP(a)) return;
   1423   SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1);
   1424 }
   1425 
   1426 void __msan_clear_and_unpoison(void *a, uptr size) {
   1427   REAL(memset)(a, 0, size);
   1428   SetShadow(a, size, 0);
   1429 }
   1430 
   1431 void *__msan_memcpy(void *dest, const void *src, SIZE_T n) {
   1432   if (!msan_inited) return internal_memcpy(dest, src, n);
   1433   if (msan_init_is_running || __msan::IsInSymbolizer())
   1434     return REAL(memcpy)(dest, src, n);
   1435   ENSURE_MSAN_INITED();
   1436   GET_STORE_STACK_TRACE;
   1437   void *res = REAL(memcpy)(dest, src, n);
   1438   CopyShadowAndOrigin(dest, src, n, &stack);
   1439   return res;
   1440 }
   1441 
   1442 void *__msan_memset(void *s, int c, SIZE_T n) {
   1443   if (!msan_inited) return internal_memset(s, c, n);
   1444   if (msan_init_is_running) return REAL(memset)(s, c, n);
   1445   ENSURE_MSAN_INITED();
   1446   void *res = REAL(memset)(s, c, n);
   1447   __msan_unpoison(s, n);
   1448   return res;
   1449 }
   1450 
   1451 void *__msan_memmove(void *dest, const void *src, SIZE_T n) {
   1452   if (!msan_inited) return internal_memmove(dest, src, n);
   1453   if (msan_init_is_running) return REAL(memmove)(dest, src, n);
   1454   ENSURE_MSAN_INITED();
   1455   GET_STORE_STACK_TRACE;
   1456   void *res = REAL(memmove)(dest, src, n);
   1457   MoveShadowAndOrigin(dest, src, n, &stack);
   1458   return res;
   1459 }
   1460 
   1461 void __msan_unpoison_string(const char* s) {
   1462   if (!MEM_IS_APP(s)) return;
   1463   __msan_unpoison(s, REAL(strlen)(s) + 1);
   1464 }
   1465 
   1466 namespace __msan {
   1467 
   1468 void InitializeInterceptors() {
   1469   static int inited = 0;
   1470   CHECK_EQ(inited, 0);
   1471   InitializeCommonInterceptors();
   1472 
   1473   INTERCEPT_FUNCTION(mmap);
   1474   MSAN_MAYBE_INTERCEPT_MMAP64;
   1475   INTERCEPT_FUNCTION(posix_memalign);
   1476   MSAN_MAYBE_INTERCEPT_MEMALIGN;
   1477   INTERCEPT_FUNCTION(__libc_memalign);
   1478   INTERCEPT_FUNCTION(valloc);
   1479   MSAN_MAYBE_INTERCEPT_PVALLOC;
   1480   INTERCEPT_FUNCTION(malloc);
   1481   INTERCEPT_FUNCTION(calloc);
   1482   INTERCEPT_FUNCTION(realloc);
   1483   INTERCEPT_FUNCTION(free);
   1484   MSAN_MAYBE_INTERCEPT_CFREE;
   1485   INTERCEPT_FUNCTION(malloc_usable_size);
   1486   MSAN_MAYBE_INTERCEPT_MALLINFO;
   1487   MSAN_MAYBE_INTERCEPT_MALLOPT;
   1488   MSAN_MAYBE_INTERCEPT_MALLOC_STATS;
   1489   INTERCEPT_FUNCTION(fread);
   1490   MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED;
   1491   INTERCEPT_FUNCTION(readlink);
   1492   INTERCEPT_FUNCTION(memcpy);
   1493   INTERCEPT_FUNCTION(memccpy);
   1494   INTERCEPT_FUNCTION(mempcpy);
   1495   INTERCEPT_FUNCTION(memset);
   1496   INTERCEPT_FUNCTION(memmove);
   1497   INTERCEPT_FUNCTION(bcopy);
   1498   INTERCEPT_FUNCTION(wmemset);
   1499   INTERCEPT_FUNCTION(wmemcpy);
   1500   INTERCEPT_FUNCTION(wmempcpy);
   1501   INTERCEPT_FUNCTION(wmemmove);
   1502   INTERCEPT_FUNCTION(strcpy);  // NOLINT
   1503   INTERCEPT_FUNCTION(stpcpy);  // NOLINT
   1504   INTERCEPT_FUNCTION(strdup);
   1505   MSAN_MAYBE_INTERCEPT___STRDUP;
   1506   INTERCEPT_FUNCTION(strndup);
   1507   MSAN_MAYBE_INTERCEPT___STRNDUP;
   1508   INTERCEPT_FUNCTION(strncpy);  // NOLINT
   1509   INTERCEPT_FUNCTION(gcvt);
   1510   INTERCEPT_FUNCTION(strcat);  // NOLINT
   1511   INTERCEPT_FUNCTION(strncat);  // NOLINT
   1512   INTERCEPT_STRTO(strtod);
   1513   INTERCEPT_STRTO(strtof);
   1514   INTERCEPT_STRTO(strtold);
   1515   INTERCEPT_STRTO(strtol);
   1516   INTERCEPT_STRTO(strtoul);
   1517   INTERCEPT_STRTO(strtoll);
   1518   INTERCEPT_STRTO(strtoull);
   1519   INTERCEPT_STRTO(wcstod);
   1520   INTERCEPT_STRTO(wcstof);
   1521   INTERCEPT_STRTO(wcstold);
   1522   INTERCEPT_STRTO(wcstol);
   1523   INTERCEPT_STRTO(wcstoul);
   1524   INTERCEPT_STRTO(wcstoll);
   1525   INTERCEPT_STRTO(wcstoull);
   1526 #ifdef SANITIZER_NLDBL_VERSION
   1527   INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION);
   1528   INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION);
   1529 #else
   1530   INTERCEPT_FUNCTION(vswprintf);
   1531   INTERCEPT_FUNCTION(swprintf);
   1532 #endif
   1533   INTERCEPT_FUNCTION(strxfrm);
   1534   INTERCEPT_FUNCTION(strxfrm_l);
   1535   INTERCEPT_FUNCTION(strftime);
   1536   INTERCEPT_FUNCTION(strftime_l);
   1537   MSAN_MAYBE_INTERCEPT___STRFTIME_L;
   1538   INTERCEPT_FUNCTION(wcsftime);
   1539   INTERCEPT_FUNCTION(wcsftime_l);
   1540   MSAN_MAYBE_INTERCEPT___WCSFTIME_L;
   1541   INTERCEPT_FUNCTION(mbtowc);
   1542   INTERCEPT_FUNCTION(mbrtowc);
   1543   INTERCEPT_FUNCTION(wcslen);
   1544   INTERCEPT_FUNCTION(wcschr);
   1545   INTERCEPT_FUNCTION(wcscpy);
   1546   INTERCEPT_FUNCTION(wcscmp);
   1547   INTERCEPT_FUNCTION(getenv);
   1548   INTERCEPT_FUNCTION(setenv);
   1549   INTERCEPT_FUNCTION(putenv);
   1550   INTERCEPT_FUNCTION(gettimeofday);
   1551   INTERCEPT_FUNCTION(fcvt);
   1552   MSAN_MAYBE_INTERCEPT___FXSTAT;
   1553   MSAN_INTERCEPT_FSTATAT;
   1554   MSAN_MAYBE_INTERCEPT___FXSTAT64;
   1555   MSAN_MAYBE_INTERCEPT___FXSTATAT64;
   1556   INTERCEPT_FUNCTION(pipe);
   1557   INTERCEPT_FUNCTION(pipe2);
   1558   INTERCEPT_FUNCTION(socketpair);
   1559   INTERCEPT_FUNCTION(fgets);
   1560   MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED;
   1561   INTERCEPT_FUNCTION(getrlimit);
   1562   MSAN_MAYBE_INTERCEPT_GETRLIMIT64;
   1563   MSAN_MAYBE_INTERCEPT_PRLIMIT;
   1564   MSAN_MAYBE_INTERCEPT_PRLIMIT64;
   1565   MSAN_INTERCEPT_UNAME;
   1566   INTERCEPT_FUNCTION(gethostname);
   1567   MSAN_MAYBE_INTERCEPT_EPOLL_WAIT;
   1568   MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT;
   1569   INTERCEPT_FUNCTION(dladdr);
   1570   INTERCEPT_FUNCTION(dlerror);
   1571   INTERCEPT_FUNCTION(dl_iterate_phdr);
   1572   INTERCEPT_FUNCTION(getrusage);
   1573   INTERCEPT_FUNCTION(sigaction);
   1574   INTERCEPT_FUNCTION(signal);
   1575 #if defined(__mips__)
   1576   INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2");
   1577 #else
   1578   INTERCEPT_FUNCTION(pthread_create);
   1579 #endif
   1580   INTERCEPT_FUNCTION(pthread_key_create);
   1581   INTERCEPT_FUNCTION(pthread_join);
   1582   INTERCEPT_FUNCTION(tzset);
   1583   INTERCEPT_FUNCTION(__cxa_atexit);
   1584   INTERCEPT_FUNCTION(shmat);
   1585   INTERCEPT_FUNCTION(fork);
   1586   INTERCEPT_FUNCTION(openpty);
   1587   INTERCEPT_FUNCTION(forkpty);
   1588 
   1589   inited = 1;
   1590 }
   1591 } // namespace __msan
   1592