Home | History | Annotate | Download | only in sanitizer_common
      1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
      2 //
      3 //                     The LLVM Compiler Infrastructure
      4 //
      5 // This file is distributed under the University of Illinois Open Source
      6 // License. See LICENSE.TXT for details.
      7 //
      8 //===----------------------------------------------------------------------===//
      9 //
     10 // Common function interceptors for tools like AddressSanitizer,
     11 // ThreadSanitizer, MemorySanitizer, etc.
     12 //
     13 // This file should be included into the tool's interceptor file,
     14 // which has to define its own macros:
     15 //   COMMON_INTERCEPTOR_ENTER
     16 //   COMMON_INTERCEPTOR_ENTER_NOIGNORE
     17 //   COMMON_INTERCEPTOR_READ_RANGE
     18 //   COMMON_INTERCEPTOR_WRITE_RANGE
     19 //   COMMON_INTERCEPTOR_INITIALIZE_RANGE
     20 //   COMMON_INTERCEPTOR_DIR_ACQUIRE
     21 //   COMMON_INTERCEPTOR_FD_ACQUIRE
     22 //   COMMON_INTERCEPTOR_FD_RELEASE
     23 //   COMMON_INTERCEPTOR_FD_ACCESS
     24 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
     25 //   COMMON_INTERCEPTOR_ON_DLOPEN
     26 //   COMMON_INTERCEPTOR_ON_EXIT
     27 //   COMMON_INTERCEPTOR_MUTEX_LOCK
     28 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
     29 //   COMMON_INTERCEPTOR_MUTEX_REPAIR
     30 //   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
     31 //   COMMON_INTERCEPTOR_HANDLE_RECVMSG
     32 //   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
     33 //===----------------------------------------------------------------------===//
     34 
     35 #include "interception/interception.h"
     36 #include "sanitizer_addrhashmap.h"
     37 #include "sanitizer_placement_new.h"
     38 #include "sanitizer_platform_interceptors.h"
     39 #include "sanitizer_tls_get_addr.h"
     40 
     41 #include <stdarg.h>
     42 
     43 #if SANITIZER_INTERCEPTOR_HOOKS
     44 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \
     45   do {                                                                         \
     46     if (f)                                                                     \
     47       f(__VA_ARGS__);                                                          \
     48   } while (false);
     49 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)                                  \
     50   extern "C" {                                                                 \
     51   SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);  \
     52   } // extern "C"
     53 #else
     54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
     55 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
     56 
     57 #endif  // SANITIZER_INTERCEPTOR_HOOKS
     58 
     59 #if SANITIZER_WINDOWS && !defined(va_copy)
     60 #define va_copy(dst, src) ((dst) = (src))
     61 #endif // _WIN32
     62 
     63 #if SANITIZER_FREEBSD
     64 #define pthread_setname_np pthread_set_name_np
     65 #define inet_aton __inet_aton
     66 #define inet_pton __inet_pton
     67 #define iconv __bsd_iconv
     68 #endif
     69 
     70 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
     71 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
     72 #endif
     73 
     74 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
     75 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
     76 #endif
     77 
     78 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
     79 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
     80 #endif
     81 
     82 #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
     83 #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
     84 #endif
     85 
     86 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
     87 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
     88 #endif
     89 
     90 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
     91 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
     92 #endif
     93 
     94 #ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
     95 #define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
     96 #endif
     97 
     98 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
     99 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
    100 #endif
    101 
    102 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
    103 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
    104 #endif
    105 
    106 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
    107 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
    108 #endif
    109 
    110 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
    111 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
    112 #endif
    113 
    114 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
    115 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
    116 #endif
    117 
    118 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
    119 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
    120   COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
    121 #endif
    122 
    123 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
    124 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
    125 #endif
    126 
    127 #define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \
    128     COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
    129       common_flags()->strict_string_checks ? (len) + 1 : (n) )
    130 
    131 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
    132     COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
    133 
    134 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
    135 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
    136 #endif
    137 
    138 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
    139 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
    140 #endif
    141 
    142 #ifndef COMMON_INTERCEPTOR_ACQUIRE
    143 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
    144 #endif
    145 
    146 #ifndef COMMON_INTERCEPTOR_RELEASE
    147 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
    148 #endif
    149 
    150 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
    151 #define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
    152 #endif
    153 
    154 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
    155 #define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
    156 #endif
    157 
    158 #ifdef SANITIZER_NLDBL_VERSION
    159 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
    160     COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
    161 #else
    162 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
    163     COMMON_INTERCEPT_FUNCTION(fn)
    164 #endif
    165 
    166 struct FileMetadata {
    167   // For open_memstream().
    168   char **addr;
    169   SIZE_T *size;
    170 };
    171 
    172 struct CommonInterceptorMetadata {
    173   enum {
    174     CIMT_INVALID = 0,
    175     CIMT_FILE
    176   } type;
    177   union {
    178     FileMetadata file;
    179   };
    180 };
    181 
    182 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
    183 
    184 static MetadataHashMap *interceptor_metadata_map;
    185 
    186 #if SI_NOT_WINDOWS
    187 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
    188                                           const FileMetadata &file) {
    189   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
    190   CHECK(h.created());
    191   h->type = CommonInterceptorMetadata::CIMT_FILE;
    192   h->file = file;
    193 }
    194 
    195 UNUSED static const FileMetadata *GetInterceptorMetadata(
    196     __sanitizer_FILE *addr) {
    197   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
    198                             /* remove */ false,
    199                             /* create */ false);
    200   if (h.exists()) {
    201     CHECK(!h.created());
    202     CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
    203     return &h->file;
    204   } else {
    205     return 0;
    206   }
    207 }
    208 
    209 UNUSED static void DeleteInterceptorMetadata(void *addr) {
    210   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
    211   CHECK(h.exists());
    212 }
    213 #endif  // SI_NOT_WINDOWS
    214 
    215 #if SANITIZER_INTERCEPT_STRLEN
    216 INTERCEPTOR(SIZE_T, strlen, const char *s) {
    217   // Sometimes strlen is called prior to InitializeCommonInterceptors,
    218   // in which case the REAL(strlen) typically used in
    219   // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
    220   // to handle that.
    221   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    222     return internal_strlen(s);
    223   void *ctx;
    224   COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
    225   SIZE_T result = REAL(strlen)(s);
    226   if (common_flags()->intercept_strlen)
    227     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
    228   return result;
    229 }
    230 #define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
    231 #else
    232 #define INIT_STRLEN
    233 #endif
    234 
    235 #if SANITIZER_INTERCEPT_STRNLEN
    236 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
    237   void *ctx;
    238   COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
    239   SIZE_T length = REAL(strnlen)(s, maxlen);
    240   if (common_flags()->intercept_strlen)
    241     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
    242   return length;
    243 }
    244 #define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
    245 #else
    246 #define INIT_STRNLEN
    247 #endif
    248 
    249 #if SANITIZER_INTERCEPT_TEXTDOMAIN
    250 INTERCEPTOR(char*, textdomain, const char *domainname) {
    251   void *ctx;
    252   COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
    253   COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
    254   char *domain = REAL(textdomain)(domainname);
    255   if (domain) {
    256     COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
    257   }
    258   return domain;
    259 }
    260 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
    261 #else
    262 #define INIT_TEXTDOMAIN
    263 #endif
    264 
    265 #if SANITIZER_INTERCEPT_STRCMP
    266 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
    267   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
    268 }
    269 
    270 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
    271                               const char *s1, const char *s2, int result)
    272 
    273 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
    274   void *ctx;
    275   COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
    276   unsigned char c1, c2;
    277   uptr i;
    278   for (i = 0;; i++) {
    279     c1 = (unsigned char)s1[i];
    280     c2 = (unsigned char)s2[i];
    281     if (c1 != c2 || c1 == '\0') break;
    282   }
    283   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
    284   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
    285   int result = CharCmpX(c1, c2);
    286   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
    287                              s2, result);
    288   return result;
    289 }
    290 
    291 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
    292                               const char *s1, const char *s2, uptr n,
    293                               int result)
    294 
    295 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
    296   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    297     return internal_strncmp(s1, s2, size);
    298   void *ctx;
    299   COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
    300   unsigned char c1 = 0, c2 = 0;
    301   uptr i;
    302   for (i = 0; i < size; i++) {
    303     c1 = (unsigned char)s1[i];
    304     c2 = (unsigned char)s2[i];
    305     if (c1 != c2 || c1 == '\0') break;
    306   }
    307   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
    308   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
    309   int result = CharCmpX(c1, c2);
    310   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
    311                              s2, size, result);
    312   return result;
    313 }
    314 
    315 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
    316 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
    317 #else
    318 #define INIT_STRCMP
    319 #define INIT_STRNCMP
    320 #endif
    321 
    322 #if SANITIZER_INTERCEPT_STRCASECMP
    323 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
    324   int c1_low = ToLower(c1);
    325   int c2_low = ToLower(c2);
    326   return c1_low - c2_low;
    327 }
    328 
    329 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
    330   void *ctx;
    331   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
    332   unsigned char c1 = 0, c2 = 0;
    333   uptr i;
    334   for (i = 0;; i++) {
    335     c1 = (unsigned char)s1[i];
    336     c2 = (unsigned char)s2[i];
    337     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    338   }
    339   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
    340   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
    341   return CharCaseCmp(c1, c2);
    342 }
    343 
    344 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
    345   void *ctx;
    346   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
    347   unsigned char c1 = 0, c2 = 0;
    348   uptr i;
    349   for (i = 0; i < n; i++) {
    350     c1 = (unsigned char)s1[i];
    351     c2 = (unsigned char)s2[i];
    352     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
    353   }
    354   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
    355   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
    356   return CharCaseCmp(c1, c2);
    357 }
    358 
    359 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
    360 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
    361 #else
    362 #define INIT_STRCASECMP
    363 #define INIT_STRNCASECMP
    364 #endif
    365 
    366 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
    367 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
    368                                const char *s2) {
    369     uptr len1 = REAL(strlen)(s1);
    370     uptr len2 = REAL(strlen)(s2);
    371     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
    372                                           r ? r - s1 + len2 : len1 + 1);
    373     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
    374 }
    375 #endif
    376 
    377 #if SANITIZER_INTERCEPT_STRSTR
    378 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
    379   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    380     return internal_strstr(s1, s2);
    381   void *ctx;
    382   COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
    383   char *r = REAL(strstr)(s1, s2);
    384   if (common_flags()->intercept_strstr)
    385     StrstrCheck(ctx, r, s1, s2);
    386   return r;
    387 }
    388 
    389 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
    390 #else
    391 #define INIT_STRSTR
    392 #endif
    393 
    394 #if SANITIZER_INTERCEPT_STRCASESTR
    395 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
    396   void *ctx;
    397   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
    398   char *r = REAL(strcasestr)(s1, s2);
    399   if (common_flags()->intercept_strstr)
    400     StrstrCheck(ctx, r, s1, s2);
    401   return r;
    402 }
    403 
    404 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
    405 #else
    406 #define INIT_STRCASESTR
    407 #endif
    408 
    409 #if SANITIZER_INTERCEPT_STRCHR
    410 INTERCEPTOR(char*, strchr, const char *s, int c) {
    411   void *ctx;
    412   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    413     return internal_strchr(s, c);
    414   COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
    415   char *result = REAL(strchr)(s, c);
    416   uptr len = internal_strlen(s);
    417   uptr n = result ? result - s + 1 : len + 1;
    418   if (common_flags()->intercept_strchr)
    419     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n);
    420   return result;
    421 }
    422 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
    423 #else
    424 #define INIT_STRCHR
    425 #endif
    426 
    427 #if SANITIZER_INTERCEPT_STRCHRNUL
    428 INTERCEPTOR(char*, strchrnul, const char *s, int c) {
    429   void *ctx;
    430   COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
    431   char *result = REAL(strchrnul)(s, c);
    432   uptr len = result - s + 1;
    433   if (common_flags()->intercept_strchr)
    434     COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
    435   return result;
    436 }
    437 #define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
    438 #else
    439 #define INIT_STRCHRNUL
    440 #endif
    441 
    442 #if SANITIZER_INTERCEPT_STRRCHR
    443 INTERCEPTOR(char*, strrchr, const char *s, int c) {
    444   void *ctx;
    445   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    446     return internal_strrchr(s, c);
    447   COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
    448   uptr len = internal_strlen(s);
    449   if (common_flags()->intercept_strchr)
    450     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, len + 1);
    451   return REAL(strrchr)(s, c);
    452 }
    453 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
    454 #else
    455 #define INIT_STRRCHR
    456 #endif
    457 
    458 #if SANITIZER_INTERCEPT_STRSPN
    459 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
    460   void *ctx;
    461   COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
    462   SIZE_T r = REAL(strspn)(s1, s2);
    463   if (common_flags()->intercept_strspn) {
    464     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    465     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
    466   }
    467   return r;
    468 }
    469 
    470 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
    471   void *ctx;
    472   COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
    473   SIZE_T r = REAL(strcspn)(s1, s2);
    474   if (common_flags()->intercept_strspn) {
    475     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    476     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
    477   }
    478   return r;
    479 }
    480 
    481 #define INIT_STRSPN \
    482   COMMON_INTERCEPT_FUNCTION(strspn); \
    483   COMMON_INTERCEPT_FUNCTION(strcspn);
    484 #else
    485 #define INIT_STRSPN
    486 #endif
    487 
    488 #if SANITIZER_INTERCEPT_STRPBRK
    489 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
    490   void *ctx;
    491   COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
    492   char *r = REAL(strpbrk)(s1, s2);
    493   if (common_flags()->intercept_strpbrk) {
    494     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
    495     COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
    496         r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
    497   }
    498   return r;
    499 }
    500 
    501 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
    502 #else
    503 #define INIT_STRPBRK
    504 #endif
    505 
    506 #if SANITIZER_INTERCEPT_MEMSET
    507 INTERCEPTOR(void*, memset, void *dst, int v, uptr size) {
    508   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    509     return internal_memset(dst, v, size);
    510   void *ctx;
    511   COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);
    512   if (common_flags()->intercept_intrin)
    513     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
    514   return REAL(memset)(dst, v, size);
    515 }
    516 
    517 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
    518 #else
    519 #define INIT_MEMSET
    520 #endif
    521 
    522 #if SANITIZER_INTERCEPT_MEMMOVE
    523 INTERCEPTOR(void*, memmove, void *dst, const void *src, uptr size) {
    524   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    525     return internal_memmove(dst, src, size);
    526   void *ctx;
    527   COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);
    528   if (common_flags()->intercept_intrin) {
    529     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
    530     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
    531   }
    532   return REAL(memmove)(dst, src, size);
    533 }
    534 
    535 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
    536 #else
    537 #define INIT_MEMMOVE
    538 #endif
    539 
    540 #if SANITIZER_INTERCEPT_MEMCPY
    541 INTERCEPTOR(void*, memcpy, void *dst, const void *src, uptr size) {
    542   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {
    543     // On OS X, calling internal_memcpy here will cause memory corruptions,
    544     // because memcpy and memmove are actually aliases of the same
    545     // implementation.  We need to use internal_memmove here.
    546     return internal_memmove(dst, src, size);
    547   }
    548   void *ctx;
    549   COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);
    550   if (common_flags()->intercept_intrin) {
    551     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);
    552     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);
    553   }
    554   // N.B.: If we switch this to internal_ we'll have to use internal_memmove
    555   // due to memcpy being an alias of memmove on OS X.
    556   return REAL(memcpy)(dst, src, size);
    557 }
    558 
    559 #define INIT_MEMCPY COMMON_INTERCEPT_FUNCTION(memcpy)
    560 #else
    561 #define INIT_MEMCPY
    562 #endif
    563 
    564 #if SANITIZER_INTERCEPT_MEMCMP
    565 
    566 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
    567                               const void *s1, const void *s2, uptr n,
    568                               int result)
    569 
    570 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
    571   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    572     return internal_memcmp(a1, a2, size);
    573   void *ctx;
    574   COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
    575   if (common_flags()->intercept_memcmp) {
    576     if (common_flags()->strict_memcmp) {
    577       // Check the entire regions even if the first bytes of the buffers are
    578       // different.
    579       COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
    580       COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
    581       // Fallthrough to REAL(memcmp) below.
    582     } else {
    583       unsigned char c1 = 0, c2 = 0;
    584       const unsigned char *s1 = (const unsigned char*)a1;
    585       const unsigned char *s2 = (const unsigned char*)a2;
    586       uptr i;
    587       for (i = 0; i < size; i++) {
    588         c1 = s1[i];
    589         c2 = s2[i];
    590         if (c1 != c2) break;
    591       }
    592       COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
    593       COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
    594       int r = CharCmpX(c1, c2);
    595       CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
    596                                  a1, a2, size, r);
    597       return r;
    598     }
    599   }
    600   int result = REAL(memcmp(a1, a2, size));
    601   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
    602                              a2, size, result);
    603   return result;
    604 }
    605 
    606 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
    607 #else
    608 #define INIT_MEMCMP
    609 #endif
    610 
    611 #if SANITIZER_INTERCEPT_MEMCHR
    612 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
    613   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
    614     return internal_memchr(s, c, n);
    615   void *ctx;
    616   COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
    617   void *res = REAL(memchr)(s, c, n);
    618   uptr len = res ? (char *)res - (const char *)s + 1 : n;
    619   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
    620   return res;
    621 }
    622 
    623 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
    624 #else
    625 #define INIT_MEMCHR
    626 #endif
    627 
    628 #if SANITIZER_INTERCEPT_MEMRCHR
    629 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
    630   void *ctx;
    631   COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
    632   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
    633   return REAL(memrchr)(s, c, n);
    634 }
    635 
    636 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
    637 #else
    638 #define INIT_MEMRCHR
    639 #endif
    640 
    641 #if SANITIZER_INTERCEPT_FREXP
    642 INTERCEPTOR(double, frexp, double x, int *exp) {
    643   void *ctx;
    644   COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
    645   // Assuming frexp() always writes to |exp|.
    646   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    647   double res = REAL(frexp)(x, exp);
    648   return res;
    649 }
    650 
    651 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
    652 #else
    653 #define INIT_FREXP
    654 #endif  // SANITIZER_INTERCEPT_FREXP
    655 
    656 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
    657 INTERCEPTOR(float, frexpf, float x, int *exp) {
    658   void *ctx;
    659   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
    660   // FIXME: under ASan the call below may write to freed memory and corrupt
    661   // its metadata. See
    662   // https://github.com/google/sanitizers/issues/321.
    663   float res = REAL(frexpf)(x, exp);
    664   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    665   return res;
    666 }
    667 
    668 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
    669   void *ctx;
    670   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
    671   // FIXME: under ASan the call below may write to freed memory and corrupt
    672   // its metadata. See
    673   // https://github.com/google/sanitizers/issues/321.
    674   long double res = REAL(frexpl)(x, exp);
    675   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
    676   return res;
    677 }
    678 
    679 #define INIT_FREXPF_FREXPL           \
    680   COMMON_INTERCEPT_FUNCTION(frexpf); \
    681   COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
    682 #else
    683 #define INIT_FREXPF_FREXPL
    684 #endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
    685 
    686 #if SI_NOT_WINDOWS
    687 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
    688                         SIZE_T iovlen, SIZE_T maxlen) {
    689   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
    690     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
    691     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
    692     maxlen -= sz;
    693   }
    694 }
    695 
    696 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
    697                        SIZE_T iovlen, SIZE_T maxlen) {
    698   COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
    699   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
    700     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
    701     COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
    702     maxlen -= sz;
    703   }
    704 }
    705 #endif
    706 
    707 #if SANITIZER_INTERCEPT_READ
    708 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
    709   void *ctx;
    710   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
    711   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    712   // FIXME: under ASan the call below may write to freed memory and corrupt
    713   // its metadata. See
    714   // https://github.com/google/sanitizers/issues/321.
    715   SSIZE_T res = REAL(read)(fd, ptr, count);
    716   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
    717   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    718   return res;
    719 }
    720 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
    721 #else
    722 #define INIT_READ
    723 #endif
    724 
    725 #if SANITIZER_INTERCEPT_PREAD
    726 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
    727   void *ctx;
    728   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
    729   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    730   // FIXME: under ASan the call below may write to freed memory and corrupt
    731   // its metadata. See
    732   // https://github.com/google/sanitizers/issues/321.
    733   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
    734   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
    735   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    736   return res;
    737 }
    738 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
    739 #else
    740 #define INIT_PREAD
    741 #endif
    742 
    743 #if SANITIZER_INTERCEPT_PREAD64
    744 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
    745   void *ctx;
    746   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
    747   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    748   // FIXME: under ASan the call below may write to freed memory and corrupt
    749   // its metadata. See
    750   // https://github.com/google/sanitizers/issues/321.
    751   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
    752   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
    753   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    754   return res;
    755 }
    756 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
    757 #else
    758 #define INIT_PREAD64
    759 #endif
    760 
    761 #if SANITIZER_INTERCEPT_READV
    762 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
    763                         int iovcnt) {
    764   void *ctx;
    765   COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
    766   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    767   SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
    768   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
    769   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    770   return res;
    771 }
    772 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
    773 #else
    774 #define INIT_READV
    775 #endif
    776 
    777 #if SANITIZER_INTERCEPT_PREADV
    778 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
    779             OFF_T offset) {
    780   void *ctx;
    781   COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
    782   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    783   SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
    784   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
    785   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    786   return res;
    787 }
    788 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
    789 #else
    790 #define INIT_PREADV
    791 #endif
    792 
    793 #if SANITIZER_INTERCEPT_PREADV64
    794 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
    795             OFF64_T offset) {
    796   void *ctx;
    797   COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
    798   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    799   SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
    800   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
    801   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
    802   return res;
    803 }
    804 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
    805 #else
    806 #define INIT_PREADV64
    807 #endif
    808 
    809 #if SANITIZER_INTERCEPT_WRITE
    810 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
    811   void *ctx;
    812   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
    813   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    814   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    815   SSIZE_T res = REAL(write)(fd, ptr, count);
    816   // FIXME: this check should be _before_ the call to REAL(write), not after
    817   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
    818   return res;
    819 }
    820 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
    821 #else
    822 #define INIT_WRITE
    823 #endif
    824 
    825 #if SANITIZER_INTERCEPT_PWRITE
    826 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
    827   void *ctx;
    828   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
    829   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    830   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    831   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
    832   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
    833   return res;
    834 }
    835 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
    836 #else
    837 #define INIT_PWRITE
    838 #endif
    839 
    840 #if SANITIZER_INTERCEPT_PWRITE64
    841 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
    842             OFF64_T offset) {
    843   void *ctx;
    844   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
    845   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    846   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    847   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
    848   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
    849   return res;
    850 }
    851 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
    852 #else
    853 #define INIT_PWRITE64
    854 #endif
    855 
    856 #if SANITIZER_INTERCEPT_WRITEV
    857 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
    858                         int iovcnt) {
    859   void *ctx;
    860   COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
    861   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    862   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    863   SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
    864   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
    865   return res;
    866 }
    867 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
    868 #else
    869 #define INIT_WRITEV
    870 #endif
    871 
    872 #if SANITIZER_INTERCEPT_PWRITEV
    873 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
    874             OFF_T offset) {
    875   void *ctx;
    876   COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
    877   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    878   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    879   SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
    880   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
    881   return res;
    882 }
    883 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
    884 #else
    885 #define INIT_PWRITEV
    886 #endif
    887 
    888 #if SANITIZER_INTERCEPT_PWRITEV64
    889 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
    890             OFF64_T offset) {
    891   void *ctx;
    892   COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
    893   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
    894   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
    895   SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
    896   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
    897   return res;
    898 }
    899 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
    900 #else
    901 #define INIT_PWRITEV64
    902 #endif
    903 
    904 #if SANITIZER_INTERCEPT_PRCTL
    905 INTERCEPTOR(int, prctl, int option, unsigned long arg2,
    906             unsigned long arg3,                        // NOLINT
    907             unsigned long arg4, unsigned long arg5) {  // NOLINT
    908   void *ctx;
    909   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
    910   static const int PR_SET_NAME = 15;
    911   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
    912   if (option == PR_SET_NAME) {
    913     char buff[16];
    914     internal_strncpy(buff, (char *)arg2, 15);
    915     buff[15] = 0;
    916     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
    917   }
    918   return res;
    919 }
    920 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
    921 #else
    922 #define INIT_PRCTL
    923 #endif  // SANITIZER_INTERCEPT_PRCTL
    924 
    925 #if SANITIZER_INTERCEPT_TIME
    926 INTERCEPTOR(unsigned long, time, unsigned long *t) {
    927   void *ctx;
    928   COMMON_INTERCEPTOR_ENTER(ctx, time, t);
    929   unsigned long local_t;
    930   unsigned long res = REAL(time)(&local_t);
    931   if (t && res != (unsigned long)-1) {
    932     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
    933     *t = local_t;
    934   }
    935   return res;
    936 }
    937 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
    938 #else
    939 #define INIT_TIME
    940 #endif  // SANITIZER_INTERCEPT_TIME
    941 
    942 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
    943 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
    944   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
    945   if (tm->tm_zone) {
    946     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
    947     // can point to shared memory and tsan would report a data race.
    948     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
    949                                         REAL(strlen(tm->tm_zone)) + 1);
    950   }
    951 }
    952 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
    953   void *ctx;
    954   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
    955   __sanitizer_tm *res = REAL(localtime)(timep);
    956   if (res) {
    957     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
    958     unpoison_tm(ctx, res);
    959   }
    960   return res;
    961 }
    962 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
    963   void *ctx;
    964   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
    965   __sanitizer_tm *res = REAL(localtime_r)(timep, result);
    966   if (res) {
    967     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
    968     unpoison_tm(ctx, res);
    969   }
    970   return res;
    971 }
    972 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
    973   void *ctx;
    974   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
    975   __sanitizer_tm *res = REAL(gmtime)(timep);
    976   if (res) {
    977     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
    978     unpoison_tm(ctx, res);
    979   }
    980   return res;
    981 }
    982 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
    983   void *ctx;
    984   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
    985   __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
    986   if (res) {
    987     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
    988     unpoison_tm(ctx, res);
    989   }
    990   return res;
    991 }
    992 INTERCEPTOR(char *, ctime, unsigned long *timep) {
    993   void *ctx;
    994   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
    995   // FIXME: under ASan the call below may write to freed memory and corrupt
    996   // its metadata. See
    997   // https://github.com/google/sanitizers/issues/321.
    998   char *res = REAL(ctime)(timep);
    999   if (res) {
   1000     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1001     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1002   }
   1003   return res;
   1004 }
   1005 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
   1006   void *ctx;
   1007   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
   1008   // FIXME: under ASan the call below may write to freed memory and corrupt
   1009   // its metadata. See
   1010   // https://github.com/google/sanitizers/issues/321.
   1011   char *res = REAL(ctime_r)(timep, result);
   1012   if (res) {
   1013     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
   1014     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1015   }
   1016   return res;
   1017 }
   1018 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
   1019   void *ctx;
   1020   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
   1021   // FIXME: under ASan the call below may write to freed memory and corrupt
   1022   // its metadata. See
   1023   // https://github.com/google/sanitizers/issues/321.
   1024   char *res = REAL(asctime)(tm);
   1025   if (res) {
   1026     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
   1027     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1028   }
   1029   return res;
   1030 }
   1031 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
   1032   void *ctx;
   1033   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
   1034   // FIXME: under ASan the call below may write to freed memory and corrupt
   1035   // its metadata. See
   1036   // https://github.com/google/sanitizers/issues/321.
   1037   char *res = REAL(asctime_r)(tm, result);
   1038   if (res) {
   1039     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
   1040     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   1041   }
   1042   return res;
   1043 }
   1044 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
   1045   void *ctx;
   1046   COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
   1047   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
   1048   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
   1049   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
   1050   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
   1051   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
   1052   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
   1053   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
   1054   long res = REAL(mktime)(tm);
   1055   if (res != -1) unpoison_tm(ctx, tm);
   1056   return res;
   1057 }
   1058 #define INIT_LOCALTIME_AND_FRIENDS        \
   1059   COMMON_INTERCEPT_FUNCTION(localtime);   \
   1060   COMMON_INTERCEPT_FUNCTION(localtime_r); \
   1061   COMMON_INTERCEPT_FUNCTION(gmtime);      \
   1062   COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
   1063   COMMON_INTERCEPT_FUNCTION(ctime);       \
   1064   COMMON_INTERCEPT_FUNCTION(ctime_r);     \
   1065   COMMON_INTERCEPT_FUNCTION(asctime);     \
   1066   COMMON_INTERCEPT_FUNCTION(asctime_r);   \
   1067   COMMON_INTERCEPT_FUNCTION(mktime);
   1068 #else
   1069 #define INIT_LOCALTIME_AND_FRIENDS
   1070 #endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
   1071 
   1072 #if SANITIZER_INTERCEPT_STRPTIME
   1073 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
   1074   void *ctx;
   1075   COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
   1076   if (format)
   1077     COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
   1078   // FIXME: under ASan the call below may write to freed memory and corrupt
   1079   // its metadata. See
   1080   // https://github.com/google/sanitizers/issues/321.
   1081   char *res = REAL(strptime)(s, format, tm);
   1082   COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
   1083   if (res && tm) {
   1084     // Do not call unpoison_tm here, because strptime does not, in fact,
   1085     // initialize the entire struct tm. For example, tm_zone pointer is left
   1086     // uninitialized.
   1087     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
   1088   }
   1089   return res;
   1090 }
   1091 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
   1092 #else
   1093 #define INIT_STRPTIME
   1094 #endif
   1095 
   1096 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
   1097 #include "sanitizer_common_interceptors_format.inc"
   1098 
   1099 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
   1100   {                                                                            \
   1101     void *ctx;                                                                 \
   1102     va_list ap;                                                                \
   1103     va_start(ap, format);                                                      \
   1104     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
   1105     int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
   1106     va_end(ap);                                                                \
   1107     return res;                                                                \
   1108   }
   1109 
   1110 #endif
   1111 
   1112 #if SANITIZER_INTERCEPT_SCANF
   1113 
   1114 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
   1115   {                                                                            \
   1116     void *ctx;                                                                 \
   1117     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
   1118     va_list aq;                                                                \
   1119     va_copy(aq, ap);                                                           \
   1120     int res = REAL(vname)(__VA_ARGS__);                                        \
   1121     if (res > 0)                                                               \
   1122       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
   1123     va_end(aq);                                                                \
   1124     return res;                                                                \
   1125   }
   1126 
   1127 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
   1128 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
   1129 
   1130 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
   1131 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
   1132 
   1133 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
   1134 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
   1135 
   1136 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1137 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
   1138 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
   1139 
   1140 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
   1141             va_list ap)
   1142 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
   1143 
   1144 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
   1145 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
   1146 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
   1147 
   1148 INTERCEPTOR(int, scanf, const char *format, ...)
   1149 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
   1150 
   1151 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
   1152 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
   1153 
   1154 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
   1155 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
   1156 
   1157 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1158 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
   1159 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
   1160 
   1161 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
   1162 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
   1163 
   1164 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
   1165 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
   1166 #endif
   1167 
   1168 #endif
   1169 
   1170 #if SANITIZER_INTERCEPT_SCANF
   1171 #define INIT_SCANF                    \
   1172   COMMON_INTERCEPT_FUNCTION(scanf);   \
   1173   COMMON_INTERCEPT_FUNCTION(sscanf);  \
   1174   COMMON_INTERCEPT_FUNCTION(fscanf);  \
   1175   COMMON_INTERCEPT_FUNCTION(vscanf);  \
   1176   COMMON_INTERCEPT_FUNCTION(vsscanf); \
   1177   COMMON_INTERCEPT_FUNCTION(vfscanf);
   1178 #else
   1179 #define INIT_SCANF
   1180 #endif
   1181 
   1182 #if SANITIZER_INTERCEPT_ISOC99_SCANF
   1183 #define INIT_ISOC99_SCANF                      \
   1184   COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
   1185   COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
   1186   COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
   1187   COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
   1188   COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
   1189   COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
   1190 #else
   1191 #define INIT_ISOC99_SCANF
   1192 #endif
   1193 
   1194 #if SANITIZER_INTERCEPT_PRINTF
   1195 
   1196 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
   1197   void *ctx;                                                                   \
   1198   COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
   1199   va_list aq;                                                                  \
   1200   va_copy(aq, ap);
   1201 
   1202 #define VPRINTF_INTERCEPTOR_RETURN()                                           \
   1203   va_end(aq);
   1204 
   1205 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
   1206   {                                                                            \
   1207     VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
   1208     if (common_flags()->check_printf)                                          \
   1209       printf_common(ctx, format, aq);                                          \
   1210     int res = REAL(vname)(__VA_ARGS__);                                        \
   1211     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1212     return res;                                                                \
   1213   }
   1214 
   1215 // FIXME: under ASan the REAL() call below may write to freed memory and
   1216 // corrupt its metadata. See
   1217 // https://github.com/google/sanitizers/issues/321.
   1218 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
   1219   {                                                                            \
   1220     VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
   1221     if (common_flags()->check_printf) {                                        \
   1222       printf_common(ctx, format, aq);                                          \
   1223     }                                                                          \
   1224     int res = REAL(vname)(str, __VA_ARGS__);                                   \
   1225     if (res >= 0) {                                                            \
   1226       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
   1227     }                                                                          \
   1228     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1229     return res;                                                                \
   1230   }
   1231 
   1232 // FIXME: under ASan the REAL() call below may write to freed memory and
   1233 // corrupt its metadata. See
   1234 // https://github.com/google/sanitizers/issues/321.
   1235 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
   1236   {                                                                            \
   1237     VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
   1238     if (common_flags()->check_printf) {                                        \
   1239       printf_common(ctx, format, aq);                                          \
   1240     }                                                                          \
   1241     int res = REAL(vname)(str, size, __VA_ARGS__);                             \
   1242     if (res >= 0) {                                                            \
   1243       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
   1244     }                                                                          \
   1245     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1246     return res;                                                                \
   1247   }
   1248 
   1249 // FIXME: under ASan the REAL() call below may write to freed memory and
   1250 // corrupt its metadata. See
   1251 // https://github.com/google/sanitizers/issues/321.
   1252 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
   1253   {                                                                            \
   1254     VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
   1255     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
   1256     if (common_flags()->check_printf) {                                        \
   1257       printf_common(ctx, format, aq);                                          \
   1258     }                                                                          \
   1259     int res = REAL(vname)(strp, __VA_ARGS__);                                  \
   1260     if (res >= 0) {                                                            \
   1261       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
   1262     }                                                                          \
   1263     VPRINTF_INTERCEPTOR_RETURN();                                              \
   1264     return res;                                                                \
   1265   }
   1266 
   1267 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
   1268 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
   1269 
   1270 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
   1271             va_list ap)
   1272 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
   1273 
   1274 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
   1275             va_list ap)
   1276 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
   1277 
   1278 #if SANITIZER_INTERCEPT_PRINTF_L
   1279 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
   1280             const char *format, va_list ap)
   1281 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
   1282 
   1283 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
   1284             const char *format, ...)
   1285 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
   1286 #endif  // SANITIZER_INTERCEPT_PRINTF_L
   1287 
   1288 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
   1289 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
   1290 
   1291 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
   1292 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
   1293 
   1294 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1295 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
   1296 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
   1297 
   1298 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
   1299             const char *format, va_list ap)
   1300 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
   1301 
   1302 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
   1303             va_list ap)
   1304 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
   1305 
   1306 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
   1307             va_list ap)
   1308 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
   1309                           ap)
   1310 
   1311 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
   1312 
   1313 INTERCEPTOR(int, printf, const char *format, ...)
   1314 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
   1315 
   1316 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
   1317 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
   1318 
   1319 INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
   1320 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
   1321 
   1322 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
   1323 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
   1324 
   1325 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
   1326 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
   1327 
   1328 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1329 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
   1330 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
   1331 
   1332 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
   1333             ...)
   1334 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
   1335 
   1336 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
   1337 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
   1338 
   1339 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
   1340             const char *format, ...)
   1341 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
   1342                         format)
   1343 
   1344 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
   1345 
   1346 #endif  // SANITIZER_INTERCEPT_PRINTF
   1347 
   1348 #if SANITIZER_INTERCEPT_PRINTF
   1349 #define INIT_PRINTF                     \
   1350   COMMON_INTERCEPT_FUNCTION(printf);    \
   1351   COMMON_INTERCEPT_FUNCTION(sprintf);   \
   1352   COMMON_INTERCEPT_FUNCTION(snprintf);  \
   1353   COMMON_INTERCEPT_FUNCTION(asprintf);  \
   1354   COMMON_INTERCEPT_FUNCTION(fprintf);   \
   1355   COMMON_INTERCEPT_FUNCTION(vprintf);   \
   1356   COMMON_INTERCEPT_FUNCTION(vsprintf);  \
   1357   COMMON_INTERCEPT_FUNCTION(vsnprintf); \
   1358   COMMON_INTERCEPT_FUNCTION(vasprintf); \
   1359   COMMON_INTERCEPT_FUNCTION(vfprintf);
   1360 #else
   1361 #define INIT_PRINTF
   1362 #endif
   1363 
   1364 #if SANITIZER_INTERCEPT_PRINTF_L
   1365 #define INIT_PRINTF_L                     \
   1366   COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
   1367   COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
   1368 #else
   1369 #define INIT_PRINTF_L
   1370 #endif
   1371 
   1372 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
   1373 #define INIT_ISOC99_PRINTF                       \
   1374   COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
   1375   COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
   1376   COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
   1377   COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
   1378   COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
   1379   COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
   1380   COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
   1381   COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
   1382 #else
   1383 #define INIT_ISOC99_PRINTF
   1384 #endif
   1385 
   1386 #if SANITIZER_INTERCEPT_IOCTL
   1387 #include "sanitizer_common_interceptors_ioctl.inc"
   1388 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
   1389   // We need a frame pointer, because we call into ioctl_common_[pre|post] which
   1390   // can trigger a report and we need to be able to unwind through this
   1391   // function.  On Mac in debug mode we might not have a frame pointer, because
   1392   // ioctl_common_[pre|post] doesn't get inlined here.
   1393   ENABLE_FRAME_POINTER;
   1394 
   1395   void *ctx;
   1396   va_list ap;
   1397   va_start(ap, request);
   1398   void *arg = va_arg(ap, void *);
   1399   va_end(ap);
   1400   COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
   1401 
   1402   CHECK(ioctl_initialized);
   1403 
   1404   // Note: TSan does not use common flags, and they are zero-initialized.
   1405   // This effectively disables ioctl handling in TSan.
   1406   if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
   1407 
   1408   // Although request is unsigned long, the rest of the interceptor uses it
   1409   // as just "unsigned" to save space, because we know that all values fit in
   1410   // "unsigned" - they are compile-time constants.
   1411 
   1412   const ioctl_desc *desc = ioctl_lookup(request);
   1413   ioctl_desc decoded_desc;
   1414   if (!desc) {
   1415     VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
   1416     if (!ioctl_decode(request, &decoded_desc))
   1417       Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
   1418     else
   1419       desc = &decoded_desc;
   1420   }
   1421 
   1422   if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
   1423   int res = REAL(ioctl)(d, request, arg);
   1424   // FIXME: some ioctls have different return values for success and failure.
   1425   if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
   1426   return res;
   1427 }
   1428 #define INIT_IOCTL \
   1429   ioctl_init();    \
   1430   COMMON_INTERCEPT_FUNCTION(ioctl);
   1431 #else
   1432 #define INIT_IOCTL
   1433 #endif
   1434 
   1435 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
   1436     SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
   1437     SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
   1438 static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
   1439   if (pwd) {
   1440     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
   1441     if (pwd->pw_name)
   1442       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
   1443                                           REAL(strlen)(pwd->pw_name) + 1);
   1444     if (pwd->pw_passwd)
   1445       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
   1446                                           REAL(strlen)(pwd->pw_passwd) + 1);
   1447 #if !SANITIZER_ANDROID
   1448     if (pwd->pw_gecos)
   1449       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
   1450                                           REAL(strlen)(pwd->pw_gecos) + 1);
   1451 #endif
   1452 #if SANITIZER_MAC
   1453     if (pwd->pw_class)
   1454       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
   1455                                           REAL(strlen)(pwd->pw_class) + 1);
   1456 #endif
   1457     if (pwd->pw_dir)
   1458       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
   1459                                           REAL(strlen)(pwd->pw_dir) + 1);
   1460     if (pwd->pw_shell)
   1461       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
   1462                                           REAL(strlen)(pwd->pw_shell) + 1);
   1463   }
   1464 }
   1465 
   1466 static void unpoison_group(void *ctx, __sanitizer_group *grp) {
   1467   if (grp) {
   1468     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
   1469     if (grp->gr_name)
   1470       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
   1471                                           REAL(strlen)(grp->gr_name) + 1);
   1472     if (grp->gr_passwd)
   1473       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
   1474                                           REAL(strlen)(grp->gr_passwd) + 1);
   1475     char **p = grp->gr_mem;
   1476     for (; *p; ++p) {
   1477       COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
   1478     }
   1479     COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
   1480                                         (p - grp->gr_mem + 1) * sizeof(*p));
   1481   }
   1482 }
   1483 #endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
   1484         // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
   1485         // SANITIZER_INTERCEPT_GETPWENT_R ||
   1486         // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
   1487 
   1488 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
   1489 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
   1490   void *ctx;
   1491   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
   1492   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1493   __sanitizer_passwd *res = REAL(getpwnam)(name);
   1494   if (res) unpoison_passwd(ctx, res);
   1495   return res;
   1496 }
   1497 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
   1498   void *ctx;
   1499   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
   1500   __sanitizer_passwd *res = REAL(getpwuid)(uid);
   1501   if (res) unpoison_passwd(ctx, res);
   1502   return res;
   1503 }
   1504 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
   1505   void *ctx;
   1506   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
   1507   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1508   __sanitizer_group *res = REAL(getgrnam)(name);
   1509   if (res) unpoison_group(ctx, res);
   1510   return res;
   1511 }
   1512 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
   1513   void *ctx;
   1514   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
   1515   __sanitizer_group *res = REAL(getgrgid)(gid);
   1516   if (res) unpoison_group(ctx, res);
   1517   return res;
   1518 }
   1519 #define INIT_GETPWNAM_AND_FRIENDS      \
   1520   COMMON_INTERCEPT_FUNCTION(getpwnam); \
   1521   COMMON_INTERCEPT_FUNCTION(getpwuid); \
   1522   COMMON_INTERCEPT_FUNCTION(getgrnam); \
   1523   COMMON_INTERCEPT_FUNCTION(getgrgid);
   1524 #else
   1525 #define INIT_GETPWNAM_AND_FRIENDS
   1526 #endif
   1527 
   1528 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
   1529 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
   1530             char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
   1531   void *ctx;
   1532   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
   1533   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1534   // FIXME: under ASan the call below may write to freed memory and corrupt
   1535   // its metadata. See
   1536   // https://github.com/google/sanitizers/issues/321.
   1537   int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
   1538   if (!res) {
   1539     if (result && *result) unpoison_passwd(ctx, *result);
   1540     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1541   }
   1542   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1543   return res;
   1544 }
   1545 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
   1546             SIZE_T buflen, __sanitizer_passwd **result) {
   1547   void *ctx;
   1548   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
   1549   // FIXME: under ASan the call below may write to freed memory and corrupt
   1550   // its metadata. See
   1551   // https://github.com/google/sanitizers/issues/321.
   1552   int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
   1553   if (!res) {
   1554     if (result && *result) unpoison_passwd(ctx, *result);
   1555     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1556   }
   1557   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1558   return res;
   1559 }
   1560 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
   1561             char *buf, SIZE_T buflen, __sanitizer_group **result) {
   1562   void *ctx;
   1563   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
   1564   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   1565   // FIXME: under ASan the call below may write to freed memory and corrupt
   1566   // its metadata. See
   1567   // https://github.com/google/sanitizers/issues/321.
   1568   int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
   1569   if (!res) {
   1570     if (result && *result) unpoison_group(ctx, *result);
   1571     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1572   }
   1573   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1574   return res;
   1575 }
   1576 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
   1577             SIZE_T buflen, __sanitizer_group **result) {
   1578   void *ctx;
   1579   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
   1580   // FIXME: under ASan the call below may write to freed memory and corrupt
   1581   // its metadata. See
   1582   // https://github.com/google/sanitizers/issues/321.
   1583   int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
   1584   if (!res) {
   1585     if (result && *result) unpoison_group(ctx, *result);
   1586     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1587   }
   1588   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   1589   return res;
   1590 }
   1591 #define INIT_GETPWNAM_R_AND_FRIENDS      \
   1592   COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
   1593   COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
   1594   COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
   1595   COMMON_INTERCEPT_FUNCTION(getgrgid_r);
   1596 #else
   1597 #define INIT_GETPWNAM_R_AND_FRIENDS
   1598 #endif
   1599 
   1600 #if SANITIZER_INTERCEPT_GETPWENT
   1601 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
   1602   void *ctx;
   1603   COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
   1604   __sanitizer_passwd *res = REAL(getpwent)(dummy);
   1605   if (res) unpoison_passwd(ctx, res);
   1606   return res;
   1607 }
   1608 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
   1609   void *ctx;
   1610   COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
   1611   __sanitizer_group *res = REAL(getgrent)(dummy);
   1612   if (res) unpoison_group(ctx, res);;
   1613   return res;
   1614 }
   1615 #define INIT_GETPWENT                  \
   1616   COMMON_INTERCEPT_FUNCTION(getpwent); \
   1617   COMMON_INTERCEPT_FUNCTION(getgrent);
   1618 #else
   1619 #define INIT_GETPWENT
   1620 #endif
   1621 
   1622 #if SANITIZER_INTERCEPT_FGETPWENT
   1623 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
   1624   void *ctx;
   1625   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
   1626   __sanitizer_passwd *res = REAL(fgetpwent)(fp);
   1627   if (res) unpoison_passwd(ctx, res);
   1628   return res;
   1629 }
   1630 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
   1631   void *ctx;
   1632   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
   1633   __sanitizer_group *res = REAL(fgetgrent)(fp);
   1634   if (res) unpoison_group(ctx, res);
   1635   return res;
   1636 }
   1637 #define INIT_FGETPWENT                  \
   1638   COMMON_INTERCEPT_FUNCTION(fgetpwent); \
   1639   COMMON_INTERCEPT_FUNCTION(fgetgrent);
   1640 #else
   1641 #define INIT_FGETPWENT
   1642 #endif
   1643 
   1644 #if SANITIZER_INTERCEPT_GETPWENT_R
   1645 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
   1646             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
   1647   void *ctx;
   1648   COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
   1649   // FIXME: under ASan the call below may write to freed memory and corrupt
   1650   // its metadata. See
   1651   // https://github.com/google/sanitizers/issues/321.
   1652   int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
   1653   if (!res) {
   1654     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
   1655     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1656   }
   1657   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   1658   return res;
   1659 }
   1660 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
   1661             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
   1662   void *ctx;
   1663   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
   1664   // FIXME: under ASan the call below may write to freed memory and corrupt
   1665   // its metadata. See
   1666   // https://github.com/google/sanitizers/issues/321.
   1667   int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
   1668   if (!res) {
   1669     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
   1670     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1671   }
   1672   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   1673   return res;
   1674 }
   1675 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
   1676             __sanitizer_group **pwbufp) {
   1677   void *ctx;
   1678   COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
   1679   // FIXME: under ASan the call below may write to freed memory and corrupt
   1680   // its metadata. See
   1681   // https://github.com/google/sanitizers/issues/321.
   1682   int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
   1683   if (!res) {
   1684     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
   1685     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1686   }
   1687   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   1688   return res;
   1689 }
   1690 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
   1691             SIZE_T buflen, __sanitizer_group **pwbufp) {
   1692   void *ctx;
   1693   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
   1694   // FIXME: under ASan the call below may write to freed memory and corrupt
   1695   // its metadata. See
   1696   // https://github.com/google/sanitizers/issues/321.
   1697   int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
   1698   if (!res) {
   1699     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
   1700     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
   1701   }
   1702   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
   1703   return res;
   1704 }
   1705 #define INIT_GETPWENT_R                   \
   1706   COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
   1707   COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
   1708   COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
   1709   COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
   1710 #else
   1711 #define INIT_GETPWENT_R
   1712 #endif
   1713 
   1714 #if SANITIZER_INTERCEPT_SETPWENT
   1715 // The only thing these interceptors do is disable any nested interceptors.
   1716 // These functions may open nss modules and call uninstrumented functions from
   1717 // them, and we don't want things like strlen() to trigger.
   1718 INTERCEPTOR(void, setpwent, int dummy) {
   1719   void *ctx;
   1720   COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
   1721   REAL(setpwent)(dummy);
   1722 }
   1723 INTERCEPTOR(void, endpwent, int dummy) {
   1724   void *ctx;
   1725   COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
   1726   REAL(endpwent)(dummy);
   1727 }
   1728 INTERCEPTOR(void, setgrent, int dummy) {
   1729   void *ctx;
   1730   COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
   1731   REAL(setgrent)(dummy);
   1732 }
   1733 INTERCEPTOR(void, endgrent, int dummy) {
   1734   void *ctx;
   1735   COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
   1736   REAL(endgrent)(dummy);
   1737 }
   1738 #define INIT_SETPWENT                  \
   1739   COMMON_INTERCEPT_FUNCTION(setpwent); \
   1740   COMMON_INTERCEPT_FUNCTION(endpwent); \
   1741   COMMON_INTERCEPT_FUNCTION(setgrent); \
   1742   COMMON_INTERCEPT_FUNCTION(endgrent);
   1743 #else
   1744 #define INIT_SETPWENT
   1745 #endif
   1746 
   1747 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
   1748 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
   1749   void *ctx;
   1750   COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
   1751   // FIXME: under ASan the call below may write to freed memory and corrupt
   1752   // its metadata. See
   1753   // https://github.com/google/sanitizers/issues/321.
   1754   int res = REAL(clock_getres)(clk_id, tp);
   1755   if (!res && tp) {
   1756     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
   1757   }
   1758   return res;
   1759 }
   1760 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
   1761   void *ctx;
   1762   COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
   1763   // FIXME: under ASan the call below may write to freed memory and corrupt
   1764   // its metadata. See
   1765   // https://github.com/google/sanitizers/issues/321.
   1766   int res = REAL(clock_gettime)(clk_id, tp);
   1767   if (!res) {
   1768     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
   1769   }
   1770   return res;
   1771 }
   1772 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
   1773   void *ctx;
   1774   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
   1775   COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
   1776   return REAL(clock_settime)(clk_id, tp);
   1777 }
   1778 #define INIT_CLOCK_GETTIME                  \
   1779   COMMON_INTERCEPT_FUNCTION(clock_getres);  \
   1780   COMMON_INTERCEPT_FUNCTION(clock_gettime); \
   1781   COMMON_INTERCEPT_FUNCTION(clock_settime);
   1782 #else
   1783 #define INIT_CLOCK_GETTIME
   1784 #endif
   1785 
   1786 #if SANITIZER_INTERCEPT_GETITIMER
   1787 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
   1788   void *ctx;
   1789   COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
   1790   // FIXME: under ASan the call below may write to freed memory and corrupt
   1791   // its metadata. See
   1792   // https://github.com/google/sanitizers/issues/321.
   1793   int res = REAL(getitimer)(which, curr_value);
   1794   if (!res && curr_value) {
   1795     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
   1796   }
   1797   return res;
   1798 }
   1799 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
   1800   void *ctx;
   1801   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
   1802   if (new_value)
   1803     COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
   1804   // FIXME: under ASan the call below may write to freed memory and corrupt
   1805   // its metadata. See
   1806   // https://github.com/google/sanitizers/issues/321.
   1807   int res = REAL(setitimer)(which, new_value, old_value);
   1808   if (!res && old_value) {
   1809     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
   1810   }
   1811   return res;
   1812 }
   1813 #define INIT_GETITIMER                  \
   1814   COMMON_INTERCEPT_FUNCTION(getitimer); \
   1815   COMMON_INTERCEPT_FUNCTION(setitimer);
   1816 #else
   1817 #define INIT_GETITIMER
   1818 #endif
   1819 
   1820 #if SANITIZER_INTERCEPT_GLOB
   1821 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
   1822   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
   1823   // +1 for NULL pointer at the end.
   1824   if (pglob->gl_pathv)
   1825     COMMON_INTERCEPTOR_WRITE_RANGE(
   1826         ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
   1827   for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
   1828     char *p = pglob->gl_pathv[i];
   1829     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
   1830   }
   1831 }
   1832 
   1833 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
   1834 
   1835 static void wrapped_gl_closedir(void *dir) {
   1836   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   1837   pglob_copy->gl_closedir(dir);
   1838 }
   1839 
   1840 static void *wrapped_gl_readdir(void *dir) {
   1841   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   1842   return pglob_copy->gl_readdir(dir);
   1843 }
   1844 
   1845 static void *wrapped_gl_opendir(const char *s) {
   1846   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   1847   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   1848   return pglob_copy->gl_opendir(s);
   1849 }
   1850 
   1851 static int wrapped_gl_lstat(const char *s, void *st) {
   1852   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   1853   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   1854   return pglob_copy->gl_lstat(s, st);
   1855 }
   1856 
   1857 static int wrapped_gl_stat(const char *s, void *st) {
   1858   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   1859   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
   1860   return pglob_copy->gl_stat(s, st);
   1861 }
   1862 
   1863 static const __sanitizer_glob_t kGlobCopy = {
   1864       0,                  0,                   0,
   1865       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
   1866       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
   1867 
   1868 INTERCEPTOR(int, glob, const char *pattern, int flags,
   1869             int (*errfunc)(const char *epath, int eerrno),
   1870             __sanitizer_glob_t *pglob) {
   1871   void *ctx;
   1872   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
   1873   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
   1874   __sanitizer_glob_t glob_copy;
   1875   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
   1876   if (flags & glob_altdirfunc) {
   1877     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   1878     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   1879     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   1880     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   1881     Swap(pglob->gl_stat, glob_copy.gl_stat);
   1882     pglob_copy = &glob_copy;
   1883   }
   1884   int res = REAL(glob)(pattern, flags, errfunc, pglob);
   1885   if (flags & glob_altdirfunc) {
   1886     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   1887     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   1888     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   1889     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   1890     Swap(pglob->gl_stat, glob_copy.gl_stat);
   1891   }
   1892   pglob_copy = 0;
   1893   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   1894   return res;
   1895 }
   1896 
   1897 INTERCEPTOR(int, glob64, const char *pattern, int flags,
   1898             int (*errfunc)(const char *epath, int eerrno),
   1899             __sanitizer_glob_t *pglob) {
   1900   void *ctx;
   1901   COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
   1902   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
   1903   __sanitizer_glob_t glob_copy;
   1904   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
   1905   if (flags & glob_altdirfunc) {
   1906     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   1907     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   1908     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   1909     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   1910     Swap(pglob->gl_stat, glob_copy.gl_stat);
   1911     pglob_copy = &glob_copy;
   1912   }
   1913   int res = REAL(glob64)(pattern, flags, errfunc, pglob);
   1914   if (flags & glob_altdirfunc) {
   1915     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
   1916     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
   1917     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
   1918     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
   1919     Swap(pglob->gl_stat, glob_copy.gl_stat);
   1920   }
   1921   pglob_copy = 0;
   1922   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
   1923   return res;
   1924 }
   1925 #define INIT_GLOB                  \
   1926   COMMON_INTERCEPT_FUNCTION(glob); \
   1927   COMMON_INTERCEPT_FUNCTION(glob64);
   1928 #else  // SANITIZER_INTERCEPT_GLOB
   1929 #define INIT_GLOB
   1930 #endif  // SANITIZER_INTERCEPT_GLOB
   1931 
   1932 #if SANITIZER_INTERCEPT_WAIT
   1933 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
   1934 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
   1935 // details.
   1936 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
   1937   void *ctx;
   1938   COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
   1939   // FIXME: under ASan the call below may write to freed memory and corrupt
   1940   // its metadata. See
   1941   // https://github.com/google/sanitizers/issues/321.
   1942   int res = REAL(wait)(status);
   1943   if (res != -1 && status)
   1944     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   1945   return res;
   1946 }
   1947 // On FreeBSD id_t is always 64-bit wide.
   1948 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
   1949 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
   1950                         int options) {
   1951 #else
   1952 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
   1953                         int options) {
   1954 #endif
   1955   void *ctx;
   1956   COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
   1957   // FIXME: under ASan the call below may write to freed memory and corrupt
   1958   // its metadata. See
   1959   // https://github.com/google/sanitizers/issues/321.
   1960   int res = REAL(waitid)(idtype, id, infop, options);
   1961   if (res != -1 && infop)
   1962     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
   1963   return res;
   1964 }
   1965 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
   1966   void *ctx;
   1967   COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
   1968   // FIXME: under ASan the call below may write to freed memory and corrupt
   1969   // its metadata. See
   1970   // https://github.com/google/sanitizers/issues/321.
   1971   int res = REAL(waitpid)(pid, status, options);
   1972   if (res != -1 && status)
   1973     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   1974   return res;
   1975 }
   1976 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
   1977   void *ctx;
   1978   COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
   1979   // FIXME: under ASan the call below may write to freed memory and corrupt
   1980   // its metadata. See
   1981   // https://github.com/google/sanitizers/issues/321.
   1982   int res = REAL(wait3)(status, options, rusage);
   1983   if (res != -1) {
   1984     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   1985     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   1986   }
   1987   return res;
   1988 }
   1989 #if SANITIZER_ANDROID
   1990 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
   1991   void *ctx;
   1992   COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
   1993   // FIXME: under ASan the call below may write to freed memory and corrupt
   1994   // its metadata. See
   1995   // https://github.com/google/sanitizers/issues/321.
   1996   int res = REAL(__wait4)(pid, status, options, rusage);
   1997   if (res != -1) {
   1998     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   1999     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   2000   }
   2001   return res;
   2002 }
   2003 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
   2004 #else
   2005 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
   2006   void *ctx;
   2007   COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
   2008   // FIXME: under ASan the call below may write to freed memory and corrupt
   2009   // its metadata. See
   2010   // https://github.com/google/sanitizers/issues/321.
   2011   int res = REAL(wait4)(pid, status, options, rusage);
   2012   if (res != -1) {
   2013     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
   2014     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
   2015   }
   2016   return res;
   2017 }
   2018 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
   2019 #endif  // SANITIZER_ANDROID
   2020 #define INIT_WAIT                     \
   2021   COMMON_INTERCEPT_FUNCTION(wait);    \
   2022   COMMON_INTERCEPT_FUNCTION(waitid);  \
   2023   COMMON_INTERCEPT_FUNCTION(waitpid); \
   2024   COMMON_INTERCEPT_FUNCTION(wait3);
   2025 #else
   2026 #define INIT_WAIT
   2027 #define INIT_WAIT4
   2028 #endif
   2029 
   2030 #if SANITIZER_INTERCEPT_INET
   2031 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
   2032   void *ctx;
   2033   COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
   2034   uptr sz = __sanitizer_in_addr_sz(af);
   2035   if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
   2036   // FIXME: figure out read size based on the address family.
   2037   // FIXME: under ASan the call below may write to freed memory and corrupt
   2038   // its metadata. See
   2039   // https://github.com/google/sanitizers/issues/321.
   2040   char *res = REAL(inet_ntop)(af, src, dst, size);
   2041   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   2042   return res;
   2043 }
   2044 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
   2045   void *ctx;
   2046   COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
   2047   COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
   2048   // FIXME: figure out read size based on the address family.
   2049   // FIXME: under ASan the call below may write to freed memory and corrupt
   2050   // its metadata. See
   2051   // https://github.com/google/sanitizers/issues/321.
   2052   int res = REAL(inet_pton)(af, src, dst);
   2053   if (res == 1) {
   2054     uptr sz = __sanitizer_in_addr_sz(af);
   2055     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
   2056   }
   2057   return res;
   2058 }
   2059 #define INIT_INET                       \
   2060   COMMON_INTERCEPT_FUNCTION(inet_ntop); \
   2061   COMMON_INTERCEPT_FUNCTION(inet_pton);
   2062 #else
   2063 #define INIT_INET
   2064 #endif
   2065 
   2066 #if SANITIZER_INTERCEPT_INET
   2067 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
   2068   void *ctx;
   2069   COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
   2070   if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
   2071   // FIXME: under ASan the call below may write to freed memory and corrupt
   2072   // its metadata. See
   2073   // https://github.com/google/sanitizers/issues/321.
   2074   int res = REAL(inet_aton)(cp, dst);
   2075   if (res != 0) {
   2076     uptr sz = __sanitizer_in_addr_sz(af_inet);
   2077     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
   2078   }
   2079   return res;
   2080 }
   2081 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
   2082 #else
   2083 #define INIT_INET_ATON
   2084 #endif
   2085 
   2086 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
   2087 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
   2088   void *ctx;
   2089   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
   2090   // FIXME: under ASan the call below may write to freed memory and corrupt
   2091   // its metadata. See
   2092   // https://github.com/google/sanitizers/issues/321.
   2093   int res = REAL(pthread_getschedparam)(thread, policy, param);
   2094   if (res == 0) {
   2095     if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
   2096     if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
   2097   }
   2098   return res;
   2099 }
   2100 #define INIT_PTHREAD_GETSCHEDPARAM \
   2101   COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
   2102 #else
   2103 #define INIT_PTHREAD_GETSCHEDPARAM
   2104 #endif
   2105 
   2106 #if SANITIZER_INTERCEPT_GETADDRINFO
   2107 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
   2108             struct __sanitizer_addrinfo *hints,
   2109             struct __sanitizer_addrinfo **out) {
   2110   void *ctx;
   2111   COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
   2112   if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
   2113   if (service)
   2114     COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
   2115   if (hints)
   2116     COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
   2117   // FIXME: under ASan the call below may write to freed memory and corrupt
   2118   // its metadata. See
   2119   // https://github.com/google/sanitizers/issues/321.
   2120   int res = REAL(getaddrinfo)(node, service, hints, out);
   2121   if (res == 0 && out) {
   2122     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
   2123     struct __sanitizer_addrinfo *p = *out;
   2124     while (p) {
   2125       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   2126       if (p->ai_addr)
   2127         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
   2128       if (p->ai_canonname)
   2129         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
   2130                                        REAL(strlen)(p->ai_canonname) + 1);
   2131       p = p->ai_next;
   2132     }
   2133   }
   2134   return res;
   2135 }
   2136 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
   2137 #else
   2138 #define INIT_GETADDRINFO
   2139 #endif
   2140 
   2141 #if SANITIZER_INTERCEPT_GETNAMEINFO
   2142 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
   2143             unsigned hostlen, char *serv, unsigned servlen, int flags) {
   2144   void *ctx;
   2145   COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
   2146                            serv, servlen, flags);
   2147   // FIXME: consider adding READ_RANGE(sockaddr, salen)
   2148   // There is padding in in_addr that may make this too noisy
   2149   // FIXME: under ASan the call below may write to freed memory and corrupt
   2150   // its metadata. See
   2151   // https://github.com/google/sanitizers/issues/321.
   2152   int res =
   2153       REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
   2154   if (res == 0) {
   2155     if (host && hostlen)
   2156       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
   2157     if (serv && servlen)
   2158       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
   2159   }
   2160   return res;
   2161 }
   2162 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
   2163 #else
   2164 #define INIT_GETNAMEINFO
   2165 #endif
   2166 
   2167 #if SANITIZER_INTERCEPT_GETSOCKNAME
   2168 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
   2169   void *ctx;
   2170   COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
   2171   COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2172   int addrlen_in = *addrlen;
   2173   // FIXME: under ASan the call below may write to freed memory and corrupt
   2174   // its metadata. See
   2175   // https://github.com/google/sanitizers/issues/321.
   2176   int res = REAL(getsockname)(sock_fd, addr, addrlen);
   2177   if (res == 0) {
   2178     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
   2179   }
   2180   return res;
   2181 }
   2182 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
   2183 #else
   2184 #define INIT_GETSOCKNAME
   2185 #endif
   2186 
   2187 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
   2188 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
   2189   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
   2190   if (h->h_name)
   2191     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
   2192   char **p = h->h_aliases;
   2193   while (*p) {
   2194     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   2195     ++p;
   2196   }
   2197   COMMON_INTERCEPTOR_WRITE_RANGE(
   2198       ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
   2199   p = h->h_addr_list;
   2200   while (*p) {
   2201     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
   2202     ++p;
   2203   }
   2204   COMMON_INTERCEPTOR_WRITE_RANGE(
   2205       ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
   2206 }
   2207 #endif
   2208 
   2209 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
   2210 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
   2211   void *ctx;
   2212   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
   2213   struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
   2214   if (res) write_hostent(ctx, res);
   2215   return res;
   2216 }
   2217 
   2218 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
   2219             int type) {
   2220   void *ctx;
   2221   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
   2222   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
   2223   struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
   2224   if (res) write_hostent(ctx, res);
   2225   return res;
   2226 }
   2227 
   2228 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
   2229   void *ctx;
   2230   COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
   2231   struct __sanitizer_hostent *res = REAL(gethostent)(fake);
   2232   if (res) write_hostent(ctx, res);
   2233   return res;
   2234 }
   2235 
   2236 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
   2237   void *ctx;
   2238   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
   2239   struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
   2240   if (res) write_hostent(ctx, res);
   2241   return res;
   2242 }
   2243 #define INIT_GETHOSTBYNAME                  \
   2244   COMMON_INTERCEPT_FUNCTION(gethostent);    \
   2245   COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
   2246   COMMON_INTERCEPT_FUNCTION(gethostbyname); \
   2247   COMMON_INTERCEPT_FUNCTION(gethostbyname2);
   2248 #else
   2249 #define INIT_GETHOSTBYNAME
   2250 #endif
   2251 
   2252 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
   2253 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
   2254             char *buf, SIZE_T buflen, __sanitizer_hostent **result,
   2255             int *h_errnop) {
   2256   void *ctx;
   2257   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
   2258                            h_errnop);
   2259   // FIXME: under ASan the call below may write to freed memory and corrupt
   2260   // its metadata. See
   2261   // https://github.com/google/sanitizers/issues/321.
   2262   int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
   2263   if (result) {
   2264     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2265     if (res == 0 && *result) write_hostent(ctx, *result);
   2266   }
   2267   if (h_errnop)
   2268     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2269   return res;
   2270 }
   2271 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
   2272 #else
   2273 #define INIT_GETHOSTBYNAME_R
   2274 #endif
   2275 
   2276 #if SANITIZER_INTERCEPT_GETHOSTENT_R
   2277 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
   2278             SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
   2279   void *ctx;
   2280   COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
   2281                            h_errnop);
   2282   // FIXME: under ASan the call below may write to freed memory and corrupt
   2283   // its metadata. See
   2284   // https://github.com/google/sanitizers/issues/321.
   2285   int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
   2286   if (result) {
   2287     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2288     if (res == 0 && *result) write_hostent(ctx, *result);
   2289   }
   2290   if (h_errnop)
   2291     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2292   return res;
   2293 }
   2294 #define INIT_GETHOSTENT_R                  \
   2295   COMMON_INTERCEPT_FUNCTION(gethostent_r);
   2296 #else
   2297 #define INIT_GETHOSTENT_R
   2298 #endif
   2299 
   2300 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
   2301 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
   2302             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
   2303             __sanitizer_hostent **result, int *h_errnop) {
   2304   void *ctx;
   2305   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
   2306                            buflen, result, h_errnop);
   2307   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
   2308   // FIXME: under ASan the call below may write to freed memory and corrupt
   2309   // its metadata. See
   2310   // https://github.com/google/sanitizers/issues/321.
   2311   int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
   2312                                   h_errnop);
   2313   if (result) {
   2314     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2315     if (res == 0 && *result) write_hostent(ctx, *result);
   2316   }
   2317   if (h_errnop)
   2318     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2319   return res;
   2320 }
   2321 #define INIT_GETHOSTBYADDR_R                  \
   2322   COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
   2323 #else
   2324 #define INIT_GETHOSTBYADDR_R
   2325 #endif
   2326 
   2327 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
   2328 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
   2329             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
   2330             __sanitizer_hostent **result, int *h_errnop) {
   2331   void *ctx;
   2332   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
   2333                            result, h_errnop);
   2334   // FIXME: under ASan the call below may write to freed memory and corrupt
   2335   // its metadata. See
   2336   // https://github.com/google/sanitizers/issues/321.
   2337   int res =
   2338       REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
   2339   if (result) {
   2340     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2341     if (res == 0 && *result) write_hostent(ctx, *result);
   2342   }
   2343   if (h_errnop)
   2344     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
   2345   return res;
   2346 }
   2347 #define INIT_GETHOSTBYNAME2_R                  \
   2348   COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
   2349 #else
   2350 #define INIT_GETHOSTBYNAME2_R
   2351 #endif
   2352 
   2353 #if SANITIZER_INTERCEPT_GETSOCKOPT
   2354 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
   2355             int *optlen) {
   2356   void *ctx;
   2357   COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
   2358                            optlen);
   2359   if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
   2360   // FIXME: under ASan the call below may write to freed memory and corrupt
   2361   // its metadata. See
   2362   // https://github.com/google/sanitizers/issues/321.
   2363   int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
   2364   if (res == 0)
   2365     if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
   2366   return res;
   2367 }
   2368 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
   2369 #else
   2370 #define INIT_GETSOCKOPT
   2371 #endif
   2372 
   2373 #if SANITIZER_INTERCEPT_ACCEPT
   2374 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
   2375   void *ctx;
   2376   COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
   2377   unsigned addrlen0 = 0;
   2378   if (addrlen) {
   2379     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2380     addrlen0 = *addrlen;
   2381   }
   2382   int fd2 = REAL(accept)(fd, addr, addrlen);
   2383   if (fd2 >= 0) {
   2384     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
   2385     if (addr && addrlen)
   2386       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
   2387   }
   2388   return fd2;
   2389 }
   2390 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
   2391 #else
   2392 #define INIT_ACCEPT
   2393 #endif
   2394 
   2395 #if SANITIZER_INTERCEPT_ACCEPT4
   2396 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
   2397   void *ctx;
   2398   COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
   2399   unsigned addrlen0 = 0;
   2400   if (addrlen) {
   2401     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
   2402     addrlen0 = *addrlen;
   2403   }
   2404   // FIXME: under ASan the call below may write to freed memory and corrupt
   2405   // its metadata. See
   2406   // https://github.com/google/sanitizers/issues/321.
   2407   int fd2 = REAL(accept4)(fd, addr, addrlen, f);
   2408   if (fd2 >= 0) {
   2409     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
   2410     if (addr && addrlen)
   2411       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
   2412   }
   2413   return fd2;
   2414 }
   2415 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
   2416 #else
   2417 #define INIT_ACCEPT4
   2418 #endif
   2419 
   2420 #if SANITIZER_INTERCEPT_MODF
   2421 INTERCEPTOR(double, modf, double x, double *iptr) {
   2422   void *ctx;
   2423   COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
   2424   // FIXME: under ASan the call below may write to freed memory and corrupt
   2425   // its metadata. See
   2426   // https://github.com/google/sanitizers/issues/321.
   2427   double res = REAL(modf)(x, iptr);
   2428   if (iptr) {
   2429     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2430   }
   2431   return res;
   2432 }
   2433 INTERCEPTOR(float, modff, float x, float *iptr) {
   2434   void *ctx;
   2435   COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
   2436   // FIXME: under ASan the call below may write to freed memory and corrupt
   2437   // its metadata. See
   2438   // https://github.com/google/sanitizers/issues/321.
   2439   float res = REAL(modff)(x, iptr);
   2440   if (iptr) {
   2441     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2442   }
   2443   return res;
   2444 }
   2445 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
   2446   void *ctx;
   2447   COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
   2448   // FIXME: under ASan the call below may write to freed memory and corrupt
   2449   // its metadata. See
   2450   // https://github.com/google/sanitizers/issues/321.
   2451   long double res = REAL(modfl)(x, iptr);
   2452   if (iptr) {
   2453     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
   2454   }
   2455   return res;
   2456 }
   2457 #define INIT_MODF                   \
   2458   COMMON_INTERCEPT_FUNCTION(modf);  \
   2459   COMMON_INTERCEPT_FUNCTION(modff); \
   2460   COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
   2461 #else
   2462 #define INIT_MODF
   2463 #endif
   2464 
   2465 #if SANITIZER_INTERCEPT_RECVMSG
   2466 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
   2467                          SSIZE_T maxlen) {
   2468   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
   2469   if (msg->msg_name && msg->msg_namelen)
   2470     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
   2471   if (msg->msg_iov && msg->msg_iovlen)
   2472     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
   2473                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
   2474   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
   2475   if (msg->msg_control && msg->msg_controllen)
   2476     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
   2477 }
   2478 
   2479 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
   2480             int flags) {
   2481   void *ctx;
   2482   COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
   2483   // FIXME: under ASan the call below may write to freed memory and corrupt
   2484   // its metadata. See
   2485   // https://github.com/google/sanitizers/issues/321.
   2486   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
   2487   if (res >= 0) {
   2488     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   2489     if (msg) {
   2490       write_msghdr(ctx, msg, res);
   2491       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
   2492     }
   2493   }
   2494   return res;
   2495 }
   2496 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
   2497 #else
   2498 #define INIT_RECVMSG
   2499 #endif
   2500 
   2501 #if SANITIZER_INTERCEPT_SENDMSG
   2502 static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
   2503   const unsigned kCmsgDataOffset =
   2504       RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
   2505 
   2506   char *p = (char *)control;
   2507   char *const control_end = p + controllen;
   2508   while (true) {
   2509     if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
   2510     __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
   2511     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
   2512 
   2513     if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
   2514 
   2515     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
   2516                                   sizeof(cmsg->cmsg_level));
   2517     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
   2518                                   sizeof(cmsg->cmsg_type));
   2519 
   2520     if (cmsg->cmsg_len > kCmsgDataOffset) {
   2521       char *data = p + kCmsgDataOffset;
   2522       unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
   2523       if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
   2524     }
   2525 
   2526     p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
   2527   }
   2528 }
   2529 
   2530 static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
   2531                         SSIZE_T maxlen) {
   2532 #define R(f) \
   2533   COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
   2534   R(name);
   2535   R(namelen);
   2536   R(iov);
   2537   R(iovlen);
   2538   R(control);
   2539   R(controllen);
   2540   R(flags);
   2541 #undef R
   2542   if (msg->msg_name && msg->msg_namelen)
   2543     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
   2544   if (msg->msg_iov && msg->msg_iovlen)
   2545     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
   2546                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
   2547   read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
   2548   if (msg->msg_control && msg->msg_controllen)
   2549     read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
   2550 }
   2551 
   2552 INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
   2553             int flags) {
   2554   void *ctx;
   2555   COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
   2556   if (fd >= 0) {
   2557     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   2558     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   2559   }
   2560   SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
   2561   if (common_flags()->intercept_send && res >= 0 && msg)
   2562     read_msghdr(ctx, msg, res);
   2563   return res;
   2564 }
   2565 #define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
   2566 #else
   2567 #define INIT_SENDMSG
   2568 #endif
   2569 
   2570 #if SANITIZER_INTERCEPT_GETPEERNAME
   2571 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
   2572   void *ctx;
   2573   COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
   2574   unsigned addr_sz;
   2575   if (addrlen) addr_sz = *addrlen;
   2576   // FIXME: under ASan the call below may write to freed memory and corrupt
   2577   // its metadata. See
   2578   // https://github.com/google/sanitizers/issues/321.
   2579   int res = REAL(getpeername)(sockfd, addr, addrlen);
   2580   if (!res && addr && addrlen)
   2581     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
   2582   return res;
   2583 }
   2584 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
   2585 #else
   2586 #define INIT_GETPEERNAME
   2587 #endif
   2588 
   2589 #if SANITIZER_INTERCEPT_SYSINFO
   2590 INTERCEPTOR(int, sysinfo, void *info) {
   2591   void *ctx;
   2592   // FIXME: under ASan the call below may write to freed memory and corrupt
   2593   // its metadata. See
   2594   // https://github.com/google/sanitizers/issues/321.
   2595   COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
   2596   int res = REAL(sysinfo)(info);
   2597   if (!res && info)
   2598     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
   2599   return res;
   2600 }
   2601 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
   2602 #else
   2603 #define INIT_SYSINFO
   2604 #endif
   2605 
   2606 #if SANITIZER_INTERCEPT_READDIR
   2607 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
   2608   void *ctx;
   2609   COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
   2610   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   2611   __sanitizer_dirent *res = REAL(opendir)(path);
   2612   if (res)
   2613     COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
   2614   return res;
   2615 }
   2616 
   2617 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
   2618   void *ctx;
   2619   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
   2620   // FIXME: under ASan the call below may write to freed memory and corrupt
   2621   // its metadata. See
   2622   // https://github.com/google/sanitizers/issues/321.
   2623   __sanitizer_dirent *res = REAL(readdir)(dirp);
   2624   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   2625   return res;
   2626 }
   2627 
   2628 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
   2629             __sanitizer_dirent **result) {
   2630   void *ctx;
   2631   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
   2632   // FIXME: under ASan the call below may write to freed memory and corrupt
   2633   // its metadata. See
   2634   // https://github.com/google/sanitizers/issues/321.
   2635   int res = REAL(readdir_r)(dirp, entry, result);
   2636   if (!res) {
   2637     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2638     if (*result)
   2639       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
   2640   }
   2641   return res;
   2642 }
   2643 
   2644 #define INIT_READDIR                  \
   2645   COMMON_INTERCEPT_FUNCTION(opendir); \
   2646   COMMON_INTERCEPT_FUNCTION(readdir); \
   2647   COMMON_INTERCEPT_FUNCTION(readdir_r);
   2648 #else
   2649 #define INIT_READDIR
   2650 #endif
   2651 
   2652 #if SANITIZER_INTERCEPT_READDIR64
   2653 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
   2654   void *ctx;
   2655   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
   2656   // FIXME: under ASan the call below may write to freed memory and corrupt
   2657   // its metadata. See
   2658   // https://github.com/google/sanitizers/issues/321.
   2659   __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
   2660   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
   2661   return res;
   2662 }
   2663 
   2664 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
   2665             __sanitizer_dirent64 **result) {
   2666   void *ctx;
   2667   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
   2668   // FIXME: under ASan the call below may write to freed memory and corrupt
   2669   // its metadata. See
   2670   // https://github.com/google/sanitizers/issues/321.
   2671   int res = REAL(readdir64_r)(dirp, entry, result);
   2672   if (!res) {
   2673     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   2674     if (*result)
   2675       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
   2676   }
   2677   return res;
   2678 }
   2679 #define INIT_READDIR64                  \
   2680   COMMON_INTERCEPT_FUNCTION(readdir64); \
   2681   COMMON_INTERCEPT_FUNCTION(readdir64_r);
   2682 #else
   2683 #define INIT_READDIR64
   2684 #endif
   2685 
   2686 #if SANITIZER_INTERCEPT_PTRACE
   2687 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
   2688   void *ctx;
   2689   COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
   2690   __sanitizer_iovec local_iovec;
   2691 
   2692   if (data) {
   2693     if (request == ptrace_setregs)
   2694       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
   2695     else if (request == ptrace_setfpregs)
   2696       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
   2697     else if (request == ptrace_setfpxregs)
   2698       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
   2699     else if (request == ptrace_setvfpregs)
   2700       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
   2701     else if (request == ptrace_setsiginfo)
   2702       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
   2703     // Some kernel might zero the iovec::iov_base in case of invalid
   2704     // write access.  In this case copy the invalid address for further
   2705     // inspection.
   2706     else if (request == ptrace_setregset || request == ptrace_getregset) {
   2707       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
   2708       COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
   2709       local_iovec = *iovec;
   2710       if (request == ptrace_setregset)
   2711         COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
   2712     }
   2713   }
   2714 
   2715   // FIXME: under ASan the call below may write to freed memory and corrupt
   2716   // its metadata. See
   2717   // https://github.com/google/sanitizers/issues/321.
   2718   uptr res = REAL(ptrace)(request, pid, addr, data);
   2719 
   2720   if (!res && data) {
   2721     // Note that PEEK* requests assign different meaning to the return value.
   2722     // This function does not handle them (nor does it need to).
   2723     if (request == ptrace_getregs)
   2724       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
   2725     else if (request == ptrace_getfpregs)
   2726       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
   2727     else if (request == ptrace_getfpxregs)
   2728       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
   2729     else if (request == ptrace_getvfpregs)
   2730       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
   2731     else if (request == ptrace_getsiginfo)
   2732       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
   2733     else if (request == ptrace_geteventmsg)
   2734       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
   2735     else if (request == ptrace_getregset) {
   2736       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
   2737       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
   2738       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
   2739                                      local_iovec.iov_len);
   2740     }
   2741   }
   2742   return res;
   2743 }
   2744 
   2745 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
   2746 #else
   2747 #define INIT_PTRACE
   2748 #endif
   2749 
   2750 #if SANITIZER_INTERCEPT_SETLOCALE
   2751 INTERCEPTOR(char *, setlocale, int category, char *locale) {
   2752   void *ctx;
   2753   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
   2754   if (locale)
   2755     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
   2756   char *res = REAL(setlocale)(category, locale);
   2757   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   2758   return res;
   2759 }
   2760 
   2761 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
   2762 #else
   2763 #define INIT_SETLOCALE
   2764 #endif
   2765 
   2766 #if SANITIZER_INTERCEPT_GETCWD
   2767 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
   2768   void *ctx;
   2769   COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
   2770   // FIXME: under ASan the call below may write to freed memory and corrupt
   2771   // its metadata. See
   2772   // https://github.com/google/sanitizers/issues/321.
   2773   char *res = REAL(getcwd)(buf, size);
   2774   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   2775   return res;
   2776 }
   2777 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
   2778 #else
   2779 #define INIT_GETCWD
   2780 #endif
   2781 
   2782 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
   2783 INTERCEPTOR(char *, get_current_dir_name, int fake) {
   2784   void *ctx;
   2785   COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
   2786   // FIXME: under ASan the call below may write to freed memory and corrupt
   2787   // its metadata. See
   2788   // https://github.com/google/sanitizers/issues/321.
   2789   char *res = REAL(get_current_dir_name)(fake);
   2790   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   2791   return res;
   2792 }
   2793 
   2794 #define INIT_GET_CURRENT_DIR_NAME \
   2795   COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
   2796 #else
   2797 #define INIT_GET_CURRENT_DIR_NAME
   2798 #endif
   2799 
   2800 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
   2801   CHECK(endptr);
   2802   if (nptr == *endptr) {
   2803     // No digits were found at strtol call, we need to find out the last
   2804     // symbol accessed by strtoll on our own.
   2805     // We get this symbol by skipping leading blanks and optional +/- sign.
   2806     while (IsSpace(*nptr)) nptr++;
   2807     if (*nptr == '+' || *nptr == '-') nptr++;
   2808     *endptr = const_cast<char *>(nptr);
   2809   }
   2810   CHECK(*endptr >= nptr);
   2811 }
   2812 
   2813 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
   2814                              char **endptr, char *real_endptr, int base) {
   2815   if (endptr) {
   2816     *endptr = real_endptr;
   2817     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
   2818   }
   2819   // If base has unsupported value, strtol can exit with EINVAL
   2820   // without reading any characters. So do additional checks only
   2821   // if base is valid.
   2822   bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
   2823   if (is_valid_base) {
   2824     FixRealStrtolEndptr(nptr, &real_endptr);
   2825   }
   2826   COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
   2827                                  (real_endptr - nptr) + 1 : 0);
   2828 }
   2829 
   2830 
   2831 #if SANITIZER_INTERCEPT_STRTOIMAX
   2832 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
   2833   void *ctx;
   2834   COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
   2835   // FIXME: under ASan the call below may write to freed memory and corrupt
   2836   // its metadata. See
   2837   // https://github.com/google/sanitizers/issues/321.
   2838   char *real_endptr;
   2839   INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
   2840   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   2841   return res;
   2842 }
   2843 
   2844 INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
   2845   void *ctx;
   2846   COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
   2847   // FIXME: under ASan the call below may write to freed memory and corrupt
   2848   // its metadata. See
   2849   // https://github.com/google/sanitizers/issues/321.
   2850   char *real_endptr;
   2851   INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
   2852   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
   2853   return res;
   2854 }
   2855 
   2856 #define INIT_STRTOIMAX                  \
   2857   COMMON_INTERCEPT_FUNCTION(strtoimax); \
   2858   COMMON_INTERCEPT_FUNCTION(strtoumax);
   2859 #else
   2860 #define INIT_STRTOIMAX
   2861 #endif
   2862 
   2863 #if SANITIZER_INTERCEPT_MBSTOWCS
   2864 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
   2865   void *ctx;
   2866   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
   2867   // FIXME: under ASan the call below may write to freed memory and corrupt
   2868   // its metadata. See
   2869   // https://github.com/google/sanitizers/issues/321.
   2870   SIZE_T res = REAL(mbstowcs)(dest, src, len);
   2871   if (res != (SIZE_T) - 1 && dest) {
   2872     SIZE_T write_cnt = res + (res < len);
   2873     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   2874   }
   2875   return res;
   2876 }
   2877 
   2878 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
   2879             void *ps) {
   2880   void *ctx;
   2881   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
   2882   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   2883   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   2884   // FIXME: under ASan the call below may write to freed memory and corrupt
   2885   // its metadata. See
   2886   // https://github.com/google/sanitizers/issues/321.
   2887   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
   2888   if (res != (SIZE_T)(-1) && dest && src) {
   2889     // This function, and several others, may or may not write the terminating
   2890     // \0 character. They write it iff they clear *src.
   2891     SIZE_T write_cnt = res + !*src;
   2892     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   2893   }
   2894   return res;
   2895 }
   2896 
   2897 #define INIT_MBSTOWCS                  \
   2898   COMMON_INTERCEPT_FUNCTION(mbstowcs); \
   2899   COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
   2900 #else
   2901 #define INIT_MBSTOWCS
   2902 #endif
   2903 
   2904 #if SANITIZER_INTERCEPT_MBSNRTOWCS
   2905 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
   2906             SIZE_T len, void *ps) {
   2907   void *ctx;
   2908   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
   2909   if (src) {
   2910     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   2911     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   2912   }
   2913   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   2914   // FIXME: under ASan the call below may write to freed memory and corrupt
   2915   // its metadata. See
   2916   // https://github.com/google/sanitizers/issues/321.
   2917   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
   2918   if (res != (SIZE_T)(-1) && dest && src) {
   2919     SIZE_T write_cnt = res + !*src;
   2920     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
   2921   }
   2922   return res;
   2923 }
   2924 
   2925 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
   2926 #else
   2927 #define INIT_MBSNRTOWCS
   2928 #endif
   2929 
   2930 #if SANITIZER_INTERCEPT_WCSTOMBS
   2931 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
   2932   void *ctx;
   2933   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
   2934   // FIXME: under ASan the call below may write to freed memory and corrupt
   2935   // its metadata. See
   2936   // https://github.com/google/sanitizers/issues/321.
   2937   SIZE_T res = REAL(wcstombs)(dest, src, len);
   2938   if (res != (SIZE_T) - 1 && dest) {
   2939     SIZE_T write_cnt = res + (res < len);
   2940     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   2941   }
   2942   return res;
   2943 }
   2944 
   2945 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
   2946             void *ps) {
   2947   void *ctx;
   2948   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
   2949   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   2950   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   2951   // FIXME: under ASan the call below may write to freed memory and corrupt
   2952   // its metadata. See
   2953   // https://github.com/google/sanitizers/issues/321.
   2954   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
   2955   if (res != (SIZE_T) - 1 && dest && src) {
   2956     SIZE_T write_cnt = res + !*src;
   2957     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   2958   }
   2959   return res;
   2960 }
   2961 
   2962 #define INIT_WCSTOMBS                  \
   2963   COMMON_INTERCEPT_FUNCTION(wcstombs); \
   2964   COMMON_INTERCEPT_FUNCTION(wcsrtombs);
   2965 #else
   2966 #define INIT_WCSTOMBS
   2967 #endif
   2968 
   2969 #if SANITIZER_INTERCEPT_WCSNRTOMBS
   2970 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
   2971             SIZE_T len, void *ps) {
   2972   void *ctx;
   2973   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
   2974   if (src) {
   2975     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
   2976     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
   2977   }
   2978   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   2979   // FIXME: under ASan the call below may write to freed memory and corrupt
   2980   // its metadata. See
   2981   // https://github.com/google/sanitizers/issues/321.
   2982   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
   2983   if (res != ((SIZE_T)-1) && dest && src) {
   2984     SIZE_T write_cnt = res + !*src;
   2985     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   2986   }
   2987   return res;
   2988 }
   2989 
   2990 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
   2991 #else
   2992 #define INIT_WCSNRTOMBS
   2993 #endif
   2994 
   2995 
   2996 #if SANITIZER_INTERCEPT_WCRTOMB
   2997 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
   2998   void *ctx;
   2999   COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
   3000   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
   3001   // FIXME: under ASan the call below may write to freed memory and corrupt
   3002   // its metadata. See
   3003   // https://github.com/google/sanitizers/issues/321.
   3004   SIZE_T res = REAL(wcrtomb)(dest, src, ps);
   3005   if (res != ((SIZE_T)-1) && dest) {
   3006     SIZE_T write_cnt = res;
   3007     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
   3008   }
   3009   return res;
   3010 }
   3011 
   3012 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
   3013 #else
   3014 #define INIT_WCRTOMB
   3015 #endif
   3016 
   3017 #if SANITIZER_INTERCEPT_TCGETATTR
   3018 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
   3019   void *ctx;
   3020   COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
   3021   // FIXME: under ASan the call below may write to freed memory and corrupt
   3022   // its metadata. See
   3023   // https://github.com/google/sanitizers/issues/321.
   3024   int res = REAL(tcgetattr)(fd, termios_p);
   3025   if (!res && termios_p)
   3026     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
   3027   return res;
   3028 }
   3029 
   3030 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
   3031 #else
   3032 #define INIT_TCGETATTR
   3033 #endif
   3034 
   3035 #if SANITIZER_INTERCEPT_REALPATH
   3036 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
   3037   void *ctx;
   3038   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
   3039   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3040 
   3041   // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
   3042   // version of a versioned symbol. For realpath(), this gives us something
   3043   // (called __old_realpath) that does not handle NULL in the second argument.
   3044   // Handle it as part of the interceptor.
   3045   char *allocated_path = nullptr;
   3046   if (!resolved_path)
   3047     allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
   3048 
   3049   char *res = REAL(realpath)(path, resolved_path);
   3050   if (allocated_path && !res) WRAP(free)(allocated_path);
   3051   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3052   return res;
   3053 }
   3054 #define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
   3055 #else
   3056 #define INIT_REALPATH
   3057 #endif
   3058 
   3059 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
   3060 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
   3061   void *ctx;
   3062   COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
   3063   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3064   char *res = REAL(canonicalize_file_name)(path);
   3065   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3066   return res;
   3067 }
   3068 #define INIT_CANONICALIZE_FILE_NAME \
   3069   COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
   3070 #else
   3071 #define INIT_CANONICALIZE_FILE_NAME
   3072 #endif
   3073 
   3074 #if SANITIZER_INTERCEPT_CONFSTR
   3075 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
   3076   void *ctx;
   3077   COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
   3078   // FIXME: under ASan the call below may write to freed memory and corrupt
   3079   // its metadata. See
   3080   // https://github.com/google/sanitizers/issues/321.
   3081   SIZE_T res = REAL(confstr)(name, buf, len);
   3082   if (buf && res)
   3083     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
   3084   return res;
   3085 }
   3086 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
   3087 #else
   3088 #define INIT_CONFSTR
   3089 #endif
   3090 
   3091 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
   3092 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
   3093   void *ctx;
   3094   COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
   3095   // FIXME: under ASan the call below may write to freed memory and corrupt
   3096   // its metadata. See
   3097   // https://github.com/google/sanitizers/issues/321.
   3098   int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
   3099   if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
   3100   return res;
   3101 }
   3102 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
   3103 #else
   3104 #define INIT_SCHED_GETAFFINITY
   3105 #endif
   3106 
   3107 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
   3108 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
   3109   void *ctx;
   3110   COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
   3111   int res = REAL(sched_getparam)(pid, param);
   3112   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
   3113   return res;
   3114 }
   3115 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
   3116 #else
   3117 #define INIT_SCHED_GETPARAM
   3118 #endif
   3119 
   3120 #if SANITIZER_INTERCEPT_STRERROR
   3121 INTERCEPTOR(char *, strerror, int errnum) {
   3122   void *ctx;
   3123   COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
   3124   char *res = REAL(strerror)(errnum);
   3125   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   3126   return res;
   3127 }
   3128 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
   3129 #else
   3130 #define INIT_STRERROR
   3131 #endif
   3132 
   3133 #if SANITIZER_INTERCEPT_STRERROR_R
   3134 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
   3135   void *ctx;
   3136   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
   3137   // FIXME: under ASan the call below may write to freed memory and corrupt
   3138   // its metadata. See
   3139   // https://github.com/google/sanitizers/issues/321.
   3140   char *res = REAL(strerror_r)(errnum, buf, buflen);
   3141   // There are 2 versions of strerror_r:
   3142   //  * POSIX version returns 0 on success, negative error code on failure,
   3143   //    writes message to buf.
   3144   //  * GNU version returns message pointer, which points to either buf or some
   3145   //    static storage.
   3146   SIZE_T posix_res = (SIZE_T)res;
   3147   if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
   3148     // POSIX version. Spec is not clear on whether buf is NULL-terminated.
   3149     // At least on OSX, buf contents are valid even when the call fails.
   3150     SIZE_T sz = internal_strnlen(buf, buflen);
   3151     if (sz < buflen) ++sz;
   3152     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
   3153   } else {
   3154     // GNU version.
   3155     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3156   }
   3157   return res;
   3158 }
   3159 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
   3160 #else
   3161 #define INIT_STRERROR_R
   3162 #endif
   3163 
   3164 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
   3165 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
   3166   void *ctx;
   3167   COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
   3168   // FIXME: under ASan the call below may write to freed memory and corrupt
   3169   // its metadata. See
   3170   // https://github.com/google/sanitizers/issues/321.
   3171   int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
   3172   // This version always returns a null-terminated string.
   3173   if (buf && buflen)
   3174     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   3175   return res;
   3176 }
   3177 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
   3178 #else
   3179 #define INIT_XPG_STRERROR_R
   3180 #endif
   3181 
   3182 #if SANITIZER_INTERCEPT_SCANDIR
   3183 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
   3184 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
   3185                                 const struct __sanitizer_dirent **);
   3186 
   3187 static THREADLOCAL scandir_filter_f scandir_filter;
   3188 static THREADLOCAL scandir_compar_f scandir_compar;
   3189 
   3190 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
   3191   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   3192   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
   3193   return scandir_filter(dir);
   3194 }
   3195 
   3196 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
   3197                                   const struct __sanitizer_dirent **b) {
   3198   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   3199   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
   3200   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
   3201   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
   3202   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
   3203   return scandir_compar(a, b);
   3204 }
   3205 
   3206 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
   3207             scandir_filter_f filter, scandir_compar_f compar) {
   3208   void *ctx;
   3209   COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
   3210   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
   3211   scandir_filter = filter;
   3212   scandir_compar = compar;
   3213   // FIXME: under ASan the call below may write to freed memory and corrupt
   3214   // its metadata. See
   3215   // https://github.com/google/sanitizers/issues/321.
   3216   int res = REAL(scandir)(dirp, namelist,
   3217                           filter ? wrapped_scandir_filter : nullptr,
   3218                           compar ? wrapped_scandir_compar : nullptr);
   3219   scandir_filter = nullptr;
   3220   scandir_compar = nullptr;
   3221   if (namelist && res > 0) {
   3222     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
   3223     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
   3224     for (int i = 0; i < res; ++i)
   3225       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
   3226                                      (*namelist)[i]->d_reclen);
   3227   }
   3228   return res;
   3229 }
   3230 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
   3231 #else
   3232 #define INIT_SCANDIR
   3233 #endif
   3234 
   3235 #if SANITIZER_INTERCEPT_SCANDIR64
   3236 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
   3237 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
   3238                                   const struct __sanitizer_dirent64 **);
   3239 
   3240 static THREADLOCAL scandir64_filter_f scandir64_filter;
   3241 static THREADLOCAL scandir64_compar_f scandir64_compar;
   3242 
   3243 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
   3244   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   3245   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
   3246   return scandir64_filter(dir);
   3247 }
   3248 
   3249 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
   3250                                     const struct __sanitizer_dirent64 **b) {
   3251   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
   3252   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
   3253   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
   3254   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
   3255   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
   3256   return scandir64_compar(a, b);
   3257 }
   3258 
   3259 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
   3260             scandir64_filter_f filter, scandir64_compar_f compar) {
   3261   void *ctx;
   3262   COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
   3263   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
   3264   scandir64_filter = filter;
   3265   scandir64_compar = compar;
   3266   // FIXME: under ASan the call below may write to freed memory and corrupt
   3267   // its metadata. See
   3268   // https://github.com/google/sanitizers/issues/321.
   3269   int res =
   3270       REAL(scandir64)(dirp, namelist,
   3271                       filter ? wrapped_scandir64_filter : nullptr,
   3272                       compar ? wrapped_scandir64_compar : nullptr);
   3273   scandir64_filter = nullptr;
   3274   scandir64_compar = nullptr;
   3275   if (namelist && res > 0) {
   3276     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
   3277     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
   3278     for (int i = 0; i < res; ++i)
   3279       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
   3280                                      (*namelist)[i]->d_reclen);
   3281   }
   3282   return res;
   3283 }
   3284 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
   3285 #else
   3286 #define INIT_SCANDIR64
   3287 #endif
   3288 
   3289 #if SANITIZER_INTERCEPT_GETGROUPS
   3290 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
   3291   void *ctx;
   3292   COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
   3293   // FIXME: under ASan the call below may write to freed memory and corrupt
   3294   // its metadata. See
   3295   // https://github.com/google/sanitizers/issues/321.
   3296   int res = REAL(getgroups)(size, lst);
   3297   if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
   3298   return res;
   3299 }
   3300 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
   3301 #else
   3302 #define INIT_GETGROUPS
   3303 #endif
   3304 
   3305 #if SANITIZER_INTERCEPT_POLL
   3306 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
   3307                         __sanitizer_nfds_t nfds) {
   3308   for (unsigned i = 0; i < nfds; ++i) {
   3309     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
   3310     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
   3311   }
   3312 }
   3313 
   3314 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
   3315                          __sanitizer_nfds_t nfds) {
   3316   for (unsigned i = 0; i < nfds; ++i)
   3317     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
   3318                                    sizeof(fds[i].revents));
   3319 }
   3320 
   3321 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
   3322             int timeout) {
   3323   void *ctx;
   3324   COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
   3325   if (fds && nfds) read_pollfd(ctx, fds, nfds);
   3326   int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
   3327   if (fds && nfds) write_pollfd(ctx, fds, nfds);
   3328   return res;
   3329 }
   3330 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
   3331 #else
   3332 #define INIT_POLL
   3333 #endif
   3334 
   3335 #if SANITIZER_INTERCEPT_PPOLL
   3336 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
   3337             void *timeout_ts, __sanitizer_sigset_t *sigmask) {
   3338   void *ctx;
   3339   COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
   3340   if (fds && nfds) read_pollfd(ctx, fds, nfds);
   3341   if (timeout_ts)
   3342     COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
   3343   // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
   3344   int res =
   3345       COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
   3346   if (fds && nfds) write_pollfd(ctx, fds, nfds);
   3347   return res;
   3348 }
   3349 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
   3350 #else
   3351 #define INIT_PPOLL
   3352 #endif
   3353 
   3354 #if SANITIZER_INTERCEPT_WORDEXP
   3355 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
   3356   void *ctx;
   3357   COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
   3358   if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
   3359   // FIXME: under ASan the call below may write to freed memory and corrupt
   3360   // its metadata. See
   3361   // https://github.com/google/sanitizers/issues/321.
   3362   int res = REAL(wordexp)(s, p, flags);
   3363   if (!res && p) {
   3364     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   3365     if (p->we_wordc)
   3366       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
   3367                                      sizeof(*p->we_wordv) * p->we_wordc);
   3368     for (uptr i = 0; i < p->we_wordc; ++i) {
   3369       char *w = p->we_wordv[i];
   3370       if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
   3371     }
   3372   }
   3373   return res;
   3374 }
   3375 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
   3376 #else
   3377 #define INIT_WORDEXP
   3378 #endif
   3379 
   3380 #if SANITIZER_INTERCEPT_SIGWAIT
   3381 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
   3382   void *ctx;
   3383   COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
   3384   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
   3385   // FIXME: under ASan the call below may write to freed memory and corrupt
   3386   // its metadata. See
   3387   // https://github.com/google/sanitizers/issues/321.
   3388   int res = REAL(sigwait)(set, sig);
   3389   if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
   3390   return res;
   3391 }
   3392 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
   3393 #else
   3394 #define INIT_SIGWAIT
   3395 #endif
   3396 
   3397 #if SANITIZER_INTERCEPT_SIGWAITINFO
   3398 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
   3399   void *ctx;
   3400   COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
   3401   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
   3402   // FIXME: under ASan the call below may write to freed memory and corrupt
   3403   // its metadata. See
   3404   // https://github.com/google/sanitizers/issues/321.
   3405   int res = REAL(sigwaitinfo)(set, info);
   3406   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
   3407   return res;
   3408 }
   3409 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
   3410 #else
   3411 #define INIT_SIGWAITINFO
   3412 #endif
   3413 
   3414 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
   3415 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
   3416             void *timeout) {
   3417   void *ctx;
   3418   COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
   3419   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
   3420   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
   3421   // FIXME: under ASan the call below may write to freed memory and corrupt
   3422   // its metadata. See
   3423   // https://github.com/google/sanitizers/issues/321.
   3424   int res = REAL(sigtimedwait)(set, info, timeout);
   3425   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
   3426   return res;
   3427 }
   3428 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
   3429 #else
   3430 #define INIT_SIGTIMEDWAIT
   3431 #endif
   3432 
   3433 #if SANITIZER_INTERCEPT_SIGSETOPS
   3434 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
   3435   void *ctx;
   3436   COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
   3437   // FIXME: under ASan the call below may write to freed memory and corrupt
   3438   // its metadata. See
   3439   // https://github.com/google/sanitizers/issues/321.
   3440   int res = REAL(sigemptyset)(set);
   3441   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   3442   return res;
   3443 }
   3444 
   3445 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
   3446   void *ctx;
   3447   COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
   3448   // FIXME: under ASan the call below may write to freed memory and corrupt
   3449   // its metadata. See
   3450   // https://github.com/google/sanitizers/issues/321.
   3451   int res = REAL(sigfillset)(set);
   3452   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   3453   return res;
   3454 }
   3455 #define INIT_SIGSETOPS                    \
   3456   COMMON_INTERCEPT_FUNCTION(sigemptyset); \
   3457   COMMON_INTERCEPT_FUNCTION(sigfillset);
   3458 #else
   3459 #define INIT_SIGSETOPS
   3460 #endif
   3461 
   3462 #if SANITIZER_INTERCEPT_SIGPENDING
   3463 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
   3464   void *ctx;
   3465   COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
   3466   // FIXME: under ASan the call below may write to freed memory and corrupt
   3467   // its metadata. See
   3468   // https://github.com/google/sanitizers/issues/321.
   3469   int res = REAL(sigpending)(set);
   3470   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
   3471   return res;
   3472 }
   3473 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
   3474 #else
   3475 #define INIT_SIGPENDING
   3476 #endif
   3477 
   3478 #if SANITIZER_INTERCEPT_SIGPROCMASK
   3479 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
   3480             __sanitizer_sigset_t *oldset) {
   3481   void *ctx;
   3482   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
   3483   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
   3484   // FIXME: under ASan the call below may write to freed memory and corrupt
   3485   // its metadata. See
   3486   // https://github.com/google/sanitizers/issues/321.
   3487   int res = REAL(sigprocmask)(how, set, oldset);
   3488   if (!res && oldset)
   3489     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
   3490   return res;
   3491 }
   3492 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
   3493 #else
   3494 #define INIT_SIGPROCMASK
   3495 #endif
   3496 
   3497 #if SANITIZER_INTERCEPT_BACKTRACE
   3498 INTERCEPTOR(int, backtrace, void **buffer, int size) {
   3499   void *ctx;
   3500   COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
   3501   // FIXME: under ASan the call below may write to freed memory and corrupt
   3502   // its metadata. See
   3503   // https://github.com/google/sanitizers/issues/321.
   3504   int res = REAL(backtrace)(buffer, size);
   3505   if (res && buffer)
   3506     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
   3507   return res;
   3508 }
   3509 
   3510 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
   3511   void *ctx;
   3512   COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
   3513   if (buffer && size)
   3514     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
   3515   // FIXME: under ASan the call below may write to freed memory and corrupt
   3516   // its metadata. See
   3517   // https://github.com/google/sanitizers/issues/321.
   3518   char **res = REAL(backtrace_symbols)(buffer, size);
   3519   if (res && size) {
   3520     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
   3521     for (int i = 0; i < size; ++i)
   3522       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
   3523   }
   3524   return res;
   3525 }
   3526 #define INIT_BACKTRACE                  \
   3527   COMMON_INTERCEPT_FUNCTION(backtrace); \
   3528   COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
   3529 #else
   3530 #define INIT_BACKTRACE
   3531 #endif
   3532 
   3533 #if SANITIZER_INTERCEPT__EXIT
   3534 INTERCEPTOR(void, _exit, int status) {
   3535   void *ctx;
   3536   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
   3537   COMMON_INTERCEPTOR_USER_CALLBACK_START();
   3538   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
   3539   COMMON_INTERCEPTOR_USER_CALLBACK_END();
   3540   if (status == 0) status = status1;
   3541   REAL(_exit)(status);
   3542 }
   3543 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
   3544 #else
   3545 #define INIT__EXIT
   3546 #endif
   3547 
   3548 #if SANITIZER_INTERCEPT_PHTREAD_MUTEX
   3549 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
   3550   void *ctx;
   3551   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
   3552   int res = REAL(pthread_mutex_lock)(m);
   3553   if (res == errno_EOWNERDEAD)
   3554     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
   3555   if (res == 0 || res == errno_EOWNERDEAD)
   3556     COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
   3557   if (res == errno_EINVAL)
   3558     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
   3559   return res;
   3560 }
   3561 
   3562 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
   3563   void *ctx;
   3564   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
   3565   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
   3566   int res = REAL(pthread_mutex_unlock)(m);
   3567   if (res == errno_EINVAL)
   3568     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
   3569   return res;
   3570 }
   3571 
   3572 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
   3573 #define INIT_PTHREAD_MUTEX_UNLOCK \
   3574   COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
   3575 #else
   3576 #define INIT_PTHREAD_MUTEX_LOCK
   3577 #define INIT_PTHREAD_MUTEX_UNLOCK
   3578 #endif
   3579 
   3580 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
   3581 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
   3582   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
   3583   if (mnt->mnt_fsname)
   3584     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
   3585                                    REAL(strlen)(mnt->mnt_fsname) + 1);
   3586   if (mnt->mnt_dir)
   3587     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
   3588                                    REAL(strlen)(mnt->mnt_dir) + 1);
   3589   if (mnt->mnt_type)
   3590     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
   3591                                    REAL(strlen)(mnt->mnt_type) + 1);
   3592   if (mnt->mnt_opts)
   3593     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
   3594                                    REAL(strlen)(mnt->mnt_opts) + 1);
   3595 }
   3596 #endif
   3597 
   3598 #if SANITIZER_INTERCEPT_GETMNTENT
   3599 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
   3600   void *ctx;
   3601   COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
   3602   __sanitizer_mntent *res = REAL(getmntent)(fp);
   3603   if (res) write_mntent(ctx, res);
   3604   return res;
   3605 }
   3606 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
   3607 #else
   3608 #define INIT_GETMNTENT
   3609 #endif
   3610 
   3611 #if SANITIZER_INTERCEPT_GETMNTENT_R
   3612 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
   3613             __sanitizer_mntent *mntbuf, char *buf, int buflen) {
   3614   void *ctx;
   3615   COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
   3616   __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
   3617   if (res) write_mntent(ctx, res);
   3618   return res;
   3619 }
   3620 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
   3621 #else
   3622 #define INIT_GETMNTENT_R
   3623 #endif
   3624 
   3625 #if SANITIZER_INTERCEPT_STATFS
   3626 INTERCEPTOR(int, statfs, char *path, void *buf) {
   3627   void *ctx;
   3628   COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
   3629   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3630   // FIXME: under ASan the call below may write to freed memory and corrupt
   3631   // its metadata. See
   3632   // https://github.com/google/sanitizers/issues/321.
   3633   int res = REAL(statfs)(path, buf);
   3634   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
   3635   return res;
   3636 }
   3637 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
   3638   void *ctx;
   3639   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
   3640   // FIXME: under ASan the call below may write to freed memory and corrupt
   3641   // its metadata. See
   3642   // https://github.com/google/sanitizers/issues/321.
   3643   int res = REAL(fstatfs)(fd, buf);
   3644   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
   3645   return res;
   3646 }
   3647 #define INIT_STATFS                  \
   3648   COMMON_INTERCEPT_FUNCTION(statfs); \
   3649   COMMON_INTERCEPT_FUNCTION(fstatfs);
   3650 #else
   3651 #define INIT_STATFS
   3652 #endif
   3653 
   3654 #if SANITIZER_INTERCEPT_STATFS64
   3655 INTERCEPTOR(int, statfs64, char *path, void *buf) {
   3656   void *ctx;
   3657   COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
   3658   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3659   // FIXME: under ASan the call below may write to freed memory and corrupt
   3660   // its metadata. See
   3661   // https://github.com/google/sanitizers/issues/321.
   3662   int res = REAL(statfs64)(path, buf);
   3663   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
   3664   return res;
   3665 }
   3666 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
   3667   void *ctx;
   3668   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
   3669   // FIXME: under ASan the call below may write to freed memory and corrupt
   3670   // its metadata. See
   3671   // https://github.com/google/sanitizers/issues/321.
   3672   int res = REAL(fstatfs64)(fd, buf);
   3673   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
   3674   return res;
   3675 }
   3676 #define INIT_STATFS64                  \
   3677   COMMON_INTERCEPT_FUNCTION(statfs64); \
   3678   COMMON_INTERCEPT_FUNCTION(fstatfs64);
   3679 #else
   3680 #define INIT_STATFS64
   3681 #endif
   3682 
   3683 #if SANITIZER_INTERCEPT_STATVFS
   3684 INTERCEPTOR(int, statvfs, char *path, void *buf) {
   3685   void *ctx;
   3686   COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
   3687   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3688   // FIXME: under ASan the call below may write to freed memory and corrupt
   3689   // its metadata. See
   3690   // https://github.com/google/sanitizers/issues/321.
   3691   int res = REAL(statvfs)(path, buf);
   3692   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   3693   return res;
   3694 }
   3695 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
   3696   void *ctx;
   3697   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
   3698   // FIXME: under ASan the call below may write to freed memory and corrupt
   3699   // its metadata. See
   3700   // https://github.com/google/sanitizers/issues/321.
   3701   int res = REAL(fstatvfs)(fd, buf);
   3702   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
   3703   return res;
   3704 }
   3705 #define INIT_STATVFS                  \
   3706   COMMON_INTERCEPT_FUNCTION(statvfs); \
   3707   COMMON_INTERCEPT_FUNCTION(fstatvfs);
   3708 #else
   3709 #define INIT_STATVFS
   3710 #endif
   3711 
   3712 #if SANITIZER_INTERCEPT_STATVFS64
   3713 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
   3714   void *ctx;
   3715   COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
   3716   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   3717   // FIXME: under ASan the call below may write to freed memory and corrupt
   3718   // its metadata. See
   3719   // https://github.com/google/sanitizers/issues/321.
   3720   int res = REAL(statvfs64)(path, buf);
   3721   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
   3722   return res;
   3723 }
   3724 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
   3725   void *ctx;
   3726   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
   3727   // FIXME: under ASan the call below may write to freed memory and corrupt
   3728   // its metadata. See
   3729   // https://github.com/google/sanitizers/issues/321.
   3730   int res = REAL(fstatvfs64)(fd, buf);
   3731   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
   3732   return res;
   3733 }
   3734 #define INIT_STATVFS64                  \
   3735   COMMON_INTERCEPT_FUNCTION(statvfs64); \
   3736   COMMON_INTERCEPT_FUNCTION(fstatvfs64);
   3737 #else
   3738 #define INIT_STATVFS64
   3739 #endif
   3740 
   3741 #if SANITIZER_INTERCEPT_INITGROUPS
   3742 INTERCEPTOR(int, initgroups, char *user, u32 group) {
   3743   void *ctx;
   3744   COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
   3745   if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
   3746   int res = REAL(initgroups)(user, group);
   3747   return res;
   3748 }
   3749 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
   3750 #else
   3751 #define INIT_INITGROUPS
   3752 #endif
   3753 
   3754 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
   3755 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
   3756   void *ctx;
   3757   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
   3758   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   3759   char *res = REAL(ether_ntoa)(addr);
   3760   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   3761   return res;
   3762 }
   3763 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
   3764   void *ctx;
   3765   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
   3766   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   3767   __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
   3768   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
   3769   return res;
   3770 }
   3771 #define INIT_ETHER_NTOA_ATON             \
   3772   COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
   3773   COMMON_INTERCEPT_FUNCTION(ether_aton);
   3774 #else
   3775 #define INIT_ETHER_NTOA_ATON
   3776 #endif
   3777 
   3778 #if SANITIZER_INTERCEPT_ETHER_HOST
   3779 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
   3780   void *ctx;
   3781   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
   3782   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   3783   // FIXME: under ASan the call below may write to freed memory and corrupt
   3784   // its metadata. See
   3785   // https://github.com/google/sanitizers/issues/321.
   3786   int res = REAL(ether_ntohost)(hostname, addr);
   3787   if (!res && hostname)
   3788     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   3789   return res;
   3790 }
   3791 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
   3792   void *ctx;
   3793   COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
   3794   if (hostname)
   3795     COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   3796   // FIXME: under ASan the call below may write to freed memory and corrupt
   3797   // its metadata. See
   3798   // https://github.com/google/sanitizers/issues/321.
   3799   int res = REAL(ether_hostton)(hostname, addr);
   3800   if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   3801   return res;
   3802 }
   3803 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
   3804             char *hostname) {
   3805   void *ctx;
   3806   COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
   3807   if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
   3808   // FIXME: under ASan the call below may write to freed memory and corrupt
   3809   // its metadata. See
   3810   // https://github.com/google/sanitizers/issues/321.
   3811   int res = REAL(ether_line)(line, addr, hostname);
   3812   if (!res) {
   3813     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   3814     if (hostname)
   3815       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
   3816   }
   3817   return res;
   3818 }
   3819 #define INIT_ETHER_HOST                     \
   3820   COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
   3821   COMMON_INTERCEPT_FUNCTION(ether_hostton); \
   3822   COMMON_INTERCEPT_FUNCTION(ether_line);
   3823 #else
   3824 #define INIT_ETHER_HOST
   3825 #endif
   3826 
   3827 #if SANITIZER_INTERCEPT_ETHER_R
   3828 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
   3829   void *ctx;
   3830   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
   3831   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
   3832   // FIXME: under ASan the call below may write to freed memory and corrupt
   3833   // its metadata. See
   3834   // https://github.com/google/sanitizers/issues/321.
   3835   char *res = REAL(ether_ntoa_r)(addr, buf);
   3836   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
   3837   return res;
   3838 }
   3839 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
   3840             __sanitizer_ether_addr *addr) {
   3841   void *ctx;
   3842   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
   3843   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
   3844   // FIXME: under ASan the call below may write to freed memory and corrupt
   3845   // its metadata. See
   3846   // https://github.com/google/sanitizers/issues/321.
   3847   __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
   3848   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
   3849   return res;
   3850 }
   3851 #define INIT_ETHER_R                       \
   3852   COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
   3853   COMMON_INTERCEPT_FUNCTION(ether_aton_r);
   3854 #else
   3855 #define INIT_ETHER_R
   3856 #endif
   3857 
   3858 #if SANITIZER_INTERCEPT_SHMCTL
   3859 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
   3860   void *ctx;
   3861   COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
   3862   // FIXME: under ASan the call below may write to freed memory and corrupt
   3863   // its metadata. See
   3864   // https://github.com/google/sanitizers/issues/321.
   3865   int res = REAL(shmctl)(shmid, cmd, buf);
   3866   if (res >= 0) {
   3867     unsigned sz = 0;
   3868     if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
   3869       sz = sizeof(__sanitizer_shmid_ds);
   3870     else if (cmd == shmctl_ipc_info)
   3871       sz = struct_shminfo_sz;
   3872     else if (cmd == shmctl_shm_info)
   3873       sz = struct_shm_info_sz;
   3874     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
   3875   }
   3876   return res;
   3877 }
   3878 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
   3879 #else
   3880 #define INIT_SHMCTL
   3881 #endif
   3882 
   3883 #if SANITIZER_INTERCEPT_RANDOM_R
   3884 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
   3885   void *ctx;
   3886   COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
   3887   // FIXME: under ASan the call below may write to freed memory and corrupt
   3888   // its metadata. See
   3889   // https://github.com/google/sanitizers/issues/321.
   3890   int res = REAL(random_r)(buf, result);
   3891   if (!res && result)
   3892     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   3893   return res;
   3894 }
   3895 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
   3896 #else
   3897 #define INIT_RANDOM_R
   3898 #endif
   3899 
   3900 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
   3901 // its metadata. See
   3902 // https://github.com/google/sanitizers/issues/321.
   3903 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
   3904     SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
   3905     SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
   3906     SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
   3907     SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
   3908     SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
   3909 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
   3910   INTERCEPTOR(int, fn, void *attr, void *r) {                  \
   3911     void *ctx;                                                 \
   3912     COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
   3913     int res = REAL(fn)(attr, r);                               \
   3914     if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
   3915     return res;                                                \
   3916   }
   3917 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
   3918   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
   3919 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
   3920   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
   3921 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
   3922   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
   3923 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
   3924   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
   3925 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
   3926   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
   3927 #endif
   3928 
   3929 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
   3930 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
   3931 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
   3932 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
   3933 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
   3934 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
   3935 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
   3936 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
   3937   void *ctx;
   3938   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
   3939   // FIXME: under ASan the call below may write to freed memory and corrupt
   3940   // its metadata. See
   3941   // https://github.com/google/sanitizers/issues/321.
   3942   int res = REAL(pthread_attr_getstack)(attr, addr, size);
   3943   if (!res) {
   3944     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
   3945     if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
   3946   }
   3947   return res;
   3948 }
   3949 
   3950 // We may need to call the real pthread_attr_getstack from the run-time
   3951 // in sanitizer_common, but we don't want to include the interception headers
   3952 // there. So, just define this function here.
   3953 namespace __sanitizer {
   3954 extern "C" {
   3955 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
   3956   return REAL(pthread_attr_getstack)(attr, addr, size);
   3957 }
   3958 }  // extern "C"
   3959 }  // namespace __sanitizer
   3960 
   3961 #define INIT_PTHREAD_ATTR_GET                             \
   3962   COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
   3963   COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
   3964   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
   3965   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
   3966   COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
   3967   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
   3968   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
   3969 #else
   3970 #define INIT_PTHREAD_ATTR_GET
   3971 #endif
   3972 
   3973 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
   3974 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
   3975 
   3976 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
   3977   COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
   3978 #else
   3979 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
   3980 #endif
   3981 
   3982 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
   3983 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
   3984             void *cpuset) {
   3985   void *ctx;
   3986   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
   3987                            cpuset);
   3988   // FIXME: under ASan the call below may write to freed memory and corrupt
   3989   // its metadata. See
   3990   // https://github.com/google/sanitizers/issues/321.
   3991   int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
   3992   if (!res && cpusetsize && cpuset)
   3993     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
   3994   return res;
   3995 }
   3996 
   3997 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
   3998   COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
   3999 #else
   4000 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
   4001 #endif
   4002 
   4003 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
   4004 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
   4005 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
   4006   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
   4007 #else
   4008 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
   4009 #endif
   4010 
   4011 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
   4012 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
   4013 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
   4014   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
   4015 #else
   4016 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
   4017 #endif
   4018 
   4019 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
   4020 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
   4021 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
   4022   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
   4023 #else
   4024 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
   4025 #endif
   4026 
   4027 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
   4028 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
   4029 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
   4030   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
   4031 #else
   4032 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
   4033 #endif
   4034 
   4035 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
   4036 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
   4037 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
   4038   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
   4039 #else
   4040 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
   4041 #endif
   4042 
   4043 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
   4044 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
   4045 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
   4046   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
   4047 #else
   4048 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
   4049 #endif
   4050 
   4051 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
   4052 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
   4053 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
   4054   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
   4055 #else
   4056 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
   4057 #endif
   4058 
   4059 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
   4060 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
   4061 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
   4062   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
   4063 #else
   4064 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
   4065 #endif
   4066 
   4067 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
   4068 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
   4069 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
   4070   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
   4071 #else
   4072 #define INIT_PTHREAD_CONDATTR_GETPSHARED
   4073 #endif
   4074 
   4075 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
   4076 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
   4077 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
   4078   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
   4079 #else
   4080 #define INIT_PTHREAD_CONDATTR_GETCLOCK
   4081 #endif
   4082 
   4083 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
   4084 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
   4085 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
   4086   COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
   4087 #else
   4088 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
   4089 #endif
   4090 
   4091 #if SANITIZER_INTERCEPT_TMPNAM
   4092 INTERCEPTOR(char *, tmpnam, char *s) {
   4093   void *ctx;
   4094   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
   4095   char *res = REAL(tmpnam)(s);
   4096   if (res) {
   4097     if (s)
   4098       // FIXME: under ASan the call below may write to freed memory and corrupt
   4099       // its metadata. See
   4100       // https://github.com/google/sanitizers/issues/321.
   4101       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
   4102     else
   4103       COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   4104   }
   4105   return res;
   4106 }
   4107 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
   4108 #else
   4109 #define INIT_TMPNAM
   4110 #endif
   4111 
   4112 #if SANITIZER_INTERCEPT_TMPNAM_R
   4113 INTERCEPTOR(char *, tmpnam_r, char *s) {
   4114   void *ctx;
   4115   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
   4116   // FIXME: under ASan the call below may write to freed memory and corrupt
   4117   // its metadata. See
   4118   // https://github.com/google/sanitizers/issues/321.
   4119   char *res = REAL(tmpnam_r)(s);
   4120   if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
   4121   return res;
   4122 }
   4123 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
   4124 #else
   4125 #define INIT_TMPNAM_R
   4126 #endif
   4127 
   4128 #if SANITIZER_INTERCEPT_TEMPNAM
   4129 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
   4130   void *ctx;
   4131   COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
   4132   if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
   4133   if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
   4134   char *res = REAL(tempnam)(dir, pfx);
   4135   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   4136   return res;
   4137 }
   4138 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
   4139 #else
   4140 #define INIT_TEMPNAM
   4141 #endif
   4142 
   4143 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
   4144 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
   4145   void *ctx;
   4146   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
   4147   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
   4148   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
   4149   return REAL(pthread_setname_np)(thread, name);
   4150 }
   4151 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
   4152 #else
   4153 #define INIT_PTHREAD_SETNAME_NP
   4154 #endif
   4155 
   4156 #if SANITIZER_INTERCEPT_SINCOS
   4157 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
   4158   void *ctx;
   4159   COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
   4160   // FIXME: under ASan the call below may write to freed memory and corrupt
   4161   // its metadata. See
   4162   // https://github.com/google/sanitizers/issues/321.
   4163   REAL(sincos)(x, sin, cos);
   4164   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4165   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4166 }
   4167 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
   4168   void *ctx;
   4169   COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
   4170   // FIXME: under ASan the call below may write to freed memory and corrupt
   4171   // its metadata. See
   4172   // https://github.com/google/sanitizers/issues/321.
   4173   REAL(sincosf)(x, sin, cos);
   4174   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4175   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4176 }
   4177 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
   4178   void *ctx;
   4179   COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
   4180   // FIXME: under ASan the call below may write to freed memory and corrupt
   4181   // its metadata. See
   4182   // https://github.com/google/sanitizers/issues/321.
   4183   REAL(sincosl)(x, sin, cos);
   4184   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
   4185   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
   4186 }
   4187 #define INIT_SINCOS                   \
   4188   COMMON_INTERCEPT_FUNCTION(sincos);  \
   4189   COMMON_INTERCEPT_FUNCTION(sincosf); \
   4190   COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
   4191 #else
   4192 #define INIT_SINCOS
   4193 #endif
   4194 
   4195 #if SANITIZER_INTERCEPT_REMQUO
   4196 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
   4197   void *ctx;
   4198   COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
   4199   // FIXME: under ASan the call below may write to freed memory and corrupt
   4200   // its metadata. See
   4201   // https://github.com/google/sanitizers/issues/321.
   4202   double res = REAL(remquo)(x, y, quo);
   4203   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4204   return res;
   4205 }
   4206 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
   4207   void *ctx;
   4208   COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
   4209   // FIXME: under ASan the call below may write to freed memory and corrupt
   4210   // its metadata. See
   4211   // https://github.com/google/sanitizers/issues/321.
   4212   float res = REAL(remquof)(x, y, quo);
   4213   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4214   return res;
   4215 }
   4216 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
   4217   void *ctx;
   4218   COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
   4219   // FIXME: under ASan the call below may write to freed memory and corrupt
   4220   // its metadata. See
   4221   // https://github.com/google/sanitizers/issues/321.
   4222   long double res = REAL(remquol)(x, y, quo);
   4223   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
   4224   return res;
   4225 }
   4226 #define INIT_REMQUO                   \
   4227   COMMON_INTERCEPT_FUNCTION(remquo);  \
   4228   COMMON_INTERCEPT_FUNCTION(remquof); \
   4229   COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
   4230 #else
   4231 #define INIT_REMQUO
   4232 #endif
   4233 
   4234 #if SANITIZER_INTERCEPT_LGAMMA
   4235 extern int signgam;
   4236 INTERCEPTOR(double, lgamma, double x) {
   4237   void *ctx;
   4238   COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
   4239   double res = REAL(lgamma)(x);
   4240   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4241   return res;
   4242 }
   4243 INTERCEPTOR(float, lgammaf, float x) {
   4244   void *ctx;
   4245   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
   4246   float res = REAL(lgammaf)(x);
   4247   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4248   return res;
   4249 }
   4250 INTERCEPTOR(long double, lgammal, long double x) {
   4251   void *ctx;
   4252   COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
   4253   long double res = REAL(lgammal)(x);
   4254   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
   4255   return res;
   4256 }
   4257 #define INIT_LGAMMA                   \
   4258   COMMON_INTERCEPT_FUNCTION(lgamma);  \
   4259   COMMON_INTERCEPT_FUNCTION(lgammaf); \
   4260   COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
   4261 #else
   4262 #define INIT_LGAMMA
   4263 #endif
   4264 
   4265 #if SANITIZER_INTERCEPT_LGAMMA_R
   4266 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
   4267   void *ctx;
   4268   COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
   4269   // FIXME: under ASan the call below may write to freed memory and corrupt
   4270   // its metadata. See
   4271   // https://github.com/google/sanitizers/issues/321.
   4272   double res = REAL(lgamma_r)(x, signp);
   4273   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4274   return res;
   4275 }
   4276 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
   4277   void *ctx;
   4278   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
   4279   // FIXME: under ASan the call below may write to freed memory and corrupt
   4280   // its metadata. See
   4281   // https://github.com/google/sanitizers/issues/321.
   4282   float res = REAL(lgammaf_r)(x, signp);
   4283   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4284   return res;
   4285 }
   4286 #define INIT_LGAMMA_R                   \
   4287   COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
   4288   COMMON_INTERCEPT_FUNCTION(lgammaf_r);
   4289 #else
   4290 #define INIT_LGAMMA_R
   4291 #endif
   4292 
   4293 #if SANITIZER_INTERCEPT_LGAMMAL_R
   4294 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
   4295   void *ctx;
   4296   COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
   4297   // FIXME: under ASan the call below may write to freed memory and corrupt
   4298   // its metadata. See
   4299   // https://github.com/google/sanitizers/issues/321.
   4300   long double res = REAL(lgammal_r)(x, signp);
   4301   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
   4302   return res;
   4303 }
   4304 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
   4305 #else
   4306 #define INIT_LGAMMAL_R
   4307 #endif
   4308 
   4309 #if SANITIZER_INTERCEPT_DRAND48_R
   4310 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
   4311   void *ctx;
   4312   COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
   4313   // FIXME: under ASan the call below may write to freed memory and corrupt
   4314   // its metadata. See
   4315   // https://github.com/google/sanitizers/issues/321.
   4316   int res = REAL(drand48_r)(buffer, result);
   4317   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   4318   return res;
   4319 }
   4320 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
   4321   void *ctx;
   4322   COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
   4323   // FIXME: under ASan the call below may write to freed memory and corrupt
   4324   // its metadata. See
   4325   // https://github.com/google/sanitizers/issues/321.
   4326   int res = REAL(lrand48_r)(buffer, result);
   4327   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
   4328   return res;
   4329 }
   4330 #define INIT_DRAND48_R                  \
   4331   COMMON_INTERCEPT_FUNCTION(drand48_r); \
   4332   COMMON_INTERCEPT_FUNCTION(lrand48_r);
   4333 #else
   4334 #define INIT_DRAND48_R
   4335 #endif
   4336 
   4337 #if SANITIZER_INTERCEPT_RAND_R
   4338 INTERCEPTOR(int, rand_r, unsigned *seedp) {
   4339   void *ctx;
   4340   COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
   4341   COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
   4342   return REAL(rand_r)(seedp);
   4343 }
   4344 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
   4345 #else
   4346 #define INIT_RAND_R
   4347 #endif
   4348 
   4349 #if SANITIZER_INTERCEPT_GETLINE
   4350 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
   4351   void *ctx;
   4352   COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
   4353   // FIXME: under ASan the call below may write to freed memory and corrupt
   4354   // its metadata. See
   4355   // https://github.com/google/sanitizers/issues/321.
   4356   SSIZE_T res = REAL(getline)(lineptr, n, stream);
   4357   if (res > 0) {
   4358     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
   4359     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
   4360     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
   4361   }
   4362   return res;
   4363 }
   4364 
   4365 // FIXME: under ASan the call below may write to freed memory and corrupt its
   4366 // metadata. See
   4367 // https://github.com/google/sanitizers/issues/321.
   4368 #define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
   4369   {                                                                            \
   4370     void *ctx;                                                                 \
   4371     COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
   4372     SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
   4373     if (res > 0) {                                                             \
   4374       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
   4375       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
   4376       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
   4377     }                                                                          \
   4378     return res;                                                                \
   4379   }
   4380 
   4381 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
   4382             void *stream)
   4383 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
   4384 
   4385 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
   4386 // with its own body.
   4387 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
   4388             void *stream)
   4389 GETDELIM_INTERCEPTOR_IMPL(getdelim)
   4390 
   4391 #define INIT_GETLINE                     \
   4392   COMMON_INTERCEPT_FUNCTION(getline);    \
   4393   COMMON_INTERCEPT_FUNCTION(__getdelim); \
   4394   COMMON_INTERCEPT_FUNCTION(getdelim);
   4395 #else
   4396 #define INIT_GETLINE
   4397 #endif
   4398 
   4399 #if SANITIZER_INTERCEPT_ICONV
   4400 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
   4401             char **outbuf, SIZE_T *outbytesleft) {
   4402   void *ctx;
   4403   COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
   4404                            outbytesleft);
   4405   if (inbytesleft)
   4406     COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
   4407   if (inbuf && inbytesleft)
   4408     COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
   4409   if (outbytesleft)
   4410     COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
   4411   void *outbuf_orig = outbuf ? *outbuf : nullptr;
   4412   // FIXME: under ASan the call below may write to freed memory and corrupt
   4413   // its metadata. See
   4414   // https://github.com/google/sanitizers/issues/321.
   4415   SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
   4416   if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
   4417     SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
   4418     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
   4419   }
   4420   return res;
   4421 }
   4422 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
   4423 #else
   4424 #define INIT_ICONV
   4425 #endif
   4426 
   4427 #if SANITIZER_INTERCEPT_TIMES
   4428 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
   4429   void *ctx;
   4430   COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
   4431   // FIXME: under ASan the call below may write to freed memory and corrupt
   4432   // its metadata. See
   4433   // https://github.com/google/sanitizers/issues/321.
   4434   __sanitizer_clock_t res = REAL(times)(tms);
   4435   if (res != (__sanitizer_clock_t)-1 && tms)
   4436     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
   4437   return res;
   4438 }
   4439 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
   4440 #else
   4441 #define INIT_TIMES
   4442 #endif
   4443 
   4444 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
   4445 #if !SANITIZER_S390
   4446 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
   4447 // If you see any crashes around this functions, there are 2 known issues with
   4448 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
   4449 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
   4450 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
   4451 // to access thread local variables (it should not happen normally,
   4452 // because sanitizers use initial-exec tls model).
   4453 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
   4454   void *ctx;
   4455   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
   4456   void *res = REAL(__tls_get_addr)(arg);
   4457   uptr tls_begin, tls_end;
   4458   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
   4459   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
   4460   if (dtv) {
   4461     // New DTLS block has been allocated.
   4462     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
   4463   }
   4464   return res;
   4465 }
   4466 #if SANITIZER_PPC
   4467 // On PowerPC, we also need to intercept __tls_get_addr_opt, which has
   4468 // mostly the same semantics as __tls_get_addr, but its presence enables
   4469 // some optimizations in linker (which are safe to ignore here).
   4470 extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
   4471                           visibility("default")))
   4472 void *__tls_get_addr_opt(void *arg);
   4473 #endif
   4474 #else // SANITIZER_S390
   4475 // On s390, we have to intercept two functions here:
   4476 // - __tls_get_addr_internal, which is a glibc-internal function that is like
   4477 //   the usual __tls_get_addr, but returns a TP-relative offset instead of
   4478 //   a proper pointer.  It is used by dlsym for TLS symbols.
   4479 // - __tls_get_offset, which is like the above, but also takes a GOT-relative
   4480 //   descriptor offset as an argument instead of a pointer.  GOT address
   4481 //   is passed in r12, so it's necessary to write it in assembly.  This is
   4482 //   the function used by the compiler.
   4483 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr_internal)
   4484 INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
   4485   void *ctx;
   4486   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
   4487   uptr res = REAL(__tls_get_addr_internal)(arg);
   4488   uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
   4489   void *ptr = reinterpret_cast<void *>(res + tp);
   4490   uptr tls_begin, tls_end;
   4491   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
   4492   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
   4493   if (dtv) {
   4494     // New DTLS block has been allocated.
   4495     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
   4496   }
   4497   return res;
   4498 }
   4499 // We need a protected symbol aliasing the above, so that we can jump
   4500 // directly to it from the assembly below.
   4501 extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
   4502                           visibility("protected")))
   4503 uptr __interceptor___tls_get_addr_internal_protected(void *arg);
   4504 // Now carefully intercept __tls_get_offset.
   4505 asm(
   4506   ".text\n"
   4507   ".global __tls_get_offset\n"
   4508   "__tls_get_offset:\n"
   4509 // The __intercept_ version has to exist, so that gen_dynamic_list.py
   4510 // exports our symbol.
   4511   ".global __interceptor___tls_get_offset\n"
   4512   "__interceptor___tls_get_offset:\n"
   4513 #ifdef __s390x__
   4514   "la %r2, 0(%r2,%r12)\n"
   4515   "jg __interceptor___tls_get_addr_internal_protected\n"
   4516 #else
   4517   "basr %r3,0\n"
   4518   "0: la %r2,0(%r2,%r12)\n"
   4519   "l %r4,1f-0b(%r3)\n"
   4520   "b 0(%r4,%r3)\n"
   4521   "1: .long __interceptor___tls_get_addr_internal_protected - 0b\n"
   4522 #endif
   4523   ".type __tls_get_offset, @function\n"
   4524   ".size __tls_get_offset, .-__tls_get_offset\n"
   4525 );
   4526 #endif // SANITIZER_S390
   4527 #else
   4528 #define INIT_TLS_GET_ADDR
   4529 #endif
   4530 
   4531 #if SANITIZER_INTERCEPT_LISTXATTR
   4532 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
   4533   void *ctx;
   4534   COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
   4535   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4536   // FIXME: under ASan the call below may write to freed memory and corrupt
   4537   // its metadata. See
   4538   // https://github.com/google/sanitizers/issues/321.
   4539   SSIZE_T res = REAL(listxattr)(path, list, size);
   4540   // Here and below, size == 0 is a special case where nothing is written to the
   4541   // buffer, and res contains the desired buffer size.
   4542   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   4543   return res;
   4544 }
   4545 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
   4546   void *ctx;
   4547   COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
   4548   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4549   // FIXME: under ASan the call below may write to freed memory and corrupt
   4550   // its metadata. See
   4551   // https://github.com/google/sanitizers/issues/321.
   4552   SSIZE_T res = REAL(llistxattr)(path, list, size);
   4553   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   4554   return res;
   4555 }
   4556 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
   4557   void *ctx;
   4558   COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
   4559   // FIXME: under ASan the call below may write to freed memory and corrupt
   4560   // its metadata. See
   4561   // https://github.com/google/sanitizers/issues/321.
   4562   SSIZE_T res = REAL(flistxattr)(fd, list, size);
   4563   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
   4564   return res;
   4565 }
   4566 #define INIT_LISTXATTR                   \
   4567   COMMON_INTERCEPT_FUNCTION(listxattr);  \
   4568   COMMON_INTERCEPT_FUNCTION(llistxattr); \
   4569   COMMON_INTERCEPT_FUNCTION(flistxattr);
   4570 #else
   4571 #define INIT_LISTXATTR
   4572 #endif
   4573 
   4574 #if SANITIZER_INTERCEPT_GETXATTR
   4575 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
   4576             SIZE_T size) {
   4577   void *ctx;
   4578   COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
   4579   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4580   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   4581   // FIXME: under ASan the call below may write to freed memory and corrupt
   4582   // its metadata. See
   4583   // https://github.com/google/sanitizers/issues/321.
   4584   SSIZE_T res = REAL(getxattr)(path, name, value, size);
   4585   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   4586   return res;
   4587 }
   4588 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
   4589             SIZE_T size) {
   4590   void *ctx;
   4591   COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
   4592   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   4593   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   4594   // FIXME: under ASan the call below may write to freed memory and corrupt
   4595   // its metadata. See
   4596   // https://github.com/google/sanitizers/issues/321.
   4597   SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
   4598   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   4599   return res;
   4600 }
   4601 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
   4602             SIZE_T size) {
   4603   void *ctx;
   4604   COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
   4605   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
   4606   // FIXME: under ASan the call below may write to freed memory and corrupt
   4607   // its metadata. See
   4608   // https://github.com/google/sanitizers/issues/321.
   4609   SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
   4610   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
   4611   return res;
   4612 }
   4613 #define INIT_GETXATTR                   \
   4614   COMMON_INTERCEPT_FUNCTION(getxattr);  \
   4615   COMMON_INTERCEPT_FUNCTION(lgetxattr); \
   4616   COMMON_INTERCEPT_FUNCTION(fgetxattr);
   4617 #else
   4618 #define INIT_GETXATTR
   4619 #endif
   4620 
   4621 #if SANITIZER_INTERCEPT_GETRESID
   4622 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
   4623   void *ctx;
   4624   COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
   4625   // FIXME: under ASan the call below may write to freed memory and corrupt
   4626   // its metadata. See
   4627   // https://github.com/google/sanitizers/issues/321.
   4628   int res = REAL(getresuid)(ruid, euid, suid);
   4629   if (res >= 0) {
   4630     if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
   4631     if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
   4632     if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
   4633   }
   4634   return res;
   4635 }
   4636 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
   4637   void *ctx;
   4638   COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
   4639   // FIXME: under ASan the call below may write to freed memory and corrupt
   4640   // its metadata. See
   4641   // https://github.com/google/sanitizers/issues/321.
   4642   int res = REAL(getresgid)(rgid, egid, sgid);
   4643   if (res >= 0) {
   4644     if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
   4645     if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
   4646     if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
   4647   }
   4648   return res;
   4649 }
   4650 #define INIT_GETRESID                   \
   4651   COMMON_INTERCEPT_FUNCTION(getresuid); \
   4652   COMMON_INTERCEPT_FUNCTION(getresgid);
   4653 #else
   4654 #define INIT_GETRESID
   4655 #endif
   4656 
   4657 #if SANITIZER_INTERCEPT_GETIFADDRS
   4658 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
   4659 // intercept freeifaddrs(). If that ceases to be the case, we might need to
   4660 // intercept it to poison the memory again.
   4661 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
   4662   void *ctx;
   4663   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
   4664   // FIXME: under ASan the call below may write to freed memory and corrupt
   4665   // its metadata. See
   4666   // https://github.com/google/sanitizers/issues/321.
   4667   int res = REAL(getifaddrs)(ifap);
   4668   if (res == 0 && ifap) {
   4669     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
   4670     __sanitizer_ifaddrs *p = *ifap;
   4671     while (p) {
   4672       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
   4673       if (p->ifa_name)
   4674         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
   4675                                        REAL(strlen)(p->ifa_name) + 1);
   4676       if (p->ifa_addr)
   4677         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
   4678       if (p->ifa_netmask)
   4679         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
   4680       // On Linux this is a union, but the other member also points to a
   4681       // struct sockaddr, so the following is sufficient.
   4682       if (p->ifa_dstaddr)
   4683         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
   4684       // FIXME(smatveev): Unpoison p->ifa_data as well.
   4685       p = p->ifa_next;
   4686     }
   4687   }
   4688   return res;
   4689 }
   4690 #define INIT_GETIFADDRS                  \
   4691   COMMON_INTERCEPT_FUNCTION(getifaddrs);
   4692 #else
   4693 #define INIT_GETIFADDRS
   4694 #endif
   4695 
   4696 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
   4697 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
   4698   void *ctx;
   4699   COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
   4700   // FIXME: under ASan the call below may write to freed memory and corrupt
   4701   // its metadata. See
   4702   // https://github.com/google/sanitizers/issues/321.
   4703   char *res = REAL(if_indextoname)(ifindex, ifname);
   4704   if (res && ifname)
   4705     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
   4706   return res;
   4707 }
   4708 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
   4709   void *ctx;
   4710   COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
   4711   if (ifname)
   4712     COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
   4713   return REAL(if_nametoindex)(ifname);
   4714 }
   4715 #define INIT_IF_INDEXTONAME                  \
   4716   COMMON_INTERCEPT_FUNCTION(if_indextoname); \
   4717   COMMON_INTERCEPT_FUNCTION(if_nametoindex);
   4718 #else
   4719 #define INIT_IF_INDEXTONAME
   4720 #endif
   4721 
   4722 #if SANITIZER_INTERCEPT_CAPGET
   4723 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
   4724   void *ctx;
   4725   COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
   4726   if (hdrp)
   4727     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
   4728   // FIXME: under ASan the call below may write to freed memory and corrupt
   4729   // its metadata. See
   4730   // https://github.com/google/sanitizers/issues/321.
   4731   int res = REAL(capget)(hdrp, datap);
   4732   if (res == 0 && datap)
   4733     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
   4734   // We can also return -1 and write to hdrp->version if the version passed in
   4735   // hdrp->version is unsupported. But that's not a trivial condition to check,
   4736   // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
   4737   return res;
   4738 }
   4739 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
   4740   void *ctx;
   4741   COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
   4742   if (hdrp)
   4743     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
   4744   if (datap)
   4745     COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
   4746   return REAL(capset)(hdrp, datap);
   4747 }
   4748 #define INIT_CAPGET                  \
   4749   COMMON_INTERCEPT_FUNCTION(capget); \
   4750   COMMON_INTERCEPT_FUNCTION(capset);
   4751 #else
   4752 #define INIT_CAPGET
   4753 #endif
   4754 
   4755 #if SANITIZER_INTERCEPT_AEABI_MEM
   4756 DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)
   4757 DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)
   4758 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)
   4759 
   4760 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
   4761   return WRAP(memmove)(to, from, size);
   4762 }
   4763 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
   4764   return WRAP(memmove)(to, from, size);
   4765 }
   4766 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
   4767   return WRAP(memmove)(to, from, size);
   4768 }
   4769 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
   4770   return WRAP(memcpy)(to, from, size);
   4771 }
   4772 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
   4773   return WRAP(memcpy)(to, from, size);
   4774 }
   4775 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
   4776   return WRAP(memcpy)(to, from, size);
   4777 }
   4778 // Note the argument order.
   4779 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
   4780   return WRAP(memset)(block, c, size);
   4781 }
   4782 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
   4783   return WRAP(memset)(block, c, size);
   4784 }
   4785 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
   4786   return WRAP(memset)(block, c, size);
   4787 }
   4788 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
   4789   return WRAP(memset)(block, 0, size);
   4790 }
   4791 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
   4792   return WRAP(memset)(block, 0, size);
   4793 }
   4794 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
   4795   return WRAP(memset)(block, 0, size);
   4796 }
   4797 #define INIT_AEABI_MEM                         \
   4798   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
   4799   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
   4800   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
   4801   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
   4802   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
   4803   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
   4804   COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
   4805   COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
   4806   COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
   4807   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
   4808   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
   4809   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
   4810 #else
   4811 #define INIT_AEABI_MEM
   4812 #endif  // SANITIZER_INTERCEPT_AEABI_MEM
   4813 
   4814 #if SANITIZER_INTERCEPT___BZERO
   4815 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
   4816 
   4817 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
   4818   return WRAP(memset)(block, 0, size);
   4819 }
   4820 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
   4821 #else
   4822 #define INIT___BZERO
   4823 #endif  // SANITIZER_INTERCEPT___BZERO
   4824 
   4825 #if SANITIZER_INTERCEPT_FTIME
   4826 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
   4827   void *ctx;
   4828   COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
   4829   // FIXME: under ASan the call below may write to freed memory and corrupt
   4830   // its metadata. See
   4831   // https://github.com/google/sanitizers/issues/321.
   4832   int res = REAL(ftime)(tp);
   4833   if (tp)
   4834     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
   4835   return res;
   4836 }
   4837 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
   4838 #else
   4839 #define INIT_FTIME
   4840 #endif  // SANITIZER_INTERCEPT_FTIME
   4841 
   4842 #if SANITIZER_INTERCEPT_XDR
   4843 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
   4844             unsigned size, int op) {
   4845   void *ctx;
   4846   COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
   4847   // FIXME: under ASan the call below may write to freed memory and corrupt
   4848   // its metadata. See
   4849   // https://github.com/google/sanitizers/issues/321.
   4850   REAL(xdrmem_create)(xdrs, addr, size, op);
   4851   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
   4852   if (op == __sanitizer_XDR_ENCODE) {
   4853     // It's not obvious how much data individual xdr_ routines write.
   4854     // Simply unpoison the entire target buffer in advance.
   4855     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
   4856   }
   4857 }
   4858 
   4859 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
   4860   void *ctx;
   4861   COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
   4862   // FIXME: under ASan the call below may write to freed memory and corrupt
   4863   // its metadata. See
   4864   // https://github.com/google/sanitizers/issues/321.
   4865   REAL(xdrstdio_create)(xdrs, file, op);
   4866   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
   4867 }
   4868 
   4869 // FIXME: under ASan the call below may write to freed memory and corrupt
   4870 // its metadata. See
   4871 // https://github.com/google/sanitizers/issues/321.
   4872 #define XDR_INTERCEPTOR(F, T)                             \
   4873   INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
   4874     void *ctx;                                            \
   4875     COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
   4876     if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
   4877       COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
   4878     int res = REAL(F)(xdrs, p);                           \
   4879     if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
   4880       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
   4881     return res;                                           \
   4882   }
   4883 
   4884 XDR_INTERCEPTOR(xdr_short, short)
   4885 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
   4886 XDR_INTERCEPTOR(xdr_int, int)
   4887 XDR_INTERCEPTOR(xdr_u_int, unsigned)
   4888 XDR_INTERCEPTOR(xdr_long, long)
   4889 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
   4890 XDR_INTERCEPTOR(xdr_hyper, long long)
   4891 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
   4892 XDR_INTERCEPTOR(xdr_longlong_t, long long)
   4893 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
   4894 XDR_INTERCEPTOR(xdr_int8_t, u8)
   4895 XDR_INTERCEPTOR(xdr_uint8_t, u8)
   4896 XDR_INTERCEPTOR(xdr_int16_t, u16)
   4897 XDR_INTERCEPTOR(xdr_uint16_t, u16)
   4898 XDR_INTERCEPTOR(xdr_int32_t, u32)
   4899 XDR_INTERCEPTOR(xdr_uint32_t, u32)
   4900 XDR_INTERCEPTOR(xdr_int64_t, u64)
   4901 XDR_INTERCEPTOR(xdr_uint64_t, u64)
   4902 XDR_INTERCEPTOR(xdr_quad_t, long long)
   4903 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
   4904 XDR_INTERCEPTOR(xdr_bool, bool)
   4905 XDR_INTERCEPTOR(xdr_enum, int)
   4906 XDR_INTERCEPTOR(xdr_char, char)
   4907 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
   4908 XDR_INTERCEPTOR(xdr_float, float)
   4909 XDR_INTERCEPTOR(xdr_double, double)
   4910 
   4911 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
   4912 // wrapstring, sizeof
   4913 
   4914 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
   4915             unsigned maxsize) {
   4916   void *ctx;
   4917   COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
   4918   if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
   4919     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
   4920     COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
   4921     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
   4922   }
   4923   // FIXME: under ASan the call below may write to freed memory and corrupt
   4924   // its metadata. See
   4925   // https://github.com/google/sanitizers/issues/321.
   4926   int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
   4927   if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
   4928     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   4929     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
   4930     if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
   4931   }
   4932   return res;
   4933 }
   4934 
   4935 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
   4936             unsigned maxsize) {
   4937   void *ctx;
   4938   COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
   4939   if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
   4940     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
   4941     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   4942   }
   4943   // FIXME: under ASan the call below may write to freed memory and corrupt
   4944   // its metadata. See
   4945   // https://github.com/google/sanitizers/issues/321.
   4946   int res = REAL(xdr_string)(xdrs, p, maxsize);
   4947   if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
   4948     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
   4949     if (res && *p)
   4950       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
   4951   }
   4952   return res;
   4953 }
   4954 
   4955 #define INIT_XDR                               \
   4956   COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
   4957   COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
   4958   COMMON_INTERCEPT_FUNCTION(xdr_short);        \
   4959   COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
   4960   COMMON_INTERCEPT_FUNCTION(xdr_int);          \
   4961   COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
   4962   COMMON_INTERCEPT_FUNCTION(xdr_long);         \
   4963   COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
   4964   COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
   4965   COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
   4966   COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
   4967   COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
   4968   COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
   4969   COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
   4970   COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
   4971   COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
   4972   COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
   4973   COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
   4974   COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
   4975   COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
   4976   COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
   4977   COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
   4978   COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
   4979   COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
   4980   COMMON_INTERCEPT_FUNCTION(xdr_char);         \
   4981   COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
   4982   COMMON_INTERCEPT_FUNCTION(xdr_float);        \
   4983   COMMON_INTERCEPT_FUNCTION(xdr_double);       \
   4984   COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
   4985   COMMON_INTERCEPT_FUNCTION(xdr_string);
   4986 #else
   4987 #define INIT_XDR
   4988 #endif  // SANITIZER_INTERCEPT_XDR
   4989 
   4990 #if SANITIZER_INTERCEPT_TSEARCH
   4991 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
   4992             int (*compar)(const void *, const void *)) {
   4993   void *ctx;
   4994   COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
   4995   // FIXME: under ASan the call below may write to freed memory and corrupt
   4996   // its metadata. See
   4997   // https://github.com/google/sanitizers/issues/321.
   4998   void *res = REAL(tsearch)(key, rootp, compar);
   4999   if (res && *(void **)res == key)
   5000     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
   5001   return res;
   5002 }
   5003 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
   5004 #else
   5005 #define INIT_TSEARCH
   5006 #endif
   5007 
   5008 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
   5009     SANITIZER_INTERCEPT_OPEN_MEMSTREAM
   5010 void unpoison_file(__sanitizer_FILE *fp) {
   5011 #if SANITIZER_HAS_STRUCT_FILE
   5012   COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
   5013   if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
   5014     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
   5015                                         fp->_IO_read_end - fp->_IO_read_base);
   5016 #endif  // SANITIZER_HAS_STRUCT_FILE
   5017 }
   5018 #endif
   5019 
   5020 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
   5021 // These guys are called when a .c source is built with -O2.
   5022 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
   5023   void *ctx;
   5024   COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
   5025   int res = REAL(__uflow)(fp);
   5026   unpoison_file(fp);
   5027   return res;
   5028 }
   5029 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
   5030   void *ctx;
   5031   COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
   5032   int res = REAL(__underflow)(fp);
   5033   unpoison_file(fp);
   5034   return res;
   5035 }
   5036 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
   5037   void *ctx;
   5038   COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
   5039   int res = REAL(__overflow)(fp, ch);
   5040   unpoison_file(fp);
   5041   return res;
   5042 }
   5043 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
   5044   void *ctx;
   5045   COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
   5046   int res = REAL(__wuflow)(fp);
   5047   unpoison_file(fp);
   5048   return res;
   5049 }
   5050 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
   5051   void *ctx;
   5052   COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
   5053   int res = REAL(__wunderflow)(fp);
   5054   unpoison_file(fp);
   5055   return res;
   5056 }
   5057 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
   5058   void *ctx;
   5059   COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
   5060   int res = REAL(__woverflow)(fp, ch);
   5061   unpoison_file(fp);
   5062   return res;
   5063 }
   5064 #define INIT_LIBIO_INTERNALS               \
   5065   COMMON_INTERCEPT_FUNCTION(__uflow);      \
   5066   COMMON_INTERCEPT_FUNCTION(__underflow);  \
   5067   COMMON_INTERCEPT_FUNCTION(__overflow);   \
   5068   COMMON_INTERCEPT_FUNCTION(__wuflow);     \
   5069   COMMON_INTERCEPT_FUNCTION(__wunderflow); \
   5070   COMMON_INTERCEPT_FUNCTION(__woverflow);
   5071 #else
   5072 #define INIT_LIBIO_INTERNALS
   5073 #endif
   5074 
   5075 #if SANITIZER_INTERCEPT_FOPEN
   5076 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
   5077   void *ctx;
   5078   COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
   5079   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5080   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5081   __sanitizer_FILE *res = REAL(fopen)(path, mode);
   5082   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5083   if (res) unpoison_file(res);
   5084   return res;
   5085 }
   5086 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
   5087   void *ctx;
   5088   COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
   5089   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5090   __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
   5091   if (res) unpoison_file(res);
   5092   return res;
   5093 }
   5094 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
   5095             __sanitizer_FILE *fp) {
   5096   void *ctx;
   5097   COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
   5098   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5099   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5100   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5101   __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
   5102   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5103   if (res) unpoison_file(res);
   5104   return res;
   5105 }
   5106 #define INIT_FOPEN                   \
   5107   COMMON_INTERCEPT_FUNCTION(fopen);  \
   5108   COMMON_INTERCEPT_FUNCTION(fdopen); \
   5109   COMMON_INTERCEPT_FUNCTION(freopen);
   5110 #else
   5111 #define INIT_FOPEN
   5112 #endif
   5113 
   5114 #if SANITIZER_INTERCEPT_FOPEN64
   5115 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
   5116   void *ctx;
   5117   COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
   5118   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5119   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5120   __sanitizer_FILE *res = REAL(fopen64)(path, mode);
   5121   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5122   if (res) unpoison_file(res);
   5123   return res;
   5124 }
   5125 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
   5126             __sanitizer_FILE *fp) {
   5127   void *ctx;
   5128   COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
   5129   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
   5130   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
   5131   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5132   __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
   5133   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
   5134   if (res) unpoison_file(res);
   5135   return res;
   5136 }
   5137 #define INIT_FOPEN64                  \
   5138   COMMON_INTERCEPT_FUNCTION(fopen64); \
   5139   COMMON_INTERCEPT_FUNCTION(freopen64);
   5140 #else
   5141 #define INIT_FOPEN64
   5142 #endif
   5143 
   5144 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
   5145 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
   5146   void *ctx;
   5147   COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
   5148   // FIXME: under ASan the call below may write to freed memory and corrupt
   5149   // its metadata. See
   5150   // https://github.com/google/sanitizers/issues/321.
   5151   __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
   5152   if (res) {
   5153     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
   5154     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
   5155     unpoison_file(res);
   5156     FileMetadata file = {ptr, sizeloc};
   5157     SetInterceptorMetadata(res, file);
   5158   }
   5159   return res;
   5160 }
   5161 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
   5162             SIZE_T *sizeloc) {
   5163   void *ctx;
   5164   COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
   5165   __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
   5166   if (res) {
   5167     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
   5168     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
   5169     unpoison_file(res);
   5170     FileMetadata file = {(char **)ptr, sizeloc};
   5171     SetInterceptorMetadata(res, file);
   5172   }
   5173   return res;
   5174 }
   5175 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
   5176             const char *mode) {
   5177   void *ctx;
   5178   COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
   5179   // FIXME: under ASan the call below may write to freed memory and corrupt
   5180   // its metadata. See
   5181   // https://github.com/google/sanitizers/issues/321.
   5182   __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
   5183   if (res) unpoison_file(res);
   5184   return res;
   5185 }
   5186 #define INIT_OPEN_MEMSTREAM                   \
   5187   COMMON_INTERCEPT_FUNCTION(open_memstream);  \
   5188   COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
   5189   COMMON_INTERCEPT_FUNCTION(fmemopen);
   5190 #else
   5191 #define INIT_OPEN_MEMSTREAM
   5192 #endif
   5193 
   5194 #if SANITIZER_INTERCEPT_OBSTACK
   5195 static void initialize_obstack(__sanitizer_obstack *obstack) {
   5196   COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
   5197   if (obstack->chunk)
   5198     COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
   5199                                         sizeof(*obstack->chunk));
   5200 }
   5201 
   5202 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
   5203             int align, void *(*alloc_fn)(uptr arg, uptr sz),
   5204             void (*free_fn)(uptr arg, void *p)) {
   5205   void *ctx;
   5206   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
   5207                            free_fn);
   5208   int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
   5209   if (res) initialize_obstack(obstack);
   5210   return res;
   5211 }
   5212 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
   5213             int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
   5214   void *ctx;
   5215   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
   5216                            free_fn);
   5217   int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
   5218   if (res) initialize_obstack(obstack);
   5219   return res;
   5220 }
   5221 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
   5222   void *ctx;
   5223   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
   5224   REAL(_obstack_newchunk)(obstack, length);
   5225   if (obstack->chunk)
   5226     COMMON_INTERCEPTOR_INITIALIZE_RANGE(
   5227         obstack->chunk, obstack->next_free - (char *)obstack->chunk);
   5228 }
   5229 #define INIT_OBSTACK                           \
   5230   COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
   5231   COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
   5232   COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
   5233 #else
   5234 #define INIT_OBSTACK
   5235 #endif
   5236 
   5237 #if SANITIZER_INTERCEPT_FFLUSH
   5238 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
   5239   void *ctx;
   5240   COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
   5241   int res = REAL(fflush)(fp);
   5242   // FIXME: handle fp == NULL
   5243   if (fp) {
   5244     const FileMetadata *m = GetInterceptorMetadata(fp);
   5245     if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
   5246   }
   5247   return res;
   5248 }
   5249 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
   5250 #else
   5251 #define INIT_FFLUSH
   5252 #endif
   5253 
   5254 #if SANITIZER_INTERCEPT_FCLOSE
   5255 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
   5256   void *ctx;
   5257   COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
   5258   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
   5259   const FileMetadata *m = GetInterceptorMetadata(fp);
   5260   int res = REAL(fclose)(fp);
   5261   if (m) {
   5262     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
   5263     DeleteInterceptorMetadata(fp);
   5264   }
   5265   return res;
   5266 }
   5267 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
   5268 #else
   5269 #define INIT_FCLOSE
   5270 #endif
   5271 
   5272 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
   5273 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
   5274   void *ctx;
   5275   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
   5276   if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
   5277   COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
   5278   void *res = REAL(dlopen)(filename, flag);
   5279   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
   5280   return res;
   5281 }
   5282 
   5283 INTERCEPTOR(int, dlclose, void *handle) {
   5284   void *ctx;
   5285   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
   5286   int res = REAL(dlclose)(handle);
   5287   COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
   5288   return res;
   5289 }
   5290 #define INIT_DLOPEN_DLCLOSE          \
   5291   COMMON_INTERCEPT_FUNCTION(dlopen); \
   5292   COMMON_INTERCEPT_FUNCTION(dlclose);
   5293 #else
   5294 #define INIT_DLOPEN_DLCLOSE
   5295 #endif
   5296 
   5297 #if SANITIZER_INTERCEPT_GETPASS
   5298 INTERCEPTOR(char *, getpass, const char *prompt) {
   5299   void *ctx;
   5300   COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
   5301   if (prompt)
   5302     COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
   5303   char *res = REAL(getpass)(prompt);
   5304   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
   5305   return res;
   5306 }
   5307 
   5308 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
   5309 #else
   5310 #define INIT_GETPASS
   5311 #endif
   5312 
   5313 #if SANITIZER_INTERCEPT_TIMERFD
   5314 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
   5315             void *old_value) {
   5316   void *ctx;
   5317   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
   5318                            old_value);
   5319   COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
   5320   int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
   5321   if (res != -1 && old_value)
   5322     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
   5323   return res;
   5324 }
   5325 
   5326 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
   5327   void *ctx;
   5328   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
   5329   int res = REAL(timerfd_gettime)(fd, curr_value);
   5330   if (res != -1 && curr_value)
   5331     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
   5332   return res;
   5333 }
   5334 #define INIT_TIMERFD                          \
   5335   COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
   5336   COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
   5337 #else
   5338 #define INIT_TIMERFD
   5339 #endif
   5340 
   5341 #if SANITIZER_INTERCEPT_MLOCKX
   5342 // Linux kernel has a bug that leads to kernel deadlock if a process
   5343 // maps TBs of memory and then calls mlock().
   5344 static void MlockIsUnsupported() {
   5345   static atomic_uint8_t printed;
   5346   if (atomic_exchange(&printed, 1, memory_order_relaxed))
   5347     return;
   5348   VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
   5349           SanitizerToolName);
   5350 }
   5351 
   5352 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
   5353   MlockIsUnsupported();
   5354   return 0;
   5355 }
   5356 
   5357 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
   5358   MlockIsUnsupported();
   5359   return 0;
   5360 }
   5361 
   5362 INTERCEPTOR(int, mlockall, int flags) {
   5363   MlockIsUnsupported();
   5364   return 0;
   5365 }
   5366 
   5367 INTERCEPTOR(int, munlockall, void) {
   5368   MlockIsUnsupported();
   5369   return 0;
   5370 }
   5371 
   5372 #define INIT_MLOCKX                                                            \
   5373   COMMON_INTERCEPT_FUNCTION(mlock);                                            \
   5374   COMMON_INTERCEPT_FUNCTION(munlock);                                          \
   5375   COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
   5376   COMMON_INTERCEPT_FUNCTION(munlockall);
   5377 
   5378 #else
   5379 #define INIT_MLOCKX
   5380 #endif  // SANITIZER_INTERCEPT_MLOCKX
   5381 
   5382 #if SANITIZER_INTERCEPT_FOPENCOOKIE
   5383 struct WrappedCookie {
   5384   void *real_cookie;
   5385   __sanitizer_cookie_io_functions_t real_io_funcs;
   5386 };
   5387 
   5388 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
   5389   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   5390   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   5391   __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
   5392   return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
   5393 }
   5394 
   5395 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
   5396   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   5397   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   5398   __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
   5399   return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
   5400 }
   5401 
   5402 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
   5403   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
   5404   COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
   5405   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   5406   __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
   5407   return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
   5408                    : -1;
   5409 }
   5410 
   5411 static int wrapped_close(void *cookie) {
   5412   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
   5413   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
   5414   __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
   5415   int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
   5416   InternalFree(wrapped_cookie);
   5417   return res;
   5418 }
   5419 
   5420 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
   5421             __sanitizer_cookie_io_functions_t io_funcs) {
   5422   void *ctx;
   5423   COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
   5424   WrappedCookie *wrapped_cookie =
   5425       (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
   5426   wrapped_cookie->real_cookie = cookie;
   5427   wrapped_cookie->real_io_funcs = io_funcs;
   5428   __sanitizer_FILE *res =
   5429       REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
   5430                                                wrapped_seek, wrapped_close});
   5431   return res;
   5432 }
   5433 
   5434 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
   5435 #else
   5436 #define INIT_FOPENCOOKIE
   5437 #endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
   5438 
   5439 #if SANITIZER_INTERCEPT_SEM
   5440 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
   5441   void *ctx;
   5442   COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
   5443   // Workaround a bug in glibc's "old" semaphore implementation by
   5444   // zero-initializing the sem_t contents. This has to be done here because
   5445   // interceptors bind to the lowest symbols version by default, hitting the
   5446   // buggy code path while the non-sanitized build of the same code works fine.
   5447   REAL(memset)(s, 0, sizeof(*s));
   5448   int res = REAL(sem_init)(s, pshared, value);
   5449   return res;
   5450 }
   5451 
   5452 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
   5453   void *ctx;
   5454   COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
   5455   int res = REAL(sem_destroy)(s);
   5456   return res;
   5457 }
   5458 
   5459 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
   5460   void *ctx;
   5461   COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
   5462   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
   5463   if (res == 0) {
   5464     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   5465   }
   5466   return res;
   5467 }
   5468 
   5469 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
   5470   void *ctx;
   5471   COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
   5472   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
   5473   if (res == 0) {
   5474     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   5475   }
   5476   return res;
   5477 }
   5478 
   5479 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
   5480   void *ctx;
   5481   COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
   5482   COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
   5483   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
   5484   if (res == 0) {
   5485     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   5486   }
   5487   return res;
   5488 }
   5489 
   5490 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
   5491   void *ctx;
   5492   COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
   5493   COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
   5494   int res = REAL(sem_post)(s);
   5495   return res;
   5496 }
   5497 
   5498 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
   5499   void *ctx;
   5500   COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
   5501   int res = REAL(sem_getvalue)(s, sval);
   5502   if (res == 0) {
   5503     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
   5504     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
   5505   }
   5506   return res;
   5507 }
   5508 #define INIT_SEM                                                               \
   5509   COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
   5510   COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
   5511   COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
   5512   COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
   5513   COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
   5514   COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
   5515   COMMON_INTERCEPT_FUNCTION(sem_getvalue);
   5516 #else
   5517 #define INIT_SEM
   5518 #endif // SANITIZER_INTERCEPT_SEM
   5519 
   5520 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
   5521 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
   5522   void *ctx;
   5523   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
   5524   int res = REAL(pthread_setcancelstate)(state, oldstate);
   5525   if (res == 0)
   5526     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
   5527   return res;
   5528 }
   5529 
   5530 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
   5531   void *ctx;
   5532   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
   5533   int res = REAL(pthread_setcanceltype)(type, oldtype);
   5534   if (res == 0)
   5535     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
   5536   return res;
   5537 }
   5538 #define INIT_PTHREAD_SETCANCEL                                                 \
   5539   COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
   5540   COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
   5541 #else
   5542 #define INIT_PTHREAD_SETCANCEL
   5543 #endif
   5544 
   5545 #if SANITIZER_INTERCEPT_MINCORE
   5546 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
   5547   void *ctx;
   5548   COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
   5549   int res = REAL(mincore)(addr, length, vec);
   5550   if (res == 0) {
   5551     uptr page_size = GetPageSizeCached();
   5552     uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
   5553     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
   5554   }
   5555   return res;
   5556 }
   5557 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
   5558 #else
   5559 #define INIT_MINCORE
   5560 #endif
   5561 
   5562 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
   5563 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
   5564             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
   5565             uptr flags) {
   5566   void *ctx;
   5567   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
   5568                            remote_iov, riovcnt, flags);
   5569   SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
   5570                                        riovcnt, flags);
   5571   if (res > 0)
   5572     write_iovec(ctx, local_iov, liovcnt, res);
   5573   return res;
   5574 }
   5575 
   5576 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
   5577             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
   5578             uptr flags) {
   5579   void *ctx;
   5580   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
   5581                            remote_iov, riovcnt, flags);
   5582   SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
   5583                                         riovcnt, flags);
   5584   if (res > 0)
   5585     read_iovec(ctx, local_iov, liovcnt, res);
   5586   return res;
   5587 }
   5588 #define INIT_PROCESS_VM_READV                                                  \
   5589   COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
   5590   COMMON_INTERCEPT_FUNCTION(process_vm_writev);
   5591 #else
   5592 #define INIT_PROCESS_VM_READV
   5593 #endif
   5594 
   5595 #if SANITIZER_INTERCEPT_CTERMID
   5596 INTERCEPTOR(char *, ctermid, char *s) {
   5597   void *ctx;
   5598   COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
   5599   char *res = REAL(ctermid)(s);
   5600   if (res) {
   5601     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   5602   }
   5603   return res;
   5604 }
   5605 #define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
   5606 #else
   5607 #define INIT_CTERMID
   5608 #endif
   5609 
   5610 #if SANITIZER_INTERCEPT_CTERMID_R
   5611 INTERCEPTOR(char *, ctermid_r, char *s) {
   5612   void *ctx;
   5613   COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
   5614   char *res = REAL(ctermid_r)(s);
   5615   if (res) {
   5616     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
   5617   }
   5618   return res;
   5619 }
   5620 #define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
   5621 #else
   5622 #define INIT_CTERMID_R
   5623 #endif
   5624 
   5625 #if SANITIZER_INTERCEPT_RECV_RECVFROM
   5626 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
   5627   void *ctx;
   5628   COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
   5629   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5630   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
   5631   if (res > 0) {
   5632     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
   5633   }
   5634   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   5635   return res;
   5636 }
   5637 
   5638 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
   5639             void *srcaddr, int *addrlen) {
   5640   void *ctx;
   5641   COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
   5642                            addrlen);
   5643   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5644   SIZE_T srcaddr_sz;
   5645   if (srcaddr) srcaddr_sz = *addrlen;
   5646   (void)srcaddr_sz;  // prevent "set but not used" warning
   5647   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
   5648   if (res > 0) {
   5649     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
   5650     if (srcaddr)
   5651       COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
   5652                                           Min((SIZE_T)*addrlen, srcaddr_sz));
   5653   }
   5654   return res;
   5655 }
   5656 #define INIT_RECV_RECVFROM          \
   5657   COMMON_INTERCEPT_FUNCTION(recv);  \
   5658   COMMON_INTERCEPT_FUNCTION(recvfrom);
   5659 #else
   5660 #define INIT_RECV_RECVFROM
   5661 #endif
   5662 
   5663 #if SANITIZER_INTERCEPT_SEND_SENDTO
   5664 INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
   5665   void *ctx;
   5666   COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
   5667   if (fd >= 0) {
   5668     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5669     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   5670   }
   5671   SSIZE_T res = REAL(send)(fd, buf, len, flags);
   5672   if (common_flags()->intercept_send && res > 0)
   5673     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
   5674   return res;
   5675 }
   5676 
   5677 INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
   5678             void *dstaddr, int addrlen) {
   5679   void *ctx;
   5680   COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
   5681   if (fd >= 0) {
   5682     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5683     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   5684   }
   5685   // Can't check dstaddr as it may have uninitialized padding at the end.
   5686   SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
   5687   if (common_flags()->intercept_send && res > 0)
   5688     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
   5689   return res;
   5690 }
   5691 #define INIT_SEND_SENDTO           \
   5692   COMMON_INTERCEPT_FUNCTION(send); \
   5693   COMMON_INTERCEPT_FUNCTION(sendto);
   5694 #else
   5695 #define INIT_SEND_SENDTO
   5696 #endif
   5697 
   5698 #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
   5699 INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
   5700   void *ctx;
   5701   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
   5702   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5703   int res = REAL(eventfd_read)(fd, value);
   5704   if (res == 0) {
   5705     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
   5706     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
   5707   }
   5708   return res;
   5709 }
   5710 INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
   5711   void *ctx;
   5712   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
   5713   if (fd >= 0) {
   5714     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
   5715     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
   5716   }
   5717   int res = REAL(eventfd_write)(fd, value);
   5718   return res;
   5719 }
   5720 #define INIT_EVENTFD_READ_WRITE            \
   5721   COMMON_INTERCEPT_FUNCTION(eventfd_read); \
   5722   COMMON_INTERCEPT_FUNCTION(eventfd_write)
   5723 #else
   5724 #define INIT_EVENTFD_READ_WRITE
   5725 #endif
   5726 
   5727 #if SANITIZER_INTERCEPT_STAT
   5728 INTERCEPTOR(int, stat, const char *path, void *buf) {
   5729   void *ctx;
   5730   COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
   5731   if (common_flags()->intercept_stat)
   5732     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   5733   int res = REAL(stat)(path, buf);
   5734   if (!res)
   5735     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   5736   return res;
   5737 }
   5738 #define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
   5739 #else
   5740 #define INIT_STAT
   5741 #endif
   5742 
   5743 #if SANITIZER_INTERCEPT___XSTAT
   5744 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
   5745   void *ctx;
   5746   COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
   5747   if (common_flags()->intercept_stat)
   5748     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   5749   int res = REAL(__xstat)(version, path, buf);
   5750   if (!res)
   5751     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   5752   return res;
   5753 }
   5754 #define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
   5755 #else
   5756 #define INIT___XSTAT
   5757 #endif
   5758 
   5759 #if SANITIZER_INTERCEPT___XSTAT64
   5760 INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
   5761   void *ctx;
   5762   COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
   5763   if (common_flags()->intercept_stat)
   5764     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   5765   int res = REAL(__xstat64)(version, path, buf);
   5766   if (!res)
   5767     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
   5768   return res;
   5769 }
   5770 #define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
   5771 #else
   5772 #define INIT___XSTAT64
   5773 #endif
   5774 
   5775 #if SANITIZER_INTERCEPT___LXSTAT
   5776 INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
   5777   void *ctx;
   5778   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
   5779   if (common_flags()->intercept_stat)
   5780     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   5781   int res = REAL(__lxstat)(version, path, buf);
   5782   if (!res)
   5783     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
   5784   return res;
   5785 }
   5786 #define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
   5787 #else
   5788 #define INIT___LXSTAT
   5789 #endif
   5790 
   5791 #if SANITIZER_INTERCEPT___LXSTAT64
   5792 INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
   5793   void *ctx;
   5794   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
   5795   if (common_flags()->intercept_stat)
   5796     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
   5797   int res = REAL(__lxstat64)(version, path, buf);
   5798   if (!res)
   5799     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
   5800   return res;
   5801 }
   5802 #define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
   5803 #else
   5804 #define INIT___LXSTAT64
   5805 #endif
   5806 
   5807 // FIXME: add other *stat interceptor
   5808 
   5809 static void InitializeCommonInterceptors() {
   5810   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
   5811   interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
   5812 
   5813   INIT_TEXTDOMAIN;
   5814   INIT_STRLEN;
   5815   INIT_STRNLEN;
   5816   INIT_STRCMP;
   5817   INIT_STRNCMP;
   5818   INIT_STRCASECMP;
   5819   INIT_STRNCASECMP;
   5820   INIT_STRSTR;
   5821   INIT_STRCASESTR;
   5822   INIT_STRCHR;
   5823   INIT_STRCHRNUL;
   5824   INIT_STRRCHR;
   5825   INIT_STRSPN;
   5826   INIT_STRPBRK;
   5827   INIT_MEMSET;
   5828   INIT_MEMMOVE;
   5829   INIT_MEMCPY;
   5830   INIT_MEMCHR;
   5831   INIT_MEMCMP;
   5832   INIT_MEMRCHR;
   5833   INIT_READ;
   5834   INIT_PREAD;
   5835   INIT_PREAD64;
   5836   INIT_READV;
   5837   INIT_PREADV;
   5838   INIT_PREADV64;
   5839   INIT_WRITE;
   5840   INIT_PWRITE;
   5841   INIT_PWRITE64;
   5842   INIT_WRITEV;
   5843   INIT_PWRITEV;
   5844   INIT_PWRITEV64;
   5845   INIT_PRCTL;
   5846   INIT_LOCALTIME_AND_FRIENDS;
   5847   INIT_STRPTIME;
   5848   INIT_SCANF;
   5849   INIT_ISOC99_SCANF;
   5850   INIT_PRINTF;
   5851   INIT_PRINTF_L;
   5852   INIT_ISOC99_PRINTF;
   5853   INIT_FREXP;
   5854   INIT_FREXPF_FREXPL;
   5855   INIT_GETPWNAM_AND_FRIENDS;
   5856   INIT_GETPWNAM_R_AND_FRIENDS;
   5857   INIT_GETPWENT;
   5858   INIT_FGETPWENT;
   5859   INIT_GETPWENT_R;
   5860   INIT_SETPWENT;
   5861   INIT_CLOCK_GETTIME;
   5862   INIT_GETITIMER;
   5863   INIT_TIME;
   5864   INIT_GLOB;
   5865   INIT_WAIT;
   5866   INIT_WAIT4;
   5867   INIT_INET;
   5868   INIT_PTHREAD_GETSCHEDPARAM;
   5869   INIT_GETADDRINFO;
   5870   INIT_GETNAMEINFO;
   5871   INIT_GETSOCKNAME;
   5872   INIT_GETHOSTBYNAME;
   5873   INIT_GETHOSTBYNAME_R;
   5874   INIT_GETHOSTBYNAME2_R;
   5875   INIT_GETHOSTBYADDR_R;
   5876   INIT_GETHOSTENT_R;
   5877   INIT_GETSOCKOPT;
   5878   INIT_ACCEPT;
   5879   INIT_ACCEPT4;
   5880   INIT_MODF;
   5881   INIT_RECVMSG;
   5882   INIT_SENDMSG;
   5883   INIT_GETPEERNAME;
   5884   INIT_IOCTL;
   5885   INIT_INET_ATON;
   5886   INIT_SYSINFO;
   5887   INIT_READDIR;
   5888   INIT_READDIR64;
   5889   INIT_PTRACE;
   5890   INIT_SETLOCALE;
   5891   INIT_GETCWD;
   5892   INIT_GET_CURRENT_DIR_NAME;
   5893   INIT_STRTOIMAX;
   5894   INIT_MBSTOWCS;
   5895   INIT_MBSNRTOWCS;
   5896   INIT_WCSTOMBS;
   5897   INIT_WCSNRTOMBS;
   5898   INIT_WCRTOMB;
   5899   INIT_TCGETATTR;
   5900   INIT_REALPATH;
   5901   INIT_CANONICALIZE_FILE_NAME;
   5902   INIT_CONFSTR;
   5903   INIT_SCHED_GETAFFINITY;
   5904   INIT_SCHED_GETPARAM;
   5905   INIT_STRERROR;
   5906   INIT_STRERROR_R;
   5907   INIT_XPG_STRERROR_R;
   5908   INIT_SCANDIR;
   5909   INIT_SCANDIR64;
   5910   INIT_GETGROUPS;
   5911   INIT_POLL;
   5912   INIT_PPOLL;
   5913   INIT_WORDEXP;
   5914   INIT_SIGWAIT;
   5915   INIT_SIGWAITINFO;
   5916   INIT_SIGTIMEDWAIT;
   5917   INIT_SIGSETOPS;
   5918   INIT_SIGPENDING;
   5919   INIT_SIGPROCMASK;
   5920   INIT_BACKTRACE;
   5921   INIT__EXIT;
   5922   INIT_PTHREAD_MUTEX_LOCK;
   5923   INIT_PTHREAD_MUTEX_UNLOCK;
   5924   INIT_GETMNTENT;
   5925   INIT_GETMNTENT_R;
   5926   INIT_STATFS;
   5927   INIT_STATFS64;
   5928   INIT_STATVFS;
   5929   INIT_STATVFS64;
   5930   INIT_INITGROUPS;
   5931   INIT_ETHER_NTOA_ATON;
   5932   INIT_ETHER_HOST;
   5933   INIT_ETHER_R;
   5934   INIT_SHMCTL;
   5935   INIT_RANDOM_R;
   5936   INIT_PTHREAD_ATTR_GET;
   5937   INIT_PTHREAD_ATTR_GETINHERITSCHED;
   5938   INIT_PTHREAD_ATTR_GETAFFINITY_NP;
   5939   INIT_PTHREAD_MUTEXATTR_GETPSHARED;
   5940   INIT_PTHREAD_MUTEXATTR_GETTYPE;
   5941   INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
   5942   INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
   5943   INIT_PTHREAD_MUTEXATTR_GETROBUST;
   5944   INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
   5945   INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
   5946   INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
   5947   INIT_PTHREAD_CONDATTR_GETPSHARED;
   5948   INIT_PTHREAD_CONDATTR_GETCLOCK;
   5949   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
   5950   INIT_TMPNAM;
   5951   INIT_TMPNAM_R;
   5952   INIT_TEMPNAM;
   5953   INIT_PTHREAD_SETNAME_NP;
   5954   INIT_SINCOS;
   5955   INIT_REMQUO;
   5956   INIT_LGAMMA;
   5957   INIT_LGAMMA_R;
   5958   INIT_LGAMMAL_R;
   5959   INIT_DRAND48_R;
   5960   INIT_RAND_R;
   5961   INIT_GETLINE;
   5962   INIT_ICONV;
   5963   INIT_TIMES;
   5964   INIT_TLS_GET_ADDR;
   5965   INIT_LISTXATTR;
   5966   INIT_GETXATTR;
   5967   INIT_GETRESID;
   5968   INIT_GETIFADDRS;
   5969   INIT_IF_INDEXTONAME;
   5970   INIT_CAPGET;
   5971   INIT_AEABI_MEM;
   5972   INIT___BZERO;
   5973   INIT_FTIME;
   5974   INIT_XDR;
   5975   INIT_TSEARCH;
   5976   INIT_LIBIO_INTERNALS;
   5977   INIT_FOPEN;
   5978   INIT_FOPEN64;
   5979   INIT_OPEN_MEMSTREAM;
   5980   INIT_OBSTACK;
   5981   INIT_FFLUSH;
   5982   INIT_FCLOSE;
   5983   INIT_DLOPEN_DLCLOSE;
   5984   INIT_GETPASS;
   5985   INIT_TIMERFD;
   5986   INIT_MLOCKX;
   5987   INIT_FOPENCOOKIE;
   5988   INIT_SEM;
   5989   INIT_PTHREAD_SETCANCEL;
   5990   INIT_MINCORE;
   5991   INIT_PROCESS_VM_READV;
   5992   INIT_CTERMID;
   5993   INIT_CTERMID_R;
   5994   INIT_RECV_RECVFROM;
   5995   INIT_SEND_SENDTO;
   5996   INIT_STAT;
   5997   INIT_EVENTFD_READ_WRITE;
   5998   INIT___XSTAT;
   5999   INIT___XSTAT64;
   6000   INIT___LXSTAT;
   6001   INIT___LXSTAT64;
   6002   // FIXME: add other *stat interceptors.
   6003 }
   6004