master
    1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
    2//
    3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
    4// See https://llvm.org/LICENSE.txt for license information.
    5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
    6//
    7//===----------------------------------------------------------------------===//
    8//
    9// Common function interceptors for tools like AddressSanitizer,
   10// ThreadSanitizer, MemorySanitizer, etc.
   11//
   12// This file should be included into the tool's interceptor file,
   13// which has to define its own macros:
   14//   COMMON_INTERCEPTOR_ENTER
   15//   COMMON_INTERCEPTOR_ENTER_NOIGNORE
   16//   COMMON_INTERCEPTOR_READ_RANGE
   17//   COMMON_INTERCEPTOR_WRITE_RANGE
   18//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
   19//   COMMON_INTERCEPTOR_DIR_ACQUIRE
   20//   COMMON_INTERCEPTOR_FD_ACQUIRE
   21//   COMMON_INTERCEPTOR_FD_RELEASE
   22//   COMMON_INTERCEPTOR_FD_ACCESS
   23//   COMMON_INTERCEPTOR_SET_THREAD_NAME
   24//   COMMON_INTERCEPTOR_DLOPEN
   25//   COMMON_INTERCEPTOR_ON_EXIT
   26//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
   27//   COMMON_INTERCEPTOR_HANDLE_RECVMSG
   28//   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
   29//   COMMON_INTERCEPTOR_MMAP_IMPL
   30//   COMMON_INTERCEPTOR_MUNMAP_IMPL
   31//   COMMON_INTERCEPTOR_COPY_STRING
   32//   COMMON_INTERCEPTOR_STRNDUP_IMPL
   33//   COMMON_INTERCEPTOR_STRERROR
   34//===----------------------------------------------------------------------===//
   35
   36#include <stdarg.h>
   37
   38#include "interception/interception.h"
   39#include "sanitizer_addrhashmap.h"
   40#include "sanitizer_dl.h"
   41#include "sanitizer_errno.h"
   42#include "sanitizer_placement_new.h"
   43#include "sanitizer_platform_interceptors.h"
   44#include "sanitizer_platform_limits_posix.h"
   45#include "sanitizer_symbolizer.h"
   46#include "sanitizer_tls_get_addr.h"
   47
   48#if SANITIZER_INTERCEPTOR_HOOKS
   49#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);
   50#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
   51  SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}
   52#else
   53#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
   54#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
   55
   56#endif  // SANITIZER_INTERCEPTOR_HOOKS
   57
   58#if SANITIZER_WINDOWS && !defined(va_copy)
   59#define va_copy(dst, src) ((dst) = (src))
   60#endif // _WIN32
   61
   62#if SANITIZER_FREEBSD
   63#define pthread_setname_np pthread_set_name_np
   64#define inet_aton __inet_aton
   65#define inet_pton __inet_pton
   66#define iconv __bsd_iconv
   67#endif
   68
   69#if SANITIZER_NETBSD
   70#define clock_getres __clock_getres50
   71#define clock_gettime __clock_gettime50
   72#define clock_settime __clock_settime50
   73#define ctime __ctime50
   74#define ctime_r __ctime_r50
   75#define devname __devname50
   76#define fgetpos __fgetpos50
   77#define fsetpos __fsetpos50
   78#define fstatvfs __fstatvfs90
   79#define fstatvfs1 __fstatvfs190
   80#define fts_children __fts_children60
   81#define fts_close __fts_close60
   82#define fts_open __fts_open60
   83#define fts_read __fts_read60
   84#define fts_set __fts_set60
   85#define getitimer __getitimer50
   86#define getmntinfo __getmntinfo90
   87#define getpwent __getpwent50
   88#define getpwnam __getpwnam50
   89#define getpwnam_r __getpwnam_r50
   90#define getpwuid __getpwuid50
   91#define getpwuid_r __getpwuid_r50
   92#define getutent __getutent50
   93#define getutxent __getutxent50
   94#define getutxid __getutxid50
   95#define getutxline __getutxline50
   96#define getvfsstat __getvfsstat90
   97#define pututxline __pututxline50
   98#define glob __glob30
   99#define gmtime __gmtime50
  100#define gmtime_r __gmtime_r50
  101#define localtime __locatime50
  102#define localtime_r __localtime_r50
  103#define mktime __mktime50
  104#define lstat __lstat50
  105#define opendir __opendir30
  106#define readdir __readdir30
  107#define readdir_r __readdir_r30
  108#define scandir __scandir30
  109#define setitimer __setitimer50
  110#define setlocale __setlocale50
  111#define shmctl __shmctl50
  112#define sigaltstack __sigaltstack14
  113#define sigemptyset __sigemptyset14
  114#define sigfillset __sigfillset14
  115#define sigpending __sigpending14
  116#define sigprocmask __sigprocmask14
  117#define sigtimedwait __sigtimedwait50
  118#define stat __stat50
  119#define statvfs __statvfs90
  120#define statvfs1 __statvfs190
  121#define time __time50
  122#define times __times13
  123#define unvis __unvis50
  124#define wait3 __wait350
  125#define wait4 __wait450
  126extern const unsigned short *_ctype_tab_;
  127extern const short *_toupper_tab_;
  128extern const short *_tolower_tab_;
  129#endif
  130
  131#if SANITIZER_LINUX && SANITIZER_SPARC32
  132// On 32-bit Linux/sparc64, double and long double are identical and glibc
  133// uses a __nldbl_ (no long double) prefix for various stdio functions.
  134#  define __isoc23_fscanf __nldbl___isoc23_fscanf
  135#  define __isoc23_scanf __nldbl___isoc23_scanf
  136#  define __isoc23_sscanf __nldbl___isoc23_sscanf
  137#  define __isoc23_vfscanf __nldbl___isoc23_vfscanf
  138#  define __isoc23_vscanf __nldbl___isoc23_vscanf
  139#  define __isoc23_vsscanf __nldbl___isoc23_vsscanf
  140#  define __isoc99_fscanf __nldbl___isoc99_fscanf
  141#  define __isoc99_scanf __nldbl___isoc99_scanf
  142#  define __isoc99_sscanf __nldbl___isoc99_sscanf
  143#  define __isoc99_vfscanf __nldbl___isoc99_vfscanf
  144#  define __isoc99_vscanf __nldbl___isoc99_vscanf
  145#  define __isoc99_vsscanf __nldbl___isoc99_vsscanf
  146#  define asprintf __nldbl_asprintf
  147#  define fprintf __nldbl_fprintf
  148#  define fscanf __nldbl_fscanf
  149#  define printf __nldbl_printf
  150#  define scanf __nldbl_scanf
  151#  define snprintf __nldbl_snprintf
  152#  define sprintf __nldbl_sprintf
  153#  define sscanf __nldbl_sscanf
  154#  define vasprintf __nldbl_vasprintf
  155#  define vfprintf __nldbl_vfprintf
  156#  define vfscanf __nldbl_vfscanf
  157#  define vprintf __nldbl_vprintf
  158#  define vscanf __nldbl_vscanf
  159#  define vsnprintf __nldbl_vsnprintf
  160#  define vsprintf __nldbl_vsprintf
  161#  define vsscanf __nldbl_vsscanf
  162#endif
  163
  164#if SANITIZER_MUSL && \
  165  (defined(__i386__) || defined(__arm__) || SANITIZER_MIPS32 || SANITIZER_PPC32)
  166// musl 1.2.0 on existing 32-bit architectures uses new symbol names for the
  167// time-related functions that take 64-bit time_t values.  See
  168// https://musl.libc.org/time64.html
  169#define adjtime __adjtime64
  170#define adjtimex __adjtimex_time64
  171#define aio_suspend __aio_suspend_time64
  172#define clock_adjtime __clock_adjtime64
  173#define clock_getres __clock_getres_time64
  174#define clock_gettime __clock_gettime64
  175#define clock_nanosleep __clock_nanosleep_time64
  176#define clock_settime __clock_settime64
  177#define cnd_timedwait __cnd_timedwait_time64
  178#define ctime __ctime64
  179#define ctime_r __ctime64_r
  180#define difftime __difftime64
  181#define dlsym __dlsym_time64
  182#define fstatat __fstatat_time64
  183#define fstat __fstat_time64
  184#define ftime __ftime64
  185#define futimens __futimens_time64
  186#define futimesat __futimesat_time64
  187#define futimes __futimes_time64
  188#define getitimer __getitimer_time64
  189#define getrusage __getrusage_time64
  190#define gettimeofday __gettimeofday_time64
  191#define gmtime __gmtime64
  192#define gmtime_r __gmtime64_r
  193#define localtime __localtime64
  194#define localtime_r __localtime64_r
  195#define lstat __lstat_time64
  196#define lutimes __lutimes_time64
  197#define mktime __mktime64
  198#define mq_timedreceive __mq_timedreceive_time64
  199#define mq_timedsend __mq_timedsend_time64
  200#define mtx_timedlock __mtx_timedlock_time64
  201#define nanosleep __nanosleep_time64
  202#define ppoll __ppoll_time64
  203#define pselect __pselect_time64
  204#define pthread_cond_timedwait __pthread_cond_timedwait_time64
  205#define pthread_mutex_timedlock __pthread_mutex_timedlock_time64
  206#define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock_time64
  207#define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock_time64
  208#define pthread_timedjoin_np __pthread_timedjoin_np_time64
  209#define recvmmsg __recvmmsg_time64
  210#define sched_rr_get_interval __sched_rr_get_interval_time64
  211#define select __select_time64
  212#define semtimedop __semtimedop_time64
  213#define sem_timedwait __sem_timedwait_time64
  214#define setitimer __setitimer_time64
  215#define settimeofday __settimeofday_time64
  216#define sigtimedwait __sigtimedwait_time64
  217#define stat __stat_time64
  218#define stime __stime64
  219#define thrd_sleep __thrd_sleep_time64
  220#define timegm __timegm_time64
  221#define timerfd_gettime __timerfd_gettime64
  222#define timerfd_settime __timerfd_settime64
  223#define timer_gettime __timer_gettime64
  224#define timer_settime __timer_settime64
  225#define timespec_get __timespec_get_time64
  226#define time __time64
  227#define utimensat __utimensat_time64
  228#define utimes __utimes_time64
  229#define utime __utime64
  230#define wait3 __wait3_time64
  231#define wait4 __wait4_time64
  232#endif
  233
  234#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
  235#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
  236#endif
  237
  238#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
  239#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
  240#endif
  241
  242#ifndef COMMON_INTERCEPTOR_FD_ACCESS
  243#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
  244#endif
  245
  246#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
  247#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
  248#endif
  249
  250#ifndef COMMON_INTERCEPTOR_FILE_OPEN
  251#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
  252#endif
  253
  254#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
  255#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
  256#endif
  257
  258#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
  259#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
  260#endif
  261
  262#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
  263#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
  264#endif
  265
  266#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
  267#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
  268  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
  269#endif
  270
  271#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
  272#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
  273#endif
  274
  275#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
  276    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
  277      common_flags()->strict_string_checks ? (internal_strlen(s)) + 1 : (n) )
  278
  279#ifndef COMMON_INTERCEPTOR_DLOPEN
  280#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \
  281  ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); })
  282#endif
  283
  284#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
  285#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
  286#endif
  287
  288#ifndef COMMON_INTERCEPTOR_ACQUIRE
  289#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
  290#endif
  291
  292#ifndef COMMON_INTERCEPTOR_RELEASE
  293#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
  294#endif
  295
  296#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
  297#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
  298#endif
  299
  300#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
  301#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
  302#endif
  303
  304#ifdef SANITIZER_NLDBL_VERSION
  305#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
  306    COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
  307#else
  308#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
  309    COMMON_INTERCEPT_FUNCTION(fn)
  310#endif
  311
  312#if SANITIZER_GLIBC
  313// If we could not find the versioned symbol, fall back to an unversioned
  314// lookup. This is needed to work around a GLibc bug that causes dlsym
  315// with RTLD_NEXT to return the oldest versioned symbol.
  316// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932.
  317// For certain symbols (e.g. regexec) we have to perform a versioned lookup,
  318// but that versioned symbol will only exist for architectures where the
  319// oldest Glibc version pre-dates support for that architecture.
  320// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V.
  321// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920.
  322#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
  323  COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver)
  324#else
  325#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
  326  COMMON_INTERCEPT_FUNCTION(fn)
  327#endif
  328
  329#ifndef COMMON_INTERCEPTOR_MMAP_IMPL
  330#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
  331                                     off)                                  \
  332  { return REAL(mmap)(addr, sz, prot, flags, fd, off); }
  333#endif
  334
  335#ifndef COMMON_INTERCEPTOR_MUNMAP_IMPL
  336#define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz) \
  337  { return REAL(munmap)(addr, sz); }
  338#endif
  339
  340#ifndef COMMON_INTERCEPTOR_COPY_STRING
  341#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
  342#endif
  343
  344#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
  345#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size)                         \
  346  COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size);                            \
  347  uptr copy_length = internal_strnlen(s, size);                               \
  348  char *new_mem = (char *)WRAP(malloc)(copy_length + 1);                      \
  349  if (common_flags()->intercept_strndup) {                                    \
  350    COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min<uptr>(size, copy_length + 1)); \
  351  }                                                                           \
  352  if (new_mem) {                                                              \
  353    COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length);             \
  354    internal_memcpy(new_mem, s, copy_length);                                 \
  355    new_mem[copy_length] = '\0';                                              \
  356  }                                                                           \
  357  return new_mem;
  358#endif
  359
  360#ifndef COMMON_INTERCEPTOR_STRERROR
  361#define COMMON_INTERCEPTOR_STRERROR() {}
  362#endif
  363
  364struct FileMetadata {
  365  // For open_memstream().
  366  char **addr;
  367  SIZE_T *size;
  368};
  369
  370struct CommonInterceptorMetadata {
  371  enum {
  372    CIMT_INVALID = 0,
  373    CIMT_FILE
  374  } type;
  375  union {
  376    FileMetadata file;
  377  };
  378};
  379
  380#if SI_POSIX
  381typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
  382
  383static MetadataHashMap *interceptor_metadata_map;
  384
  385UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
  386                                          const FileMetadata &file) {
  387  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
  388  CHECK(h.created());
  389  h->type = CommonInterceptorMetadata::CIMT_FILE;
  390  h->file = file;
  391}
  392
  393UNUSED static const FileMetadata *GetInterceptorMetadata(
  394    __sanitizer_FILE *addr) {
  395  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
  396                            /* remove */ false,
  397                            /* create */ false);
  398  if (addr && h.exists()) {
  399    CHECK(!h.created());
  400    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
  401    return &h->file;
  402  } else {
  403    return 0;
  404  }
  405}
  406
  407UNUSED static void DeleteInterceptorMetadata(void *addr) {
  408  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
  409  CHECK(h.exists());
  410}
  411#endif  // SI_POSIX
  412
  413#if SANITIZER_INTERCEPT_STRLEN
  414INTERCEPTOR(SIZE_T, strlen, const char *s) {
  415  // Sometimes strlen is called prior to InitializeCommonInterceptors,
  416  // in which case the REAL(strlen) typically used in
  417  // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
  418  // to handle that.
  419  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  420    return internal_strlen(s);
  421  void *ctx;
  422  COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
  423  SIZE_T result = REAL(strlen)(s);
  424  if (common_flags()->intercept_strlen)
  425    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
  426  return result;
  427}
  428#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
  429#else
  430#define INIT_STRLEN
  431#endif
  432
  433#if SANITIZER_INTERCEPT_STRNLEN
  434INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
  435  void *ctx;
  436  COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
  437  SIZE_T length = REAL(strnlen)(s, maxlen);
  438  if (common_flags()->intercept_strlen)
  439    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
  440  return length;
  441}
  442#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
  443#else
  444#define INIT_STRNLEN
  445#endif
  446
  447#if SANITIZER_INTERCEPT_STRNDUP
  448INTERCEPTOR(char*, strndup, const char *s, usize size) {
  449  void *ctx;
  450  COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
  451}
  452#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
  453#else
  454#define INIT_STRNDUP
  455#endif // SANITIZER_INTERCEPT_STRNDUP
  456
  457#if SANITIZER_INTERCEPT___STRNDUP
  458INTERCEPTOR(char*, __strndup, const char *s, usize size) {
  459  void *ctx;
  460  COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
  461}
  462#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
  463#else
  464#define INIT___STRNDUP
  465#endif // SANITIZER_INTERCEPT___STRNDUP
  466
  467#if SANITIZER_INTERCEPT_TEXTDOMAIN
  468INTERCEPTOR(char*, textdomain, const char *domainname) {
  469  void *ctx;
  470  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
  471  if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
  472  char *domain = REAL(textdomain)(domainname);
  473  if (domain) {
  474    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, internal_strlen(domain) + 1);
  475  }
  476  return domain;
  477}
  478#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
  479#else
  480#define INIT_TEXTDOMAIN
  481#endif
  482
  483#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP
  484[[maybe_unused]] static inline int CharCmpX(unsigned char c1,
  485                                            unsigned char c2) {
  486  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
  487}
  488#endif
  489
  490#if SANITIZER_INTERCEPT_STRCMP
  491DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
  492                              const char *s1, const char *s2, int result)
  493
  494INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
  495  void *ctx;
  496  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
  497  unsigned char c1, c2;
  498  uptr i;
  499  for (i = 0;; i++) {
  500    c1 = (unsigned char)s1[i];
  501    c2 = (unsigned char)s2[i];
  502    if (c1 != c2 || c1 == '\0') break;
  503  }
  504  if (common_flags()->intercept_strcmp) {
  505    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
  506    COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
  507  }
  508  int result = CharCmpX(c1, c2);
  509  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
  510                             s2, result);
  511  return result;
  512}
  513
  514DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
  515                              const char *s1, const char *s2, usize n,
  516                              int result)
  517
  518INTERCEPTOR(int, strncmp, const char *s1, const char *s2, usize size) {
  519  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  520    return internal_strncmp(s1, s2, size);
  521  void *ctx;
  522  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
  523  unsigned char c1 = 0, c2 = 0;
  524  usize i;
  525  for (i = 0; i < size; i++) {
  526    c1 = (unsigned char)s1[i];
  527    c2 = (unsigned char)s2[i];
  528    if (c1 != c2 || c1 == '\0') break;
  529  }
  530  usize i1 = i;
  531  usize i2 = i;
  532  if (common_flags()->strict_string_checks) {
  533    for (; i1 < size && s1[i1]; i1++) {}
  534    for (; i2 < size && s2[i2]; i2++) {}
  535  }
  536  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
  537  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
  538  int result = CharCmpX(c1, c2);
  539  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
  540                             s2, size, result);
  541  return result;
  542}
  543
  544#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
  545#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
  546#else
  547#define INIT_STRCMP
  548#define INIT_STRNCMP
  549#endif
  550
  551#if SANITIZER_INTERCEPT_STRCASECMP
  552static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
  553  int c1_low = ToLower(c1);
  554  int c2_low = ToLower(c2);
  555  return c1_low - c2_low;
  556}
  557
  558DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
  559                              const char *s1, const char *s2, int result)
  560
  561INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
  562  void *ctx;
  563  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
  564  unsigned char c1 = 0, c2 = 0;
  565  uptr i;
  566  for (i = 0;; i++) {
  567    c1 = (unsigned char)s1[i];
  568    c2 = (unsigned char)s2[i];
  569    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
  570  }
  571  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
  572  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
  573  int result = CharCaseCmp(c1, c2);
  574  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
  575                             s1, s2, result);
  576  return result;
  577}
  578
  579DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
  580                              const char *s1, const char *s2, usize size,
  581                              int result)
  582
  583INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {
  584  void *ctx;
  585  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
  586  unsigned char c1 = 0, c2 = 0;
  587  usize i;
  588  for (i = 0; i < size; i++) {
  589    c1 = (unsigned char)s1[i];
  590    c2 = (unsigned char)s2[i];
  591    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
  592  }
  593  usize i1 = i;
  594  usize i2 = i;
  595  if (common_flags()->strict_string_checks) {
  596    for (; i1 < size && s1[i1]; i1++) {}
  597    for (; i2 < size && s2[i2]; i2++) {}
  598  }
  599  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
  600  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
  601  int result = CharCaseCmp(c1, c2);
  602  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
  603                             s1, s2, size, result);
  604  return result;
  605}
  606
  607#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
  608#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
  609#else
  610#define INIT_STRCASECMP
  611#define INIT_STRNCASECMP
  612#endif
  613
  614#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
  615static inline void StrstrCheck(void *ctx, char *r, const char *s1,
  616                               const char *s2) {
  617    uptr len1 = internal_strlen(s1);
  618    uptr len2 = internal_strlen(s2);
  619    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
  620    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
  621}
  622#endif
  623
  624#if SANITIZER_INTERCEPT_STRSTR
  625
  626DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
  627                              const char *s1, const char *s2, char *result)
  628
  629INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
  630  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  631    return internal_strstr(s1, s2);
  632  void *ctx;
  633  COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
  634  char *r = REAL(strstr)(s1, s2);
  635  if (common_flags()->intercept_strstr)
  636    StrstrCheck(ctx, r, s1, s2);
  637  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
  638                             s2, r);
  639  return r;
  640}
  641
  642#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
  643#else
  644#define INIT_STRSTR
  645#endif
  646
  647#if SANITIZER_INTERCEPT_STRCASESTR
  648
  649DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
  650                              const char *s1, const char *s2, char *result)
  651
  652INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
  653  void *ctx;
  654  COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
  655  char *r = REAL(strcasestr)(s1, s2);
  656  if (common_flags()->intercept_strstr)
  657    StrstrCheck(ctx, r, s1, s2);
  658  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
  659                             s1, s2, r);
  660  return r;
  661}
  662
  663#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
  664#else
  665#define INIT_STRCASESTR
  666#endif
  667
  668#if SANITIZER_INTERCEPT_STRTOK
  669
  670INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
  671  void *ctx;
  672  COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);
  673  if (!common_flags()->intercept_strtok) {
  674    return REAL(strtok)(str, delimiters);
  675  }
  676  if (common_flags()->strict_string_checks) {
  677    // If strict_string_checks is enabled, we check the whole first argument
  678    // string on the first call (strtok saves this string in a static buffer
  679    // for subsequent calls). We do not need to check strtok's result.
  680    // As the delimiters can change, we check them every call.
  681    if (str != nullptr) {
  682      COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
  683    }
  684    COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,
  685                                  internal_strlen(delimiters) + 1);
  686    return REAL(strtok)(str, delimiters);
  687  } else {
  688    // However, when strict_string_checks is disabled we cannot check the
  689    // whole string on the first call. Instead, we check the result string
  690    // which is guaranteed to be a NULL-terminated substring of the first
  691    // argument. We also conservatively check one character of str and the
  692    // delimiters.
  693    if (str != nullptr) {
  694      COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);
  695    }
  696    COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);
  697    char *result = REAL(strtok)(str, delimiters);
  698    if (result != nullptr) {
  699      COMMON_INTERCEPTOR_READ_RANGE(ctx, result, internal_strlen(result) + 1);
  700    } else if (str != nullptr) {
  701      // No delimiter were found, it's safe to assume that the entire str was
  702      // scanned.
  703      COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
  704    }
  705    return result;
  706  }
  707}
  708
  709#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)
  710#else
  711#define INIT_STRTOK
  712#endif
  713
  714#if SANITIZER_INTERCEPT_MEMMEM
  715DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
  716                              const void *s1, SIZE_T len1, const void *s2,
  717                              SIZE_T len2, void *result)
  718
  719INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
  720            SIZE_T len2) {
  721  void *ctx;
  722  COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
  723  void *r = REAL(memmem)(s1, len1, s2, len2);
  724  if (common_flags()->intercept_memmem) {
  725    COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
  726    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
  727  }
  728  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
  729                             s1, len1, s2, len2, r);
  730  return r;
  731}
  732
  733#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
  734#else
  735#define INIT_MEMMEM
  736#endif  // SANITIZER_INTERCEPT_MEMMEM
  737
  738#if SANITIZER_INTERCEPT_STRCHR
  739INTERCEPTOR(char*, strchr, const char *s, int c) {
  740  void *ctx;
  741  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  742    return internal_strchr(s, c);
  743  COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
  744  char *result = REAL(strchr)(s, c);
  745  if (common_flags()->intercept_strchr) {
  746    // Keep strlen as macro argument, as macro may ignore it.
  747    COMMON_INTERCEPTOR_READ_STRING(ctx, s,
  748      (result ? result - s : internal_strlen(s)) + 1);
  749  }
  750  return result;
  751}
  752#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
  753#else
  754#define INIT_STRCHR
  755#endif
  756
  757#if SANITIZER_INTERCEPT_STRCHRNUL
  758INTERCEPTOR(char*, strchrnul, const char *s, int c) {
  759  void *ctx;
  760  COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
  761  char *result = REAL(strchrnul)(s, c);
  762  uptr len = result - s + 1;
  763  if (common_flags()->intercept_strchr)
  764    COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
  765  return result;
  766}
  767#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
  768#else
  769#define INIT_STRCHRNUL
  770#endif
  771
  772#if SANITIZER_INTERCEPT_STRRCHR
  773INTERCEPTOR(char*, strrchr, const char *s, int c) {
  774  void *ctx;
  775  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  776    return internal_strrchr(s, c);
  777  COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
  778  if (common_flags()->intercept_strchr)
  779    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
  780  return REAL(strrchr)(s, c);
  781}
  782#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
  783#else
  784#define INIT_STRRCHR
  785#endif
  786
  787#if SANITIZER_INTERCEPT_STRSPN
  788INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
  789  void *ctx;
  790  COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
  791  SIZE_T r = REAL(strspn)(s1, s2);
  792  if (common_flags()->intercept_strspn) {
  793    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
  794    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
  795  }
  796  return r;
  797}
  798
  799INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
  800  void *ctx;
  801  COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
  802  SIZE_T r = REAL(strcspn)(s1, s2);
  803  if (common_flags()->intercept_strspn) {
  804    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
  805    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
  806  }
  807  return r;
  808}
  809
  810#define INIT_STRSPN \
  811  COMMON_INTERCEPT_FUNCTION(strspn); \
  812  COMMON_INTERCEPT_FUNCTION(strcspn);
  813#else
  814#define INIT_STRSPN
  815#endif
  816
  817#if SANITIZER_INTERCEPT_STRPBRK
  818INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
  819  void *ctx;
  820  COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
  821  char *r = REAL(strpbrk)(s1, s2);
  822  if (common_flags()->intercept_strpbrk) {
  823    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
  824    COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
  825        r ? r - s1 + 1 : internal_strlen(s1) + 1);
  826  }
  827  return r;
  828}
  829
  830#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
  831#else
  832#define INIT_STRPBRK
  833#endif
  834
  835#if SANITIZER_INTERCEPT_MEMCMP
  836DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
  837                              const void *s1, const void *s2, usize n,
  838                              int result)
  839
  840// Common code for `memcmp` and `bcmp`.
  841int MemcmpInterceptorCommon(void *ctx,
  842                            int (*real_fn)(const void *, const void *, usize),
  843                            const void *a1, const void *a2, usize size) {
  844  if (common_flags()->intercept_memcmp) {
  845    if (common_flags()->strict_memcmp) {
  846      // Check the entire regions even if the first bytes of the buffers are
  847      // different.
  848      COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
  849      COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
  850      // Fallthrough to REAL(memcmp) below.
  851    } else {
  852      unsigned char c1 = 0, c2 = 0;
  853      const unsigned char *s1 = (const unsigned char*)a1;
  854      const unsigned char *s2 = (const unsigned char*)a2;
  855      usize i;
  856      for (i = 0; i < size; i++) {
  857        c1 = s1[i];
  858        c2 = s2[i];
  859        if (c1 != c2) break;
  860      }
  861      COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
  862      COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
  863      int r = CharCmpX(c1, c2);
  864      CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
  865                                 a1, a2, size, r);
  866      return r;
  867    }
  868  }
  869  int result = real_fn(a1, a2, size);
  870  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
  871                             a2, size, result);
  872  return result;
  873}
  874
  875INTERCEPTOR(int, memcmp, const void *a1, const void *a2, usize size) {
  876  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  877    return internal_memcmp(a1, a2, size);
  878  void *ctx;
  879  COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
  880  return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
  881}
  882
  883#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
  884#else
  885#define INIT_MEMCMP
  886#endif
  887
  888#if SANITIZER_INTERCEPT_BCMP
  889INTERCEPTOR(int, bcmp, const void *a1, const void *a2, usize size) {
  890  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  891    return internal_memcmp(a1, a2, size);
  892  void *ctx;
  893  COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
  894  return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
  895}
  896
  897#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
  898#else
  899#define INIT_BCMP
  900#endif
  901
  902#if SANITIZER_INTERCEPT_MEMCHR
  903INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
  904  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
  905    return internal_memchr(s, c, n);
  906  void *ctx;
  907  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
  908#if SANITIZER_WINDOWS
  909  void *res;
  910  if (REAL(memchr)) {
  911    res = REAL(memchr)(s, c, n);
  912  } else {
  913    res = internal_memchr(s, c, n);
  914  }
  915#else
  916  void *res = REAL(memchr)(s, c, n);
  917#endif
  918  uptr len = res ? (char *)res - (const char *)s + 1 : n;
  919  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
  920  return res;
  921}
  922
  923#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
  924#else
  925#define INIT_MEMCHR
  926#endif
  927
  928#if SANITIZER_INTERCEPT_MEMRCHR
  929INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
  930  void *ctx;
  931  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
  932  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
  933  return REAL(memrchr)(s, c, n);
  934}
  935
  936#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
  937#else
  938#define INIT_MEMRCHR
  939#endif
  940
  941#if SANITIZER_INTERCEPT_FREXP
  942INTERCEPTOR(double, frexp, double x, int *exp) {
  943  void *ctx;
  944  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
  945  // Assuming frexp() always writes to |exp|.
  946  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
  947  double res = REAL(frexp)(x, exp);
  948  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
  949  return res;
  950}
  951
  952#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
  953#else
  954#define INIT_FREXP
  955#endif  // SANITIZER_INTERCEPT_FREXP
  956
  957#if SANITIZER_INTERCEPT_FREXPF
  958INTERCEPTOR(float, frexpf, float x, int *exp) {
  959  void *ctx;
  960  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
  961  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
  962  float res = REAL(frexpf)(x, exp);
  963  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
  964  return res;
  965}
  966
  967#  define INIT_FREXPF COMMON_INTERCEPT_FUNCTION(frexpf);
  968#else
  969#  define INIT_FREXPF
  970#endif
  971
  972#if SANITIZER_INTERCEPT_FREXPL
  973INTERCEPTOR(long double, frexpl, long double x, int *exp) {
  974  void *ctx;
  975  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
  976  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
  977  long double res = REAL(frexpl)(x, exp);
  978  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
  979  return res;
  980}
  981
  982#  define INIT_FREXPL COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
  983#else
  984#  define INIT_FREXPL
  985#endif
  986
  987#if SI_POSIX
  988static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
  989                        SIZE_T iovlen, SIZE_T maxlen) {
  990  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
  991    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
  992    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
  993    maxlen -= sz;
  994  }
  995}
  996
  997static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
  998                       SIZE_T iovlen, SIZE_T maxlen) {
  999  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
 1000  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
 1001    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
 1002    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
 1003    maxlen -= sz;
 1004  }
 1005}
 1006#endif
 1007
 1008#if SANITIZER_INTERCEPT_READ
 1009INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
 1010  void *ctx;
 1011  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
 1012  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1013  // FIXME: under ASan the call below may write to freed memory and corrupt
 1014  // its metadata. See
 1015  // https://github.com/google/sanitizers/issues/321.
 1016  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(read)(fd, ptr, count);
 1017  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
 1018  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1019  return res;
 1020}
 1021#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
 1022#else
 1023#define INIT_READ
 1024#endif
 1025
 1026#if SANITIZER_INTERCEPT_FREAD
 1027INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
 1028  // libc file streams can call user-supplied functions, see fopencookie.
 1029  void *ctx;
 1030  COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
 1031  // FIXME: under ASan the call below may write to freed memory and corrupt
 1032  // its metadata. See
 1033  // https://github.com/google/sanitizers/issues/321.
 1034  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
 1035  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
 1036  return res;
 1037}
 1038#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
 1039#else
 1040#define INIT_FREAD
 1041#endif
 1042
 1043#if SANITIZER_INTERCEPT_PREAD
 1044INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
 1045  void *ctx;
 1046  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
 1047  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1048  // FIXME: under ASan the call below may write to freed memory and corrupt
 1049  // its metadata. See
 1050  // https://github.com/google/sanitizers/issues/321.
 1051  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread)(fd, ptr, count, offset);
 1052  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
 1053  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1054  return res;
 1055}
 1056#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
 1057#else
 1058#define INIT_PREAD
 1059#endif
 1060
 1061#if SANITIZER_INTERCEPT_PREAD64
 1062INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
 1063  void *ctx;
 1064  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
 1065  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1066  // FIXME: under ASan the call below may write to freed memory and corrupt
 1067  // its metadata. See
 1068  // https://github.com/google/sanitizers/issues/321.
 1069  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pread64)(fd, ptr, count, offset);
 1070  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
 1071  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1072  return res;
 1073}
 1074#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
 1075#else
 1076#define INIT_PREAD64
 1077#endif
 1078
 1079#if SANITIZER_INTERCEPT_READV
 1080INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
 1081                        int iovcnt) {
 1082  void *ctx;
 1083  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
 1084  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1085  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(readv)(fd, iov, iovcnt);
 1086  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
 1087  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1088  return res;
 1089}
 1090#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
 1091#else
 1092#define INIT_READV
 1093#endif
 1094
 1095#if SANITIZER_INTERCEPT_PREADV
 1096INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
 1097            OFF_T offset) {
 1098  void *ctx;
 1099  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
 1100  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1101  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(preadv)(fd, iov, iovcnt, offset);
 1102  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
 1103  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1104  return res;
 1105}
 1106#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
 1107#else
 1108#define INIT_PREADV
 1109#endif
 1110
 1111#if SANITIZER_INTERCEPT_PREADV64
 1112INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
 1113            OFF64_T offset) {
 1114  void *ctx;
 1115  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
 1116  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1117  SSIZE_T res =
 1118      COMMON_INTERCEPTOR_BLOCK_REAL(preadv64)(fd, iov, iovcnt, offset);
 1119  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
 1120  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 1121  return res;
 1122}
 1123#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
 1124#else
 1125#define INIT_PREADV64
 1126#endif
 1127
 1128#if SANITIZER_INTERCEPT_WRITE
 1129INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
 1130  void *ctx;
 1131  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
 1132  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1133  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1134  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(write)(fd, ptr, count);
 1135  // FIXME: this check should be _before_ the call to
 1136  // COMMON_INTERCEPTOR_BLOCK_REAL(write), not after
 1137  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
 1138  return res;
 1139}
 1140#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
 1141#else
 1142#define INIT_WRITE
 1143#endif
 1144
 1145#if SANITIZER_INTERCEPT_FWRITE
 1146INTERCEPTOR(SIZE_T, fwrite, const void *p, usize size, usize nmemb, void *file) {
 1147  // libc file streams can call user-supplied functions, see fopencookie.
 1148  void *ctx;
 1149  COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
 1150  SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
 1151  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
 1152  return res;
 1153}
 1154#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
 1155#else
 1156#define INIT_FWRITE
 1157#endif
 1158
 1159#if SANITIZER_INTERCEPT_PWRITE
 1160INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
 1161  void *ctx;
 1162  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
 1163  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1164  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1165  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite)(fd, ptr, count, offset);
 1166  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
 1167  return res;
 1168}
 1169#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
 1170#else
 1171#define INIT_PWRITE
 1172#endif
 1173
 1174#if SANITIZER_INTERCEPT_PWRITE64
 1175INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
 1176            OFF64_T offset) {
 1177  void *ctx;
 1178  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
 1179  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1180  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1181  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwrite64)(fd, ptr, count, offset);
 1182  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
 1183  return res;
 1184}
 1185#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
 1186#else
 1187#define INIT_PWRITE64
 1188#endif
 1189
 1190#if SANITIZER_INTERCEPT_WRITEV
 1191INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
 1192                        int iovcnt) {
 1193  void *ctx;
 1194  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
 1195  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1196  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1197  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(writev)(fd, iov, iovcnt);
 1198  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
 1199  return res;
 1200}
 1201#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
 1202#else
 1203#define INIT_WRITEV
 1204#endif
 1205
 1206#if SANITIZER_INTERCEPT_PWRITEV
 1207INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
 1208            OFF_T offset) {
 1209  void *ctx;
 1210  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
 1211  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1212  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1213  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(pwritev)(fd, iov, iovcnt, offset);
 1214  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
 1215  return res;
 1216}
 1217#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
 1218#else
 1219#define INIT_PWRITEV
 1220#endif
 1221
 1222#if SANITIZER_INTERCEPT_PWRITEV64
 1223INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
 1224            OFF64_T offset) {
 1225  void *ctx;
 1226  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
 1227  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 1228  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 1229  SSIZE_T res =
 1230      COMMON_INTERCEPTOR_BLOCK_REAL(pwritev64)(fd, iov, iovcnt, offset);
 1231  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
 1232  return res;
 1233}
 1234#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
 1235#else
 1236#define INIT_PWRITEV64
 1237#endif
 1238
 1239#if SANITIZER_INTERCEPT_FGETS
 1240INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {
 1241  // libc file streams can call user-supplied functions, see fopencookie.
 1242  void *ctx;
 1243  COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);
 1244  // FIXME: under ASan the call below may write to freed memory and corrupt
 1245  // its metadata. See
 1246  // https://github.com/google/sanitizers/issues/321.
 1247  char *res = REAL(fgets)(s, size, file);
 1248  if (res)
 1249    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
 1250  return res;
 1251}
 1252#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)
 1253#else
 1254#define INIT_FGETS
 1255#endif
 1256
 1257#if SANITIZER_INTERCEPT_FPUTS
 1258INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
 1259  // libc file streams can call user-supplied functions, see fopencookie.
 1260  void *ctx;
 1261  COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
 1262  if (!SANITIZER_APPLE || s) {  // `fputs(NULL, file)` is supported on Darwin.
 1263    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
 1264  }
 1265  return REAL(fputs)(s, file);
 1266}
 1267#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
 1268#else
 1269#define INIT_FPUTS
 1270#endif
 1271
 1272#if SANITIZER_INTERCEPT_PUTS
 1273INTERCEPTOR(int, puts, char *s) {
 1274  // libc file streams can call user-supplied functions, see fopencookie.
 1275  void *ctx;
 1276  COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
 1277  if (!SANITIZER_APPLE || s) {  // `puts(NULL)` is supported on Darwin.
 1278    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
 1279  }
 1280  return REAL(puts)(s);
 1281}
 1282#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
 1283#else
 1284#define INIT_PUTS
 1285#endif
 1286
 1287#if SANITIZER_INTERCEPT_PRCTL
 1288INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
 1289            unsigned long arg4, unsigned long arg5) {
 1290  void *ctx;
 1291  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
 1292  static const int PR_SET_NAME = 15;
 1293  static const int PR_GET_NAME = 16;
 1294  static const int PR_SET_VMA = 0x53564d41;
 1295  static const int PR_SCHED_CORE = 62;
 1296  static const int PR_SCHED_CORE_GET = 0;
 1297  static const int PR_GET_PDEATHSIG = 2;
 1298
 1299#  if !SANITIZER_ANDROID
 1300  static const int PR_SET_SECCOMP = 22;
 1301  static const int SECCOMP_MODE_FILTER = 2;
 1302#  endif
 1303  if (option == PR_SET_VMA && arg2 == 0UL) {
 1304    char *name = (char *)arg5;
 1305    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 1306  }
 1307  int res = REAL(prctl)(option, arg2, arg3, arg4, arg5);
 1308  if (option == PR_SET_NAME) {
 1309    char buff[16];
 1310    internal_strncpy(buff, (char *)arg2, 15);
 1311    buff[15] = 0;
 1312    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
 1313  } else if (res == 0 && option == PR_GET_NAME) {
 1314    char *name = (char *)arg2;
 1315    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
 1316  } else if (res != -1 && option == PR_SCHED_CORE &&
 1317             arg2 == PR_SCHED_CORE_GET) {
 1318    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg5), sizeof(u64));
 1319  } else if (res != -1 && option == PR_GET_PDEATHSIG) {
 1320    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg2), sizeof(int));
 1321#  if SANITIZER_GLIBC
 1322  } else if (res != -1 && option == PR_SET_SECCOMP &&
 1323             arg2 == SECCOMP_MODE_FILTER) {
 1324    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg3), struct_sock_fprog_sz);
 1325#  endif
 1326  }
 1327  return res;
 1328}
 1329#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
 1330#else
 1331#define INIT_PRCTL
 1332#endif  // SANITIZER_INTERCEPT_PRCTL
 1333
 1334#if SANITIZER_INTERCEPT_TIME
 1335INTERCEPTOR(unsigned long, time, unsigned long *t) {
 1336  void *ctx;
 1337  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
 1338  unsigned long local_t;
 1339  unsigned long res = REAL(time)(&local_t);
 1340  if (t && res != (unsigned long)-1) {
 1341    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
 1342    *t = local_t;
 1343  }
 1344  return res;
 1345}
 1346#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
 1347#else
 1348#define INIT_TIME
 1349#endif  // SANITIZER_INTERCEPT_TIME
 1350
 1351#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
 1352static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
 1353  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
 1354// AIX tm struct does not have tm_zone field.
 1355#  if !SANITIZER_SOLARIS && !SANITIZER_AIX
 1356  if (tm->tm_zone) {
 1357    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
 1358    // can point to shared memory and tsan would report a data race.
 1359    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
 1360                                        internal_strlen(tm->tm_zone) + 1);
 1361  }
 1362#endif
 1363}
 1364INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
 1365  void *ctx;
 1366  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
 1367  __sanitizer_tm *res = REAL(localtime)(timep);
 1368  if (res) {
 1369    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1370    unpoison_tm(ctx, res);
 1371  }
 1372  return res;
 1373}
 1374INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
 1375  void *ctx;
 1376  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
 1377  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
 1378  if (res) {
 1379    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1380    unpoison_tm(ctx, res);
 1381  }
 1382  return res;
 1383}
 1384INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
 1385  void *ctx;
 1386  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
 1387  __sanitizer_tm *res = REAL(gmtime)(timep);
 1388  if (res) {
 1389    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1390    unpoison_tm(ctx, res);
 1391  }
 1392  return res;
 1393}
 1394INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
 1395  void *ctx;
 1396  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
 1397  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
 1398  if (res) {
 1399    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1400    unpoison_tm(ctx, res);
 1401  }
 1402  return res;
 1403}
 1404INTERCEPTOR(char *, ctime, unsigned long *timep) {
 1405  void *ctx;
 1406  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
 1407  // FIXME: under ASan the call below may write to freed memory and corrupt
 1408  // its metadata. See
 1409  // https://github.com/google/sanitizers/issues/321.
 1410  char *res = REAL(ctime)(timep);
 1411  if (res) {
 1412    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1413    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 1414  }
 1415  return res;
 1416}
 1417INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
 1418  void *ctx;
 1419  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
 1420  // FIXME: under ASan the call below may write to freed memory and corrupt
 1421  // its metadata. See
 1422  // https://github.com/google/sanitizers/issues/321.
 1423  char *res = REAL(ctime_r)(timep, result);
 1424  if (res) {
 1425    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
 1426    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 1427  }
 1428  return res;
 1429}
 1430INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
 1431  void *ctx;
 1432  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
 1433  // FIXME: under ASan the call below may write to freed memory and corrupt
 1434  // its metadata. See
 1435  // https://github.com/google/sanitizers/issues/321.
 1436  char *res = REAL(asctime)(tm);
 1437  if (res) {
 1438    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
 1439    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 1440  }
 1441  return res;
 1442}
 1443INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
 1444  void *ctx;
 1445  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
 1446  // FIXME: under ASan the call below may write to freed memory and corrupt
 1447  // its metadata. See
 1448  // https://github.com/google/sanitizers/issues/321.
 1449  char *res = REAL(asctime_r)(tm, result);
 1450  if (res) {
 1451    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
 1452    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 1453  }
 1454  return res;
 1455}
 1456INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
 1457  void *ctx;
 1458  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
 1459  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
 1460  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
 1461  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
 1462  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
 1463  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
 1464  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
 1465  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
 1466  long res = REAL(mktime)(tm);
 1467  if (res != -1) unpoison_tm(ctx, tm);
 1468  return res;
 1469}
 1470#define INIT_LOCALTIME_AND_FRIENDS        \
 1471  COMMON_INTERCEPT_FUNCTION(localtime);   \
 1472  COMMON_INTERCEPT_FUNCTION(localtime_r); \
 1473  COMMON_INTERCEPT_FUNCTION(gmtime);      \
 1474  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
 1475  COMMON_INTERCEPT_FUNCTION(ctime);       \
 1476  COMMON_INTERCEPT_FUNCTION(ctime_r);     \
 1477  COMMON_INTERCEPT_FUNCTION(asctime);     \
 1478  COMMON_INTERCEPT_FUNCTION(asctime_r);   \
 1479  COMMON_INTERCEPT_FUNCTION(mktime);
 1480#else
 1481#define INIT_LOCALTIME_AND_FRIENDS
 1482#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
 1483
 1484#if SANITIZER_INTERCEPT_STRPTIME
 1485INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
 1486  void *ctx;
 1487  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
 1488  if (format)
 1489    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);
 1490  // FIXME: under ASan the call below may write to freed memory and corrupt
 1491  // its metadata. See
 1492  // https://github.com/google/sanitizers/issues/321.
 1493  char *res = REAL(strptime)(s, format, tm);
 1494  COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
 1495  if (res && tm) {
 1496    // Do not call unpoison_tm here, because strptime does not, in fact,
 1497    // initialize the entire struct tm. For example, tm_zone pointer is left
 1498    // uninitialized.
 1499    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
 1500  }
 1501  return res;
 1502}
 1503#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
 1504#else
 1505#define INIT_STRPTIME
 1506#endif
 1507
 1508#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
 1509#include "sanitizer_common_interceptors_format.inc"
 1510
 1511#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
 1512  {                                                                            \
 1513    void *ctx;                                                                 \
 1514    va_list ap;                                                                \
 1515    va_start(ap, format);                                                      \
 1516    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
 1517    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
 1518    va_end(ap);                                                                \
 1519    return res;                                                                \
 1520  }
 1521
 1522#endif
 1523
 1524#if SANITIZER_INTERCEPT_SCANF
 1525
 1526#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
 1527  {                                                                            \
 1528    void *ctx;                                                                 \
 1529    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
 1530    va_list aq;                                                                \
 1531    va_copy(aq, ap);                                                           \
 1532    int res = REAL(vname)(__VA_ARGS__);                                        \
 1533    if (res > 0)                                                               \
 1534      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
 1535    va_end(aq);                                                                \
 1536    return res;                                                                \
 1537  }
 1538
 1539INTERCEPTOR(int, vscanf, const char *format, va_list ap)
 1540VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
 1541
 1542INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
 1543VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
 1544
 1545INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
 1546VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
 1547
 1548#if SANITIZER_INTERCEPT_ISOC99_SCANF
 1549INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
 1550VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
 1551
 1552INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
 1553            va_list ap)
 1554VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
 1555
 1556INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
 1557VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
 1558
 1559INTERCEPTOR(int, __isoc23_vscanf, const char *format, va_list ap)
 1560VSCANF_INTERCEPTOR_IMPL(__isoc23_vscanf, false, format, ap)
 1561
 1562INTERCEPTOR(int, __isoc23_vsscanf, const char *str, const char *format,
 1563            va_list ap)
 1564VSCANF_INTERCEPTOR_IMPL(__isoc23_vsscanf, false, str, format, ap)
 1565
 1566INTERCEPTOR(int, __isoc23_vfscanf, void *stream, const char *format, va_list ap)
 1567VSCANF_INTERCEPTOR_IMPL(__isoc23_vfscanf, false, stream, format, ap)
 1568#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
 1569
 1570INTERCEPTOR(int, scanf, const char *format, ...)
 1571FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
 1572
 1573INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
 1574FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
 1575
 1576INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
 1577FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
 1578
 1579#if SANITIZER_INTERCEPT_ISOC99_SCANF
 1580INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
 1581FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
 1582
 1583INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
 1584FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
 1585
 1586INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
 1587FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
 1588
 1589INTERCEPTOR(int, __isoc23_scanf, const char *format, ...)
 1590FORMAT_INTERCEPTOR_IMPL(__isoc23_scanf, __isoc23_vscanf, format)
 1591
 1592INTERCEPTOR(int, __isoc23_fscanf, void *stream, const char *format, ...)
 1593FORMAT_INTERCEPTOR_IMPL(__isoc23_fscanf, __isoc23_vfscanf, stream, format)
 1594
 1595INTERCEPTOR(int, __isoc23_sscanf, const char *str, const char *format, ...)
 1596FORMAT_INTERCEPTOR_IMPL(__isoc23_sscanf, __isoc23_vsscanf, str, format)
 1597#endif
 1598
 1599#endif
 1600
 1601#if SANITIZER_INTERCEPT_SCANF
 1602#define INIT_SCANF                    \
 1603  COMMON_INTERCEPT_FUNCTION_LDBL(scanf);   \
 1604  COMMON_INTERCEPT_FUNCTION_LDBL(sscanf);  \
 1605  COMMON_INTERCEPT_FUNCTION_LDBL(fscanf);  \
 1606  COMMON_INTERCEPT_FUNCTION_LDBL(vscanf);  \
 1607  COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \
 1608  COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);
 1609#else
 1610#define INIT_SCANF
 1611#endif
 1612
 1613#if SANITIZER_INTERCEPT_ISOC99_SCANF
 1614#define INIT_ISOC99_SCANF                      \
 1615  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
 1616  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
 1617  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
 1618  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
 1619  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
 1620  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); \
 1621  COMMON_INTERCEPT_FUNCTION(__isoc23_scanf);   \
 1622  COMMON_INTERCEPT_FUNCTION(__isoc23_sscanf);  \
 1623  COMMON_INTERCEPT_FUNCTION(__isoc23_fscanf);  \
 1624  COMMON_INTERCEPT_FUNCTION(__isoc23_vscanf);  \
 1625  COMMON_INTERCEPT_FUNCTION(__isoc23_vsscanf); \
 1626  COMMON_INTERCEPT_FUNCTION(__isoc23_vfscanf);
 1627#else
 1628#define INIT_ISOC99_SCANF
 1629#endif
 1630
 1631#if SANITIZER_INTERCEPT_PRINTF
 1632
 1633#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
 1634  void *ctx;                                                                   \
 1635  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
 1636  va_list aq;                                                                  \
 1637  va_copy(aq, ap);
 1638
 1639#define VPRINTF_INTERCEPTOR_RETURN()                                           \
 1640  va_end(aq);
 1641
 1642#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
 1643  {                                                                            \
 1644    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
 1645    if (common_flags()->check_printf)                                          \
 1646      printf_common(ctx, format, aq);                                          \
 1647    int res = REAL(vname)(__VA_ARGS__);                                        \
 1648    VPRINTF_INTERCEPTOR_RETURN();                                              \
 1649    return res;                                                                \
 1650  }
 1651
 1652// FIXME: under ASan the REAL() call below may write to freed memory and
 1653// corrupt its metadata. See
 1654// https://github.com/google/sanitizers/issues/321.
 1655#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
 1656  {                                                                            \
 1657    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
 1658    if (common_flags()->check_printf) {                                        \
 1659      printf_common(ctx, format, aq);                                          \
 1660    }                                                                          \
 1661    int res = REAL(vname)(str, __VA_ARGS__);                                   \
 1662    if (res >= 0) {                                                            \
 1663      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
 1664    }                                                                          \
 1665    VPRINTF_INTERCEPTOR_RETURN();                                              \
 1666    return res;                                                                \
 1667  }
 1668
 1669// FIXME: under ASan the REAL() call below may write to freed memory and
 1670// corrupt its metadata. See
 1671// https://github.com/google/sanitizers/issues/321.
 1672#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
 1673  {                                                                            \
 1674    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
 1675    if (common_flags()->check_printf) {                                        \
 1676      printf_common(ctx, format, aq);                                          \
 1677    }                                                                          \
 1678    int res = REAL(vname)(str, size, __VA_ARGS__);                             \
 1679    if (res >= 0) {                                                            \
 1680      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
 1681    }                                                                          \
 1682    VPRINTF_INTERCEPTOR_RETURN();                                              \
 1683    return res;                                                                \
 1684  }
 1685
 1686// FIXME: under ASan the REAL() call below may write to freed memory and
 1687// corrupt its metadata. See
 1688// https://github.com/google/sanitizers/issues/321.
 1689#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
 1690  {                                                                            \
 1691    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
 1692    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
 1693    if (common_flags()->check_printf) {                                        \
 1694      printf_common(ctx, format, aq);                                          \
 1695    }                                                                          \
 1696    int res = REAL(vname)(strp, __VA_ARGS__);                                  \
 1697    if (res >= 0) {                                                            \
 1698      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
 1699    }                                                                          \
 1700    VPRINTF_INTERCEPTOR_RETURN();                                              \
 1701    return res;                                                                \
 1702  }
 1703
 1704INTERCEPTOR(int, vprintf, const char *format, va_list ap)
 1705VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
 1706
 1707INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
 1708            va_list ap)
 1709VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
 1710
 1711INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
 1712            va_list ap)
 1713VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
 1714
 1715#if SANITIZER_INTERCEPT___PRINTF_CHK
 1716INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
 1717            SIZE_T size_to, const char *format, va_list ap)
 1718VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
 1719#endif
 1720
 1721#if SANITIZER_INTERCEPT_PRINTF_L
 1722INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
 1723            const char *format, va_list ap)
 1724VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
 1725
 1726INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
 1727            const char *format, ...)
 1728FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
 1729#endif  // SANITIZER_INTERCEPT_PRINTF_L
 1730
 1731INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
 1732VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
 1733
 1734#if SANITIZER_INTERCEPT___PRINTF_CHK
 1735INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
 1736            const char *format, va_list ap)
 1737VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
 1738#endif
 1739
 1740#  if SANITIZER_INTERCEPT_VASPRINTF
 1741INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
 1742VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
 1743#  endif
 1744
 1745#  if SANITIZER_INTERCEPT_ISOC99_PRINTF
 1746INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
 1747VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
 1748
 1749INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
 1750            const char *format, va_list ap)
 1751VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
 1752
 1753INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
 1754            va_list ap)
 1755VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
 1756
 1757INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
 1758            va_list ap)
 1759VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
 1760                          ap)
 1761
 1762#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
 1763
 1764INTERCEPTOR(int, printf, const char *format, ...)
 1765FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
 1766
 1767INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
 1768FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
 1769
 1770#if SANITIZER_INTERCEPT___PRINTF_CHK
 1771INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
 1772            const char *format, ...)
 1773FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
 1774#endif
 1775
 1776INTERCEPTOR(int, sprintf, char *str, const char *format, ...)
 1777FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)
 1778
 1779#if SANITIZER_INTERCEPT___PRINTF_CHK
 1780INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
 1781            const char *format, ...)
 1782FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)
 1783#endif
 1784
 1785INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
 1786FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
 1787
 1788#if SANITIZER_INTERCEPT___PRINTF_CHK
 1789INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
 1790            SIZE_T size_to, const char *format, ...)
 1791FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
 1792#endif
 1793
 1794#  if SANITIZER_INTERCEPT_ASPRINTF
 1795INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
 1796FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
 1797#  endif
 1798
 1799#  if SANITIZER_INTERCEPT_ISOC99_PRINTF
 1800INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
 1801FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
 1802
 1803INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
 1804            ...)
 1805FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
 1806
 1807INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
 1808FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
 1809
 1810INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
 1811            const char *format, ...)
 1812FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
 1813                        format)
 1814
 1815#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
 1816
 1817#endif  // SANITIZER_INTERCEPT_PRINTF
 1818
 1819#if SANITIZER_INTERCEPT_PRINTF
 1820#  define INIT_PRINTF_COMMON                   \
 1821    COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
 1822    COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
 1823    COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
 1824    COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
 1825    COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
 1826    COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
 1827    COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
 1828    COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
 1829#  if !SANITIZER_AIX
 1830// AIX does not have [v]asprintf.
 1831#    define INIT_PRINTF_EXTRA                   \
 1832      COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
 1833      COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf);
 1834#  else
 1835#    define INIT_PRINTF_EXTRA
 1836#  endif
 1837#  define INIT_PRINTF INIT_PRINTF_COMMON INIT_PRINTF_EXTRA
 1838#else
 1839#define INIT_PRINTF
 1840#endif
 1841
 1842#if SANITIZER_INTERCEPT___PRINTF_CHK
 1843#define INIT___PRINTF_CHK                     \
 1844  COMMON_INTERCEPT_FUNCTION(__sprintf_chk);   \
 1845  COMMON_INTERCEPT_FUNCTION(__snprintf_chk);  \
 1846  COMMON_INTERCEPT_FUNCTION(__vsprintf_chk);  \
 1847  COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
 1848  COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
 1849#else
 1850#define INIT___PRINTF_CHK
 1851#endif
 1852
 1853#if SANITIZER_INTERCEPT_PRINTF_L
 1854#define INIT_PRINTF_L                     \
 1855  COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
 1856  COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
 1857#else
 1858#define INIT_PRINTF_L
 1859#endif
 1860
 1861#if SANITIZER_INTERCEPT_ISOC99_PRINTF
 1862#define INIT_ISOC99_PRINTF                       \
 1863  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
 1864  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
 1865  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
 1866  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
 1867  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
 1868  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
 1869  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
 1870  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
 1871#else
 1872#define INIT_ISOC99_PRINTF
 1873#endif
 1874
 1875#if SANITIZER_INTERCEPT_SETPROCTITLE
 1876INTERCEPTOR(void, setproctitle, const char *fmt, ...) {
 1877  void *ctx;
 1878  va_list ap;
 1879  va_start(ap, fmt);
 1880  COMMON_INTERCEPTOR_ENTER(ctx, setproctitle, fmt, ap);
 1881  if (common_flags()->check_printf)
 1882    printf_common(ctx, fmt, ap);
 1883  REAL(setproctitle)(fmt, ap);
 1884  va_end(ap);
 1885}
 1886#  define INIT_SETPROCTITLE COMMON_INTERCEPT_FUNCTION(setproctitle);
 1887#else
 1888#  define INIT_SETPROCTITLE
 1889#endif
 1890
 1891#if SANITIZER_INTERCEPT_IOCTL
 1892#include "sanitizer_common_interceptors_ioctl.inc"
 1893#include "sanitizer_interceptors_ioctl_netbsd.inc"
 1894INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
 1895  // We need a frame pointer, because we call into ioctl_common_[pre|post] which
 1896  // can trigger a report and we need to be able to unwind through this
 1897  // function.  On Mac in debug mode we might not have a frame pointer, because
 1898  // ioctl_common_[pre|post] doesn't get inlined here.
 1899  ENABLE_FRAME_POINTER;
 1900
 1901  void *ctx;
 1902  va_list ap;
 1903  va_start(ap, request);
 1904  void *arg = va_arg(ap, void *);
 1905  va_end(ap);
 1906  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
 1907
 1908  CHECK(ioctl_initialized);
 1909
 1910  // Note: TSan does not use common flags, and they are zero-initialized.
 1911  // This effectively disables ioctl handling in TSan.
 1912  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
 1913
 1914  // Although request is unsigned long, the rest of the interceptor uses it
 1915  // as just "unsigned" to save space, because we know that all values fit in
 1916  // "unsigned" - they are compile-time constants.
 1917
 1918  const ioctl_desc *desc = ioctl_lookup(request);
 1919  ioctl_desc decoded_desc;
 1920  if (!desc) {
 1921    VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request);
 1922    if (!ioctl_decode(request, &decoded_desc))
 1923      Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request);
 1924    else
 1925      desc = &decoded_desc;
 1926  }
 1927
 1928  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
 1929  int res = REAL(ioctl)(d, request, arg);
 1930  // FIXME: some ioctls have different return values for success and failure.
 1931  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
 1932  return res;
 1933}
 1934#define INIT_IOCTL \
 1935  ioctl_init();    \
 1936  COMMON_INTERCEPT_FUNCTION(ioctl);
 1937#else
 1938#define INIT_IOCTL
 1939#endif
 1940
 1941#if SANITIZER_POSIX
 1942UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
 1943  if (pwd) {
 1944    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
 1945    if (pwd->pw_name)
 1946      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,
 1947                                     internal_strlen(pwd->pw_name) + 1);
 1948    if (pwd->pw_passwd)
 1949      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,
 1950                                     internal_strlen(pwd->pw_passwd) + 1);
 1951#if !SANITIZER_ANDROID
 1952    if (pwd->pw_gecos)
 1953      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
 1954                                     internal_strlen(pwd->pw_gecos) + 1);
 1955#endif
 1956#if SANITIZER_APPLE || SANITIZER_FREEBSD || SANITIZER_NETBSD
 1957    if (pwd->pw_class)
 1958      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
 1959                                     internal_strlen(pwd->pw_class) + 1);
 1960#endif
 1961    if (pwd->pw_dir)
 1962      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,
 1963                                     internal_strlen(pwd->pw_dir) + 1);
 1964    if (pwd->pw_shell)
 1965      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,
 1966                                     internal_strlen(pwd->pw_shell) + 1);
 1967  }
 1968}
 1969
 1970UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {
 1971  if (grp) {
 1972    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
 1973    if (grp->gr_name)
 1974      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,
 1975                                     internal_strlen(grp->gr_name) + 1);
 1976    if (grp->gr_passwd)
 1977      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,
 1978                                     internal_strlen(grp->gr_passwd) + 1);
 1979    char **p = grp->gr_mem;
 1980    for (; *p; ++p) {
 1981      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
 1982    }
 1983    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,
 1984                                   (p - grp->gr_mem + 1) * sizeof(*p));
 1985  }
 1986}
 1987#endif  // SANITIZER_POSIX
 1988
 1989#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
 1990INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
 1991  void *ctx;
 1992  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
 1993  if (name)
 1994    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 1995  __sanitizer_passwd *res = REAL(getpwnam)(name);
 1996  unpoison_passwd(ctx, res);
 1997  return res;
 1998}
 1999INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
 2000  void *ctx;
 2001  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
 2002  __sanitizer_passwd *res = REAL(getpwuid)(uid);
 2003  unpoison_passwd(ctx, res);
 2004  return res;
 2005}
 2006INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
 2007  void *ctx;
 2008  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
 2009  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 2010  __sanitizer_group *res = REAL(getgrnam)(name);
 2011  unpoison_group(ctx, res);
 2012  return res;
 2013}
 2014INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
 2015  void *ctx;
 2016  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
 2017  __sanitizer_group *res = REAL(getgrgid)(gid);
 2018  unpoison_group(ctx, res);
 2019  return res;
 2020}
 2021#define INIT_GETPWNAM_AND_FRIENDS      \
 2022  COMMON_INTERCEPT_FUNCTION(getpwnam); \
 2023  COMMON_INTERCEPT_FUNCTION(getpwuid); \
 2024  COMMON_INTERCEPT_FUNCTION(getgrnam); \
 2025  COMMON_INTERCEPT_FUNCTION(getgrgid);
 2026#else
 2027#define INIT_GETPWNAM_AND_FRIENDS
 2028#endif
 2029
 2030#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
 2031INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
 2032            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
 2033  void *ctx;
 2034  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
 2035  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 2036  // FIXME: under ASan the call below may write to freed memory and corrupt
 2037  // its metadata. See
 2038  // https://github.com/google/sanitizers/issues/321.
 2039  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
 2040  if (!res && result)
 2041    unpoison_passwd(ctx, *result);
 2042  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 2043  return res;
 2044}
 2045INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
 2046            SIZE_T buflen, __sanitizer_passwd **result) {
 2047  void *ctx;
 2048  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
 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(getpwuid_r)(uid, pwd, buf, buflen, result);
 2053  if (!res && result)
 2054    unpoison_passwd(ctx, *result);
 2055  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 2056  return res;
 2057}
 2058INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
 2059            char *buf, SIZE_T buflen, __sanitizer_group **result) {
 2060  void *ctx;
 2061  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
 2062  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 2063  // FIXME: under ASan the call below may write to freed memory and corrupt
 2064  // its metadata. See
 2065  // https://github.com/google/sanitizers/issues/321.
 2066  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
 2067  if (!res && result)
 2068    unpoison_group(ctx, *result);
 2069  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 2070  return res;
 2071}
 2072INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
 2073            SIZE_T buflen, __sanitizer_group **result) {
 2074  void *ctx;
 2075  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
 2076  // FIXME: under ASan the call below may write to freed memory and corrupt
 2077  // its metadata. See
 2078  // https://github.com/google/sanitizers/issues/321.
 2079  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
 2080  if (!res && result)
 2081    unpoison_group(ctx, *result);
 2082  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 2083  return res;
 2084}
 2085#define INIT_GETPWNAM_R_AND_FRIENDS      \
 2086  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
 2087  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
 2088  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
 2089  COMMON_INTERCEPT_FUNCTION(getgrgid_r);
 2090#else
 2091#define INIT_GETPWNAM_R_AND_FRIENDS
 2092#endif
 2093
 2094#if SANITIZER_INTERCEPT_GETPWENT
 2095INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
 2096  void *ctx;
 2097  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
 2098  __sanitizer_passwd *res = REAL(getpwent)(dummy);
 2099  unpoison_passwd(ctx, res);
 2100  return res;
 2101}
 2102INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
 2103  void *ctx;
 2104  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
 2105  __sanitizer_group *res = REAL(getgrent)(dummy);
 2106  unpoison_group(ctx, res);
 2107  return res;
 2108}
 2109#define INIT_GETPWENT                  \
 2110  COMMON_INTERCEPT_FUNCTION(getpwent); \
 2111  COMMON_INTERCEPT_FUNCTION(getgrent);
 2112#else
 2113#define INIT_GETPWENT
 2114#endif
 2115
 2116#if SANITIZER_INTERCEPT_FGETPWENT
 2117INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
 2118  void *ctx;
 2119  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
 2120  __sanitizer_passwd *res = REAL(fgetpwent)(fp);
 2121  unpoison_passwd(ctx, res);
 2122  return res;
 2123}
 2124INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
 2125  void *ctx;
 2126  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
 2127  __sanitizer_group *res = REAL(fgetgrent)(fp);
 2128  unpoison_group(ctx, res);
 2129  return res;
 2130}
 2131#define INIT_FGETPWENT                  \
 2132  COMMON_INTERCEPT_FUNCTION(fgetpwent); \
 2133  COMMON_INTERCEPT_FUNCTION(fgetgrent);
 2134#else
 2135#define INIT_FGETPWENT
 2136#endif
 2137
 2138#if SANITIZER_INTERCEPT_GETPWENT_R
 2139INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
 2140            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
 2141  void *ctx;
 2142  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
 2143  // FIXME: under ASan the call below may write to freed memory and corrupt
 2144  // its metadata. See
 2145  // https://github.com/google/sanitizers/issues/321.
 2146  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
 2147  if (!res && pwbufp)
 2148    unpoison_passwd(ctx, *pwbufp);
 2149  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
 2150  return res;
 2151}
 2152INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
 2153            __sanitizer_group **pwbufp) {
 2154  void *ctx;
 2155  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
 2156  // FIXME: under ASan the call below may write to freed memory and corrupt
 2157  // its metadata. See
 2158  // https://github.com/google/sanitizers/issues/321.
 2159  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
 2160  if (!res && pwbufp)
 2161    unpoison_group(ctx, *pwbufp);
 2162  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
 2163  return res;
 2164}
 2165#define INIT_GETPWENT_R                   \
 2166  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
 2167  COMMON_INTERCEPT_FUNCTION(getgrent_r);
 2168#else
 2169#define INIT_GETPWENT_R
 2170#endif
 2171
 2172#if SANITIZER_INTERCEPT_FGETPWENT_R
 2173INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
 2174            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
 2175  void *ctx;
 2176  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
 2177  // FIXME: under ASan the call below may write to freed memory and corrupt
 2178  // its metadata. See
 2179  // https://github.com/google/sanitizers/issues/321.
 2180  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
 2181  if (!res && pwbufp)
 2182    unpoison_passwd(ctx, *pwbufp);
 2183  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
 2184  return res;
 2185}
 2186#define INIT_FGETPWENT_R                  \
 2187  COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
 2188#else
 2189#define INIT_FGETPWENT_R
 2190#endif
 2191
 2192#if SANITIZER_INTERCEPT_FGETGRENT_R
 2193INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
 2194            SIZE_T buflen, __sanitizer_group **pwbufp) {
 2195  void *ctx;
 2196  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
 2197  // FIXME: under ASan the call below may write to freed memory and corrupt
 2198  // its metadata. See
 2199  // https://github.com/google/sanitizers/issues/321.
 2200  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
 2201  if (!res && pwbufp)
 2202    unpoison_group(ctx, *pwbufp);
 2203  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
 2204  return res;
 2205}
 2206#define INIT_FGETGRENT_R                  \
 2207  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
 2208#else
 2209#define INIT_FGETGRENT_R
 2210#endif
 2211
 2212#if SANITIZER_INTERCEPT_SETPWENT
 2213// The only thing these interceptors do is disable any nested interceptors.
 2214// These functions may open nss modules and call uninstrumented functions from
 2215// them, and we don't want things like strlen() to trigger.
 2216INTERCEPTOR(void, setpwent, int dummy) {
 2217  void *ctx;
 2218  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
 2219  REAL(setpwent)(dummy);
 2220}
 2221INTERCEPTOR(void, endpwent, int dummy) {
 2222  void *ctx;
 2223  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
 2224  REAL(endpwent)(dummy);
 2225}
 2226INTERCEPTOR(void, setgrent, int dummy) {
 2227  void *ctx;
 2228  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
 2229  REAL(setgrent)(dummy);
 2230}
 2231INTERCEPTOR(void, endgrent, int dummy) {
 2232  void *ctx;
 2233  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
 2234  REAL(endgrent)(dummy);
 2235}
 2236#define INIT_SETPWENT                  \
 2237  COMMON_INTERCEPT_FUNCTION(setpwent); \
 2238  COMMON_INTERCEPT_FUNCTION(endpwent); \
 2239  COMMON_INTERCEPT_FUNCTION(setgrent); \
 2240  COMMON_INTERCEPT_FUNCTION(endgrent);
 2241#else
 2242#define INIT_SETPWENT
 2243#endif
 2244
 2245#if SANITIZER_INTERCEPT_CLOCK_GETTIME
 2246INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
 2247  void *ctx;
 2248  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
 2249  // FIXME: under ASan the call below may write to freed memory and corrupt
 2250  // its metadata. See
 2251  // https://github.com/google/sanitizers/issues/321.
 2252  int res = REAL(clock_getres)(clk_id, tp);
 2253  if (!res && tp) {
 2254    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
 2255  }
 2256  return res;
 2257}
 2258INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
 2259  void *ctx;
 2260  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
 2261  // FIXME: under ASan the call below may write to freed memory and corrupt
 2262  // its metadata. See
 2263  // https://github.com/google/sanitizers/issues/321.
 2264  int res = REAL(clock_gettime)(clk_id, tp);
 2265  if (!res) {
 2266    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
 2267  }
 2268  return res;
 2269}
 2270#if SANITIZER_GLIBC
 2271namespace __sanitizer {
 2272extern "C" {
 2273int real_clock_gettime(u32 clk_id, void *tp) {
 2274  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 2275    return internal_clock_gettime(clk_id, tp);
 2276  return REAL(clock_gettime)(clk_id, tp);
 2277}
 2278}  // extern "C"
 2279}  // namespace __sanitizer
 2280#endif
 2281INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
 2282  void *ctx;
 2283  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
 2284  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
 2285  return REAL(clock_settime)(clk_id, tp);
 2286}
 2287#define INIT_CLOCK_GETTIME                  \
 2288  COMMON_INTERCEPT_FUNCTION(clock_getres);  \
 2289  COMMON_INTERCEPT_FUNCTION(clock_gettime); \
 2290  COMMON_INTERCEPT_FUNCTION(clock_settime);
 2291#else
 2292#define INIT_CLOCK_GETTIME
 2293#endif
 2294
 2295#if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID
 2296INTERCEPTOR(int, clock_getcpuclockid, pid_t pid,
 2297            __sanitizer_clockid_t *clockid) {
 2298  void *ctx;
 2299  COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid);
 2300  int res = REAL(clock_getcpuclockid)(pid, clockid);
 2301  if (!res && clockid) {
 2302    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
 2303  }
 2304  return res;
 2305}
 2306
 2307INTERCEPTOR(int, pthread_getcpuclockid, uptr thread,
 2308            __sanitizer_clockid_t *clockid) {
 2309  void *ctx;
 2310  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid);
 2311  int res = REAL(pthread_getcpuclockid)(thread, clockid);
 2312  if (!res && clockid) {
 2313    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
 2314  }
 2315  return res;
 2316}
 2317
 2318#define INIT_CLOCK_GETCPUCLOCKID                   \
 2319  COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid);  \
 2320  COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid);
 2321#else
 2322#define INIT_CLOCK_GETCPUCLOCKID
 2323#endif
 2324
 2325#if SANITIZER_INTERCEPT_TIMER_CREATE
 2326INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, void *sevp,
 2327            __sanitizer_timer_t *timer) {
 2328  void *ctx;
 2329  COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timer);
 2330  int res = REAL(timer_create)(clockid, sevp, timer);
 2331  if (!res && timer) {
 2332    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timer, sizeof *timer);
 2333  }
 2334  return res;
 2335}
 2336
 2337INTERCEPTOR(int, timer_delete, __sanitizer_timer_t timer) {
 2338  void *ctx;
 2339  COMMON_INTERCEPTOR_ENTER(ctx, timer_delete, timer);
 2340  int res = REAL(timer_delete)(timer);
 2341  return res;
 2342}
 2343
 2344INTERCEPTOR(int, timer_gettime, __sanitizer_timer_t timer,
 2345            struct __sanitizer_itimerspec *curr_value) {
 2346  void *ctx;
 2347  COMMON_INTERCEPTOR_ENTER(ctx, timer_gettime, timer, curr_value);
 2348  int res = REAL(timer_gettime)(timer, curr_value);
 2349  if (!res && curr_value) {
 2350    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, sizeof *curr_value);
 2351  }
 2352  return res;
 2353}
 2354
 2355INTERCEPTOR(int, timer_settime, __sanitizer_timer_t timer, int flags,
 2356            const struct __sanitizer_itimerspec *new_value,
 2357            struct __sanitizer_itimerspec *old_value) {
 2358  void *ctx;
 2359  COMMON_INTERCEPTOR_ENTER(ctx, timer_settime, timer, flags, new_value,
 2360                           old_value);
 2361  int res = REAL(timer_settime)(timer, flags, new_value, old_value);
 2362  if (!res) {
 2363    if (new_value)
 2364      COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, sizeof *new_value);
 2365    if (old_value)
 2366      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, sizeof *old_value);
 2367  }
 2368  return res;
 2369}
 2370
 2371#  define INIT_TIMER_CREATE                                                \
 2372    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_create, "GLIBC_2.3.3");  \
 2373    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_delete, "GLIBC_2.3.3");  \
 2374    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_gettime, "GLIBC_2.3.3"); \
 2375    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_settime, "GLIBC_2.3.3");
 2376#else
 2377#  define INIT_TIMER_CREATE
 2378#endif
 2379
 2380#if SANITIZER_INTERCEPT_GETITIMER
 2381INTERCEPTOR(int, getitimer, int which, void *curr_value) {
 2382  void *ctx;
 2383  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
 2384  // FIXME: under ASan the call below may write to freed memory and corrupt
 2385  // its metadata. See
 2386  // https://github.com/google/sanitizers/issues/321.
 2387  int res = REAL(getitimer)(which, curr_value);
 2388  if (!res && curr_value) {
 2389    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
 2390  }
 2391  return res;
 2392}
 2393INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
 2394  void *ctx;
 2395  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
 2396  if (new_value) {
 2397    // itimerval can contain padding that may be legitimately uninitialized
 2398    const struct __sanitizer_itimerval *nv =
 2399        (const struct __sanitizer_itimerval *)new_value;
 2400    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
 2401                                  sizeof(__sanitizer_time_t));
 2402    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
 2403                                  sizeof(__sanitizer_suseconds_t));
 2404    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
 2405                                  sizeof(__sanitizer_time_t));
 2406    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
 2407                                  sizeof(__sanitizer_suseconds_t));
 2408  }
 2409  // FIXME: under ASan the call below may write to freed memory and corrupt
 2410  // its metadata. See
 2411  // https://github.com/google/sanitizers/issues/321.
 2412  int res = REAL(setitimer)(which, new_value, old_value);
 2413  if (!res && old_value) {
 2414    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
 2415  }
 2416  return res;
 2417}
 2418#define INIT_GETITIMER                  \
 2419  COMMON_INTERCEPT_FUNCTION(getitimer); \
 2420  COMMON_INTERCEPT_FUNCTION(setitimer);
 2421#else
 2422#define INIT_GETITIMER
 2423#endif
 2424
 2425#if SANITIZER_INTERCEPT_TIMESPEC_GET
 2426INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {
 2427  void *ctx;
 2428  COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, ts, base);
 2429  // We don't yet know if ts is addressable, so we use our own scratch buffer
 2430  struct __sanitizer_timespec ts_local;
 2431  int res = REAL(timespec_get)(&ts_local, base);
 2432  if (res) {
 2433    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ts,
 2434                                   sizeof(struct __sanitizer_timespec));
 2435    internal_memcpy(ts, &ts_local, sizeof(struct __sanitizer_timespec));
 2436  }
 2437  return res;
 2438}
 2439#  define INIT_TIMESPEC_GET COMMON_INTERCEPT_FUNCTION(timespec_get);
 2440#else
 2441#  define INIT_TIMESPEC_GET
 2442#endif
 2443
 2444#if SANITIZER_INTERCEPT_GLOB
 2445static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
 2446  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
 2447  // +1 for NULL pointer at the end.
 2448  if (pglob->gl_pathv)
 2449    COMMON_INTERCEPTOR_WRITE_RANGE(
 2450        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
 2451  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
 2452    char *p = pglob->gl_pathv[i];
 2453    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);
 2454  }
 2455}
 2456
 2457#if SANITIZER_SOLARIS
 2458INTERCEPTOR(int, glob, const char *pattern, int flags,
 2459            int (*errfunc)(const char *epath, int eerrno),
 2460            __sanitizer_glob_t *pglob) {
 2461  void *ctx;
 2462  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
 2463  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
 2464  int res = REAL(glob)(pattern, flags, errfunc, pglob);
 2465  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
 2466  return res;
 2467}
 2468#else
 2469static THREADLOCAL __sanitizer_glob_t *pglob_copy;
 2470
 2471static void wrapped_gl_closedir(void *dir) {
 2472  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 2473  pglob_copy->gl_closedir(dir);
 2474}
 2475
 2476static void *wrapped_gl_readdir(void *dir) {
 2477  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 2478  return pglob_copy->gl_readdir(dir);
 2479}
 2480
 2481static void *wrapped_gl_opendir(const char *s) {
 2482  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 2483  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
 2484  return pglob_copy->gl_opendir(s);
 2485}
 2486
 2487static int wrapped_gl_lstat(const char *s, void *st) {
 2488  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
 2489  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
 2490  return pglob_copy->gl_lstat(s, st);
 2491}
 2492
 2493static int wrapped_gl_stat(const char *s, void *st) {
 2494  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
 2495  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
 2496  return pglob_copy->gl_stat(s, st);
 2497}
 2498
 2499static const __sanitizer_glob_t kGlobCopy = {
 2500      0,                  0,                   0,
 2501      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
 2502      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
 2503
 2504INTERCEPTOR(int, glob, const char *pattern, int flags,
 2505            int (*errfunc)(const char *epath, int eerrno),
 2506            __sanitizer_glob_t *pglob) {
 2507  void *ctx;
 2508  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
 2509  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
 2510  __sanitizer_glob_t glob_copy;
 2511  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
 2512  if (flags & glob_altdirfunc) {
 2513    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
 2514    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
 2515    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
 2516    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
 2517    Swap(pglob->gl_stat, glob_copy.gl_stat);
 2518    pglob_copy = &glob_copy;
 2519  }
 2520  int res = REAL(glob)(pattern, flags, errfunc, pglob);
 2521  if (flags & glob_altdirfunc) {
 2522    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
 2523    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
 2524    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
 2525    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
 2526    Swap(pglob->gl_stat, glob_copy.gl_stat);
 2527  }
 2528  pglob_copy = 0;
 2529  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
 2530  return res;
 2531}
 2532#endif  // SANITIZER_SOLARIS
 2533#define INIT_GLOB                  \
 2534  COMMON_INTERCEPT_FUNCTION(glob);
 2535#else  // SANITIZER_INTERCEPT_GLOB
 2536#define INIT_GLOB
 2537#endif  // SANITIZER_INTERCEPT_GLOB
 2538
 2539#if SANITIZER_INTERCEPT_GLOB64
 2540INTERCEPTOR(int, glob64, const char *pattern, int flags,
 2541            int (*errfunc)(const char *epath, int eerrno),
 2542            __sanitizer_glob_t *pglob) {
 2543  void *ctx;
 2544  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
 2545  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
 2546  __sanitizer_glob_t glob_copy;
 2547  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
 2548  if (flags & glob_altdirfunc) {
 2549    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
 2550    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
 2551    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
 2552    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
 2553    Swap(pglob->gl_stat, glob_copy.gl_stat);
 2554    pglob_copy = &glob_copy;
 2555  }
 2556  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
 2557  if (flags & glob_altdirfunc) {
 2558    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
 2559    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
 2560    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
 2561    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
 2562    Swap(pglob->gl_stat, glob_copy.gl_stat);
 2563  }
 2564  pglob_copy = 0;
 2565  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
 2566  return res;
 2567}
 2568#define INIT_GLOB64                \
 2569  COMMON_INTERCEPT_FUNCTION(glob64);
 2570#else  // SANITIZER_INTERCEPT_GLOB64
 2571#define INIT_GLOB64
 2572#endif  // SANITIZER_INTERCEPT_GLOB64
 2573
 2574#if SANITIZER_INTERCEPT___B64_TO
 2575INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,
 2576            char *target, SIZE_T targsize) {
 2577  void *ctx;
 2578  COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);
 2579  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);
 2580  int res = REAL(__b64_ntop)(src, srclength, target, targsize);
 2581  if (res >= 0)
 2582    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);
 2583  return res;
 2584}
 2585INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {
 2586  void *ctx;
 2587  COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);
 2588  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 2589  int res = REAL(__b64_pton)(src, target, targsize);
 2590  if (res >= 0)
 2591    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);
 2592  return res;
 2593}
 2594#define INIT___B64_TO                      \
 2595    COMMON_INTERCEPT_FUNCTION(__b64_ntop); \
 2596    COMMON_INTERCEPT_FUNCTION(__b64_pton);
 2597#else  // SANITIZER_INTERCEPT___B64_TO
 2598#define INIT___B64_TO
 2599#endif  // SANITIZER_INTERCEPT___B64_TO
 2600
 2601#if SANITIZER_INTERCEPT_DN_COMP_EXPAND
 2602#  if __GLIBC_PREREQ(2, 34)
 2603// Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf
 2604#    define DN_COMP_INTERCEPTOR_NAME dn_comp
 2605#    define DN_EXPAND_INTERCEPTOR_NAME dn_expand
 2606#  else
 2607#    define DN_COMP_INTERCEPTOR_NAME __dn_comp
 2608#    define DN_EXPAND_INTERCEPTOR_NAME __dn_expand
 2609#  endif
 2610INTERCEPTOR(int, DN_COMP_INTERCEPTOR_NAME, unsigned char *exp_dn,
 2611            unsigned char *comp_dn, int length, unsigned char **dnptrs,
 2612            unsigned char **lastdnptr) {
 2613  void *ctx;
 2614  COMMON_INTERCEPTOR_ENTER(ctx, DN_COMP_INTERCEPTOR_NAME, exp_dn, comp_dn,
 2615                           length, dnptrs, lastdnptr);
 2616  int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs,
 2617                                           lastdnptr);
 2618  if (res >= 0) {
 2619    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, comp_dn, res);
 2620    if (dnptrs && lastdnptr) {
 2621      unsigned char **p = dnptrs;
 2622      for (; p != lastdnptr && *p; ++p)
 2623        ;
 2624      if (p != lastdnptr)
 2625        ++p;
 2626      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dnptrs, (p - dnptrs) * sizeof(*p));
 2627    }
 2628  }
 2629  return res;
 2630}
 2631INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base,
 2632            unsigned char const *end, unsigned char const *src, char *dest,
 2633            int space) {
 2634  void *ctx;
 2635  COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src,
 2636                           dest, space);
 2637  // TODO: add read check if __dn_comp intercept added
 2638  int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);
 2639  if (res >= 0)
 2640    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1);
 2641  return res;
 2642}
 2643#  define INIT_DN_COMP_EXPAND                            \
 2644    COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \
 2645    COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME);
 2646#else  // SANITIZER_INTERCEPT_DN_COMP_EXPAND
 2647#  define INIT_DN_COMP_EXPAND
 2648#endif  // SANITIZER_INTERCEPT_DN_COMP_EXPAND
 2649
 2650#if SANITIZER_INTERCEPT_POSIX_SPAWN
 2651
 2652template <class RealSpawnPtr>
 2653static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,
 2654                          const char *file_or_path, const void *file_actions,
 2655                          const void *attrp, char *const argv[],
 2656                          char *const envp[]) {
 2657  COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,
 2658                                internal_strlen(file_or_path) + 1);
 2659  if (argv) {
 2660    for (char *const *s = argv; ; ++s) {
 2661      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
 2662      if (!*s) break;
 2663      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
 2664    }
 2665  }
 2666  if (envp) {
 2667    for (char *const *s = envp; ; ++s) {
 2668      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
 2669      if (!*s) break;
 2670      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
 2671    }
 2672  }
 2673  int res =
 2674      real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);
 2675  if (res == 0)
 2676    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));
 2677  return res;
 2678}
 2679INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,
 2680            const void *file_actions, const void *attrp, char *const argv[],
 2681            char *const envp[]) {
 2682  void *ctx;
 2683  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,
 2684                           argv, envp);
 2685  return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,
 2686                        argv, envp);
 2687}
 2688INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,
 2689            const void *file_actions, const void *attrp, char *const argv[],
 2690            char *const envp[]) {
 2691  void *ctx;
 2692  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,
 2693                           argv, envp);
 2694  return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,
 2695                        argv, envp);
 2696}
 2697#  define INIT_POSIX_SPAWN                  \
 2698    COMMON_INTERCEPT_FUNCTION(posix_spawn); \
 2699    COMMON_INTERCEPT_FUNCTION(posix_spawnp);
 2700#else  // SANITIZER_INTERCEPT_POSIX_SPAWN
 2701#  define INIT_POSIX_SPAWN
 2702#endif  // SANITIZER_INTERCEPT_POSIX_SPAWN
 2703
 2704#if SANITIZER_INTERCEPT_WAIT
 2705// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
 2706// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
 2707// details.
 2708INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
 2709  void *ctx;
 2710  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
 2711  // FIXME: under ASan the call below may write to freed memory and corrupt
 2712  // its metadata. See
 2713  // https://github.com/google/sanitizers/issues/321.
 2714  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait)(status);
 2715  if (res != -1 && status)
 2716    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
 2717  return res;
 2718}
 2719// On FreeBSD id_t is always 64-bit wide.
 2720#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
 2721INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
 2722                        int options) {
 2723#else
 2724INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
 2725                        int options) {
 2726#endif
 2727  void *ctx;
 2728  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
 2729  // FIXME: under ASan the call below may write to freed memory and corrupt
 2730  // its metadata. See
 2731  // https://github.com/google/sanitizers/issues/321.
 2732  int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitid)(idtype, id, infop, options);
 2733  if (res != -1 && infop)
 2734    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
 2735  return res;
 2736}
 2737INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
 2738  void *ctx;
 2739  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
 2740  // FIXME: under ASan the call below may write to freed memory and corrupt
 2741  // its metadata. See
 2742  // https://github.com/google/sanitizers/issues/321.
 2743  int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitpid)(pid, status, options);
 2744  if (res != -1 && status)
 2745    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
 2746  return res;
 2747}
 2748INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
 2749  void *ctx;
 2750  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
 2751  // FIXME: under ASan the call below may write to freed memory and corrupt
 2752  // its metadata. See
 2753  // https://github.com/google/sanitizers/issues/321.
 2754  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait3)(status, options, rusage);
 2755  if (res != -1) {
 2756    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
 2757    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
 2758  }
 2759  return res;
 2760}
 2761#if SANITIZER_ANDROID
 2762INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
 2763  void *ctx;
 2764  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
 2765  // FIXME: under ASan the call below may write to freed memory and corrupt
 2766  // its metadata. See
 2767  // https://github.com/google/sanitizers/issues/321.
 2768  int res =
 2769      COMMON_INTERCEPTOR_BLOCK_REAL(__wait4)(pid, status, options, rusage);
 2770  if (res != -1) {
 2771    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
 2772    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
 2773  }
 2774  return res;
 2775}
 2776#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
 2777#else
 2778INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
 2779  void *ctx;
 2780  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
 2781  // FIXME: under ASan the call below may write to freed memory and corrupt
 2782  // its metadata. See
 2783  // https://github.com/google/sanitizers/issues/321.
 2784  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait4)(pid, status, options, rusage);
 2785  if (res != -1) {
 2786    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
 2787    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
 2788  }
 2789  return res;
 2790}
 2791#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
 2792#endif  // SANITIZER_ANDROID
 2793#define INIT_WAIT                     \
 2794  COMMON_INTERCEPT_FUNCTION(wait);    \
 2795  COMMON_INTERCEPT_FUNCTION(waitid);  \
 2796  COMMON_INTERCEPT_FUNCTION(waitpid); \
 2797  COMMON_INTERCEPT_FUNCTION(wait3);
 2798#else
 2799#define INIT_WAIT
 2800#define INIT_WAIT4
 2801#endif
 2802
 2803#if SANITIZER_INTERCEPT_INET
 2804INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
 2805  void *ctx;
 2806  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
 2807  uptr sz = __sanitizer_in_addr_sz(af);
 2808  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
 2809  // FIXME: figure out read size based on the address family.
 2810  // FIXME: under ASan the call below may write to freed memory and corrupt
 2811  // its metadata. See
 2812  // https://github.com/google/sanitizers/issues/321.
 2813  char *res = REAL(inet_ntop)(af, src, dst, size);
 2814  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 2815  return res;
 2816}
 2817INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
 2818  void *ctx;
 2819  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
 2820  COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
 2821  // FIXME: figure out read size based on the address family.
 2822  // FIXME: under ASan the call below may write to freed memory and corrupt
 2823  // its metadata. See
 2824  // https://github.com/google/sanitizers/issues/321.
 2825  int res = REAL(inet_pton)(af, src, dst);
 2826  if (res == 1) {
 2827    uptr sz = __sanitizer_in_addr_sz(af);
 2828    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
 2829  }
 2830  return res;
 2831}
 2832#define INIT_INET                       \
 2833  COMMON_INTERCEPT_FUNCTION(inet_ntop); \
 2834  COMMON_INTERCEPT_FUNCTION(inet_pton);
 2835#else
 2836#define INIT_INET
 2837#endif
 2838
 2839#if SANITIZER_INTERCEPT_INET
 2840INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
 2841  void *ctx;
 2842  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
 2843  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1);
 2844  // FIXME: under ASan the call below may write to freed memory and corrupt
 2845  // its metadata. See
 2846  // https://github.com/google/sanitizers/issues/321.
 2847  int res = REAL(inet_aton)(cp, dst);
 2848  if (res != 0) {
 2849    uptr sz = __sanitizer_in_addr_sz(af_inet);
 2850    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
 2851  }
 2852  return res;
 2853}
 2854#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
 2855#else
 2856#define INIT_INET_ATON
 2857#endif
 2858
 2859#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
 2860INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
 2861  void *ctx;
 2862  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
 2863  // FIXME: under ASan the call below may write to freed memory and corrupt
 2864  // its metadata. See
 2865  // https://github.com/google/sanitizers/issues/321.
 2866  int res = REAL(pthread_getschedparam)(thread, policy, param);
 2867  if (res == 0) {
 2868    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
 2869    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
 2870  }
 2871  return res;
 2872}
 2873#define INIT_PTHREAD_GETSCHEDPARAM \
 2874  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
 2875#else
 2876#define INIT_PTHREAD_GETSCHEDPARAM
 2877#endif
 2878
 2879#if SANITIZER_INTERCEPT_GETADDRINFO
 2880INTERCEPTOR(int, getaddrinfo, char *node, char *service,
 2881            struct __sanitizer_addrinfo *hints,
 2882            struct __sanitizer_addrinfo **out) {
 2883  void *ctx;
 2884  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
 2885  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1);
 2886  if (service)
 2887    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1);
 2888  if (hints)
 2889    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
 2890  // FIXME: under ASan the call below may write to freed memory and corrupt
 2891  // its metadata. See
 2892  // https://github.com/google/sanitizers/issues/321.
 2893  int res = REAL(getaddrinfo)(node, service, hints, out);
 2894  if (res == 0 && out) {
 2895    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
 2896    struct __sanitizer_addrinfo *p = *out;
 2897    while (p) {
 2898      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 2899      if (p->ai_addr)
 2900        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
 2901      if (p->ai_canonname)
 2902        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
 2903                                       internal_strlen(p->ai_canonname) + 1);
 2904      p = p->ai_next;
 2905    }
 2906  }
 2907  return res;
 2908}
 2909#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
 2910#else
 2911#define INIT_GETADDRINFO
 2912#endif
 2913
 2914#if SANITIZER_INTERCEPT_GETNAMEINFO
 2915INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
 2916            unsigned hostlen, char *serv, unsigned servlen, int flags) {
 2917  void *ctx;
 2918  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
 2919                           serv, servlen, flags);
 2920  // FIXME: consider adding READ_RANGE(sockaddr, salen)
 2921  // There is padding in in_addr that may make this too noisy
 2922  // FIXME: under ASan the call below may write to freed memory and corrupt
 2923  // its metadata. See
 2924  // https://github.com/google/sanitizers/issues/321.
 2925  int res =
 2926      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
 2927  if (res == 0) {
 2928    if (host && hostlen)
 2929      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1);
 2930    if (serv && servlen)
 2931      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1);
 2932  }
 2933  return res;
 2934}
 2935#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
 2936#else
 2937#define INIT_GETNAMEINFO
 2938#endif
 2939
 2940#if SANITIZER_INTERCEPT_GETSOCKNAME
 2941INTERCEPTOR(int, getsockname, int sock_fd, void *addr, unsigned *addrlen) {
 2942  void *ctx;
 2943  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
 2944  unsigned addr_sz;
 2945  if (addrlen) {
 2946    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
 2947    addr_sz = *addrlen;
 2948  }
 2949  // FIXME: under ASan the call below may write to freed memory and corrupt
 2950  // its metadata. See
 2951  // https://github.com/google/sanitizers/issues/321.
 2952  int res = REAL(getsockname)(sock_fd, addr, addrlen);
 2953  if (!res && addr && addrlen) {
 2954    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
 2955  }
 2956  return res;
 2957}
 2958#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
 2959#else
 2960#define INIT_GETSOCKNAME
 2961#endif
 2962
 2963#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
 2964static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
 2965  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
 2966  if (h->h_name)
 2967    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1);
 2968  char **p = h->h_aliases;
 2969  while (*p) {
 2970    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
 2971    ++p;
 2972  }
 2973  COMMON_INTERCEPTOR_WRITE_RANGE(
 2974      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
 2975  p = h->h_addr_list;
 2976  while (*p) {
 2977    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
 2978    ++p;
 2979  }
 2980  COMMON_INTERCEPTOR_WRITE_RANGE(
 2981      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
 2982}
 2983#endif
 2984
 2985#if SANITIZER_INTERCEPT_GETHOSTBYNAME
 2986INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
 2987  void *ctx;
 2988  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
 2989  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
 2990  if (res) write_hostent(ctx, res);
 2991  return res;
 2992}
 2993
 2994INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
 2995            int type) {
 2996  void *ctx;
 2997  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
 2998  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
 2999  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
 3000  if (res) write_hostent(ctx, res);
 3001  return res;
 3002}
 3003
 3004INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
 3005  void *ctx;
 3006  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
 3007  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
 3008  if (res) write_hostent(ctx, res);
 3009  return res;
 3010}
 3011#define INIT_GETHOSTBYNAME                  \
 3012  COMMON_INTERCEPT_FUNCTION(gethostent);    \
 3013  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
 3014  COMMON_INTERCEPT_FUNCTION(gethostbyname);
 3015#else
 3016#define INIT_GETHOSTBYNAME
 3017#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME
 3018
 3019#if SANITIZER_INTERCEPT_GETHOSTBYNAME2
 3020INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
 3021  void *ctx;
 3022  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
 3023  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
 3024  if (res) write_hostent(ctx, res);
 3025  return res;
 3026}
 3027#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
 3028#else
 3029#define INIT_GETHOSTBYNAME2
 3030#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME2
 3031
 3032#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
 3033INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
 3034            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
 3035            int *h_errnop) {
 3036  void *ctx;
 3037  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
 3038                           h_errnop);
 3039  // FIXME: under ASan the call below may write to freed memory and corrupt
 3040  // its metadata. See
 3041  // https://github.com/google/sanitizers/issues/321.
 3042  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
 3043  if (result) {
 3044    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3045    if (res == 0 && *result) write_hostent(ctx, *result);
 3046  }
 3047  if (h_errnop)
 3048    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
 3049  return res;
 3050}
 3051#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
 3052#else
 3053#define INIT_GETHOSTBYNAME_R
 3054#endif
 3055
 3056#if SANITIZER_INTERCEPT_GETHOSTENT_R
 3057INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
 3058            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
 3059  void *ctx;
 3060  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
 3061                           h_errnop);
 3062  // FIXME: under ASan the call below may write to freed memory and corrupt
 3063  // its metadata. See
 3064  // https://github.com/google/sanitizers/issues/321.
 3065  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
 3066  if (result) {
 3067    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3068    if (res == 0 && *result) write_hostent(ctx, *result);
 3069  }
 3070  if (h_errnop)
 3071    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
 3072  return res;
 3073}
 3074#define INIT_GETHOSTENT_R                  \
 3075  COMMON_INTERCEPT_FUNCTION(gethostent_r);
 3076#else
 3077#define INIT_GETHOSTENT_R
 3078#endif
 3079
 3080#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
 3081INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
 3082            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
 3083            __sanitizer_hostent **result, int *h_errnop) {
 3084  void *ctx;
 3085  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
 3086                           buflen, result, h_errnop);
 3087  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
 3088  // FIXME: under ASan the call below may write to freed memory and corrupt
 3089  // its metadata. See
 3090  // https://github.com/google/sanitizers/issues/321.
 3091  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
 3092                                  h_errnop);
 3093  if (result) {
 3094    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3095    if (res == 0 && *result) write_hostent(ctx, *result);
 3096  }
 3097  if (h_errnop)
 3098    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
 3099  return res;
 3100}
 3101#define INIT_GETHOSTBYADDR_R                  \
 3102  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
 3103#else
 3104#define INIT_GETHOSTBYADDR_R
 3105#endif
 3106
 3107#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
 3108INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
 3109            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
 3110            __sanitizer_hostent **result, int *h_errnop) {
 3111  void *ctx;
 3112  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
 3113                           result, h_errnop);
 3114  // FIXME: under ASan the call below may write to freed memory and corrupt
 3115  // its metadata. See
 3116  // https://github.com/google/sanitizers/issues/321.
 3117  int res =
 3118      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
 3119  if (result) {
 3120    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3121    if (res == 0 && *result) write_hostent(ctx, *result);
 3122  }
 3123  if (h_errnop)
 3124    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
 3125  return res;
 3126}
 3127#define INIT_GETHOSTBYNAME2_R                  \
 3128  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
 3129#else
 3130#define INIT_GETHOSTBYNAME2_R
 3131#endif
 3132
 3133#if SANITIZER_INTERCEPT_GETSOCKOPT
 3134INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
 3135            int *optlen) {
 3136  void *ctx;
 3137  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
 3138                           optlen);
 3139  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
 3140  // FIXME: under ASan the call below may write to freed memory and corrupt
 3141  // its metadata. See
 3142  // https://github.com/google/sanitizers/issues/321.
 3143  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
 3144  if (res == 0)
 3145    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
 3146  return res;
 3147}
 3148#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
 3149#else
 3150#define INIT_GETSOCKOPT
 3151#endif
 3152
 3153#if SANITIZER_INTERCEPT_ACCEPT
 3154INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
 3155  void *ctx;
 3156  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
 3157  unsigned addrlen0 = 0;
 3158  if (addrlen) {
 3159    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
 3160    addrlen0 = *addrlen;
 3161  }
 3162  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept)(fd, addr, addrlen);
 3163  if (fd2 >= 0) {
 3164    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
 3165    if (addr && addrlen)
 3166      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
 3167  }
 3168  return fd2;
 3169}
 3170#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
 3171#else
 3172#define INIT_ACCEPT
 3173#endif
 3174
 3175#if SANITIZER_INTERCEPT_ACCEPT4
 3176INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
 3177  void *ctx;
 3178  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
 3179  unsigned addrlen0 = 0;
 3180  if (addrlen) {
 3181    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
 3182    addrlen0 = *addrlen;
 3183  }
 3184  // FIXME: under ASan the call below may write to freed memory and corrupt
 3185  // its metadata. See
 3186  // https://github.com/google/sanitizers/issues/321.
 3187  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept4)(fd, addr, addrlen, f);
 3188  if (fd2 >= 0) {
 3189    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
 3190    if (addr && addrlen)
 3191      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
 3192  }
 3193  return fd2;
 3194}
 3195#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
 3196#else
 3197#define INIT_ACCEPT4
 3198#endif
 3199
 3200#if SANITIZER_INTERCEPT_PACCEPT
 3201INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,
 3202            __sanitizer_sigset_t *set, int f) {
 3203  void *ctx;
 3204  COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);
 3205  unsigned addrlen0 = 0;
 3206  if (addrlen) {
 3207    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
 3208    addrlen0 = *addrlen;
 3209  }
 3210  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 3211  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(paccept)(fd, addr, addrlen, set, f);
 3212  if (fd2 >= 0) {
 3213    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
 3214    if (addr && addrlen)
 3215      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
 3216  }
 3217  return fd2;
 3218}
 3219#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);
 3220#else
 3221#define INIT_PACCEPT
 3222#endif
 3223
 3224#if SANITIZER_INTERCEPT_MODF
 3225INTERCEPTOR(double, modf, double x, double *iptr) {
 3226  void *ctx;
 3227  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
 3228  // FIXME: under ASan the call below may write to freed memory and corrupt
 3229  // its metadata. See
 3230  // https://github.com/google/sanitizers/issues/321.
 3231  double res = REAL(modf)(x, iptr);
 3232  if (iptr) {
 3233    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
 3234  }
 3235  return res;
 3236}
 3237INTERCEPTOR(float, modff, float x, float *iptr) {
 3238  void *ctx;
 3239  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
 3240  // FIXME: under ASan the call below may write to freed memory and corrupt
 3241  // its metadata. See
 3242  // https://github.com/google/sanitizers/issues/321.
 3243  float res = REAL(modff)(x, iptr);
 3244  if (iptr) {
 3245    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
 3246  }
 3247  return res;
 3248}
 3249INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
 3250  void *ctx;
 3251  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
 3252  // FIXME: under ASan the call below may write to freed memory and corrupt
 3253  // its metadata. See
 3254  // https://github.com/google/sanitizers/issues/321.
 3255  long double res = REAL(modfl)(x, iptr);
 3256  if (iptr) {
 3257    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
 3258  }
 3259  return res;
 3260}
 3261#define INIT_MODF                   \
 3262  COMMON_INTERCEPT_FUNCTION(modf);  \
 3263  COMMON_INTERCEPT_FUNCTION(modff); \
 3264  COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
 3265#else
 3266#define INIT_MODF
 3267#endif
 3268
 3269#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG
 3270static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
 3271                         SSIZE_T maxlen) {
 3272  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
 3273  if (msg->msg_name && msg->msg_namelen)
 3274    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
 3275  if (msg->msg_iov && msg->msg_iovlen)
 3276    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
 3277                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
 3278  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
 3279  if (msg->msg_control && msg->msg_controllen)
 3280    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
 3281}
 3282#endif
 3283
 3284#if SANITIZER_INTERCEPT_RECVMSG
 3285INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
 3286            int flags) {
 3287  void *ctx;
 3288  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
 3289  // FIXME: under ASan the call below may write to freed memory and corrupt
 3290  // its metadata. See
 3291  // https://github.com/google/sanitizers/issues/321.
 3292  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvmsg)(fd, msg, flags);
 3293  if (res >= 0) {
 3294    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 3295    if (msg) {
 3296      write_msghdr(ctx, msg, res);
 3297      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
 3298    }
 3299  }
 3300  return res;
 3301}
 3302#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
 3303#else
 3304#define INIT_RECVMSG
 3305#endif
 3306
 3307#if SANITIZER_INTERCEPT_RECVMMSG
 3308INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
 3309            unsigned int vlen, int flags, void *timeout) {
 3310  void *ctx;
 3311  COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);
 3312  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
 3313  int res =
 3314      COMMON_INTERCEPTOR_BLOCK_REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);
 3315  if (res >= 0) {
 3316    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 3317    for (int i = 0; i < res; ++i) {
 3318      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
 3319                                     sizeof(msgvec[i].msg_len));
 3320      write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
 3321      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);
 3322    }
 3323  }
 3324  return res;
 3325}
 3326#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);
 3327#else
 3328#define INIT_RECVMMSG
 3329#endif
 3330
 3331#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG
 3332static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
 3333  const unsigned kCmsgDataOffset =
 3334      RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
 3335
 3336  char *p = (char *)control;
 3337  char *const control_end = p + controllen;
 3338  while (true) {
 3339    if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
 3340    __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
 3341    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
 3342
 3343    if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
 3344
 3345    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
 3346                                  sizeof(cmsg->cmsg_level));
 3347    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
 3348                                  sizeof(cmsg->cmsg_type));
 3349
 3350    if (cmsg->cmsg_len > kCmsgDataOffset) {
 3351      char *data = p + kCmsgDataOffset;
 3352      unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
 3353      if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
 3354    }
 3355
 3356    p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
 3357  }
 3358}
 3359
 3360static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
 3361                        SSIZE_T maxlen) {
 3362#define R(f) \
 3363  COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
 3364  R(name);
 3365  R(namelen);
 3366  R(iov);
 3367  R(iovlen);
 3368  R(control);
 3369  R(controllen);
 3370  R(flags);
 3371#undef R
 3372  if (msg->msg_name && msg->msg_namelen)
 3373    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
 3374  if (msg->msg_iov && msg->msg_iovlen)
 3375    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
 3376                                  sizeof(*msg->msg_iov) * msg->msg_iovlen);
 3377  read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
 3378  if (msg->msg_control && msg->msg_controllen)
 3379    read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
 3380}
 3381#endif
 3382
 3383#if SANITIZER_INTERCEPT_SENDMSG
 3384INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
 3385            int flags) {
 3386  void *ctx;
 3387  COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
 3388  if (fd >= 0) {
 3389    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 3390    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 3391  }
 3392  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmsg)(fd, msg, flags);
 3393  if (common_flags()->intercept_send && res >= 0 && msg)
 3394    read_msghdr(ctx, msg, res);
 3395  return res;
 3396}
 3397#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
 3398#else
 3399#define INIT_SENDMSG
 3400#endif
 3401
 3402#if SANITIZER_INTERCEPT_SENDMMSG
 3403INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
 3404            unsigned vlen, int flags) {
 3405  void *ctx;
 3406  COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);
 3407  if (fd >= 0) {
 3408    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 3409    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 3410  }
 3411  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmmsg)(fd, msgvec, vlen, flags);
 3412  if (res >= 0 && msgvec) {
 3413    for (int i = 0; i < res; ++i) {
 3414      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
 3415                                     sizeof(msgvec[i].msg_len));
 3416      if (common_flags()->intercept_send)
 3417        read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
 3418    }
 3419  }
 3420  return res;
 3421}
 3422#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);
 3423#else
 3424#define INIT_SENDMMSG
 3425#endif
 3426
 3427#if SANITIZER_INTERCEPT_SYSMSG
 3428INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz,
 3429            int msgflg) {
 3430  void *ctx;
 3431  COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg);
 3432  if (msgp)
 3433    COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz);
 3434  int res = COMMON_INTERCEPTOR_BLOCK_REAL(msgsnd)(msqid, msgp, msgsz, msgflg);
 3435  return res;
 3436}
 3437
 3438INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz,
 3439            long msgtyp, int msgflg) {
 3440  void *ctx;
 3441  COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg);
 3442  SSIZE_T len =
 3443      COMMON_INTERCEPTOR_BLOCK_REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg);
 3444  if (len != -1)
 3445    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len);
 3446  return len;
 3447}
 3448
 3449#define INIT_SYSMSG                  \
 3450  COMMON_INTERCEPT_FUNCTION(msgsnd); \
 3451  COMMON_INTERCEPT_FUNCTION(msgrcv);
 3452#else
 3453#define INIT_SYSMSG
 3454#endif
 3455
 3456#if SANITIZER_INTERCEPT_GETPEERNAME
 3457INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
 3458  void *ctx;
 3459  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
 3460  unsigned addr_sz;
 3461  if (addrlen) {
 3462    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
 3463    addr_sz = *addrlen;
 3464  }
 3465  // FIXME: under ASan the call below may write to freed memory and corrupt
 3466  // its metadata. See
 3467  // https://github.com/google/sanitizers/issues/321.
 3468  int res = REAL(getpeername)(sockfd, addr, addrlen);
 3469  if (!res && addr && addrlen) {
 3470    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
 3471  }
 3472  return res;
 3473}
 3474#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
 3475#else
 3476#define INIT_GETPEERNAME
 3477#endif
 3478
 3479#if SANITIZER_INTERCEPT_SYSINFO
 3480INTERCEPTOR(int, sysinfo, void *info) {
 3481  void *ctx;
 3482  // FIXME: under ASan the call below may write to freed memory and corrupt
 3483  // its metadata. See
 3484  // https://github.com/google/sanitizers/issues/321.
 3485  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
 3486  int res = REAL(sysinfo)(info);
 3487  if (!res && info)
 3488    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
 3489  return res;
 3490}
 3491#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
 3492#else
 3493#define INIT_SYSINFO
 3494#endif
 3495
 3496#if SANITIZER_INTERCEPT_READDIR
 3497INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
 3498  void *ctx;
 3499  COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
 3500  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 3501  __sanitizer_dirent *res = REAL(opendir)(path);
 3502  if (res)
 3503    COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
 3504  return res;
 3505}
 3506
 3507INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
 3508  void *ctx;
 3509  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
 3510  // FIXME: under ASan the call below may write to freed memory and corrupt
 3511  // its metadata. See
 3512  // https://github.com/google/sanitizers/issues/321.
 3513  __sanitizer_dirent *res = REAL(readdir)(dirp);
 3514  if (res)
 3515    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));
 3516  return res;
 3517}
 3518
 3519INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
 3520            __sanitizer_dirent **result) {
 3521  void *ctx;
 3522  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
 3523  // FIXME: under ASan the call below may write to freed memory and corrupt
 3524  // its metadata. See
 3525  // https://github.com/google/sanitizers/issues/321.
 3526  int res = REAL(readdir_r)(dirp, entry, result);
 3527  if (!res) {
 3528    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3529    if (*result)
 3530      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));
 3531  }
 3532  return res;
 3533}
 3534
 3535#define INIT_READDIR                  \
 3536  COMMON_INTERCEPT_FUNCTION(opendir); \
 3537  COMMON_INTERCEPT_FUNCTION(readdir); \
 3538  COMMON_INTERCEPT_FUNCTION(readdir_r);
 3539#else
 3540#define INIT_READDIR
 3541#endif
 3542
 3543#if SANITIZER_INTERCEPT_READDIR64
 3544INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
 3545  void *ctx;
 3546  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
 3547  // FIXME: under ASan the call below may write to freed memory and corrupt
 3548  // its metadata. See
 3549  // https://github.com/google/sanitizers/issues/321.
 3550  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
 3551  if (res)
 3552    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));
 3553  return res;
 3554}
 3555
 3556INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
 3557            __sanitizer_dirent64 **result) {
 3558  void *ctx;
 3559  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
 3560  // FIXME: under ASan the call below may write to freed memory and corrupt
 3561  // its metadata. See
 3562  // https://github.com/google/sanitizers/issues/321.
 3563  int res = REAL(readdir64_r)(dirp, entry, result);
 3564  if (!res) {
 3565    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 3566    if (*result)
 3567      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));
 3568  }
 3569  return res;
 3570}
 3571#define INIT_READDIR64                  \
 3572  COMMON_INTERCEPT_FUNCTION(readdir64); \
 3573  COMMON_INTERCEPT_FUNCTION(readdir64_r);
 3574#else
 3575#define INIT_READDIR64
 3576#endif
 3577
 3578#if SANITIZER_INTERCEPT_PTRACE
 3579INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
 3580  void *ctx;
 3581  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
 3582  __sanitizer_iovec local_iovec;
 3583
 3584  void *data_arg = ptrace_data_arg(request, addr, data);
 3585  if (data_arg) {
 3586    if (request == ptrace_setregs) {
 3587      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, struct_user_regs_struct_sz);
 3588    } else if (request == ptrace_setfpregs) {
 3589      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,
 3590                                    struct_user_fpregs_struct_sz);
 3591    } else if (request == ptrace_setfpxregs) {
 3592      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,
 3593                                    struct_user_fpxregs_struct_sz);
 3594    } else if (request == ptrace_setvfpregs) {
 3595      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,
 3596                                    struct_user_vfpregs_struct_sz);
 3597    } else if (request == ptrace_setsiginfo) {
 3598      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, siginfo_t_sz);
 3599
 3600      // Some kernel might zero the iovec::iov_base in case of invalid
 3601      // write access.  In this case copy the invalid address for further
 3602      // inspection.
 3603    } else if (request == ptrace_setregset || request == ptrace_getregset) {
 3604      __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;
 3605      COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
 3606      local_iovec = *iovec;
 3607      if (request == ptrace_setregset)
 3608        COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
 3609    }
 3610  }
 3611
 3612  // FIXME: under ASan the call below may write to freed memory and corrupt
 3613  // its metadata. See
 3614  // https://github.com/google/sanitizers/issues/321.
 3615  uptr res = REAL(ptrace)(request, pid, addr, data);
 3616
 3617  if (!res && data_arg) {
 3618    // Note that PEEK* requests assign different meaning to the return value.
 3619    // This function does not handle them (nor does it need to).
 3620    if (request == ptrace_getregs) {
 3621      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, struct_user_regs_struct_sz);
 3622    } else if (request == ptrace_getfpregs) {
 3623      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,
 3624                                     struct_user_fpregs_struct_sz);
 3625    } else if (request == ptrace_getfpxregs) {
 3626      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,
 3627                                     struct_user_fpxregs_struct_sz);
 3628    } else if (request == ptrace_getvfpregs) {
 3629      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,
 3630                                     struct_user_vfpregs_struct_sz);
 3631    } else if (request == ptrace_getsiginfo) {
 3632      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, siginfo_t_sz);
 3633    } else if (request == ptrace_geteventmsg) {
 3634      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, sizeof(unsigned long));
 3635    } else if (request == ptrace_getregset) {
 3636      __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;
 3637      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
 3638      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
 3639                                     local_iovec.iov_len);
 3640    }
 3641  }
 3642  return res;
 3643}
 3644
 3645#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
 3646#else
 3647#define INIT_PTRACE
 3648#endif
 3649
 3650#if SANITIZER_INTERCEPT_SETLOCALE
 3651static void unpoison_ctype_arrays(void *ctx) {
 3652#if SANITIZER_NETBSD
 3653  // These arrays contain 256 regular elements in unsigned char range + 1 EOF
 3654  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
 3655  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
 3656  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
 3657#endif
 3658}
 3659
 3660INTERCEPTOR(char *, setlocale, int category, char *locale) {
 3661  void *ctx;
 3662  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
 3663  if (locale)
 3664    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1);
 3665  char *res = REAL(setlocale)(category, locale);
 3666  if (res) {
 3667    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 3668    unpoison_ctype_arrays(ctx);
 3669  }
 3670  return res;
 3671}
 3672
 3673#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
 3674#else
 3675#define INIT_SETLOCALE
 3676#endif
 3677
 3678#if SANITIZER_INTERCEPT_GETCWD
 3679INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
 3680  void *ctx;
 3681  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
 3682  // FIXME: under ASan the call below may write to freed memory and corrupt
 3683  // its metadata. See
 3684  // https://github.com/google/sanitizers/issues/321.
 3685  char *res = REAL(getcwd)(buf, size);
 3686  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 3687  return res;
 3688}
 3689#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
 3690#else
 3691#define INIT_GETCWD
 3692#endif
 3693
 3694#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
 3695INTERCEPTOR(char *, get_current_dir_name, int fake) {
 3696  void *ctx;
 3697  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
 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  char *res = REAL(get_current_dir_name)(fake);
 3702  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 3703  return res;
 3704}
 3705
 3706#define INIT_GET_CURRENT_DIR_NAME \
 3707  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
 3708#else
 3709#define INIT_GET_CURRENT_DIR_NAME
 3710#endif
 3711
 3712UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
 3713  CHECK(endptr);
 3714  if (nptr == *endptr) {
 3715    // No digits were found at strtol call, we need to find out the last
 3716    // symbol accessed by strtoll on our own.
 3717    // We get this symbol by skipping leading blanks and optional +/- sign.
 3718    while (IsSpace(*nptr)) nptr++;
 3719    if (*nptr == '+' || *nptr == '-') nptr++;
 3720    *endptr = const_cast<char *>(nptr);
 3721  }
 3722  CHECK(*endptr >= nptr);
 3723}
 3724
 3725UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
 3726                             char **endptr, char *real_endptr, int base) {
 3727  if (endptr) {
 3728    *endptr = real_endptr;
 3729    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
 3730  }
 3731  // If base has unsupported value, strtol can exit with EINVAL
 3732  // without reading any characters. So do additional checks only
 3733  // if base is valid.
 3734  bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
 3735  if (is_valid_base) {
 3736    FixRealStrtolEndptr(nptr, &real_endptr);
 3737  }
 3738  COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
 3739                                 (real_endptr - nptr) + 1 : 0);
 3740}
 3741
 3742#if SANITIZER_INTERCEPT_STRTOIMAX
 3743template <typename Fn>
 3744static ALWAYS_INLINE auto StrtoimaxImpl(void *ctx, Fn real, const char *nptr,
 3745                                        char **endptr, int base)
 3746    -> decltype(real(nullptr, nullptr, 0)) {
 3747  char *real_endptr;
 3748  auto res = real(nptr, &real_endptr, base);
 3749  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
 3750  return res;
 3751}
 3752
 3753INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
 3754  void *ctx;
 3755  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
 3756  return StrtoimaxImpl(ctx, REAL(strtoimax), nptr, endptr, base);
 3757}
 3758INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
 3759  void *ctx;
 3760  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
 3761  return StrtoimaxImpl(ctx, REAL(strtoumax), nptr, endptr, base);
 3762}
 3763
 3764#define INIT_STRTOIMAX                  \
 3765  COMMON_INTERCEPT_FUNCTION(strtoimax); \
 3766  COMMON_INTERCEPT_FUNCTION(strtoumax);
 3767#else
 3768#define INIT_STRTOIMAX
 3769#endif
 3770
 3771#if SANITIZER_INTERCEPT_STRTOIMAX && SANITIZER_GLIBC
 3772INTERCEPTOR(INTMAX_T, __isoc23_strtoimax, const char *nptr, char **endptr, int base) {
 3773  void *ctx;
 3774  COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoimax, nptr, endptr, base);
 3775  return StrtoimaxImpl(ctx, REAL(__isoc23_strtoimax), nptr, endptr, base);
 3776}
 3777INTERCEPTOR(UINTMAX_T, __isoc23_strtoumax, const char *nptr, char **endptr, int base) {
 3778  void *ctx;
 3779  COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoumax, nptr, endptr, base);
 3780  return StrtoimaxImpl(ctx, REAL(__isoc23_strtoumax), nptr, endptr, base);
 3781}
 3782
 3783#  define INIT_STRTOIMAX_C23                       \
 3784    COMMON_INTERCEPT_FUNCTION(__isoc23_strtoimax); \
 3785    COMMON_INTERCEPT_FUNCTION(__isoc23_strtoumax);
 3786#else
 3787#  define INIT_STRTOIMAX_C23
 3788#endif
 3789
 3790#if SANITIZER_INTERCEPT_MBSTOWCS
 3791INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
 3792  void *ctx;
 3793  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
 3794  // FIXME: under ASan the call below may write to freed memory and corrupt
 3795  // its metadata. See
 3796  // https://github.com/google/sanitizers/issues/321.
 3797  SIZE_T res = REAL(mbstowcs)(dest, src, len);
 3798  if (res != (SIZE_T) - 1 && dest) {
 3799    SIZE_T write_cnt = res + (res < len);
 3800    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
 3801  }
 3802  return res;
 3803}
 3804
 3805INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
 3806            void *ps) {
 3807  void *ctx;
 3808  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
 3809  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 3810  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
 3811  // FIXME: under ASan the call below may write to freed memory and corrupt
 3812  // its metadata. See
 3813  // https://github.com/google/sanitizers/issues/321.
 3814  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
 3815  if (res != (SIZE_T)(-1) && dest && src) {
 3816    // This function, and several others, may or may not write the terminating
 3817    // \0 character. They write it iff they clear *src.
 3818    SIZE_T write_cnt = res + !*src;
 3819    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
 3820  }
 3821  return res;
 3822}
 3823
 3824#define INIT_MBSTOWCS                  \
 3825  COMMON_INTERCEPT_FUNCTION(mbstowcs); \
 3826  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
 3827#else
 3828#define INIT_MBSTOWCS
 3829#endif
 3830
 3831#if SANITIZER_INTERCEPT_MBSNRTOWCS
 3832INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
 3833            SIZE_T len, void *ps) {
 3834  void *ctx;
 3835  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
 3836  if (src) {
 3837    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 3838    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
 3839  }
 3840  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
 3841  // FIXME: under ASan the call below may write to freed memory and corrupt
 3842  // its metadata. See
 3843  // https://github.com/google/sanitizers/issues/321.
 3844  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
 3845  if (res != (SIZE_T)(-1) && dest && src) {
 3846    SIZE_T write_cnt = res + !*src;
 3847    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
 3848  }
 3849  return res;
 3850}
 3851
 3852#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
 3853#else
 3854#define INIT_MBSNRTOWCS
 3855#endif
 3856
 3857#if SANITIZER_INTERCEPT_WCSTOMBS
 3858INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
 3859  void *ctx;
 3860  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
 3861  // FIXME: under ASan the call below may write to freed memory and corrupt
 3862  // its metadata. See
 3863  // https://github.com/google/sanitizers/issues/321.
 3864  SIZE_T res = REAL(wcstombs)(dest, src, len);
 3865  if (res != (SIZE_T) - 1 && dest) {
 3866    SIZE_T write_cnt = res + (res < len);
 3867    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
 3868  }
 3869  return res;
 3870}
 3871
 3872INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
 3873            void *ps) {
 3874  void *ctx;
 3875  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
 3876  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 3877  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
 3878  // FIXME: under ASan the call below may write to freed memory and corrupt
 3879  // its metadata. See
 3880  // https://github.com/google/sanitizers/issues/321.
 3881  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
 3882  if (res != (SIZE_T) - 1 && dest && src) {
 3883    SIZE_T write_cnt = res + !*src;
 3884    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
 3885  }
 3886  return res;
 3887}
 3888
 3889#define INIT_WCSTOMBS                  \
 3890  COMMON_INTERCEPT_FUNCTION(wcstombs); \
 3891  COMMON_INTERCEPT_FUNCTION(wcsrtombs);
 3892#else
 3893#define INIT_WCSTOMBS
 3894#endif
 3895
 3896#if SANITIZER_INTERCEPT_WCSNRTOMBS
 3897INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
 3898            SIZE_T len, void *ps) {
 3899  void *ctx;
 3900  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
 3901  if (src) {
 3902    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 3903    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
 3904  }
 3905  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
 3906  // FIXME: under ASan the call below may write to freed memory and corrupt
 3907  // its metadata. See
 3908  // https://github.com/google/sanitizers/issues/321.
 3909  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
 3910  if (res != ((SIZE_T)-1) && dest && src) {
 3911    SIZE_T write_cnt = res + !*src;
 3912    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
 3913  }
 3914  return res;
 3915}
 3916
 3917#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
 3918#else
 3919#define INIT_WCSNRTOMBS
 3920#endif
 3921
 3922
 3923#if SANITIZER_INTERCEPT_WCRTOMB
 3924INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
 3925  void *ctx;
 3926  COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
 3927  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
 3928
 3929  if (!dest)
 3930    return REAL(wcrtomb)(dest, src, ps);
 3931
 3932  char local_dest[32];
 3933  SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
 3934  if (res != ((SIZE_T)-1)) {
 3935    CHECK_LE(res, sizeof(local_dest));
 3936    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
 3937    internal_memcpy(dest, local_dest, res);
 3938  }
 3939  return res;
 3940}
 3941
 3942#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
 3943#else
 3944#define INIT_WCRTOMB
 3945#endif
 3946
 3947#if SANITIZER_INTERCEPT_WCTOMB
 3948INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
 3949  void *ctx;
 3950  COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
 3951  if (!dest)
 3952    return REAL(wctomb)(dest, src);
 3953
 3954  char local_dest[32];
 3955  int res = REAL(wctomb)(local_dest, src);
 3956  if (res != -1) {
 3957    CHECK_LE(res, sizeof(local_dest));
 3958    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
 3959    internal_memcpy(dest, local_dest, res);
 3960  }
 3961  return res;
 3962}
 3963
 3964#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
 3965#else
 3966#define INIT_WCTOMB
 3967#endif
 3968
 3969#if SANITIZER_INTERCEPT_TCGETATTR
 3970INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
 3971  void *ctx;
 3972  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
 3973  // FIXME: under ASan the call below may write to freed memory and corrupt
 3974  // its metadata. See
 3975  // https://github.com/google/sanitizers/issues/321.
 3976  int res = REAL(tcgetattr)(fd, termios_p);
 3977  if (!res && termios_p)
 3978    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
 3979  return res;
 3980}
 3981
 3982#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
 3983#else
 3984#define INIT_TCGETATTR
 3985#endif
 3986
 3987#if SANITIZER_INTERCEPT_REALPATH
 3988INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
 3989  void *ctx;
 3990  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
 3991  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 3992
 3993  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
 3994  // version of a versioned symbol. For realpath(), this gives us something
 3995  // (called __old_realpath) that does not handle NULL in the second argument.
 3996  // Handle it as part of the interceptor.
 3997  char *allocated_path = nullptr;
 3998  if (!resolved_path)
 3999    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
 4000
 4001  char *res = REAL(realpath)(path, resolved_path);
 4002  if (allocated_path && !res)
 4003    WRAP(free)(allocated_path);
 4004  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 4005  return res;
 4006}
 4007#  define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
 4008#else
 4009#define INIT_REALPATH
 4010#endif
 4011
 4012#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
 4013INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
 4014  void *ctx;
 4015  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
 4016  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 4017  char *res = REAL(canonicalize_file_name)(path);
 4018  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 4019  return res;
 4020}
 4021#define INIT_CANONICALIZE_FILE_NAME \
 4022  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
 4023#else
 4024#define INIT_CANONICALIZE_FILE_NAME
 4025#endif
 4026
 4027#if SANITIZER_INTERCEPT_CONFSTR
 4028INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
 4029  void *ctx;
 4030  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
 4031  // FIXME: under ASan the call below may write to freed memory and corrupt
 4032  // its metadata. See
 4033  // https://github.com/google/sanitizers/issues/321.
 4034  SIZE_T res = REAL(confstr)(name, buf, len);
 4035  if (buf && res)
 4036    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
 4037  return res;
 4038}
 4039#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
 4040#else
 4041#define INIT_CONFSTR
 4042#endif
 4043
 4044#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
 4045INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
 4046  void *ctx;
 4047  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
 4048  // FIXME: under ASan the call below may write to freed memory and corrupt
 4049  // its metadata. See
 4050  // https://github.com/google/sanitizers/issues/321.
 4051  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
 4052  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
 4053  return res;
 4054}
 4055#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
 4056#else
 4057#define INIT_SCHED_GETAFFINITY
 4058#endif
 4059
 4060#if SANITIZER_INTERCEPT_SCHED_GETPARAM
 4061INTERCEPTOR(int, sched_getparam, int pid, void *param) {
 4062  void *ctx;
 4063  COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
 4064  int res = REAL(sched_getparam)(pid, param);
 4065  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
 4066  return res;
 4067}
 4068#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
 4069#else
 4070#define INIT_SCHED_GETPARAM
 4071#endif
 4072
 4073#if SANITIZER_INTERCEPT_STRERROR
 4074INTERCEPTOR(char *, strerror, int errnum) {
 4075  void *ctx;
 4076  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
 4077  COMMON_INTERCEPTOR_STRERROR();
 4078  char *res = REAL(strerror)(errnum);
 4079  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 4080  return res;
 4081}
 4082#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
 4083#else
 4084#define INIT_STRERROR
 4085#endif
 4086
 4087#if SANITIZER_INTERCEPT_STRERROR_R
 4088// There are 2 versions of strerror_r:
 4089//  * POSIX version returns 0 on success, negative error code on failure,
 4090//    writes message to buf.
 4091//  * GNU version returns message pointer, which points to either buf or some
 4092//    static storage.
 4093#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
 4094    SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD ||                 \
 4095    SANITIZER_FREEBSD
 4096// POSIX version. Spec is not clear on whether buf is NULL-terminated.
 4097// At least on OSX, buf contents are valid even when the call fails.
 4098INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
 4099  void *ctx;
 4100  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
 4101  // FIXME: under ASan the call below may write to freed memory and corrupt
 4102  // its metadata. See
 4103  // https://github.com/google/sanitizers/issues/321.
 4104  int res = REAL(strerror_r)(errnum, buf, buflen);
 4105
 4106  SIZE_T sz = internal_strnlen(buf, buflen);
 4107  if (sz < buflen) ++sz;
 4108  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
 4109  return res;
 4110}
 4111#else
 4112// GNU version.
 4113INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
 4114  void *ctx;
 4115  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
 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(strerror_r)(errnum, buf, buflen);
 4120  if (res == buf)
 4121    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 4122  else
 4123    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 4124  return res;
 4125}
 4126#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
 4127       //SANITIZER_APPLE
 4128#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
 4129#else
 4130#define INIT_STRERROR_R
 4131#endif
 4132
 4133#if SANITIZER_INTERCEPT_XPG_STRERROR_R
 4134INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
 4135  void *ctx;
 4136  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
 4137  // FIXME: under ASan the call below may write to freed memory and corrupt
 4138  // its metadata. See
 4139  // https://github.com/google/sanitizers/issues/321.
 4140  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
 4141  // This version always returns a null-terminated string.
 4142  if (buf && buflen)
 4143    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
 4144  return res;
 4145}
 4146#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
 4147#else
 4148#define INIT_XPG_STRERROR_R
 4149#endif
 4150
 4151#if SANITIZER_INTERCEPT_SCANDIR
 4152typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
 4153typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
 4154                                const struct __sanitizer_dirent **);
 4155
 4156static THREADLOCAL scandir_filter_f scandir_filter;
 4157static THREADLOCAL scandir_compar_f scandir_compar;
 4158
 4159static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
 4160  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 4161  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));
 4162  return scandir_filter(dir);
 4163}
 4164
 4165static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
 4166                                  const struct __sanitizer_dirent **b) {
 4167  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
 4168  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
 4169  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));
 4170  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
 4171  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));
 4172  return scandir_compar(a, b);
 4173}
 4174
 4175INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
 4176            scandir_filter_f filter, scandir_compar_f compar) {
 4177  void *ctx;
 4178  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
 4179  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
 4180  scandir_filter = filter;
 4181  scandir_compar = compar;
 4182  // FIXME: under ASan the call below may write to freed memory and corrupt
 4183  // its metadata. See
 4184  // https://github.com/google/sanitizers/issues/321.
 4185  int res = REAL(scandir)(dirp, namelist,
 4186                          filter ? wrapped_scandir_filter : nullptr,
 4187                          compar ? wrapped_scandir_compar : nullptr);
 4188  scandir_filter = nullptr;
 4189  scandir_compar = nullptr;
 4190  if (namelist && res > 0) {
 4191    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
 4192    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
 4193    for (int i = 0; i < res; ++i)
 4194      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
 4195                                     __sanitizer_dirsiz((*namelist)[i]));
 4196  }
 4197  return res;
 4198}
 4199#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
 4200#else
 4201#define INIT_SCANDIR
 4202#endif
 4203
 4204#if SANITIZER_INTERCEPT_SCANDIR64
 4205typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
 4206typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
 4207                                  const struct __sanitizer_dirent64 **);
 4208
 4209static THREADLOCAL scandir64_filter_f scandir64_filter;
 4210static THREADLOCAL scandir64_compar_f scandir64_compar;
 4211
 4212static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
 4213  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 4214  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));
 4215  return scandir64_filter(dir);
 4216}
 4217
 4218static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
 4219                                    const struct __sanitizer_dirent64 **b) {
 4220  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
 4221  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
 4222  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));
 4223  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
 4224  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));
 4225  return scandir64_compar(a, b);
 4226}
 4227
 4228INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
 4229            scandir64_filter_f filter, scandir64_compar_f compar) {
 4230  void *ctx;
 4231  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
 4232  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
 4233  scandir64_filter = filter;
 4234  scandir64_compar = compar;
 4235  // FIXME: under ASan the call below may write to freed memory and corrupt
 4236  // its metadata. See
 4237  // https://github.com/google/sanitizers/issues/321.
 4238  int res =
 4239      REAL(scandir64)(dirp, namelist,
 4240                      filter ? wrapped_scandir64_filter : nullptr,
 4241                      compar ? wrapped_scandir64_compar : nullptr);
 4242  scandir64_filter = nullptr;
 4243  scandir64_compar = nullptr;
 4244  if (namelist && res > 0) {
 4245    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
 4246    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
 4247    for (int i = 0; i < res; ++i)
 4248      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
 4249                                     __sanitizer_dirsiz((*namelist)[i]));
 4250  }
 4251  return res;
 4252}
 4253#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
 4254#else
 4255#define INIT_SCANDIR64
 4256#endif
 4257
 4258#if SANITIZER_INTERCEPT_GETGROUPS
 4259INTERCEPTOR(int, getgroups, int size, u32 *lst) {
 4260  void *ctx;
 4261  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
 4262  // FIXME: under ASan the call below may write to freed memory and corrupt
 4263  // its metadata. See
 4264  // https://github.com/google/sanitizers/issues/321.
 4265  int res = REAL(getgroups)(size, lst);
 4266  if (res >= 0 && lst && size > 0)
 4267    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
 4268  return res;
 4269}
 4270#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
 4271#else
 4272#define INIT_GETGROUPS
 4273#endif
 4274
 4275#if SANITIZER_INTERCEPT_POLL
 4276static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
 4277                        __sanitizer_nfds_t nfds) {
 4278  for (unsigned i = 0; i < nfds; ++i) {
 4279    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
 4280    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
 4281  }
 4282}
 4283
 4284static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
 4285                         __sanitizer_nfds_t nfds) {
 4286  for (unsigned i = 0; i < nfds; ++i)
 4287    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
 4288                                   sizeof(fds[i].revents));
 4289}
 4290
 4291INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
 4292            int timeout) {
 4293  void *ctx;
 4294  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
 4295  if (fds && nfds) read_pollfd(ctx, fds, nfds);
 4296  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
 4297  if (fds && nfds) write_pollfd(ctx, fds, nfds);
 4298  return res;
 4299}
 4300#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
 4301#else
 4302#define INIT_POLL
 4303#endif
 4304
 4305#if SANITIZER_INTERCEPT_PPOLL
 4306INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
 4307            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
 4308  void *ctx;
 4309  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
 4310  if (fds && nfds) read_pollfd(ctx, fds, nfds);
 4311  if (timeout_ts)
 4312    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
 4313  if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));
 4314  int res =
 4315      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
 4316  if (fds && nfds) write_pollfd(ctx, fds, nfds);
 4317  return res;
 4318}
 4319#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
 4320#else
 4321#define INIT_PPOLL
 4322#endif
 4323
 4324#if SANITIZER_INTERCEPT_WORDEXP
 4325INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
 4326  void *ctx;
 4327  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
 4328  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
 4329  // FIXME: under ASan the call below may write to freed memory and corrupt
 4330  // its metadata. See
 4331  // https://github.com/google/sanitizers/issues/321.
 4332  int res = REAL(wordexp)(s, p, flags);
 4333  if (!res && p) {
 4334    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 4335    uptr we_wordc =
 4336        ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc;
 4337    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
 4338                                   sizeof(*p->we_wordv) * (we_wordc + 1));
 4339    for (uptr i = 0; i < we_wordc; ++i) {
 4340      char *w = p->we_wordv[i];
 4341      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);
 4342    }
 4343  }
 4344  return res;
 4345}
 4346#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
 4347#else
 4348#define INIT_WORDEXP
 4349#endif
 4350
 4351#if SANITIZER_INTERCEPT_SIGWAIT
 4352INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
 4353  void *ctx;
 4354  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
 4355  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 4356  // FIXME: under ASan the call below may write to freed memory and corrupt
 4357  // its metadata. See
 4358  // https://github.com/google/sanitizers/issues/321.
 4359  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);
 4360  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
 4361  return res;
 4362}
 4363#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
 4364#else
 4365#define INIT_SIGWAIT
 4366#endif
 4367
 4368#if SANITIZER_INTERCEPT_SIGWAITINFO
 4369INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
 4370  void *ctx;
 4371  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
 4372  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 4373  // FIXME: under ASan the call below may write to freed memory and corrupt
 4374  // its metadata. See
 4375  // https://github.com/google/sanitizers/issues/321.
 4376  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);
 4377  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
 4378  return res;
 4379}
 4380#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
 4381#else
 4382#define INIT_SIGWAITINFO
 4383#endif
 4384
 4385#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
 4386INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
 4387            void *timeout) {
 4388  void *ctx;
 4389  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
 4390  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
 4391  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 4392  // FIXME: under ASan the call below may write to freed memory and corrupt
 4393  // its metadata. See
 4394  // https://github.com/google/sanitizers/issues/321.
 4395  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);
 4396  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
 4397  return res;
 4398}
 4399#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
 4400#else
 4401#define INIT_SIGTIMEDWAIT
 4402#endif
 4403
 4404#if SANITIZER_INTERCEPT_SIGSETOPS
 4405INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
 4406  void *ctx;
 4407  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
 4408  // FIXME: under ASan the call below may write to freed memory and corrupt
 4409  // its metadata. See
 4410  // https://github.com/google/sanitizers/issues/321.
 4411  int res = REAL(sigemptyset)(set);
 4412  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
 4413  return res;
 4414}
 4415
 4416INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
 4417  void *ctx;
 4418  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
 4419  // FIXME: under ASan the call below may write to freed memory and corrupt
 4420  // its metadata. See
 4421  // https://github.com/google/sanitizers/issues/321.
 4422  int res = REAL(sigfillset)(set);
 4423  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
 4424  return res;
 4425}
 4426#define INIT_SIGSETOPS                    \
 4427  COMMON_INTERCEPT_FUNCTION(sigemptyset); \
 4428  COMMON_INTERCEPT_FUNCTION(sigfillset);
 4429#else
 4430#define INIT_SIGSETOPS
 4431#endif
 4432
 4433#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS
 4434INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,
 4435            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
 4436  void *ctx;
 4437  COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);
 4438  if (src1)
 4439    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
 4440  if (src2)
 4441    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
 4442  int res = REAL(sigandset)(dst, src1, src2);
 4443  if (!res && dst)
 4444    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
 4445  return res;
 4446}
 4447
 4448INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,
 4449            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
 4450  void *ctx;
 4451  COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);
 4452  if (src1)
 4453    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
 4454  if (src2)
 4455    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
 4456  int res = REAL(sigorset)(dst, src1, src2);
 4457  if (!res && dst)
 4458    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
 4459  return res;
 4460}
 4461#define INIT_SIGSET_LOGICOPS                    \
 4462  COMMON_INTERCEPT_FUNCTION(sigandset);   \
 4463  COMMON_INTERCEPT_FUNCTION(sigorset);
 4464#else
 4465#define INIT_SIGSET_LOGICOPS
 4466#endif
 4467
 4468#if SANITIZER_INTERCEPT_SIGPENDING
 4469INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
 4470  void *ctx;
 4471  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
 4472  // FIXME: under ASan the call below may write to freed memory and corrupt
 4473  // its metadata. See
 4474  // https://github.com/google/sanitizers/issues/321.
 4475  int res = REAL(sigpending)(set);
 4476  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
 4477  return res;
 4478}
 4479#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
 4480#else
 4481#define INIT_SIGPENDING
 4482#endif
 4483
 4484#if SANITIZER_INTERCEPT_SIGPROCMASK
 4485INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
 4486            __sanitizer_sigset_t *oldset) {
 4487  void *ctx;
 4488  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
 4489  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 4490  // FIXME: under ASan the call below may write to freed memory and corrupt
 4491  // its metadata. See
 4492  // https://github.com/google/sanitizers/issues/321.
 4493  int res = REAL(sigprocmask)(how, set, oldset);
 4494  if (!res && oldset)
 4495    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
 4496  return res;
 4497}
 4498#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
 4499#else
 4500#define INIT_SIGPROCMASK
 4501#endif
 4502
 4503#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
 4504INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
 4505            __sanitizer_sigset_t *oldset) {
 4506  void *ctx;
 4507  COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
 4508  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
 4509  // FIXME: under ASan the call below may write to freed memory and corrupt
 4510  // its metadata. See
 4511  // https://github.com/google/sanitizers/issues/321.
 4512  int res = REAL(pthread_sigmask)(how, set, oldset);
 4513  if (!res && oldset)
 4514    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
 4515  return res;
 4516}
 4517#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
 4518#else
 4519#define INIT_PTHREAD_SIGMASK
 4520#endif
 4521
 4522#if SANITIZER_INTERCEPT_BACKTRACE
 4523INTERCEPTOR(int, backtrace, void **buffer, int size) {
 4524  void *ctx;
 4525  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
 4526  // 'buffer' might be freed memory, hence it is unsafe to directly call
 4527  // REAL(backtrace)(buffer, size). Instead, we use our own known-good
 4528  // scratch buffer.
 4529  void **scratch = (void**)InternalAlloc(sizeof(void*) * size);
 4530  int res = REAL(backtrace)(scratch, size);
 4531  if (res && buffer) {
 4532    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
 4533    internal_memcpy(buffer, scratch, res * sizeof(*buffer));
 4534  }
 4535  InternalFree(scratch);
 4536  return res;
 4537}
 4538
 4539INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
 4540  void *ctx;
 4541  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
 4542  if (buffer && size)
 4543    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
 4544  // The COMMON_INTERCEPTOR_READ_RANGE above ensures that 'buffer' is
 4545  // valid for reading.
 4546  char **res = REAL(backtrace_symbols)(buffer, size);
 4547  if (res && size) {
 4548    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
 4549    for (int i = 0; i < size; ++i)
 4550      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1);
 4551  }
 4552  return res;
 4553}
 4554#define INIT_BACKTRACE                  \
 4555  COMMON_INTERCEPT_FUNCTION(backtrace); \
 4556  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
 4557#else
 4558#define INIT_BACKTRACE
 4559#endif
 4560
 4561#if SANITIZER_INTERCEPT__EXIT
 4562INTERCEPTOR(void, _exit, int status) {
 4563  void *ctx;
 4564  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
 4565  COMMON_INTERCEPTOR_USER_CALLBACK_START();
 4566  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
 4567  COMMON_INTERCEPTOR_USER_CALLBACK_END();
 4568  if (status == 0) status = status1;
 4569  REAL(_exit)(status);
 4570}
 4571#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
 4572#else
 4573#define INIT__EXIT
 4574#endif
 4575
 4576#if SANITIZER_INTERCEPT___LIBC_MUTEX
 4577INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
 4578ALIAS(WRAP(pthread_setcancelstate));
 4579
 4580#define INIT___LIBC_THR_SETCANCELSTATE \
 4581  COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
 4582#else
 4583#define INIT___LIBC_THR_SETCANCELSTATE
 4584#endif
 4585
 4586#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
 4587static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
 4588  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
 4589  if (mnt->mnt_fsname)
 4590    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
 4591                                   internal_strlen(mnt->mnt_fsname) + 1);
 4592  if (mnt->mnt_dir)
 4593    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
 4594                                   internal_strlen(mnt->mnt_dir) + 1);
 4595  if (mnt->mnt_type)
 4596    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
 4597                                   internal_strlen(mnt->mnt_type) + 1);
 4598  if (mnt->mnt_opts)
 4599    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
 4600                                   internal_strlen(mnt->mnt_opts) + 1);
 4601}
 4602#endif
 4603
 4604#if SANITIZER_INTERCEPT_GETMNTENT
 4605INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
 4606  void *ctx;
 4607  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
 4608  __sanitizer_mntent *res = REAL(getmntent)(fp);
 4609  if (res) write_mntent(ctx, res);
 4610  return res;
 4611}
 4612#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
 4613#else
 4614#define INIT_GETMNTENT
 4615#endif
 4616
 4617#if SANITIZER_INTERCEPT_GETMNTENT_R
 4618INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
 4619            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
 4620  void *ctx;
 4621  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
 4622  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
 4623  if (res) write_mntent(ctx, res);
 4624  return res;
 4625}
 4626#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
 4627#else
 4628#define INIT_GETMNTENT_R
 4629#endif
 4630
 4631#if SANITIZER_INTERCEPT_STATFS
 4632INTERCEPTOR(int, statfs, char *path, void *buf) {
 4633  void *ctx;
 4634  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
 4635  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 4636  // FIXME: under ASan the call below may write to freed memory and corrupt
 4637  // its metadata. See
 4638  // https://github.com/google/sanitizers/issues/321.
 4639  int res = REAL(statfs)(path, buf);
 4640  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
 4641  return res;
 4642}
 4643INTERCEPTOR(int, fstatfs, int fd, void *buf) {
 4644  void *ctx;
 4645  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
 4646  // FIXME: under ASan the call below may write to freed memory and corrupt
 4647  // its metadata. See
 4648  // https://github.com/google/sanitizers/issues/321.
 4649  int res = REAL(fstatfs)(fd, buf);
 4650  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
 4651  return res;
 4652}
 4653#define INIT_STATFS                  \
 4654  COMMON_INTERCEPT_FUNCTION(statfs); \
 4655  COMMON_INTERCEPT_FUNCTION(fstatfs);
 4656#else
 4657#define INIT_STATFS
 4658#endif
 4659
 4660#if SANITIZER_INTERCEPT_STATFS64
 4661INTERCEPTOR(int, statfs64, char *path, void *buf) {
 4662  void *ctx;
 4663  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
 4664  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 4665  // FIXME: under ASan the call below may write to freed memory and corrupt
 4666  // its metadata. See
 4667  // https://github.com/google/sanitizers/issues/321.
 4668  int res = REAL(statfs64)(path, buf);
 4669  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
 4670  return res;
 4671}
 4672INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
 4673  void *ctx;
 4674  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
 4675  // FIXME: under ASan the call below may write to freed memory and corrupt
 4676  // its metadata. See
 4677  // https://github.com/google/sanitizers/issues/321.
 4678  int res = REAL(fstatfs64)(fd, buf);
 4679  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
 4680  return res;
 4681}
 4682#define INIT_STATFS64                  \
 4683  COMMON_INTERCEPT_FUNCTION(statfs64); \
 4684  COMMON_INTERCEPT_FUNCTION(fstatfs64);
 4685#else
 4686#define INIT_STATFS64
 4687#endif
 4688
 4689#if SANITIZER_INTERCEPT_STATVFS
 4690INTERCEPTOR(int, statvfs, char *path, void *buf) {
 4691  void *ctx;
 4692  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
 4693  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 4694  // FIXME: under ASan the call below may write to freed memory and corrupt
 4695  // its metadata. See
 4696  // https://github.com/google/sanitizers/issues/321.
 4697  int res = REAL(statvfs)(path, buf);
 4698  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
 4699  return res;
 4700}
 4701INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
 4702  void *ctx;
 4703  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
 4704  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 4705  // FIXME: under ASan the call below may write to freed memory and corrupt
 4706  // its metadata. See
 4707  // https://github.com/google/sanitizers/issues/321.
 4708  int res = REAL(fstatvfs)(fd, buf);
 4709  if (!res) {
 4710    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
 4711    if (fd >= 0)
 4712      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 4713  }
 4714  return res;
 4715}
 4716#define INIT_STATVFS                  \
 4717  COMMON_INTERCEPT_FUNCTION(statvfs); \
 4718  COMMON_INTERCEPT_FUNCTION(fstatvfs);
 4719#else
 4720#define INIT_STATVFS
 4721#endif
 4722
 4723#if SANITIZER_INTERCEPT_STATVFS64
 4724INTERCEPTOR(int, statvfs64, char *path, void *buf) {
 4725  void *ctx;
 4726  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
 4727  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 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(statvfs64)(path, buf);
 4732  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
 4733  return res;
 4734}
 4735INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
 4736  void *ctx;
 4737  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
 4738  // FIXME: under ASan the call below may write to freed memory and corrupt
 4739  // its metadata. See
 4740  // https://github.com/google/sanitizers/issues/321.
 4741  int res = REAL(fstatvfs64)(fd, buf);
 4742  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
 4743  return res;
 4744}
 4745#define INIT_STATVFS64                  \
 4746  COMMON_INTERCEPT_FUNCTION(statvfs64); \
 4747  COMMON_INTERCEPT_FUNCTION(fstatvfs64);
 4748#else
 4749#define INIT_STATVFS64
 4750#endif
 4751
 4752#if SANITIZER_INTERCEPT_INITGROUPS
 4753INTERCEPTOR(int, initgroups, char *user, u32 group) {
 4754  void *ctx;
 4755  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
 4756  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1);
 4757  int res = REAL(initgroups)(user, group);
 4758  return res;
 4759}
 4760#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
 4761#else
 4762#define INIT_INITGROUPS
 4763#endif
 4764
 4765#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
 4766INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
 4767  void *ctx;
 4768  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
 4769  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
 4770  char *res = REAL(ether_ntoa)(addr);
 4771  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 4772  return res;
 4773}
 4774INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
 4775  void *ctx;
 4776  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
 4777  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
 4778  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
 4779  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
 4780  return res;
 4781}
 4782#define INIT_ETHER_NTOA_ATON             \
 4783  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
 4784  COMMON_INTERCEPT_FUNCTION(ether_aton);
 4785#else
 4786#define INIT_ETHER_NTOA_ATON
 4787#endif
 4788
 4789#if SANITIZER_INTERCEPT_ETHER_HOST
 4790INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
 4791  void *ctx;
 4792  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
 4793  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
 4794  // FIXME: under ASan the call below may write to freed memory and corrupt
 4795  // its metadata. See
 4796  // https://github.com/google/sanitizers/issues/321.
 4797  int res = REAL(ether_ntohost)(hostname, addr);
 4798  if (!res && hostname)
 4799    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
 4800  return res;
 4801}
 4802INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
 4803  void *ctx;
 4804  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
 4805  if (hostname)
 4806    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
 4807  // FIXME: under ASan the call below may write to freed memory and corrupt
 4808  // its metadata. See
 4809  // https://github.com/google/sanitizers/issues/321.
 4810  int res = REAL(ether_hostton)(hostname, addr);
 4811  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
 4812  return res;
 4813}
 4814INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
 4815            char *hostname) {
 4816  void *ctx;
 4817  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
 4818  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1);
 4819  // FIXME: under ASan the call below may write to freed memory and corrupt
 4820  // its metadata. See
 4821  // https://github.com/google/sanitizers/issues/321.
 4822  int res = REAL(ether_line)(line, addr, hostname);
 4823  if (!res) {
 4824    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
 4825    if (hostname)
 4826      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
 4827  }
 4828  return res;
 4829}
 4830#define INIT_ETHER_HOST                     \
 4831  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
 4832  COMMON_INTERCEPT_FUNCTION(ether_hostton); \
 4833  COMMON_INTERCEPT_FUNCTION(ether_line);
 4834#else
 4835#define INIT_ETHER_HOST
 4836#endif
 4837
 4838#if SANITIZER_INTERCEPT_ETHER_R
 4839INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
 4840  void *ctx;
 4841  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
 4842  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
 4843  // FIXME: under ASan the call below may write to freed memory and corrupt
 4844  // its metadata. See
 4845  // https://github.com/google/sanitizers/issues/321.
 4846  char *res = REAL(ether_ntoa_r)(addr, buf);
 4847  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 4848  return res;
 4849}
 4850INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
 4851            __sanitizer_ether_addr *addr) {
 4852  void *ctx;
 4853  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
 4854  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
 4855  // FIXME: under ASan the call below may write to freed memory and corrupt
 4856  // its metadata. See
 4857  // https://github.com/google/sanitizers/issues/321.
 4858  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
 4859  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
 4860  return res;
 4861}
 4862#define INIT_ETHER_R                       \
 4863  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
 4864  COMMON_INTERCEPT_FUNCTION(ether_aton_r);
 4865#else
 4866#define INIT_ETHER_R
 4867#endif
 4868
 4869#if SANITIZER_INTERCEPT_SHMCTL
 4870INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
 4871  void *ctx;
 4872  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
 4873  // FIXME: under ASan the call below may write to freed memory and corrupt
 4874  // its metadata. See
 4875  // https://github.com/google/sanitizers/issues/321.
 4876  int res = REAL(shmctl)(shmid, cmd, buf);
 4877  if (res >= 0) {
 4878    unsigned sz = 0;
 4879    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
 4880      sz = sizeof(__sanitizer_shmid_ds);
 4881    else if (cmd == shmctl_ipc_info)
 4882      sz = struct_shminfo_sz;
 4883    else if (cmd == shmctl_shm_info)
 4884      sz = struct_shm_info_sz;
 4885    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
 4886  }
 4887  return res;
 4888}
 4889#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
 4890#else
 4891#define INIT_SHMCTL
 4892#endif
 4893
 4894#if SANITIZER_INTERCEPT_RANDOM_R
 4895INTERCEPTOR(int, random_r, void *buf, u32 *result) {
 4896  void *ctx;
 4897  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
 4898  // FIXME: under ASan the call below may write to freed memory and corrupt
 4899  // its metadata. See
 4900  // https://github.com/google/sanitizers/issues/321.
 4901  int res = REAL(random_r)(buf, result);
 4902  if (!res && result)
 4903    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 4904  return res;
 4905}
 4906#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
 4907#else
 4908#define INIT_RANDOM_R
 4909#endif
 4910
 4911// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
 4912// its metadata. See
 4913// https://github.com/google/sanitizers/issues/321.
 4914#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
 4915    SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED ||        \
 4916    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
 4917    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
 4918    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
 4919    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
 4920    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
 4921#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
 4922  INTERCEPTOR(int, fn, void *attr, void *r) {                  \
 4923    void *ctx;                                                 \
 4924    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
 4925    int res = REAL(fn)(attr, r);                               \
 4926    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
 4927    return res;                                                \
 4928  }
 4929#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
 4930  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
 4931#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
 4932  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
 4933#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
 4934  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
 4935#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
 4936  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
 4937#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
 4938  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
 4939#endif
 4940
 4941#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
 4942INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
 4943INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
 4944INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
 4945INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
 4946INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
 4947  void *ctx;
 4948  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
 4949  // FIXME: under ASan the call below may write to freed memory and corrupt
 4950  // its metadata. See
 4951  // https://github.com/google/sanitizers/issues/321.
 4952  int res = REAL(pthread_attr_getstack)(attr, addr, size);
 4953  if (!res) {
 4954    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
 4955    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
 4956  }
 4957  return res;
 4958}
 4959
 4960// We may need to call the real pthread_attr_getstack from the run-time
 4961// in sanitizer_common, but we don't want to include the interception headers
 4962// there. So, just define this function here.
 4963namespace __sanitizer {
 4964extern "C" {
 4965int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
 4966  return REAL(pthread_attr_getstack)(attr, addr, size);
 4967}
 4968}  // extern "C"
 4969}  // namespace __sanitizer
 4970
 4971#define INIT_PTHREAD_ATTR_GET                             \
 4972  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
 4973  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
 4974  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
 4975  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
 4976  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
 4977#else
 4978#define INIT_PTHREAD_ATTR_GET
 4979#endif
 4980
 4981#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED
 4982INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
 4983INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
 4984
 4985#define INIT_PTHREAD_ATTR_GET_SCHED                      \
 4986  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
 4987  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);
 4988#else
 4989#define INIT_PTHREAD_ATTR_GET_SCHED
 4990#endif
 4991
 4992#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
 4993INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
 4994
 4995#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
 4996  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
 4997#else
 4998#define INIT_PTHREAD_ATTR_GETINHERITSCHED
 4999#endif
 5000
 5001#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
 5002INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
 5003            void *cpuset) {
 5004  void *ctx;
 5005  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
 5006                           cpuset);
 5007  // FIXME: under ASan the call below may write to freed memory and corrupt
 5008  // its metadata. See
 5009  // https://github.com/google/sanitizers/issues/321.
 5010  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
 5011  if (!res && cpusetsize && cpuset)
 5012    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
 5013  return res;
 5014}
 5015
 5016#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
 5017  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
 5018#else
 5019#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
 5020#endif
 5021
 5022#if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP
 5023INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize,
 5024            void *cpuset) {
 5025  void *ctx;
 5026  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize,
 5027                           cpuset);
 5028  // FIXME: under ASan the call below may write to freed memory and corrupt
 5029  // its metadata. See
 5030  // https://github.com/google/sanitizers/issues/321.
 5031  int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset);
 5032  if (!res && cpusetsize && cpuset)
 5033    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
 5034  return res;
 5035}
 5036
 5037#define INIT_PTHREAD_GETAFFINITY_NP \
 5038  COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np);
 5039#else
 5040#define INIT_PTHREAD_GETAFFINITY_NP
 5041#endif
 5042
 5043#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
 5044INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
 5045#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
 5046  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
 5047#else
 5048#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
 5049#endif
 5050
 5051#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
 5052INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
 5053#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
 5054  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
 5055#else
 5056#define INIT_PTHREAD_MUTEXATTR_GETTYPE
 5057#endif
 5058
 5059#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
 5060INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
 5061#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
 5062  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
 5063#else
 5064#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
 5065#endif
 5066
 5067#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
 5068INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
 5069#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
 5070  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
 5071#else
 5072#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
 5073#endif
 5074
 5075#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
 5076INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
 5077#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
 5078  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
 5079#else
 5080#define INIT_PTHREAD_MUTEXATTR_GETROBUST
 5081#endif
 5082
 5083#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
 5084INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
 5085#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
 5086  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
 5087#else
 5088#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
 5089#endif
 5090
 5091#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
 5092INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
 5093#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
 5094  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
 5095#else
 5096#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
 5097#endif
 5098
 5099#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
 5100INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
 5101#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
 5102  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
 5103#else
 5104#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
 5105#endif
 5106
 5107#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
 5108INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
 5109#define INIT_PTHREAD_CONDATTR_GETPSHARED \
 5110  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
 5111#else
 5112#define INIT_PTHREAD_CONDATTR_GETPSHARED
 5113#endif
 5114
 5115#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
 5116INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
 5117#define INIT_PTHREAD_CONDATTR_GETCLOCK \
 5118  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
 5119#else
 5120#define INIT_PTHREAD_CONDATTR_GETCLOCK
 5121#endif
 5122
 5123#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
 5124INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
 5125#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
 5126  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
 5127#else
 5128#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
 5129#endif
 5130
 5131#if SANITIZER_INTERCEPT_TMPNAM
 5132INTERCEPTOR(char *, tmpnam, char *s) {
 5133  void *ctx;
 5134  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
 5135  char *res = REAL(tmpnam)(s);
 5136  if (res) {
 5137    if (s)
 5138      // FIXME: under ASan the call below may write to freed memory and corrupt
 5139      // its metadata. See
 5140      // https://github.com/google/sanitizers/issues/321.
 5141      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
 5142    else
 5143      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 5144  }
 5145  return res;
 5146}
 5147#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
 5148#else
 5149#define INIT_TMPNAM
 5150#endif
 5151
 5152#if SANITIZER_INTERCEPT_TMPNAM_R
 5153INTERCEPTOR(char *, tmpnam_r, char *s) {
 5154  void *ctx;
 5155  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
 5156  // FIXME: under ASan the call below may write to freed memory and corrupt
 5157  // its metadata. See
 5158  // https://github.com/google/sanitizers/issues/321.
 5159  char *res = REAL(tmpnam_r)(s);
 5160  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
 5161  return res;
 5162}
 5163#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
 5164#else
 5165#define INIT_TMPNAM_R
 5166#endif
 5167
 5168#if SANITIZER_INTERCEPT_PTSNAME
 5169INTERCEPTOR(char *, ptsname, int fd) {
 5170  void *ctx;
 5171  COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);
 5172  char *res = REAL(ptsname)(fd);
 5173  if (res != nullptr)
 5174    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 5175  return res;
 5176}
 5177#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);
 5178#else
 5179#define INIT_PTSNAME
 5180#endif
 5181
 5182#if SANITIZER_INTERCEPT_PTSNAME_R
 5183INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {
 5184  void *ctx;
 5185  COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);
 5186  int res = REAL(ptsname_r)(fd, name, namesize);
 5187  if (res == 0)
 5188    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
 5189  return res;
 5190}
 5191#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);
 5192#else
 5193#define INIT_PTSNAME_R
 5194#endif
 5195
 5196#if SANITIZER_INTERCEPT_TTYNAME
 5197INTERCEPTOR(char *, ttyname, int fd) {
 5198  void *ctx;
 5199  COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);
 5200  char *res = REAL(ttyname)(fd);
 5201  if (res != nullptr)
 5202    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 5203  return res;
 5204}
 5205#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);
 5206#else
 5207#define INIT_TTYNAME
 5208#endif
 5209
 5210#if SANITIZER_INTERCEPT_TTYNAME_R
 5211INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
 5212  void *ctx;
 5213  COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);
 5214  int res = REAL(ttyname_r)(fd, name, namesize);
 5215  if (res == 0)
 5216    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
 5217  return res;
 5218}
 5219#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);
 5220#else
 5221#define INIT_TTYNAME_R
 5222#endif
 5223
 5224#if SANITIZER_INTERCEPT_TEMPNAM
 5225INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
 5226  void *ctx;
 5227  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
 5228  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1);
 5229  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1);
 5230  char *res = REAL(tempnam)(dir, pfx);
 5231  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 5232  return res;
 5233}
 5234#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
 5235#else
 5236#define INIT_TEMPNAM
 5237#endif
 5238
 5239#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
 5240INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
 5241  void *ctx;
 5242  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
 5243  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
 5244  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
 5245  return REAL(pthread_setname_np)(thread, name);
 5246}
 5247#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
 5248#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
 5249INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
 5250  void *ctx;
 5251  char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
 5252  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
 5253  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
 5254  internal_snprintf(newname, sizeof(newname), name, arg);
 5255  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
 5256  return REAL(pthread_setname_np)(thread, name, arg);
 5257}
 5258#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
 5259#else
 5260#define INIT_PTHREAD_SETNAME_NP
 5261#endif
 5262
 5263#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP
 5264INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {
 5265  void *ctx;
 5266  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);
 5267  int res = REAL(pthread_getname_np)(thread, name, len);
 5268  if (!res)
 5269    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);
 5270  return res;
 5271}
 5272#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);
 5273#else
 5274#define INIT_PTHREAD_GETNAME_NP
 5275#endif
 5276
 5277#if SANITIZER_INTERCEPT_SINCOS
 5278INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
 5279  void *ctx;
 5280  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
 5281  // FIXME: under ASan the call below may write to freed memory and corrupt
 5282  // its metadata. See
 5283  // https://github.com/google/sanitizers/issues/321.
 5284  REAL(sincos)(x, sin, cos);
 5285  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
 5286  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
 5287}
 5288INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
 5289  void *ctx;
 5290  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
 5291  // FIXME: under ASan the call below may write to freed memory and corrupt
 5292  // its metadata. See
 5293  // https://github.com/google/sanitizers/issues/321.
 5294  REAL(sincosf)(x, sin, cos);
 5295  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
 5296  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
 5297}
 5298INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
 5299  void *ctx;
 5300  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
 5301  // FIXME: under ASan the call below may write to freed memory and corrupt
 5302  // its metadata. See
 5303  // https://github.com/google/sanitizers/issues/321.
 5304  REAL(sincosl)(x, sin, cos);
 5305  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
 5306  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
 5307}
 5308#define INIT_SINCOS                   \
 5309  COMMON_INTERCEPT_FUNCTION(sincos);  \
 5310  COMMON_INTERCEPT_FUNCTION(sincosf); \
 5311  COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
 5312#else
 5313#define INIT_SINCOS
 5314#endif
 5315
 5316#if SANITIZER_INTERCEPT_REMQUO
 5317INTERCEPTOR(double, remquo, double x, double y, int *quo) {
 5318  void *ctx;
 5319  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
 5320  // FIXME: under ASan the call below may write to freed memory and corrupt
 5321  // its metadata. See
 5322  // https://github.com/google/sanitizers/issues/321.
 5323  double res = REAL(remquo)(x, y, quo);
 5324  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
 5325  return res;
 5326}
 5327INTERCEPTOR(float, remquof, float x, float y, int *quo) {
 5328  void *ctx;
 5329  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
 5330  // FIXME: under ASan the call below may write to freed memory and corrupt
 5331  // its metadata. See
 5332  // https://github.com/google/sanitizers/issues/321.
 5333  float res = REAL(remquof)(x, y, quo);
 5334  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
 5335  return res;
 5336}
 5337#define INIT_REMQUO                   \
 5338  COMMON_INTERCEPT_FUNCTION(remquo);  \
 5339  COMMON_INTERCEPT_FUNCTION(remquof);
 5340#else
 5341#define INIT_REMQUO
 5342#endif
 5343
 5344#if SANITIZER_INTERCEPT_REMQUOL
 5345INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
 5346  void *ctx;
 5347  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
 5348  // FIXME: under ASan the call below may write to freed memory and corrupt
 5349  // its metadata. See
 5350  // https://github.com/google/sanitizers/issues/321.
 5351  long double res = REAL(remquol)(x, y, quo);
 5352  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
 5353  return res;
 5354}
 5355#define INIT_REMQUOL                  \
 5356  COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
 5357#else
 5358#define INIT_REMQUOL
 5359#endif
 5360
 5361#if SANITIZER_INTERCEPT_LGAMMA
 5362extern int signgam;
 5363INTERCEPTOR(double, lgamma, double x) {
 5364  void *ctx;
 5365  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
 5366  double res = REAL(lgamma)(x);
 5367  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
 5368  return res;
 5369}
 5370INTERCEPTOR(float, lgammaf, float x) {
 5371  void *ctx;
 5372  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
 5373  float res = REAL(lgammaf)(x);
 5374  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
 5375  return res;
 5376}
 5377#define INIT_LGAMMA                   \
 5378  COMMON_INTERCEPT_FUNCTION(lgamma);  \
 5379  COMMON_INTERCEPT_FUNCTION(lgammaf);
 5380#else
 5381#define INIT_LGAMMA
 5382#endif
 5383
 5384#if SANITIZER_INTERCEPT_LGAMMAL
 5385INTERCEPTOR(long double, lgammal, long double x) {
 5386  void *ctx;
 5387  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
 5388  long double res = REAL(lgammal)(x);
 5389  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
 5390  return res;
 5391}
 5392#define INIT_LGAMMAL                  \
 5393  COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
 5394#else
 5395#define INIT_LGAMMAL
 5396#endif
 5397
 5398#if SANITIZER_INTERCEPT_LGAMMA_R
 5399INTERCEPTOR(double, lgamma_r, double x, int *signp) {
 5400  void *ctx;
 5401  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
 5402  // FIXME: under ASan the call below may write to freed memory and corrupt
 5403  // its metadata. See
 5404  // https://github.com/google/sanitizers/issues/321.
 5405  double res = REAL(lgamma_r)(x, signp);
 5406  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
 5407  return res;
 5408}
 5409INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
 5410  void *ctx;
 5411  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
 5412  // FIXME: under ASan the call below may write to freed memory and corrupt
 5413  // its metadata. See
 5414  // https://github.com/google/sanitizers/issues/321.
 5415  float res = REAL(lgammaf_r)(x, signp);
 5416  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
 5417  return res;
 5418}
 5419#define INIT_LGAMMA_R                   \
 5420  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
 5421  COMMON_INTERCEPT_FUNCTION(lgammaf_r);
 5422#else
 5423#define INIT_LGAMMA_R
 5424#endif
 5425
 5426#if SANITIZER_INTERCEPT_LGAMMAL_R
 5427INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
 5428  void *ctx;
 5429  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
 5430  // FIXME: under ASan the call below may write to freed memory and corrupt
 5431  // its metadata. See
 5432  // https://github.com/google/sanitizers/issues/321.
 5433  long double res = REAL(lgammal_r)(x, signp);
 5434  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
 5435  return res;
 5436}
 5437#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
 5438#else
 5439#define INIT_LGAMMAL_R
 5440#endif
 5441
 5442#if SANITIZER_INTERCEPT_DRAND48_R
 5443INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
 5444  void *ctx;
 5445  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
 5446  // FIXME: under ASan the call below may write to freed memory and corrupt
 5447  // its metadata. See
 5448  // https://github.com/google/sanitizers/issues/321.
 5449  int res = REAL(drand48_r)(buffer, result);
 5450  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 5451  return res;
 5452}
 5453INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
 5454  void *ctx;
 5455  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
 5456  // FIXME: under ASan the call below may write to freed memory and corrupt
 5457  // its metadata. See
 5458  // https://github.com/google/sanitizers/issues/321.
 5459  int res = REAL(lrand48_r)(buffer, result);
 5460  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
 5461  return res;
 5462}
 5463#define INIT_DRAND48_R                  \
 5464  COMMON_INTERCEPT_FUNCTION(drand48_r); \
 5465  COMMON_INTERCEPT_FUNCTION(lrand48_r);
 5466#else
 5467#define INIT_DRAND48_R
 5468#endif
 5469
 5470#if SANITIZER_INTERCEPT_RAND_R
 5471INTERCEPTOR(int, rand_r, unsigned *seedp) {
 5472  void *ctx;
 5473  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
 5474  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
 5475  return REAL(rand_r)(seedp);
 5476}
 5477#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
 5478#else
 5479#define INIT_RAND_R
 5480#endif
 5481
 5482#if SANITIZER_INTERCEPT_GETLINE
 5483INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
 5484  void *ctx;
 5485  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
 5486  // FIXME: under ASan the call below may write to freed memory and corrupt
 5487  // its metadata. See
 5488  // https://github.com/google/sanitizers/issues/321.
 5489  SSIZE_T res = REAL(getline)(lineptr, n, stream);
 5490  if (res > 0) {
 5491    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
 5492    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
 5493    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
 5494  }
 5495  return res;
 5496}
 5497
 5498// FIXME: under ASan the call below may write to freed memory and corrupt its
 5499// metadata. See
 5500// https://github.com/google/sanitizers/issues/321.
 5501#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
 5502  {                                                                            \
 5503    void *ctx;                                                                 \
 5504    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
 5505    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
 5506    if (res > 0) {                                                             \
 5507      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
 5508      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
 5509      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
 5510    }                                                                          \
 5511    return res;                                                                \
 5512  }
 5513
 5514INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
 5515            void *stream)
 5516GETDELIM_INTERCEPTOR_IMPL(__getdelim)
 5517
 5518// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
 5519// with its own body.
 5520INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
 5521            void *stream)
 5522GETDELIM_INTERCEPTOR_IMPL(getdelim)
 5523
 5524#define INIT_GETLINE                     \
 5525  COMMON_INTERCEPT_FUNCTION(getline);    \
 5526  COMMON_INTERCEPT_FUNCTION(__getdelim); \
 5527  COMMON_INTERCEPT_FUNCTION(getdelim);
 5528#else
 5529#define INIT_GETLINE
 5530#endif
 5531
 5532#if SANITIZER_INTERCEPT_ICONV
 5533INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
 5534            char **outbuf, SIZE_T *outbytesleft) {
 5535  void *ctx;
 5536  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
 5537                           outbytesleft);
 5538  if (inbytesleft)
 5539    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
 5540  if (inbuf && inbytesleft)
 5541    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
 5542  if (outbytesleft)
 5543    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
 5544  void *outbuf_orig = outbuf ? *outbuf : nullptr;
 5545  // FIXME: under ASan the call below may write to freed memory and corrupt
 5546  // its metadata. See
 5547  // https://github.com/google/sanitizers/issues/321.
 5548  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
 5549  if (outbuf && *outbuf > outbuf_orig) {
 5550    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
 5551    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
 5552  }
 5553  return res;
 5554}
 5555#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
 5556#else
 5557#define INIT_ICONV
 5558#endif
 5559
 5560#if SANITIZER_INTERCEPT_TIMES
 5561INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
 5562  void *ctx;
 5563  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
 5564  // FIXME: under ASan the call below may write to freed memory and corrupt
 5565  // its metadata. See
 5566  // https://github.com/google/sanitizers/issues/321.
 5567  __sanitizer_clock_t res = REAL(times)(tms);
 5568  if (res != (__sanitizer_clock_t)-1 && tms)
 5569    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
 5570  return res;
 5571}
 5572#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
 5573#else
 5574#define INIT_TIMES
 5575#endif
 5576
 5577#if SANITIZER_S390 && \
 5578    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
 5579extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
 5580DEFINE_REAL(uptr, __tls_get_offset, void *arg)
 5581#endif
 5582
 5583#if SANITIZER_INTERCEPT_TLS_GET_ADDR
 5584#if !SANITIZER_S390
 5585#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
 5586// If you see any crashes around this functions, there are 2 known issues with
 5587// it: 1. __tls_get_addr can be called with mis-aligned stack due to:
 5588// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
 5589// 2. It can be called recursively if sanitizer code uses __tls_get_addr
 5590// to access thread local variables (it should not happen normally,
 5591// because sanitizers use initial-exec tls model).
 5592INTERCEPTOR(void *, __tls_get_addr, void *arg) {
 5593  void *ctx;
 5594  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
 5595  void *res = REAL(__tls_get_addr)(arg);
 5596  uptr tls_begin, tls_end;
 5597  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
 5598  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
 5599  if (dtv) {
 5600    // New DTLS block has been allocated.
 5601    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
 5602  }
 5603  return res;
 5604}
 5605#if SANITIZER_PPC
 5606// On PowerPC, we also need to intercept __tls_get_addr_opt, which has
 5607// mostly the same semantics as __tls_get_addr, but its presence enables
 5608// some optimizations in linker (which are safe to ignore here).
 5609INTERCEPTOR(void *, __tls_get_addr_opt, void *arg) ALIAS(WRAP(__tls_get_addr));
 5610#endif
 5611#else // SANITIZER_S390
 5612// On s390, we have to intercept two functions here:
 5613// - __tls_get_addr_internal, which is a glibc-internal function that is like
 5614//   the usual __tls_get_addr, but returns a TP-relative offset instead of
 5615//   a proper pointer.  It is used by dlsym for TLS symbols.
 5616// - __tls_get_offset, which is like the above, but also takes a GOT-relative
 5617//   descriptor offset as an argument instead of a pointer.  GOT address
 5618//   is passed in r12, so it's necessary to write it in assembly.  This is
 5619//   the function used by the compiler.
 5620#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
 5621INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
 5622  void *ctx;
 5623  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
 5624  uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
 5625  uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
 5626  void *ptr = reinterpret_cast<void *>(res + tp);
 5627  uptr tls_begin, tls_end;
 5628  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
 5629  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
 5630  if (dtv) {
 5631    // New DTLS block has been allocated.
 5632    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
 5633  }
 5634  return res;
 5635}
 5636#endif // SANITIZER_S390
 5637#else
 5638#define INIT_TLS_GET_ADDR
 5639#endif
 5640
 5641#if SANITIZER_S390 && \
 5642    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
 5643// We need a hidden symbol aliasing the above, so that we can jump
 5644// directly to it from the assembly below.
 5645extern "C" __attribute__((visibility("hidden"))) uptr __tls_get_addr_hidden(
 5646    void *arg) ALIAS(WRAP(__tls_get_addr_internal));
 5647extern "C" uptr __tls_get_offset(void *arg);
 5648extern "C" uptr TRAMPOLINE(__tls_get_offset)(void *arg);
 5649extern "C" uptr WRAP(__tls_get_offset)(void *arg);
 5650// Now carefully intercept __tls_get_offset.
 5651asm(
 5652  ".text\n"
 5653// The __intercept_ version has to exist, so that gen_dynamic_list.py
 5654// exports our symbol.
 5655  ".weak __tls_get_offset\n"
 5656  ".set __tls_get_offset, __interceptor___tls_get_offset\n"
 5657  ".global __interceptor___tls_get_offset\n"
 5658  ".type __interceptor___tls_get_offset, @function\n"
 5659  "__interceptor___tls_get_offset:\n"
 5660#ifdef __s390x__
 5661  "la %r2, 0(%r2,%r12)\n"
 5662  "jg __tls_get_addr_hidden\n"
 5663#else
 5664  "basr %r3,0\n"
 5665  "0: la %r2,0(%r2,%r12)\n"
 5666  "l %r4,1f-0b(%r3)\n"
 5667  "b 0(%r4,%r3)\n"
 5668  "1: .long __tls_get_addr_hidden - 0b\n"
 5669#endif
 5670  ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
 5671// Assembly wrapper to call REAL(__tls_get_offset)(arg)
 5672  ".type __tls_get_offset_wrapper, @function\n"
 5673  "__tls_get_offset_wrapper:\n"
 5674#ifdef __s390x__
 5675  "sgr %r2,%r12\n"
 5676#else
 5677  "sr %r2,%r12\n"
 5678#endif
 5679  "br %r3\n"
 5680  ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
 5681);
 5682#endif
 5683
 5684#if SANITIZER_INTERCEPT_LISTXATTR
 5685INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
 5686  void *ctx;
 5687  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
 5688  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 5689  // FIXME: under ASan the call below may write to freed memory and corrupt
 5690  // its metadata. See
 5691  // https://github.com/google/sanitizers/issues/321.
 5692  SSIZE_T res = REAL(listxattr)(path, list, size);
 5693  // Here and below, size == 0 is a special case where nothing is written to the
 5694  // buffer, and res contains the desired buffer size.
 5695  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
 5696  return res;
 5697}
 5698INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
 5699  void *ctx;
 5700  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
 5701  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 5702  // FIXME: under ASan the call below may write to freed memory and corrupt
 5703  // its metadata. See
 5704  // https://github.com/google/sanitizers/issues/321.
 5705  SSIZE_T res = REAL(llistxattr)(path, list, size);
 5706  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
 5707  return res;
 5708}
 5709INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
 5710  void *ctx;
 5711  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
 5712  // FIXME: under ASan the call below may write to freed memory and corrupt
 5713  // its metadata. See
 5714  // https://github.com/google/sanitizers/issues/321.
 5715  SSIZE_T res = REAL(flistxattr)(fd, list, size);
 5716  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
 5717  return res;
 5718}
 5719#define INIT_LISTXATTR                   \
 5720  COMMON_INTERCEPT_FUNCTION(listxattr);  \
 5721  COMMON_INTERCEPT_FUNCTION(llistxattr); \
 5722  COMMON_INTERCEPT_FUNCTION(flistxattr);
 5723#else
 5724#define INIT_LISTXATTR
 5725#endif
 5726
 5727#if SANITIZER_INTERCEPT_GETXATTR
 5728INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
 5729            SIZE_T size) {
 5730  void *ctx;
 5731  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
 5732  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 5733  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 5734  // FIXME: under ASan the call below may write to freed memory and corrupt
 5735  // its metadata. See
 5736  // https://github.com/google/sanitizers/issues/321.
 5737  SSIZE_T res = REAL(getxattr)(path, name, value, size);
 5738  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
 5739  return res;
 5740}
 5741INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
 5742            SIZE_T size) {
 5743  void *ctx;
 5744  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
 5745  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 5746  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 5747  // FIXME: under ASan the call below may write to freed memory and corrupt
 5748  // its metadata. See
 5749  // https://github.com/google/sanitizers/issues/321.
 5750  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
 5751  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
 5752  return res;
 5753}
 5754INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
 5755            SIZE_T size) {
 5756  void *ctx;
 5757  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
 5758  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 5759  // FIXME: under ASan the call below may write to freed memory and corrupt
 5760  // its metadata. See
 5761  // https://github.com/google/sanitizers/issues/321.
 5762  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
 5763  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
 5764  return res;
 5765}
 5766#define INIT_GETXATTR                   \
 5767  COMMON_INTERCEPT_FUNCTION(getxattr);  \
 5768  COMMON_INTERCEPT_FUNCTION(lgetxattr); \
 5769  COMMON_INTERCEPT_FUNCTION(fgetxattr);
 5770#else
 5771#define INIT_GETXATTR
 5772#endif
 5773
 5774#if SANITIZER_INTERCEPT_GETRESID
 5775INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
 5776  void *ctx;
 5777  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
 5778  // FIXME: under ASan the call below may write to freed memory and corrupt
 5779  // its metadata. See
 5780  // https://github.com/google/sanitizers/issues/321.
 5781  int res = REAL(getresuid)(ruid, euid, suid);
 5782  if (res >= 0) {
 5783    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
 5784    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
 5785    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
 5786  }
 5787  return res;
 5788}
 5789INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
 5790  void *ctx;
 5791  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
 5792  // FIXME: under ASan the call below may write to freed memory and corrupt
 5793  // its metadata. See
 5794  // https://github.com/google/sanitizers/issues/321.
 5795  int res = REAL(getresgid)(rgid, egid, sgid);
 5796  if (res >= 0) {
 5797    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
 5798    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
 5799    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
 5800  }
 5801  return res;
 5802}
 5803#define INIT_GETRESID                   \
 5804  COMMON_INTERCEPT_FUNCTION(getresuid); \
 5805  COMMON_INTERCEPT_FUNCTION(getresgid);
 5806#else
 5807#define INIT_GETRESID
 5808#endif
 5809
 5810#if SANITIZER_INTERCEPT_GETIFADDRS
 5811// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
 5812// intercept freeifaddrs(). If that ceases to be the case, we might need to
 5813// intercept it to poison the memory again.
 5814INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
 5815  void *ctx;
 5816  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
 5817  // FIXME: under ASan the call below may write to freed memory and corrupt
 5818  // its metadata. See
 5819  // https://github.com/google/sanitizers/issues/321.
 5820  int res = REAL(getifaddrs)(ifap);
 5821  if (res == 0 && ifap) {
 5822    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
 5823    __sanitizer_ifaddrs *p = *ifap;
 5824    while (p) {
 5825      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
 5826      if (p->ifa_name)
 5827        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
 5828                                       internal_strlen(p->ifa_name) + 1);
 5829      if (p->ifa_addr)
 5830        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
 5831      if (p->ifa_netmask)
 5832        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
 5833      // On Linux this is a union, but the other member also points to a
 5834      // struct sockaddr, so the following is sufficient.
 5835      if (p->ifa_dstaddr)
 5836        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
 5837      // FIXME(smatveev): Unpoison p->ifa_data as well.
 5838      p = p->ifa_next;
 5839    }
 5840  }
 5841  return res;
 5842}
 5843#define INIT_GETIFADDRS                  \
 5844  COMMON_INTERCEPT_FUNCTION(getifaddrs);
 5845#else
 5846#define INIT_GETIFADDRS
 5847#endif
 5848
 5849#if SANITIZER_INTERCEPT_IF_INDEXTONAME
 5850INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
 5851  void *ctx;
 5852  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
 5853  // FIXME: under ASan the call below may write to freed memory and corrupt
 5854  // its metadata. See
 5855  // https://github.com/google/sanitizers/issues/321.
 5856  char *res = REAL(if_indextoname)(ifindex, ifname);
 5857  if (res && ifname)
 5858    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
 5859  return res;
 5860}
 5861INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
 5862  void *ctx;
 5863  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
 5864  if (ifname)
 5865    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
 5866  return REAL(if_nametoindex)(ifname);
 5867}
 5868#define INIT_IF_INDEXTONAME                  \
 5869  COMMON_INTERCEPT_FUNCTION(if_indextoname); \
 5870  COMMON_INTERCEPT_FUNCTION(if_nametoindex);
 5871#else
 5872#define INIT_IF_INDEXTONAME
 5873#endif
 5874
 5875#if SANITIZER_INTERCEPT_CAPGET
 5876INTERCEPTOR(int, capget, void *hdrp, void *datap) {
 5877  void *ctx;
 5878  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
 5879  if (hdrp)
 5880    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
 5881  // FIXME: under ASan the call below may write to freed memory and corrupt
 5882  // its metadata. See
 5883  // https://github.com/google/sanitizers/issues/321.
 5884  int res = REAL(capget)(hdrp, datap);
 5885  if (res == 0 && datap) {
 5886    unsigned datasz = __user_cap_data_struct_sz(hdrp);
 5887    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, datasz);
 5888  }
 5889  // We can also return -1 and write to hdrp->version if the version passed in
 5890  // hdrp->version is unsupported. But that's not a trivial condition to check,
 5891  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
 5892  return res;
 5893}
 5894INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
 5895  void *ctx;
 5896  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
 5897  if (hdrp)
 5898    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
 5899  if (datap) {
 5900    unsigned datasz = __user_cap_data_struct_sz(hdrp);
 5901    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, datasz);
 5902  }
 5903  return REAL(capset)(hdrp, datap);
 5904}
 5905#define INIT_CAPGET                  \
 5906  COMMON_INTERCEPT_FUNCTION(capget); \
 5907  COMMON_INTERCEPT_FUNCTION(capset);
 5908#else
 5909#define INIT_CAPGET
 5910#endif
 5911
 5912#if SANITIZER_INTERCEPT_FTIME
 5913INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
 5914  void *ctx;
 5915  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
 5916  // FIXME: under ASan the call below may write to freed memory and corrupt
 5917  // its metadata. See
 5918  // https://github.com/google/sanitizers/issues/321.
 5919  int res = REAL(ftime)(tp);
 5920  if (tp)
 5921    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
 5922  return res;
 5923}
 5924#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
 5925#else
 5926#define INIT_FTIME
 5927#endif  // SANITIZER_INTERCEPT_FTIME
 5928
 5929#if SANITIZER_INTERCEPT_XDR
 5930INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
 5931            unsigned size, int op) {
 5932  void *ctx;
 5933  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
 5934  // FIXME: under ASan the call below may write to freed memory and corrupt
 5935  // its metadata. See
 5936  // https://github.com/google/sanitizers/issues/321.
 5937  REAL(xdrmem_create)(xdrs, addr, size, op);
 5938  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
 5939  if (op == __sanitizer_XDR_ENCODE) {
 5940    // It's not obvious how much data individual xdr_ routines write.
 5941    // Simply unpoison the entire target buffer in advance.
 5942    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
 5943  }
 5944}
 5945
 5946INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
 5947  void *ctx;
 5948  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
 5949  // FIXME: under ASan the call below may write to freed memory and corrupt
 5950  // its metadata. See
 5951  // https://github.com/google/sanitizers/issues/321.
 5952  REAL(xdrstdio_create)(xdrs, file, op);
 5953  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
 5954}
 5955
 5956// FIXME: under ASan the call below may write to freed memory and corrupt
 5957// its metadata. See
 5958// https://github.com/google/sanitizers/issues/321.
 5959#define XDR_INTERCEPTOR(F, T)                             \
 5960  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
 5961    void *ctx;                                            \
 5962    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
 5963    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
 5964      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
 5965    int res = REAL(F)(xdrs, p);                           \
 5966    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
 5967      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
 5968    return res;                                           \
 5969  }
 5970
 5971XDR_INTERCEPTOR(xdr_short, short)
 5972XDR_INTERCEPTOR(xdr_u_short, unsigned short)
 5973XDR_INTERCEPTOR(xdr_int, int)
 5974XDR_INTERCEPTOR(xdr_u_int, unsigned)
 5975XDR_INTERCEPTOR(xdr_long, long)
 5976XDR_INTERCEPTOR(xdr_u_long, unsigned long)
 5977XDR_INTERCEPTOR(xdr_hyper, long long)
 5978XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
 5979XDR_INTERCEPTOR(xdr_longlong_t, long long)
 5980XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
 5981XDR_INTERCEPTOR(xdr_int8_t, u8)
 5982XDR_INTERCEPTOR(xdr_uint8_t, u8)
 5983XDR_INTERCEPTOR(xdr_int16_t, u16)
 5984XDR_INTERCEPTOR(xdr_uint16_t, u16)
 5985XDR_INTERCEPTOR(xdr_int32_t, u32)
 5986XDR_INTERCEPTOR(xdr_uint32_t, u32)
 5987XDR_INTERCEPTOR(xdr_int64_t, u64)
 5988XDR_INTERCEPTOR(xdr_uint64_t, u64)
 5989XDR_INTERCEPTOR(xdr_quad_t, long long)
 5990XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
 5991XDR_INTERCEPTOR(xdr_bool, bool)
 5992XDR_INTERCEPTOR(xdr_enum, int)
 5993XDR_INTERCEPTOR(xdr_char, char)
 5994XDR_INTERCEPTOR(xdr_u_char, unsigned char)
 5995XDR_INTERCEPTOR(xdr_float, float)
 5996XDR_INTERCEPTOR(xdr_double, double)
 5997
 5998// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
 5999// wrapstring, sizeof
 6000
 6001INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
 6002            unsigned maxsize) {
 6003  void *ctx;
 6004  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
 6005  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
 6006    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
 6007    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
 6008    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
 6009  }
 6010  // FIXME: under ASan the call below may write to freed memory and corrupt
 6011  // its metadata. See
 6012  // https://github.com/google/sanitizers/issues/321.
 6013  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
 6014  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
 6015    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 6016    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
 6017    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
 6018  }
 6019  return res;
 6020}
 6021
 6022INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
 6023            unsigned maxsize) {
 6024  void *ctx;
 6025  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
 6026  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
 6027    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
 6028    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1);
 6029  }
 6030  // FIXME: under ASan the call below may write to freed memory and corrupt
 6031  // its metadata. See
 6032  // https://github.com/google/sanitizers/issues/321.
 6033  int res = REAL(xdr_string)(xdrs, p, maxsize);
 6034  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
 6035    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 6036    if (res && *p)
 6037      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
 6038  }
 6039  return res;
 6040}
 6041
 6042#define INIT_XDR                               \
 6043  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
 6044  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
 6045  COMMON_INTERCEPT_FUNCTION(xdr_short);        \
 6046  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
 6047  COMMON_INTERCEPT_FUNCTION(xdr_int);          \
 6048  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
 6049  COMMON_INTERCEPT_FUNCTION(xdr_long);         \
 6050  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
 6051  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
 6052  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
 6053  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
 6054  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
 6055  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
 6056  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
 6057  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
 6058  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
 6059  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
 6060  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
 6061  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
 6062  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
 6063  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
 6064  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
 6065  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
 6066  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
 6067  COMMON_INTERCEPT_FUNCTION(xdr_char);         \
 6068  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
 6069  COMMON_INTERCEPT_FUNCTION(xdr_float);        \
 6070  COMMON_INTERCEPT_FUNCTION(xdr_double);       \
 6071  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
 6072  COMMON_INTERCEPT_FUNCTION(xdr_string);
 6073#else
 6074#define INIT_XDR
 6075#endif  // SANITIZER_INTERCEPT_XDR
 6076
 6077#if SANITIZER_INTERCEPT_XDRREC
 6078typedef int (*xdrrec_cb)(char*, char*, int);
 6079struct XdrRecWrapper {
 6080  char *handle;
 6081  xdrrec_cb rd, wr;
 6082};
 6083typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;
 6084static XdrRecWrapMap *xdrrec_wrap_map;
 6085
 6086static int xdrrec_wr_wrap(char *handle, char *buf, int count) {
 6087  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 6088  COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);
 6089  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
 6090  return wrap->wr(wrap->handle, buf, count);
 6091}
 6092
 6093static int xdrrec_rd_wrap(char *handle, char *buf, int count) {
 6094  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 6095  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
 6096  return wrap->rd(wrap->handle, buf, count);
 6097}
 6098
 6099// This doesn't apply to the solaris version as it has a different function
 6100// signature.
 6101INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,
 6102            unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),
 6103            int (*wr)(char*, char*, int)) {
 6104  void *ctx;
 6105  COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,
 6106                           handle, rd, wr);
 6107  COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);
 6108
 6109  // We can't allocate a wrapper on the stack, as the handle is used outside
 6110  // this stack frame. So we put it on the heap, and keep track of it with
 6111  // the HashMap (keyed by x_private). When we later need to xdr_destroy,
 6112  // we can index the map, free the wrapper, and then clean the map entry.
 6113  XdrRecWrapper *wrap_data =
 6114      (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));
 6115  wrap_data->handle = handle;
 6116  wrap_data->rd = rd;
 6117  wrap_data->wr = wr;
 6118  if (wr)
 6119    wr = xdrrec_wr_wrap;
 6120  if (rd)
 6121    rd = xdrrec_rd_wrap;
 6122  handle = (char *)wrap_data;
 6123
 6124  REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);
 6125  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);
 6126
 6127  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);
 6128  *wrap = wrap_data;
 6129}
 6130
 6131// We have to intercept this to be able to free wrapper memory;
 6132// otherwise it's not necessary.
 6133INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {
 6134  void *ctx;
 6135  COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);
 6136
 6137  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);
 6138  InternalFree(*wrap);
 6139  REAL(xdr_destroy)(xdr);
 6140}
 6141#define INIT_XDRREC_LINUX \
 6142  static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \
 6143  xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \
 6144  COMMON_INTERCEPT_FUNCTION(xdrrec_create); \
 6145  COMMON_INTERCEPT_FUNCTION(xdr_destroy);
 6146#else
 6147#define INIT_XDRREC_LINUX
 6148#endif
 6149
 6150#if SANITIZER_INTERCEPT_TSEARCH
 6151INTERCEPTOR(void *, tsearch, void *key, void **rootp,
 6152            int (*compar)(const void *, const void *)) {
 6153  void *ctx;
 6154  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
 6155  // FIXME: under ASan the call below may write to freed memory and corrupt
 6156  // its metadata. See
 6157  // https://github.com/google/sanitizers/issues/321.
 6158  void *res = REAL(tsearch)(key, rootp, compar);
 6159  if (res && *(void **)res == key)
 6160    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
 6161  return res;
 6162}
 6163#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
 6164#else
 6165#define INIT_TSEARCH
 6166#endif
 6167
 6168#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
 6169    SANITIZER_INTERCEPT_OPEN_MEMSTREAM
 6170void unpoison_file(__sanitizer_FILE *fp) {
 6171#if SANITIZER_HAS_STRUCT_FILE
 6172  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
 6173#if SANITIZER_NETBSD
 6174  if (fp->_bf._base && fp->_bf._size > 0)
 6175    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
 6176                                        fp->_bf._size);
 6177#else
 6178  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
 6179    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
 6180                                        fp->_IO_read_end - fp->_IO_read_base);
 6181  if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)
 6182    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,
 6183                                        fp->_IO_write_end - fp->_IO_write_base);
 6184#endif
 6185#endif  // SANITIZER_HAS_STRUCT_FILE
 6186}
 6187#endif
 6188
 6189#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
 6190// These guys are called when a .c source is built with -O2.
 6191INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
 6192  void *ctx;
 6193  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
 6194  int res = REAL(__uflow)(fp);
 6195  unpoison_file(fp);
 6196  return res;
 6197}
 6198INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
 6199  void *ctx;
 6200  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
 6201  int res = REAL(__underflow)(fp);
 6202  unpoison_file(fp);
 6203  return res;
 6204}
 6205INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
 6206  void *ctx;
 6207  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
 6208  int res = REAL(__overflow)(fp, ch);
 6209  unpoison_file(fp);
 6210  return res;
 6211}
 6212INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
 6213  void *ctx;
 6214  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
 6215  int res = REAL(__wuflow)(fp);
 6216  unpoison_file(fp);
 6217  return res;
 6218}
 6219INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
 6220  void *ctx;
 6221  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
 6222  int res = REAL(__wunderflow)(fp);
 6223  unpoison_file(fp);
 6224  return res;
 6225}
 6226INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
 6227  void *ctx;
 6228  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
 6229  int res = REAL(__woverflow)(fp, ch);
 6230  unpoison_file(fp);
 6231  return res;
 6232}
 6233#define INIT_LIBIO_INTERNALS               \
 6234  COMMON_INTERCEPT_FUNCTION(__uflow);      \
 6235  COMMON_INTERCEPT_FUNCTION(__underflow);  \
 6236  COMMON_INTERCEPT_FUNCTION(__overflow);   \
 6237  COMMON_INTERCEPT_FUNCTION(__wuflow);     \
 6238  COMMON_INTERCEPT_FUNCTION(__wunderflow); \
 6239  COMMON_INTERCEPT_FUNCTION(__woverflow);
 6240#else
 6241#define INIT_LIBIO_INTERNALS
 6242#endif
 6243
 6244#if SANITIZER_INTERCEPT_FOPEN
 6245INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
 6246  void *ctx;
 6247  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
 6248  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6249  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
 6250  __sanitizer_FILE *res = REAL(fopen)(path, mode);
 6251  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
 6252  if (res) unpoison_file(res);
 6253  return res;
 6254}
 6255INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
 6256  void *ctx;
 6257  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
 6258  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
 6259  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
 6260  if (res) unpoison_file(res);
 6261  return res;
 6262}
 6263INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
 6264            __sanitizer_FILE *fp) {
 6265  void *ctx;
 6266  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
 6267  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6268  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
 6269  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
 6270  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
 6271  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
 6272  if (res) unpoison_file(res);
 6273  return res;
 6274}
 6275#define INIT_FOPEN                   \
 6276  COMMON_INTERCEPT_FUNCTION(fopen);  \
 6277  COMMON_INTERCEPT_FUNCTION(fdopen); \
 6278  COMMON_INTERCEPT_FUNCTION(freopen);
 6279#else
 6280#define INIT_FOPEN
 6281#endif
 6282
 6283#if SANITIZER_INTERCEPT_FLOPEN
 6284INTERCEPTOR(int, flopen, const char *path, int flags, ...) {
 6285  void *ctx;
 6286  va_list ap;
 6287  va_start(ap, flags);
 6288  u16 mode = static_cast<u16>(va_arg(ap, u32));
 6289  va_end(ap);
 6290  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
 6291  if (path) {
 6292    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6293  }
 6294  return COMMON_INTERCEPTOR_BLOCK_REAL(flopen)(path, flags, mode);
 6295}
 6296
 6297INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {
 6298  void *ctx;
 6299  va_list ap;
 6300  va_start(ap, flags);
 6301  u16 mode = static_cast<u16>(va_arg(ap, u32));
 6302  va_end(ap);
 6303  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
 6304  if (path) {
 6305    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6306  }
 6307  return COMMON_INTERCEPTOR_BLOCK_REAL(flopenat)(dirfd, path, flags, mode);
 6308}
 6309
 6310#define INIT_FLOPEN    \
 6311  COMMON_INTERCEPT_FUNCTION(flopen); \
 6312  COMMON_INTERCEPT_FUNCTION(flopenat);
 6313#else
 6314#define INIT_FLOPEN
 6315#endif
 6316
 6317#if SANITIZER_INTERCEPT_FOPEN64
 6318INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
 6319  void *ctx;
 6320  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
 6321  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6322  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
 6323  __sanitizer_FILE *res = REAL(fopen64)(path, mode);
 6324  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
 6325  if (res) unpoison_file(res);
 6326  return res;
 6327}
 6328INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
 6329            __sanitizer_FILE *fp) {
 6330  void *ctx;
 6331  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
 6332  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 6333  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
 6334  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
 6335  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
 6336  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
 6337  if (res) unpoison_file(res);
 6338  return res;
 6339}
 6340#define INIT_FOPEN64                  \
 6341  COMMON_INTERCEPT_FUNCTION(fopen64); \
 6342  COMMON_INTERCEPT_FUNCTION(freopen64);
 6343#else
 6344#define INIT_FOPEN64
 6345#endif
 6346
 6347#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
 6348INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
 6349  void *ctx;
 6350  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
 6351  // FIXME: under ASan the call below may write to freed memory and corrupt
 6352  // its metadata. See
 6353  // https://github.com/google/sanitizers/issues/321.
 6354  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
 6355  if (res) {
 6356    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
 6357    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
 6358    unpoison_file(res);
 6359    FileMetadata file = {ptr, sizeloc};
 6360    SetInterceptorMetadata(res, file);
 6361  }
 6362  return res;
 6363}
 6364INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
 6365            SIZE_T *sizeloc) {
 6366  void *ctx;
 6367  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
 6368  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
 6369  if (res) {
 6370    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
 6371    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
 6372    unpoison_file(res);
 6373    FileMetadata file = {(char **)ptr, sizeloc};
 6374    SetInterceptorMetadata(res, file);
 6375  }
 6376  return res;
 6377}
 6378INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
 6379            const char *mode) {
 6380  void *ctx;
 6381  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
 6382  // FIXME: under ASan the call below may write to freed memory and corrupt
 6383  // its metadata. See
 6384  // https://github.com/google/sanitizers/issues/321.
 6385  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
 6386  if (res) unpoison_file(res);
 6387  return res;
 6388}
 6389#define INIT_OPEN_MEMSTREAM                   \
 6390  COMMON_INTERCEPT_FUNCTION(open_memstream);  \
 6391  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
 6392  COMMON_INTERCEPT_FUNCTION(fmemopen);
 6393#else
 6394#define INIT_OPEN_MEMSTREAM
 6395#endif
 6396
 6397#if SANITIZER_INTERCEPT_OBSTACK
 6398static void initialize_obstack(__sanitizer_obstack *obstack) {
 6399  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
 6400  if (obstack->chunk)
 6401    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
 6402                                        sizeof(*obstack->chunk));
 6403}
 6404
 6405INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
 6406            int align, void *(*alloc_fn)(uptr arg, uptr sz),
 6407            void (*free_fn)(uptr arg, void *p)) {
 6408  void *ctx;
 6409  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
 6410                           free_fn);
 6411  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
 6412  if (res) initialize_obstack(obstack);
 6413  return res;
 6414}
 6415INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
 6416            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
 6417  void *ctx;
 6418  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
 6419                           free_fn);
 6420  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
 6421  if (res) initialize_obstack(obstack);
 6422  return res;
 6423}
 6424INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
 6425  void *ctx;
 6426  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
 6427  REAL(_obstack_newchunk)(obstack, length);
 6428  if (obstack->chunk)
 6429    COMMON_INTERCEPTOR_INITIALIZE_RANGE(
 6430        obstack->chunk, obstack->next_free - (char *)obstack->chunk);
 6431}
 6432#define INIT_OBSTACK                           \
 6433  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
 6434  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
 6435  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
 6436#else
 6437#define INIT_OBSTACK
 6438#endif
 6439
 6440#if SANITIZER_INTERCEPT_FFLUSH
 6441INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
 6442  void *ctx;
 6443  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
 6444  if (fp)
 6445    unpoison_file(fp);
 6446  int res = REAL(fflush)(fp);
 6447  // FIXME: handle fp == NULL
 6448  if (fp) {
 6449    const FileMetadata *m = GetInterceptorMetadata(fp);
 6450    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
 6451  }
 6452  return res;
 6453}
 6454#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
 6455#else
 6456#define INIT_FFLUSH
 6457#endif
 6458
 6459#if SANITIZER_INTERCEPT_FCLOSE
 6460INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
 6461  void *ctx;
 6462  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
 6463  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
 6464  const FileMetadata *m = GetInterceptorMetadata(fp);
 6465  if (fp)
 6466    unpoison_file(fp);
 6467  int res = REAL(fclose)(fp);
 6468  if (m) {
 6469    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
 6470    DeleteInterceptorMetadata(fp);
 6471  }
 6472  return res;
 6473}
 6474#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
 6475#else
 6476#define INIT_FCLOSE
 6477#endif
 6478
 6479#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
 6480INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
 6481  void *ctx;
 6482  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
 6483
 6484  if (filename) {
 6485    COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
 6486
 6487#  if !SANITIZER_DYNAMIC
 6488    // We care about a very specific use-case: dladdr on
 6489    // statically-linked ASan may return <main program>
 6490    // instead of the library.
 6491    // We therefore only take effect if the sanitizer is statically
 6492    // linked, and we don't bother canonicalizing paths because
 6493    // dladdr should return the same address both times (we assume
 6494    // the user did not canonicalize the result from dladdr).
 6495    if (common_flags()->test_only_replace_dlopen_main_program) {
 6496      VPrintf(1, "dlopen interceptor: filename: %s\n", filename);
 6497
 6498      const char *SelfFName = DladdrSelfFName();
 6499      VPrintf(1, "dlopen interceptor: DladdrSelfFName: %p %s\n",
 6500              (const void *)SelfFName, SelfFName);
 6501
 6502      if (SelfFName && internal_strcmp(SelfFName, filename) == 0) {
 6503        // It's possible they copied the string from dladdr, so
 6504        // we do a string comparison rather than pointer comparison.
 6505        VPrintf(1, "dlopen interceptor: replacing %s because it matches %s\n",
 6506                filename, SelfFName);
 6507        filename = (char *)0;  // RTLD_DEFAULT
 6508      }
 6509    }
 6510#  endif  // !SANITIZER_DYNAMIC
 6511  }
 6512
 6513  void *res = COMMON_INTERCEPTOR_DLOPEN(filename, flag);
 6514  Symbolizer::GetOrInit()->InvalidateModuleList();
 6515  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
 6516  return res;
 6517}
 6518
 6519INTERCEPTOR(int, dlclose, void *handle) {
 6520  void *ctx;
 6521  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
 6522  int res = REAL(dlclose)(handle);
 6523  Symbolizer::GetOrInit()->InvalidateModuleList();
 6524  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
 6525  return res;
 6526}
 6527#define INIT_DLOPEN_DLCLOSE          \
 6528  COMMON_INTERCEPT_FUNCTION(dlopen); \
 6529  COMMON_INTERCEPT_FUNCTION(dlclose);
 6530#else
 6531#define INIT_DLOPEN_DLCLOSE
 6532#endif
 6533
 6534#if SANITIZER_INTERCEPT_GETPASS
 6535INTERCEPTOR(char *, getpass, const char *prompt) {
 6536  void *ctx;
 6537  COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
 6538  if (prompt)
 6539    COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1);
 6540  char *res = REAL(getpass)(prompt);
 6541  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1);
 6542  return res;
 6543}
 6544
 6545#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
 6546#else
 6547#define INIT_GETPASS
 6548#endif
 6549
 6550#if SANITIZER_INTERCEPT_TIMERFD
 6551INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
 6552            void *old_value) {
 6553  void *ctx;
 6554  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
 6555                           old_value);
 6556  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
 6557  int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
 6558  if (res != -1 && old_value)
 6559    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
 6560  return res;
 6561}
 6562
 6563INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
 6564  void *ctx;
 6565  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
 6566  int res = REAL(timerfd_gettime)(fd, curr_value);
 6567  if (res != -1 && curr_value)
 6568    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
 6569  return res;
 6570}
 6571#define INIT_TIMERFD                          \
 6572  COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
 6573  COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
 6574#else
 6575#define INIT_TIMERFD
 6576#endif
 6577
 6578#if SANITIZER_INTERCEPT_MLOCKX
 6579// Linux kernel has a bug that leads to kernel deadlock if a process
 6580// maps TBs of memory and then calls mlock().
 6581static void MlockIsUnsupported() {
 6582  static atomic_uint8_t printed;
 6583  if (atomic_exchange(&printed, 1, memory_order_relaxed))
 6584    return;
 6585  VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
 6586          SanitizerToolName);
 6587}
 6588
 6589INTERCEPTOR(int, mlock, const void *addr, usize len) {
 6590  MlockIsUnsupported();
 6591  return 0;
 6592}
 6593
 6594INTERCEPTOR(int, munlock, const void *addr, usize len) {
 6595  MlockIsUnsupported();
 6596  return 0;
 6597}
 6598
 6599INTERCEPTOR(int, mlockall, int flags) {
 6600  MlockIsUnsupported();
 6601  return 0;
 6602}
 6603
 6604INTERCEPTOR(int, munlockall, void) {
 6605  MlockIsUnsupported();
 6606  return 0;
 6607}
 6608
 6609#define INIT_MLOCKX                                                            \
 6610  COMMON_INTERCEPT_FUNCTION(mlock);                                            \
 6611  COMMON_INTERCEPT_FUNCTION(munlock);                                          \
 6612  COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
 6613  COMMON_INTERCEPT_FUNCTION(munlockall);
 6614
 6615#else
 6616#define INIT_MLOCKX
 6617#endif  // SANITIZER_INTERCEPT_MLOCKX
 6618
 6619#if SANITIZER_INTERCEPT_FOPENCOOKIE
 6620struct WrappedCookie {
 6621  void *real_cookie;
 6622  __sanitizer_cookie_io_functions_t real_io_funcs;
 6623};
 6624
 6625static uptr wrapped_read(void *cookie, char *buf, uptr size) {
 6626  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 6627  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
 6628  __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
 6629  return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
 6630}
 6631
 6632static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
 6633  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 6634  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
 6635  __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
 6636  return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
 6637}
 6638
 6639static int wrapped_seek(void *cookie, u64 *offset, int whence) {
 6640  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 6641  COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
 6642  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
 6643  __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
 6644  return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
 6645                   : -1;
 6646}
 6647
 6648static int wrapped_close(void *cookie) {
 6649  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 6650  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
 6651  __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
 6652  int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
 6653  InternalFree(wrapped_cookie);
 6654  return res;
 6655}
 6656
 6657INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
 6658            __sanitizer_cookie_io_functions_t io_funcs) {
 6659  void *ctx;
 6660  COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
 6661  WrappedCookie *wrapped_cookie =
 6662      (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
 6663  wrapped_cookie->real_cookie = cookie;
 6664  wrapped_cookie->real_io_funcs = io_funcs;
 6665  __sanitizer_FILE *res =
 6666      REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
 6667                                               wrapped_seek, wrapped_close});
 6668  return res;
 6669}
 6670
 6671#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
 6672#else
 6673#define INIT_FOPENCOOKIE
 6674#endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
 6675
 6676#if SANITIZER_INTERCEPT_SEM
 6677INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
 6678  void *ctx;
 6679  COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
 6680  // Workaround a bug in glibc's "old" semaphore implementation by
 6681  // zero-initializing the sem_t contents. This has to be done here because
 6682  // interceptors bind to the lowest version before glibc 2.36, hitting the
 6683  // buggy code path while the non-sanitized build of the same code works fine.
 6684  REAL(memset)(s, 0, sizeof(*s));
 6685  int res = REAL(sem_init)(s, pshared, value);
 6686  return res;
 6687}
 6688
 6689INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
 6690  void *ctx;
 6691  COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
 6692  int res = REAL(sem_destroy)(s);
 6693  return res;
 6694}
 6695
 6696INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
 6697  void *ctx;
 6698  COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
 6699  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
 6700  if (res == 0) {
 6701    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
 6702  }
 6703  return res;
 6704}
 6705
 6706INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
 6707  void *ctx;
 6708  COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
 6709  int res = REAL(sem_trywait)(s);
 6710  if (res == 0) {
 6711    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
 6712  }
 6713  return res;
 6714}
 6715
 6716INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
 6717  void *ctx;
 6718  COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
 6719  COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
 6720  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
 6721  if (res == 0) {
 6722    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
 6723  }
 6724  return res;
 6725}
 6726
 6727INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
 6728  void *ctx;
 6729  COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
 6730  COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
 6731  int res = REAL(sem_post)(s);
 6732  return res;
 6733}
 6734
 6735INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
 6736  void *ctx;
 6737  COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
 6738  int res = REAL(sem_getvalue)(s, sval);
 6739  if (res == 0) {
 6740    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
 6741    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
 6742  }
 6743  return res;
 6744}
 6745
 6746INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {
 6747  void *ctx;
 6748  va_list ap;
 6749  va_start(ap, oflag);
 6750  u32 mode = va_arg(ap, u32);
 6751  u32 value = va_arg(ap, u32);
 6752  COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);
 6753  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 6754  __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);
 6755  if (s)
 6756    COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));
 6757  va_end(ap);
 6758  return s;
 6759}
 6760
 6761INTERCEPTOR(int, sem_unlink, const char *name) {
 6762  void *ctx;
 6763  COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);
 6764  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 6765  return REAL(sem_unlink)(name);
 6766}
 6767
 6768#  define INIT_SEM                            \
 6769    COMMON_INTERCEPT_FUNCTION(sem_init);      \
 6770    COMMON_INTERCEPT_FUNCTION(sem_destroy);   \
 6771    COMMON_INTERCEPT_FUNCTION(sem_wait);      \
 6772    COMMON_INTERCEPT_FUNCTION(sem_trywait);   \
 6773    COMMON_INTERCEPT_FUNCTION(sem_timedwait); \
 6774    COMMON_INTERCEPT_FUNCTION(sem_post);      \
 6775    COMMON_INTERCEPT_FUNCTION(sem_getvalue);  \
 6776    COMMON_INTERCEPT_FUNCTION(sem_open);      \
 6777    COMMON_INTERCEPT_FUNCTION(sem_unlink);
 6778#else
 6779#  define INIT_SEM
 6780#endif  // SANITIZER_INTERCEPT_SEM
 6781
 6782#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
 6783INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
 6784  void *ctx;
 6785  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
 6786  int res = REAL(pthread_setcancelstate)(state, oldstate);
 6787  if (res == 0 && oldstate != nullptr)
 6788    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
 6789  return res;
 6790}
 6791
 6792INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
 6793  void *ctx;
 6794  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
 6795  int res = REAL(pthread_setcanceltype)(type, oldtype);
 6796  if (res == 0 && oldtype != nullptr)
 6797    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
 6798  return res;
 6799}
 6800#define INIT_PTHREAD_SETCANCEL                                                 \
 6801  COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
 6802  COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
 6803#else
 6804#define INIT_PTHREAD_SETCANCEL
 6805#endif
 6806
 6807#if SANITIZER_INTERCEPT_MINCORE
 6808INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
 6809  void *ctx;
 6810  COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
 6811  int res = REAL(mincore)(addr, length, vec);
 6812  if (res == 0) {
 6813    uptr page_size = GetPageSizeCached();
 6814    uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
 6815    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
 6816  }
 6817  return res;
 6818}
 6819#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
 6820#else
 6821#define INIT_MINCORE
 6822#endif
 6823
 6824#if SANITIZER_INTERCEPT_PROCESS_VM_READV
 6825INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
 6826            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
 6827            uptr flags) {
 6828  void *ctx;
 6829  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
 6830                           remote_iov, riovcnt, flags);
 6831  SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
 6832                                       riovcnt, flags);
 6833  if (res > 0)
 6834    write_iovec(ctx, local_iov, liovcnt, res);
 6835  return res;
 6836}
 6837
 6838INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
 6839            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
 6840            uptr flags) {
 6841  void *ctx;
 6842  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
 6843                           remote_iov, riovcnt, flags);
 6844  SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
 6845                                        riovcnt, flags);
 6846  if (res > 0)
 6847    read_iovec(ctx, local_iov, liovcnt, res);
 6848  return res;
 6849}
 6850#define INIT_PROCESS_VM_READV                                                  \
 6851  COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
 6852  COMMON_INTERCEPT_FUNCTION(process_vm_writev);
 6853#else
 6854#define INIT_PROCESS_VM_READV
 6855#endif
 6856
 6857#if SANITIZER_INTERCEPT_CTERMID
 6858INTERCEPTOR(char *, ctermid, char *s) {
 6859  void *ctx;
 6860  COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
 6861  char *res = REAL(ctermid)(s);
 6862  if (res) {
 6863    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 6864  }
 6865  return res;
 6866}
 6867#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
 6868#else
 6869#define INIT_CTERMID
 6870#endif
 6871
 6872#if SANITIZER_INTERCEPT_CTERMID_R
 6873INTERCEPTOR(char *, ctermid_r, char *s) {
 6874  void *ctx;
 6875  COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
 6876  char *res = REAL(ctermid_r)(s);
 6877  if (res) {
 6878    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
 6879  }
 6880  return res;
 6881}
 6882#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
 6883#else
 6884#define INIT_CTERMID_R
 6885#endif
 6886
 6887#if SANITIZER_INTERCEPT_RECV_RECVFROM
 6888INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
 6889  void *ctx;
 6890  COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
 6891  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6892  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recv)(fd, buf, len, flags);
 6893  if (res > 0) {
 6894    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
 6895  }
 6896  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 6897  return res;
 6898}
 6899
 6900INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
 6901            void *srcaddr, int *addrlen) {
 6902  void *ctx;
 6903  COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
 6904                           addrlen);
 6905  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6906  SIZE_T srcaddr_sz;
 6907  if (srcaddr) srcaddr_sz = *addrlen;
 6908  (void)srcaddr_sz;  // prevent "set but not used" warning
 6909  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvfrom)(fd, buf, len, flags,
 6910                                                        srcaddr, addrlen);
 6911  if (res > 0)
 6912    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
 6913  if (res >= 0 && srcaddr)
 6914    COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
 6915                                        Min((SIZE_T)*addrlen, srcaddr_sz));
 6916  return res;
 6917}
 6918#define INIT_RECV_RECVFROM          \
 6919  COMMON_INTERCEPT_FUNCTION(recv);  \
 6920  COMMON_INTERCEPT_FUNCTION(recvfrom);
 6921#else
 6922#define INIT_RECV_RECVFROM
 6923#endif
 6924
 6925#if SANITIZER_INTERCEPT_SEND_SENDTO
 6926INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
 6927  void *ctx;
 6928  COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
 6929  if (fd >= 0) {
 6930    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6931    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 6932  }
 6933  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(send)(fd, buf, len, flags);
 6934  if (common_flags()->intercept_send && res > 0)
 6935    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
 6936  return res;
 6937}
 6938
 6939INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
 6940            void *dstaddr, int addrlen) {
 6941  void *ctx;
 6942  COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
 6943  if (fd >= 0) {
 6944    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6945    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 6946  }
 6947  // Can't check dstaddr as it may have uninitialized padding at the end.
 6948  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendto)(fd, buf, len, flags,
 6949                                                      dstaddr, addrlen);
 6950  if (common_flags()->intercept_send && res > 0)
 6951    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
 6952  return res;
 6953}
 6954#define INIT_SEND_SENDTO           \
 6955  COMMON_INTERCEPT_FUNCTION(send); \
 6956  COMMON_INTERCEPT_FUNCTION(sendto);
 6957#else
 6958#define INIT_SEND_SENDTO
 6959#endif
 6960
 6961#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
 6962INTERCEPTOR(int, eventfd_read, int fd, __sanitizer_eventfd_t *value) {
 6963  void *ctx;
 6964  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
 6965  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6966  int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_read)(fd, value);
 6967  if (res == 0) {
 6968    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
 6969    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 6970  }
 6971  return res;
 6972}
 6973INTERCEPTOR(int, eventfd_write, int fd, __sanitizer_eventfd_t value) {
 6974  void *ctx;
 6975  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
 6976  if (fd >= 0) {
 6977    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 6978    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
 6979  }
 6980  int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_write)(fd, value);
 6981  return res;
 6982}
 6983#define INIT_EVENTFD_READ_WRITE            \
 6984  COMMON_INTERCEPT_FUNCTION(eventfd_read); \
 6985  COMMON_INTERCEPT_FUNCTION(eventfd_write)
 6986#else
 6987#define INIT_EVENTFD_READ_WRITE
 6988#endif
 6989
 6990#if SANITIZER_INTERCEPT_STAT
 6991INTERCEPTOR(int, stat, const char *path, void *buf) {
 6992  void *ctx;
 6993  COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
 6994  if (common_flags()->intercept_stat)
 6995    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 6996  int res = REAL(stat)(path, buf);
 6997  if (!res)
 6998    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
 6999  return res;
 7000}
 7001#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
 7002#else
 7003#define INIT_STAT
 7004#endif
 7005
 7006#if SANITIZER_INTERCEPT_STAT64
 7007INTERCEPTOR(int, stat64, const char *path, void *buf) {
 7008  void *ctx;
 7009  COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf);
 7010  if (common_flags()->intercept_stat)
 7011    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7012  int res = REAL(stat64)(path, buf);
 7013  if (!res)
 7014    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
 7015  return res;
 7016}
 7017#define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64)
 7018#else
 7019#define INIT_STAT64
 7020#endif
 7021
 7022
 7023#if SANITIZER_INTERCEPT_LSTAT
 7024INTERCEPTOR(int, lstat, const char *path, void *buf) {
 7025  void *ctx;
 7026  COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);
 7027  if (common_flags()->intercept_stat)
 7028    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7029  int res = REAL(lstat)(path, buf);
 7030  if (!res)
 7031    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
 7032  return res;
 7033}
 7034#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)
 7035#else
 7036#define INIT_LSTAT
 7037#endif
 7038
 7039#if SANITIZER_INTERCEPT_STAT64
 7040INTERCEPTOR(int, lstat64, const char *path, void *buf) {
 7041  void *ctx;
 7042  COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf);
 7043  if (common_flags()->intercept_stat)
 7044    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7045  int res = REAL(lstat64)(path, buf);
 7046  if (!res)
 7047    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
 7048  return res;
 7049}
 7050#define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64)
 7051#else
 7052#define INIT_LSTAT64
 7053#endif
 7054
 7055#if SANITIZER_INTERCEPT___XSTAT
 7056INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
 7057  void *ctx;
 7058  COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
 7059  if (common_flags()->intercept_stat)
 7060    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7061  int res = REAL(__xstat)(version, path, buf);
 7062  if (!res)
 7063    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
 7064  return res;
 7065}
 7066#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
 7067#else
 7068#define INIT___XSTAT
 7069#endif
 7070
 7071#if SANITIZER_INTERCEPT___XSTAT64
 7072INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
 7073  void *ctx;
 7074  COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
 7075  if (common_flags()->intercept_stat)
 7076    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7077  int res = REAL(__xstat64)(version, path, buf);
 7078  if (!res)
 7079    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
 7080  return res;
 7081}
 7082#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
 7083#else
 7084#define INIT___XSTAT64
 7085#endif
 7086
 7087#if SANITIZER_INTERCEPT___LXSTAT
 7088INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
 7089  void *ctx;
 7090  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
 7091  if (common_flags()->intercept_stat)
 7092    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7093  int res = REAL(__lxstat)(version, path, buf);
 7094  if (!res)
 7095    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
 7096  return res;
 7097}
 7098#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
 7099#else
 7100#define INIT___LXSTAT
 7101#endif
 7102
 7103#if SANITIZER_INTERCEPT___LXSTAT64
 7104INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
 7105  void *ctx;
 7106  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
 7107  if (common_flags()->intercept_stat)
 7108    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
 7109  int res = REAL(__lxstat64)(version, path, buf);
 7110  if (!res)
 7111    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
 7112  return res;
 7113}
 7114#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
 7115#else
 7116#define INIT___LXSTAT64
 7117#endif
 7118
 7119// FIXME: add other *stat interceptor
 7120
 7121#if SANITIZER_INTERCEPT_UTMP
 7122INTERCEPTOR(void *, getutent, int dummy) {
 7123  void *ctx;
 7124  COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);
 7125  void *res = REAL(getutent)(dummy);
 7126  if (res)
 7127    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
 7128  return res;
 7129}
 7130INTERCEPTOR(void *, getutid, void *ut) {
 7131  void *ctx;
 7132  COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);
 7133  void *res = REAL(getutid)(ut);
 7134  if (res)
 7135    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
 7136  return res;
 7137}
 7138INTERCEPTOR(void *, getutline, void *ut) {
 7139  void *ctx;
 7140  COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);
 7141  void *res = REAL(getutline)(ut);
 7142  if (res)
 7143    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
 7144  return res;
 7145}
 7146#define INIT_UTMP                      \
 7147  COMMON_INTERCEPT_FUNCTION(getutent); \
 7148  COMMON_INTERCEPT_FUNCTION(getutid);  \
 7149  COMMON_INTERCEPT_FUNCTION(getutline);
 7150#else
 7151#define INIT_UTMP
 7152#endif
 7153
 7154#if SANITIZER_INTERCEPT_UTMPX
 7155INTERCEPTOR(void *, getutxent, int dummy) {
 7156  void *ctx;
 7157  COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);
 7158  void *res = REAL(getutxent)(dummy);
 7159  if (res)
 7160    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
 7161  return res;
 7162}
 7163INTERCEPTOR(void *, getutxid, void *ut) {
 7164  void *ctx;
 7165  COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);
 7166  void *res = REAL(getutxid)(ut);
 7167  if (res)
 7168    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
 7169  return res;
 7170}
 7171INTERCEPTOR(void *, getutxline, void *ut) {
 7172  void *ctx;
 7173  COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);
 7174  void *res = REAL(getutxline)(ut);
 7175  if (res)
 7176    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
 7177  return res;
 7178}
 7179INTERCEPTOR(void *, pututxline, const void *ut) {
 7180  void *ctx;
 7181  COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
 7182  if (ut)
 7183    COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
 7184  void *res = REAL(pututxline)(ut);
 7185  if (res)
 7186    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
 7187  return res;
 7188}
 7189#define INIT_UTMPX                      \
 7190  COMMON_INTERCEPT_FUNCTION(getutxent); \
 7191  COMMON_INTERCEPT_FUNCTION(getutxid);  \
 7192  COMMON_INTERCEPT_FUNCTION(getutxline); \
 7193  COMMON_INTERCEPT_FUNCTION(pututxline);
 7194#else
 7195#define INIT_UTMPX
 7196#endif
 7197
 7198#if SANITIZER_INTERCEPT_GETLOADAVG
 7199INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {
 7200  void *ctx;
 7201  COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);
 7202  int res = REAL(getloadavg)(loadavg, nelem);
 7203  if (res > 0)
 7204    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));
 7205  return res;
 7206}
 7207#define INIT_GETLOADAVG                      \
 7208  COMMON_INTERCEPT_FUNCTION(getloadavg);
 7209#else
 7210#define INIT_GETLOADAVG
 7211#endif
 7212
 7213#if SANITIZER_INTERCEPT_MCHECK_MPROBE
 7214INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
 7215  return 0;
 7216}
 7217
 7218INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
 7219  return 0;
 7220}
 7221
 7222INTERCEPTOR(int, mprobe, void *ptr) {
 7223  return 0;
 7224}
 7225#endif
 7226
 7227#if SANITIZER_INTERCEPT_WCSLEN
 7228INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
 7229  void *ctx;
 7230  COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
 7231  SIZE_T res = REAL(wcslen)(s);
 7232  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
 7233  return res;
 7234}
 7235
 7236INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
 7237  void *ctx;
 7238  COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
 7239  SIZE_T res = REAL(wcsnlen)(s, n);
 7240  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
 7241  return res;
 7242}
 7243#define INIT_WCSLEN                  \
 7244  COMMON_INTERCEPT_FUNCTION(wcslen); \
 7245  COMMON_INTERCEPT_FUNCTION(wcsnlen);
 7246#else
 7247#define INIT_WCSLEN
 7248#endif
 7249
 7250#if SANITIZER_INTERCEPT_WCSCAT
 7251INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
 7252  void *ctx;
 7253  COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
 7254  SIZE_T src_size = internal_wcslen(src);
 7255  SIZE_T dst_size = internal_wcslen(dst);
 7256  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
 7257  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
 7258  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
 7259                                 (src_size + 1) * sizeof(wchar_t));
 7260  return REAL(wcscat)(dst, src);
 7261}
 7262
 7263INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
 7264  void *ctx;
 7265  COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
 7266  SIZE_T src_size = internal_wcsnlen(src, n);
 7267  SIZE_T dst_size = internal_wcslen(dst);
 7268  COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
 7269                                Min(src_size + 1, n) * sizeof(wchar_t));
 7270  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
 7271  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
 7272                                 (src_size + 1) * sizeof(wchar_t));
 7273  return REAL(wcsncat)(dst, src, n);
 7274}
 7275#define INIT_WCSCAT                  \
 7276  COMMON_INTERCEPT_FUNCTION(wcscat); \
 7277  COMMON_INTERCEPT_FUNCTION(wcsncat);
 7278#else
 7279#define INIT_WCSCAT
 7280#endif
 7281
 7282#if SANITIZER_INTERCEPT_WCSDUP
 7283INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {
 7284  void *ctx;
 7285  COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);
 7286  SIZE_T len = internal_wcslen(s);
 7287  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));
 7288  wchar_t *result = REAL(wcsdup)(s);
 7289  if (result)
 7290    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));
 7291  return result;
 7292}
 7293
 7294#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);
 7295#else
 7296#define INIT_WCSDUP
 7297#endif
 7298
 7299#if SANITIZER_INTERCEPT_STRXFRM
 7300static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); }
 7301
 7302static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); }
 7303
 7304#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...)             \
 7305  {                                                                        \
 7306    void *ctx;                                                             \
 7307    COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \
 7308    COMMON_INTERCEPTOR_READ_RANGE(ctx, src,                                \
 7309                                  sizeof(*src) * (RealStrLen(src) + 1));   \
 7310    SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__);             \
 7311    if (res < len)                                                         \
 7312      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \
 7313    return res;                                                            \
 7314  }
 7315
 7316INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {
 7317  STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);
 7318}
 7319
 7320INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,
 7321            void *locale) {
 7322  STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);
 7323}
 7324
 7325#define INIT_STRXFRM                  \
 7326  COMMON_INTERCEPT_FUNCTION(strxfrm); \
 7327  COMMON_INTERCEPT_FUNCTION(strxfrm_l);
 7328#else
 7329#define INIT_STRXFRM
 7330#endif
 7331
 7332#if SANITIZER_INTERCEPT___STRXFRM_L
 7333INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,
 7334            void *locale) {
 7335  STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);
 7336}
 7337
 7338#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);
 7339#else
 7340#define INIT___STRXFRM_L
 7341#endif
 7342
 7343#if SANITIZER_INTERCEPT_WCSXFRM
 7344INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {
 7345  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);
 7346}
 7347
 7348INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
 7349            void *locale) {
 7350  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);
 7351}
 7352
 7353#define INIT_WCSXFRM                  \
 7354  COMMON_INTERCEPT_FUNCTION(wcsxfrm); \
 7355  COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);
 7356#else
 7357#define INIT_WCSXFRM
 7358#endif
 7359
 7360#if SANITIZER_INTERCEPT___WCSXFRM_L
 7361INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
 7362            void *locale) {
 7363  STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);
 7364}
 7365
 7366#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);
 7367#else
 7368#define INIT___WCSXFRM_L
 7369#endif
 7370
 7371#if SANITIZER_INTERCEPT_ACCT
 7372INTERCEPTOR(int, acct, const char *file) {
 7373  void *ctx;
 7374  COMMON_INTERCEPTOR_ENTER(ctx, acct, file);
 7375  if (file)
 7376    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
 7377  return REAL(acct)(file);
 7378}
 7379#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)
 7380#else
 7381#define INIT_ACCT
 7382#endif
 7383
 7384#if SANITIZER_INTERCEPT_USER_FROM_UID
 7385INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {
 7386  void *ctx;
 7387  const char *user;
 7388  COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);
 7389  user = REAL(user_from_uid)(uid, nouser);
 7390  if (user)
 7391    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1);
 7392  return user;
 7393}
 7394#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)
 7395#else
 7396#define INIT_USER_FROM_UID
 7397#endif
 7398
 7399#if SANITIZER_INTERCEPT_UID_FROM_USER
 7400INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {
 7401  void *ctx;
 7402  int res;
 7403  COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);
 7404  if (name)
 7405    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7406  res = REAL(uid_from_user)(name, uid);
 7407  if (uid)
 7408    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));
 7409  return res;
 7410}
 7411#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)
 7412#else
 7413#define INIT_UID_FROM_USER
 7414#endif
 7415
 7416#if SANITIZER_INTERCEPT_GROUP_FROM_GID
 7417INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {
 7418  void *ctx;
 7419  const char *group;
 7420  COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);
 7421  group = REAL(group_from_gid)(gid, nogroup);
 7422  if (group)
 7423    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1);
 7424  return group;
 7425}
 7426#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)
 7427#else
 7428#define INIT_GROUP_FROM_GID
 7429#endif
 7430
 7431#if SANITIZER_INTERCEPT_GID_FROM_GROUP
 7432INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {
 7433  void *ctx;
 7434  int res;
 7435  COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);
 7436  if (group)
 7437    COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1);
 7438  res = REAL(gid_from_group)(group, gid);
 7439  if (gid)
 7440    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));
 7441  return res;
 7442}
 7443#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)
 7444#else
 7445#define INIT_GID_FROM_GROUP
 7446#endif
 7447
 7448#if SANITIZER_INTERCEPT_ACCESS
 7449INTERCEPTOR(int, access, const char *path, int mode) {
 7450  void *ctx;
 7451  COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);
 7452  if (path)
 7453    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 7454  return REAL(access)(path, mode);
 7455}
 7456#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)
 7457#else
 7458#define INIT_ACCESS
 7459#endif
 7460
 7461#if SANITIZER_INTERCEPT_FACCESSAT
 7462INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
 7463  void *ctx;
 7464  COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);
 7465  if (path)
 7466    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 7467  return REAL(faccessat)(fd, path, mode, flags);
 7468}
 7469#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)
 7470#else
 7471#define INIT_FACCESSAT
 7472#endif
 7473
 7474#if SANITIZER_INTERCEPT_GETGROUPLIST
 7475INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
 7476            int *ngroups) {
 7477  void *ctx;
 7478  int res;
 7479  COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
 7480  if (name)
 7481    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7482  if (ngroups)
 7483    COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
 7484  res = REAL(getgrouplist)(name, basegid, groups, ngroups);
 7485  if (!res && groups && ngroups) {
 7486    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
 7487    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
 7488  }
 7489  return res;
 7490}
 7491
 7492#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);
 7493#else
 7494#define INIT_GETGROUPLIST
 7495#endif
 7496
 7497#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP
 7498INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
 7499            int maxgrp, int *ngroups) {
 7500  void *ctx;
 7501  int res;
 7502  COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,
 7503                           maxgrp, ngroups);
 7504  if (name)
 7505    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7506  res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
 7507  if (!res && groups && ngroups) {
 7508    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
 7509    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
 7510  }
 7511  return res;
 7512}
 7513
 7514#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);
 7515#else
 7516#define INIT_GETGROUPMEMBERSHIP
 7517#endif
 7518
 7519#if SANITIZER_INTERCEPT_READLINK
 7520INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
 7521  void* ctx;
 7522  COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
 7523  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 7524  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
 7525  if (res > 0)
 7526    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
 7527  return res;
 7528}
 7529
 7530#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
 7531#else
 7532#define INIT_READLINK
 7533#endif
 7534
 7535#if SANITIZER_INTERCEPT_READLINKAT
 7536INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
 7537            SIZE_T bufsiz) {
 7538  void* ctx;
 7539  COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
 7540  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 7541  SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
 7542  if (res > 0)
 7543    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
 7544  return res;
 7545}
 7546
 7547#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
 7548#else
 7549#define INIT_READLINKAT
 7550#endif
 7551
 7552#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
 7553INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
 7554            struct file_handle *handle, int *mount_id, int flags) {
 7555  void* ctx;
 7556  COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
 7557                           mount_id, flags);
 7558  COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1);
 7559
 7560  __sanitizer_file_handle *sanitizer_handle =
 7561      reinterpret_cast<__sanitizer_file_handle*>(handle);
 7562  COMMON_INTERCEPTOR_READ_RANGE(
 7563      ctx, &sanitizer_handle->handle_bytes,
 7564      sizeof(sanitizer_handle->handle_bytes));
 7565
 7566  int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
 7567  if (!res) {
 7568    COMMON_INTERCEPTOR_WRITE_RANGE(
 7569        ctx, &sanitizer_handle->handle_bytes,
 7570        sizeof(sanitizer_handle->handle_bytes));
 7571    COMMON_INTERCEPTOR_WRITE_RANGE(
 7572        ctx, &sanitizer_handle->handle_type,
 7573        sizeof(sanitizer_handle->handle_type));
 7574    COMMON_INTERCEPTOR_WRITE_RANGE(
 7575        ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
 7576    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
 7577  }
 7578  return res;
 7579}
 7580
 7581#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
 7582#else
 7583#define INIT_NAME_TO_HANDLE_AT
 7584#endif
 7585
 7586#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
 7587INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
 7588            int flags) {
 7589  void* ctx;
 7590  COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
 7591
 7592  __sanitizer_file_handle *sanitizer_handle =
 7593      reinterpret_cast<__sanitizer_file_handle*>(handle);
 7594  COMMON_INTERCEPTOR_READ_RANGE(
 7595      ctx, &sanitizer_handle->handle_bytes,
 7596      sizeof(sanitizer_handle->handle_bytes));
 7597  COMMON_INTERCEPTOR_READ_RANGE(
 7598      ctx, &sanitizer_handle->handle_type,
 7599      sizeof(sanitizer_handle->handle_type));
 7600  COMMON_INTERCEPTOR_READ_RANGE(
 7601      ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
 7602
 7603  return COMMON_INTERCEPTOR_BLOCK_REAL(open_by_handle_at)(mount_fd, handle,
 7604                                                          flags);
 7605}
 7606
 7607#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
 7608#else
 7609#define INIT_OPEN_BY_HANDLE_AT
 7610#endif
 7611
 7612#if SANITIZER_INTERCEPT_STRLCPY
 7613INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {
 7614  void *ctx;
 7615  SIZE_T res;
 7616  COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);
 7617  if (src) {
 7618    // Keep strnlen as macro argument, as macro may ignore it.
 7619    COMMON_INTERCEPTOR_READ_STRING(
 7620        ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);
 7621  }
 7622  res = REAL(strlcpy)(dst, src, size);
 7623  COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1);
 7624  return res;
 7625}
 7626
 7627INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {
 7628  void *ctx;
 7629  SIZE_T len = 0;
 7630  COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);
 7631  // src is checked in the strlcpy() interceptor
 7632  if (dst) {
 7633    len = internal_strnlen(dst, size);
 7634    COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);
 7635  }
 7636  // Reuse the rest of the code in the strlcpy() interceptor
 7637  return WRAP(strlcpy)(dst + len, src, size - len) + len;
 7638}
 7639#define INIT_STRLCPY \
 7640  COMMON_INTERCEPT_FUNCTION(strlcpy); \
 7641  COMMON_INTERCEPT_FUNCTION(strlcat);
 7642#else
 7643#define INIT_STRLCPY
 7644#endif
 7645
 7646#if SANITIZER_INTERCEPT_MMAP
 7647INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,
 7648            OFF_T off) {
 7649  void *ctx;
 7650  if (common_flags()->detect_write_exec)
 7651    ReportMmapWriteExec(prot, flags);
 7652  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 7653    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
 7654  COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
 7655  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);
 7656}
 7657
 7658INTERCEPTOR(int, munmap, void *addr, SIZE_T sz) {
 7659  void *ctx;
 7660  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 7661    return (int)internal_munmap(addr, sz);
 7662  COMMON_INTERCEPTOR_ENTER(ctx, munmap, addr, sz);
 7663  COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz);
 7664}
 7665
 7666INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {
 7667  void *ctx;
 7668  if (common_flags()->detect_write_exec)
 7669    ReportMmapWriteExec(prot, 0);
 7670  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 7671    return (int)internal_mprotect(addr, sz, prot);
 7672  COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);
 7673  MprotectMallocZones(addr, prot);
 7674  return REAL(mprotect)(addr, sz, prot);
 7675}
 7676#define INIT_MMAP                                                              \
 7677  COMMON_INTERCEPT_FUNCTION(mmap);                                             \
 7678  COMMON_INTERCEPT_FUNCTION(munmap);                                           \
 7679  COMMON_INTERCEPT_FUNCTION(mprotect);
 7680#else
 7681#define INIT_MMAP
 7682#endif
 7683
 7684#if SANITIZER_INTERCEPT_MMAP64
 7685INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,
 7686            OFF64_T off) {
 7687  void *ctx;
 7688  if (common_flags()->detect_write_exec)
 7689    ReportMmapWriteExec(prot, flags);
 7690  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 7691    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
 7692  COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
 7693  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);
 7694}
 7695#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);
 7696#else
 7697#define INIT_MMAP64
 7698#endif
 7699
 7700#if SANITIZER_INTERCEPT_DEVNAME
 7701INTERCEPTOR(char *, devname, u64 dev, u32 type) {
 7702  void *ctx;
 7703  char *name;
 7704  COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);
 7705  name = REAL(devname)(dev, type);
 7706  if (name)
 7707    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
 7708  return name;
 7709}
 7710#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);
 7711#else
 7712#define INIT_DEVNAME
 7713#endif
 7714
 7715#if SANITIZER_INTERCEPT_DEVNAME_R
 7716#if SANITIZER_NETBSD
 7717#define DEVNAME_R_RETTYPE int
 7718#define DEVNAME_R_SUCCESS(x) (!(x))
 7719#else
 7720#define DEVNAME_R_RETTYPE char*
 7721#define DEVNAME_R_SUCCESS(x) (x)
 7722#endif
 7723INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
 7724            uptr len) {
 7725  void *ctx;
 7726  COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
 7727  DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
 7728  if (DEVNAME_R_SUCCESS(res))
 7729    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1);
 7730  return res;
 7731}
 7732#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);
 7733#else
 7734#define INIT_DEVNAME_R
 7735#endif
 7736
 7737#if SANITIZER_INTERCEPT_FGETLN
 7738INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {
 7739  void *ctx;
 7740  COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);
 7741  char *str = REAL(fgetln)(stream, len);
 7742  if (str && len) {
 7743    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
 7744    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);
 7745  }
 7746  return str;
 7747}
 7748#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)
 7749#else
 7750#define INIT_FGETLN
 7751#endif
 7752
 7753#if SANITIZER_INTERCEPT_STRMODE
 7754INTERCEPTOR(void, strmode, u32 mode, char *bp) {
 7755  void *ctx;
 7756  COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);
 7757  REAL(strmode)(mode, bp);
 7758  if (bp)
 7759    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1);
 7760}
 7761#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)
 7762#else
 7763#define INIT_STRMODE
 7764#endif
 7765
 7766#if SANITIZER_INTERCEPT_TTYENT
 7767INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {
 7768  void *ctx;
 7769  COMMON_INTERCEPTOR_ENTER(ctx, getttyent);
 7770  struct __sanitizer_ttyent *ttyent = REAL(getttyent)();
 7771  if (ttyent)
 7772    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
 7773  return ttyent;
 7774}
 7775INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
 7776  void *ctx;
 7777  COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);
 7778  if (name)
 7779    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7780  struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);
 7781  if (ttyent)
 7782    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
 7783  return ttyent;
 7784}
 7785#define INIT_TTYENT \
 7786  COMMON_INTERCEPT_FUNCTION(getttyent); \
 7787  COMMON_INTERCEPT_FUNCTION(getttynam);
 7788#else
 7789#define INIT_TTYENT
 7790#endif
 7791
 7792#if SANITIZER_INTERCEPT_TTYENTPATH
 7793INTERCEPTOR(int, setttyentpath, char *path) {
 7794  void *ctx;
 7795  COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
 7796  if (path)
 7797    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 7798  return REAL(setttyentpath)(path);
 7799}
 7800#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);
 7801#else
 7802#define INIT_TTYENTPATH
 7803#endif
 7804
 7805#if SANITIZER_INTERCEPT_PROTOENT
 7806static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {
 7807  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
 7808
 7809  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1);
 7810
 7811  SIZE_T pp_size = 1; // One handles the trailing \0
 7812
 7813  for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
 7814      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1);
 7815
 7816  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, pp_size * sizeof(char *));
 7817}
 7818
 7819INTERCEPTOR(struct __sanitizer_protoent *, getprotoent,) {
 7820  void *ctx;
 7821  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent,);
 7822  struct __sanitizer_protoent *p = REAL(getprotoent)();
 7823  if (p)
 7824    write_protoent(ctx, p);
 7825  return p;
 7826}
 7827
 7828INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
 7829  void *ctx;
 7830  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);
 7831  if (name)
 7832    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7833  struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
 7834  if (p)
 7835    write_protoent(ctx, p);
 7836  return p;
 7837}
 7838
 7839INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
 7840  void *ctx;
 7841  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
 7842  struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
 7843  if (p)
 7844    write_protoent(ctx, p);
 7845  return p;
 7846}
 7847#define INIT_PROTOENT \
 7848  COMMON_INTERCEPT_FUNCTION(getprotoent); \
 7849  COMMON_INTERCEPT_FUNCTION(getprotobyname); \
 7850  COMMON_INTERCEPT_FUNCTION(getprotobynumber)
 7851#else
 7852#define INIT_PROTOENT
 7853#endif
 7854
 7855#if SANITIZER_INTERCEPT_PROTOENT_R
 7856INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,
 7857            char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {
 7858  void *ctx;
 7859  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,
 7860                           result);
 7861  int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);
 7862
 7863  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
 7864  if (!res && *result)
 7865    write_protoent(ctx, *result);
 7866  return res;
 7867}
 7868
 7869INTERCEPTOR(int, getprotobyname_r, const char *name,
 7870            struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,
 7871            struct __sanitizer_protoent **result) {
 7872  void *ctx;
 7873  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,
 7874                           buflen, result);
 7875  if (name)
 7876    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7877  int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);
 7878
 7879  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
 7880  if (!res && *result)
 7881    write_protoent(ctx, *result);
 7882  return res;
 7883}
 7884
 7885INTERCEPTOR(int, getprotobynumber_r, int num,
 7886            struct __sanitizer_protoent *result_buf, char *buf,
 7887            SIZE_T buflen, struct __sanitizer_protoent **result) {
 7888  void *ctx;
 7889  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,
 7890                           buflen, result);
 7891  int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);
 7892
 7893  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
 7894  if (!res && *result)
 7895    write_protoent(ctx, *result);
 7896  return res;
 7897}
 7898
 7899#define INIT_PROTOENT_R \
 7900  COMMON_INTERCEPT_FUNCTION(getprotoent_r); \
 7901  COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \
 7902  COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);
 7903#else
 7904#define INIT_PROTOENT_R
 7905#endif
 7906
 7907#if SANITIZER_INTERCEPT_NETENT
 7908INTERCEPTOR(struct __sanitizer_netent *, getnetent,) {
 7909  void *ctx;
 7910  COMMON_INTERCEPTOR_ENTER(ctx, getnetent,);
 7911  struct __sanitizer_netent *n = REAL(getnetent)();
 7912  if (n) {
 7913    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
 7914
 7915    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
 7916
 7917    SIZE_T nn_size = 1; // One handles the trailing \0
 7918
 7919    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
 7920      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
 7921
 7922    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));
 7923  }
 7924  return n;
 7925}
 7926
 7927INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {
 7928  void *ctx;
 7929  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);
 7930  if (name)
 7931    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 7932  struct __sanitizer_netent *n = REAL(getnetbyname)(name);
 7933  if (n) {
 7934    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
 7935
 7936    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
 7937
 7938    SIZE_T nn_size = 1; // One handles the trailing \0
 7939
 7940    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
 7941      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
 7942
 7943    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));
 7944  }
 7945  return n;
 7946}
 7947
 7948INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
 7949  void *ctx;
 7950  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);
 7951  struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);
 7952  if (n) {
 7953    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
 7954
 7955    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
 7956
 7957    SIZE_T nn_size = 1; // One handles the trailing \0
 7958
 7959    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
 7960      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
 7961
 7962    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));
 7963  }
 7964  return n;
 7965}
 7966#define INIT_NETENT \
 7967  COMMON_INTERCEPT_FUNCTION(getnetent); \
 7968  COMMON_INTERCEPT_FUNCTION(getnetbyname); \
 7969  COMMON_INTERCEPT_FUNCTION(getnetbyaddr)
 7970#else
 7971#define INIT_NETENT
 7972#endif
 7973
 7974#if SANITIZER_INTERCEPT_GETMNTINFO
 7975INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
 7976  void *ctx;
 7977  COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
 7978  int cnt = REAL(getmntinfo)(mntbufp, flags);
 7979  if (cnt > 0 && mntbufp) {
 7980    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
 7981    if (*mntbufp)
 7982#if SANITIZER_NETBSD
 7983      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
 7984#else
 7985      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
 7986#endif
 7987  }
 7988  return cnt;
 7989}
 7990#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
 7991#else
 7992#define INIT_GETMNTINFO
 7993#endif
 7994
 7995#if SANITIZER_INTERCEPT_MI_VECTOR_HASH
 7996INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
 7997            u32 hashes[3]) {
 7998  void *ctx;
 7999  COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
 8000  if (key)
 8001    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
 8002  REAL(mi_vector_hash)(key, len, seed, hashes);
 8003  if (hashes)
 8004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
 8005}
 8006#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
 8007#else
 8008#define INIT_MI_VECTOR_HASH
 8009#endif
 8010
 8011#if SANITIZER_INTERCEPT_SETVBUF
 8012INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
 8013  SIZE_T size) {
 8014  void *ctx;
 8015  COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
 8016  int ret = REAL(setvbuf)(stream, buf, mode, size);
 8017  if (buf)
 8018    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
 8019  if (stream)
 8020      unpoison_file(stream);
 8021  return ret;
 8022}
 8023
 8024INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
 8025  void *ctx;
 8026  COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
 8027  REAL(setbuf)(stream, buf);
 8028  if (buf) {
 8029    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
 8030  }
 8031  if (stream)
 8032      unpoison_file(stream);
 8033}
 8034
 8035INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, SIZE_T size) {
 8036  void *ctx;
 8037  COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, size);
 8038  REAL(setbuffer)(stream, buf, size);
 8039  if (buf) {
 8040    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
 8041  }
 8042  if (stream)
 8043    unpoison_file(stream);
 8044}
 8045
 8046INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
 8047  void *ctx;
 8048  COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
 8049  REAL(setlinebuf)(stream);
 8050  if (stream)
 8051    unpoison_file(stream);
 8052}
 8053#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
 8054    COMMON_INTERCEPT_FUNCTION(setbuf); \
 8055    COMMON_INTERCEPT_FUNCTION(setbuffer); \
 8056    COMMON_INTERCEPT_FUNCTION(setlinebuf)
 8057#else
 8058#define INIT_SETVBUF
 8059#endif
 8060
 8061#if SANITIZER_INTERCEPT_GETVFSSTAT
 8062INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
 8063  void *ctx;
 8064  COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
 8065  int ret = REAL(getvfsstat)(buf, bufsize, flags);
 8066  if (buf && ret > 0)
 8067    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
 8068  return ret;
 8069}
 8070#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
 8071#else
 8072#define INIT_GETVFSSTAT
 8073#endif
 8074
 8075#if SANITIZER_INTERCEPT_REGEX
 8076INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
 8077  void *ctx;
 8078  COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
 8079  if (pattern)
 8080    COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1);
 8081  int res = REAL(regcomp)(preg, pattern, cflags);
 8082  if (preg)
 8083    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
 8084  return res;
 8085}
 8086INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
 8087            struct __sanitizer_regmatch *pmatch[], int eflags) {
 8088  void *ctx;
 8089  COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
 8090  if (preg)
 8091    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
 8092  if (string)
 8093    COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1);
 8094  int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
 8095  if (!res && pmatch)
 8096    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
 8097  return res;
 8098}
 8099INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
 8100            SIZE_T errbuf_size) {
 8101  void *ctx;
 8102  COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
 8103  if (preg)
 8104    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
 8105  SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
 8106  if (errbuf)
 8107    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1);
 8108  return res;
 8109}
 8110INTERCEPTOR(void, regfree, const void *preg) {
 8111  void *ctx;
 8112  COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
 8113  if (preg)
 8114    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
 8115  REAL(regfree)(preg);
 8116}
 8117#define INIT_REGEX                                                             \
 8118  COMMON_INTERCEPT_FUNCTION(regcomp);                                          \
 8119  COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4");             \
 8120  COMMON_INTERCEPT_FUNCTION(regerror);                                         \
 8121  COMMON_INTERCEPT_FUNCTION(regfree);
 8122#else
 8123#define INIT_REGEX
 8124#endif
 8125
 8126#if SANITIZER_INTERCEPT_REGEXSUB
 8127INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
 8128            const struct __sanitizer_regmatch *rm, const char *str) {
 8129  void *ctx;
 8130  COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
 8131  if (sub)
 8132    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
 8133  // The implementation demands and hardcodes 10 elements
 8134  if (rm)
 8135    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
 8136  if (str)
 8137    COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
 8138  SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
 8139  if (res > 0 && buf)
 8140    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
 8141  return res;
 8142}
 8143INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
 8144            const struct __sanitizer_regmatch *rm, const char *sstr) {
 8145  void *ctx;
 8146  COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
 8147  if (sub)
 8148    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
 8149  // Hardcode 10 elements as this is hardcoded size
 8150  if (rm)
 8151    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
 8152  if (sstr)
 8153    COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1);
 8154  SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
 8155  if (res > 0 && buf) {
 8156    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
 8157    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1);
 8158  }
 8159  return res;
 8160}
 8161
 8162#define INIT_REGEXSUB                                                          \
 8163  COMMON_INTERCEPT_FUNCTION(regnsub);                                          \
 8164  COMMON_INTERCEPT_FUNCTION(regasub);
 8165#else
 8166#define INIT_REGEXSUB
 8167#endif
 8168
 8169#if SANITIZER_INTERCEPT_FTS
 8170INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
 8171            int (*compar)(void **, void **)) {
 8172  void *ctx;
 8173  COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
 8174  if (path_argv) {
 8175    for (char *const *pa = path_argv; ; ++pa) {
 8176      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
 8177      if (!*pa)
 8178        break;
 8179      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
 8180    }
 8181  }
 8182  // TODO(kamil): handle compar callback
 8183  void *fts = REAL(fts_open)(path_argv, options, compar);
 8184  if (fts)
 8185    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
 8186  return fts;
 8187}
 8188
 8189INTERCEPTOR(void *, fts_read, void *ftsp) {
 8190  void *ctx;
 8191  COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
 8192  if (ftsp)
 8193    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
 8194  void *ftsent = REAL(fts_read)(ftsp);
 8195  if (ftsent)
 8196    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
 8197  return ftsent;
 8198}
 8199
 8200INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
 8201  void *ctx;
 8202  COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
 8203  if (ftsp)
 8204    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
 8205  void *ftsent = REAL(fts_children)(ftsp, options);
 8206  if (ftsent)
 8207    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
 8208  return ftsent;
 8209}
 8210
 8211INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
 8212  void *ctx;
 8213  COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
 8214  if (ftsp)
 8215    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
 8216  if (f)
 8217    COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
 8218  return REAL(fts_set)(ftsp, f, options);
 8219}
 8220
 8221INTERCEPTOR(int, fts_close, void *ftsp) {
 8222  void *ctx;
 8223  COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
 8224  if (ftsp)
 8225    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
 8226  return REAL(fts_close)(ftsp);
 8227}
 8228#define INIT_FTS                                                               \
 8229  COMMON_INTERCEPT_FUNCTION(fts_open);                                         \
 8230  COMMON_INTERCEPT_FUNCTION(fts_read);                                         \
 8231  COMMON_INTERCEPT_FUNCTION(fts_children);                                     \
 8232  COMMON_INTERCEPT_FUNCTION(fts_set);                                          \
 8233  COMMON_INTERCEPT_FUNCTION(fts_close);
 8234#else
 8235#define INIT_FTS
 8236#endif
 8237
 8238#if SANITIZER_INTERCEPT_SYSCTL
 8239INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
 8240            SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
 8241  void *ctx;
 8242  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 8243    return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
 8244  COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
 8245                           newlen);
 8246  if (name)
 8247    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
 8248  if (oldlenp)
 8249    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
 8250  if (newp && newlen)
 8251    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
 8252  int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
 8253  if (!res) {
 8254    if (oldlenp) {
 8255      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
 8256      if (oldp)
 8257        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
 8258    }
 8259  }
 8260  return res;
 8261}
 8262
 8263INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
 8264            void *newp, SIZE_T newlen) {
 8265  void *ctx;
 8266  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
 8267    return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
 8268  COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
 8269                           newlen);
 8270  if (sname)
 8271    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
 8272  if (oldlenp)
 8273    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
 8274  if (newp && newlen)
 8275    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
 8276  int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
 8277  if (!res) {
 8278    if (oldlenp) {
 8279      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
 8280      if (oldp)
 8281        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
 8282    }
 8283  }
 8284  return res;
 8285}
 8286
 8287INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
 8288            SIZE_T *namelenp) {
 8289  void *ctx;
 8290  COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
 8291  if (sname)
 8292    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
 8293  if (namelenp)
 8294    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
 8295  int res = REAL(sysctlnametomib)(sname, name, namelenp);
 8296  if (!res) {
 8297    if (namelenp) {
 8298      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
 8299      if (name)
 8300        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
 8301    }
 8302  }
 8303  return res;
 8304}
 8305
 8306#define INIT_SYSCTL                        \
 8307  COMMON_INTERCEPT_FUNCTION(sysctl);       \
 8308  COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
 8309  COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
 8310#else
 8311#define INIT_SYSCTL
 8312#endif
 8313
 8314#if SANITIZER_INTERCEPT_ASYSCTL
 8315INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
 8316  void *ctx;
 8317  COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
 8318  if (name)
 8319    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
 8320  void *res = REAL(asysctl)(name, namelen, len);
 8321  if (res && len) {
 8322    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
 8323    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
 8324  }
 8325  return res;
 8326}
 8327
 8328INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
 8329  void *ctx;
 8330  COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
 8331  if (sname)
 8332    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
 8333  void *res = REAL(asysctlbyname)(sname, len);
 8334  if (res && len) {
 8335    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
 8336    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
 8337  }
 8338  return res;
 8339}
 8340#define INIT_ASYSCTL                           \
 8341  COMMON_INTERCEPT_FUNCTION(asysctl);          \
 8342  COMMON_INTERCEPT_FUNCTION(asysctlbyname);
 8343#else
 8344#define INIT_ASYSCTL
 8345#endif
 8346
 8347#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
 8348INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
 8349            unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
 8350            int v) {
 8351  void *ctx;
 8352  COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
 8353                           csz, rnode, v);
 8354  if (sname)
 8355    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
 8356  if (namelenp)
 8357    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
 8358  if (csz)
 8359    COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
 8360  // Skip rnode, it's rarely used and not trivial to sanitize
 8361  // It's also used mostly internally
 8362  int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
 8363  if (!res) {
 8364    if (namelenp) {
 8365      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
 8366      if (name)
 8367        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
 8368    }
 8369    if (csz) {
 8370      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
 8371      if (cname)
 8372        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
 8373    }
 8374  }
 8375  return res;
 8376}
 8377#define INIT_SYSCTLGETMIBINFO                  \
 8378  COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
 8379#else
 8380#define INIT_SYSCTLGETMIBINFO
 8381#endif
 8382
 8383#if SANITIZER_INTERCEPT_NL_LANGINFO
 8384INTERCEPTOR(char *, nl_langinfo, long item) {
 8385  void *ctx;
 8386  COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
 8387  char *ret = REAL(nl_langinfo)(item);
 8388  if (ret)
 8389    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
 8390  return ret;
 8391}
 8392#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
 8393#else
 8394#define INIT_NL_LANGINFO
 8395#endif
 8396
 8397#if SANITIZER_INTERCEPT_MODCTL
 8398INTERCEPTOR(int, modctl, int operation, void *argp) {
 8399  void *ctx;
 8400  int ret;
 8401  COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
 8402
 8403  if (operation == modctl_load) {
 8404    if (argp) {
 8405      __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
 8406      COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
 8407      if (ml->ml_filename)
 8408        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
 8409                                      internal_strlen(ml->ml_filename) + 1);
 8410      if (ml->ml_props)
 8411        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
 8412    }
 8413    ret = REAL(modctl)(operation, argp);
 8414  } else if (operation == modctl_unload) {
 8415    if (argp) {
 8416      const char *name = (const char *)argp;
 8417      COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
 8418    }
 8419    ret = REAL(modctl)(operation, argp);
 8420  } else if (operation == modctl_stat) {
 8421    uptr iov_len;
 8422    struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
 8423    if (iov) {
 8424      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
 8425      iov_len = iov->iov_len;
 8426    }
 8427    ret = REAL(modctl)(operation, argp);
 8428    if (iov)
 8429      COMMON_INTERCEPTOR_WRITE_RANGE(
 8430          ctx, iov->iov_base, Min(iov_len,  iov->iov_len));
 8431  } else if (operation == modctl_exists) {
 8432    ret = REAL(modctl)(operation, argp);
 8433  } else {
 8434    ret = REAL(modctl)(operation, argp);
 8435  }
 8436
 8437  return ret;
 8438}
 8439#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
 8440#else
 8441#define INIT_MODCTL
 8442#endif
 8443
 8444#if SANITIZER_INTERCEPT_STRTONUM
 8445INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
 8446            long long maxval, const char **errstr) {
 8447  void *ctx;
 8448  COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
 8449
 8450  // TODO(kamil): Implement strtoll as a common inteceptor
 8451  char *real_endptr;
 8452  long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
 8453  StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
 8454
 8455  ret = REAL(strtonum)(nptr, minval, maxval, errstr);
 8456  if (errstr) {
 8457    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
 8458     if (*errstr)
 8459      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1);
 8460  }
 8461  return ret;
 8462}
 8463#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
 8464#else
 8465#define INIT_STRTONUM
 8466#endif
 8467
 8468#if SANITIZER_INTERCEPT_FPARSELN
 8469INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
 8470            SIZE_T *lineno, const char delim[3], int flags) {
 8471  void *ctx;
 8472  COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
 8473  if (lineno)
 8474    COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
 8475  if (delim)
 8476    COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
 8477  char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
 8478  if (ret) {
 8479    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
 8480    if (len)
 8481      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
 8482    if (lineno)
 8483      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
 8484  }
 8485  return ret;
 8486}
 8487#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
 8488#else
 8489#define INIT_FPARSELN
 8490#endif
 8491
 8492#if SANITIZER_INTERCEPT_STATVFS1
 8493INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
 8494  void *ctx;
 8495  COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
 8496  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 8497  int res = REAL(statvfs1)(path, buf, flags);
 8498  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
 8499  return res;
 8500}
 8501INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
 8502  void *ctx;
 8503  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
 8504  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 8505  int res = REAL(fstatvfs1)(fd, buf, flags);
 8506  if (!res) {
 8507    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
 8508    if (fd >= 0)
 8509      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 8510  }
 8511  return res;
 8512}
 8513#define INIT_STATVFS1                  \
 8514  COMMON_INTERCEPT_FUNCTION(statvfs1);  \
 8515  COMMON_INTERCEPT_FUNCTION(fstatvfs1);
 8516#else
 8517#define INIT_STATVFS1
 8518#endif
 8519
 8520#if SANITIZER_INTERCEPT_STRTOI
 8521INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
 8522            INTMAX_T low, INTMAX_T high, int *rstatus) {
 8523  void *ctx;
 8524  COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
 8525  char *real_endptr;
 8526  INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
 8527  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
 8528  if (rstatus)
 8529    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
 8530  return ret;
 8531}
 8532
 8533INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
 8534            UINTMAX_T low, UINTMAX_T high, int *rstatus) {
 8535  void *ctx;
 8536  COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
 8537  char *real_endptr;
 8538  UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
 8539  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
 8540  if (rstatus)
 8541    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
 8542  return ret;
 8543}
 8544#define INIT_STRTOI                                                            \
 8545  COMMON_INTERCEPT_FUNCTION(strtoi);                                           \
 8546  COMMON_INTERCEPT_FUNCTION(strtou)
 8547#else
 8548#define INIT_STRTOI
 8549#endif
 8550
 8551#if SANITIZER_INTERCEPT_CAPSICUM
 8552#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...)          \
 8553  {                                                                        \
 8554    void *ctx;                                                             \
 8555    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
 8556    if (rights)                                                            \
 8557      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));         \
 8558    __sanitizer_cap_rights_t *ret =                                        \
 8559        REAL(cap_rights_init)(rights, ##__VA_ARGS__);                      \
 8560    if (ret)                                                               \
 8561      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));              \
 8562    return ret;                                                            \
 8563  }
 8564
 8565#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...)           \
 8566  {                                                                       \
 8567    void *ctx;                                                            \
 8568    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
 8569    if (rights)                                                           \
 8570      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));        \
 8571    __sanitizer_cap_rights_t *ret =                                       \
 8572        REAL(cap_rights_set)(rights, ##__VA_ARGS__);                      \
 8573    if (ret)                                                              \
 8574      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));             \
 8575    return ret;                                                           \
 8576  }
 8577
 8578#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...)         \
 8579  {                                                                         \
 8580    void *ctx;                                                              \
 8581    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
 8582    if (rights)                                                             \
 8583      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));          \
 8584    __sanitizer_cap_rights_t *ret =                                         \
 8585        REAL(cap_rights_clear)(rights, ##__VA_ARGS__);                      \
 8586    if (ret)                                                                \
 8587      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));               \
 8588    return ret;                                                             \
 8589  }
 8590
 8591#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...)        \
 8592  {                                                                          \
 8593    void *ctx;                                                               \
 8594    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
 8595    if (rights)                                                              \
 8596      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));           \
 8597    return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__);                   \
 8598  }
 8599
 8600INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
 8601            __sanitizer_cap_rights_t *rights) {
 8602  CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
 8603}
 8604
 8605INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
 8606            __sanitizer_cap_rights_t *rights) {
 8607  CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
 8608}
 8609
 8610INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
 8611            __sanitizer_cap_rights_t *rights) {
 8612  CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
 8613}
 8614
 8615INTERCEPTOR(bool, cap_rights_is_set,
 8616            __sanitizer_cap_rights_t *rights) {
 8617  CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
 8618}
 8619
 8620INTERCEPTOR(int, cap_rights_limit, int fd,
 8621            const __sanitizer_cap_rights_t *rights) {
 8622  void *ctx;
 8623  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
 8624  if (rights)
 8625    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
 8626
 8627  return REAL(cap_rights_limit)(fd, rights);
 8628}
 8629
 8630INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
 8631  void *ctx;
 8632  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
 8633  int ret = REAL(cap_rights_get)(fd, rights);
 8634  if (!ret && rights)
 8635    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
 8636
 8637  return ret;
 8638}
 8639
 8640INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
 8641  void *ctx;
 8642  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
 8643  if (rights)
 8644    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
 8645
 8646  return REAL(cap_rights_is_valid(rights));
 8647}
 8648
 8649INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
 8650  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
 8651  void *ctx;
 8652  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
 8653  if (src)
 8654    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 8655
 8656  __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
 8657  if (dst)
 8658    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
 8659
 8660  return ret;
 8661}
 8662
 8663INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
 8664  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
 8665  void *ctx;
 8666  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
 8667  if (src)
 8668    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
 8669
 8670  __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
 8671  if (dst)
 8672    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
 8673
 8674  return ret;
 8675}
 8676
 8677INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
 8678  const __sanitizer_cap_rights *little) {
 8679  void *ctx;
 8680  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
 8681  if (little)
 8682    COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
 8683  if (big)
 8684    COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
 8685
 8686  return REAL(cap_rights_contains)(big, little);
 8687}
 8688
 8689INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
 8690  void *ctx;
 8691  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
 8692  if (cmds)
 8693    COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
 8694
 8695  return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
 8696}
 8697
 8698INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
 8699  void *ctx;
 8700  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
 8701  int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
 8702  if (!ret && cmds)
 8703    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
 8704
 8705  return ret;
 8706}
 8707#define INIT_CAPSICUM                          \
 8708  COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
 8709  COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
 8710  COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
 8711  COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
 8712  COMMON_INTERCEPT_FUNCTION(cap_rights_get);   \
 8713  COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
 8714  COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
 8715  COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
 8716  COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
 8717  COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
 8718  COMMON_INTERCEPT_FUNCTION(cap_ioctls_get);   \
 8719  COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
 8720#else
 8721#define INIT_CAPSICUM
 8722#endif
 8723
 8724#if SANITIZER_INTERCEPT_SHA1
 8725INTERCEPTOR(void, SHA1Init, void *context) {
 8726  void *ctx;
 8727  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
 8728  REAL(SHA1Init)(context);
 8729  if (context)
 8730    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
 8731}
 8732INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
 8733  void *ctx;
 8734  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
 8735  if (data && len > 0)
 8736    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8737  if (context)
 8738    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
 8739  REAL(SHA1Update)(context, data, len);
 8740  if (context)
 8741    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
 8742}
 8743INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
 8744  void *ctx;
 8745  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
 8746  if (context)
 8747    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
 8748  REAL(SHA1Final)(digest, context);
 8749  if (digest)
 8750    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
 8751}
 8752INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
 8753  void *ctx;
 8754  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
 8755  if (state)
 8756    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
 8757  if (buffer)
 8758    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
 8759  REAL(SHA1Transform)(state, buffer);
 8760  if (state)
 8761    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
 8762}
 8763INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
 8764  void *ctx;
 8765  COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
 8766  if (context)
 8767    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
 8768  char *ret = REAL(SHA1End)(context, buf);
 8769  if (ret)
 8770    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
 8771  return ret;
 8772}
 8773INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
 8774  void *ctx;
 8775  COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
 8776  if (filename)
 8777    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 8778  char *ret = REAL(SHA1File)(filename, buf);
 8779  if (ret)
 8780    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
 8781  return ret;
 8782}
 8783INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
 8784  OFF_T length) {
 8785  void *ctx;
 8786  COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
 8787  if (filename)
 8788    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 8789  char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
 8790  if (ret)
 8791    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
 8792  return ret;
 8793}
 8794INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
 8795  void *ctx;
 8796  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
 8797  if (data)
 8798    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8799  char *ret = REAL(SHA1Data)(data, len, buf);
 8800  if (ret)
 8801    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
 8802  return ret;
 8803}
 8804#define INIT_SHA1                                                              \
 8805  COMMON_INTERCEPT_FUNCTION(SHA1Init);                                         \
 8806  COMMON_INTERCEPT_FUNCTION(SHA1Update);                                       \
 8807  COMMON_INTERCEPT_FUNCTION(SHA1Final);                                        \
 8808  COMMON_INTERCEPT_FUNCTION(SHA1Transform);                                    \
 8809  COMMON_INTERCEPT_FUNCTION(SHA1End);                                          \
 8810  COMMON_INTERCEPT_FUNCTION(SHA1File);                                         \
 8811  COMMON_INTERCEPT_FUNCTION(SHA1FileChunk);                                    \
 8812  COMMON_INTERCEPT_FUNCTION(SHA1Data)
 8813#else
 8814#define INIT_SHA1
 8815#endif
 8816
 8817#if SANITIZER_INTERCEPT_MD4
 8818INTERCEPTOR(void, MD4Init, void *context) {
 8819  void *ctx;
 8820  COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
 8821  REAL(MD4Init)(context);
 8822  if (context)
 8823    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
 8824}
 8825
 8826INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
 8827            unsigned int len) {
 8828  void *ctx;
 8829  COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
 8830  if (data && len > 0)
 8831    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8832  if (context)
 8833    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
 8834  REAL(MD4Update)(context, data, len);
 8835  if (context)
 8836    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
 8837}
 8838
 8839INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
 8840  void *ctx;
 8841  COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
 8842  if (context)
 8843    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
 8844  REAL(MD4Final)(digest, context);
 8845  if (digest)
 8846    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
 8847}
 8848
 8849INTERCEPTOR(char *, MD4End, void *context, char *buf) {
 8850  void *ctx;
 8851  COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
 8852  if (context)
 8853    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
 8854  char *ret = REAL(MD4End)(context, buf);
 8855  if (ret)
 8856    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
 8857  return ret;
 8858}
 8859
 8860INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
 8861  void *ctx;
 8862  COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
 8863  if (filename)
 8864    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 8865  char *ret = REAL(MD4File)(filename, buf);
 8866  if (ret)
 8867    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
 8868  return ret;
 8869}
 8870
 8871INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
 8872            char *buf) {
 8873  void *ctx;
 8874  COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
 8875  if (data && len > 0)
 8876    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8877  char *ret = REAL(MD4Data)(data, len, buf);
 8878  if (ret)
 8879    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
 8880  return ret;
 8881}
 8882
 8883#define INIT_MD4                                                               \
 8884  COMMON_INTERCEPT_FUNCTION(MD4Init);                                          \
 8885  COMMON_INTERCEPT_FUNCTION(MD4Update);                                        \
 8886  COMMON_INTERCEPT_FUNCTION(MD4Final);                                         \
 8887  COMMON_INTERCEPT_FUNCTION(MD4End);                                           \
 8888  COMMON_INTERCEPT_FUNCTION(MD4File);                                          \
 8889  COMMON_INTERCEPT_FUNCTION(MD4Data)
 8890#else
 8891#define INIT_MD4
 8892#endif
 8893
 8894#if SANITIZER_INTERCEPT_RMD160
 8895INTERCEPTOR(void, RMD160Init, void *context) {
 8896  void *ctx;
 8897  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
 8898  REAL(RMD160Init)(context);
 8899  if (context)
 8900    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
 8901}
 8902INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
 8903  void *ctx;
 8904  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
 8905  if (data && len > 0)
 8906    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8907  if (context)
 8908    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
 8909  REAL(RMD160Update)(context, data, len);
 8910  if (context)
 8911    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
 8912}
 8913INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
 8914  void *ctx;
 8915  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
 8916  if (context)
 8917    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
 8918  REAL(RMD160Final)(digest, context);
 8919  if (digest)
 8920    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
 8921}
 8922INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
 8923  void *ctx;
 8924  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
 8925  if (state)
 8926    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
 8927  if (buffer)
 8928    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
 8929  REAL(RMD160Transform)(state, buffer);
 8930  if (state)
 8931    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
 8932}
 8933INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
 8934  void *ctx;
 8935  COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
 8936  if (context)
 8937    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
 8938  char *ret = REAL(RMD160End)(context, buf);
 8939  if (ret)
 8940    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
 8941  return ret;
 8942}
 8943INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
 8944  void *ctx;
 8945  COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
 8946  if (filename)
 8947    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 8948  char *ret = REAL(RMD160File)(filename, buf);
 8949  if (ret)
 8950    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
 8951  return ret;
 8952}
 8953INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
 8954  OFF_T length) {
 8955  void *ctx;
 8956  COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
 8957  if (filename)
 8958    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 8959  char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
 8960  if (ret)
 8961    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
 8962  return ret;
 8963}
 8964INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
 8965  void *ctx;
 8966  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
 8967  if (data && len > 0)
 8968    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 8969  char *ret = REAL(RMD160Data)(data, len, buf);
 8970  if (ret)
 8971    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
 8972  return ret;
 8973}
 8974#define INIT_RMD160                                                            \
 8975  COMMON_INTERCEPT_FUNCTION(RMD160Init);                                       \
 8976  COMMON_INTERCEPT_FUNCTION(RMD160Update);                                     \
 8977  COMMON_INTERCEPT_FUNCTION(RMD160Final);                                      \
 8978  COMMON_INTERCEPT_FUNCTION(RMD160Transform);                                  \
 8979  COMMON_INTERCEPT_FUNCTION(RMD160End);                                        \
 8980  COMMON_INTERCEPT_FUNCTION(RMD160File);                                       \
 8981  COMMON_INTERCEPT_FUNCTION(RMD160FileChunk);                                  \
 8982  COMMON_INTERCEPT_FUNCTION(RMD160Data)
 8983#else
 8984#define INIT_RMD160
 8985#endif
 8986
 8987#if SANITIZER_INTERCEPT_FSEEK
 8988INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
 8989  void *ctx;
 8990  COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
 8991  return REAL(fseek)(stream, offset, whence);
 8992}
 8993INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
 8994  void *ctx;
 8995  COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
 8996  return REAL(fseeko)(stream, offset, whence);
 8997}
 8998INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
 8999  void *ctx;
 9000  COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
 9001  return REAL(ftell)(stream);
 9002}
 9003INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
 9004  void *ctx;
 9005  COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
 9006  return REAL(ftello)(stream);
 9007}
 9008INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
 9009  void *ctx;
 9010  COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
 9011  return REAL(rewind)(stream);
 9012}
 9013INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
 9014  void *ctx;
 9015  COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
 9016  int ret = REAL(fgetpos)(stream, pos);
 9017  if (pos && !ret)
 9018    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
 9019  return ret;
 9020}
 9021INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
 9022  void *ctx;
 9023  COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
 9024  if (pos)
 9025    COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
 9026  return REAL(fsetpos)(stream, pos);
 9027}
 9028#define INIT_FSEEK \
 9029  COMMON_INTERCEPT_FUNCTION(fseek); \
 9030  COMMON_INTERCEPT_FUNCTION(fseeko); \
 9031  COMMON_INTERCEPT_FUNCTION(ftell); \
 9032  COMMON_INTERCEPT_FUNCTION(ftello); \
 9033  COMMON_INTERCEPT_FUNCTION(rewind); \
 9034  COMMON_INTERCEPT_FUNCTION(fgetpos); \
 9035  COMMON_INTERCEPT_FUNCTION(fsetpos)
 9036#else
 9037#define INIT_FSEEK
 9038#endif
 9039
 9040#if SANITIZER_INTERCEPT_MD2
 9041INTERCEPTOR(void, MD2Init, void *context) {
 9042  void *ctx;
 9043  COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
 9044  REAL(MD2Init)(context);
 9045  if (context)
 9046    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
 9047}
 9048
 9049INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
 9050            unsigned int len) {
 9051  void *ctx;
 9052  COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
 9053  if (data && len > 0)
 9054    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 9055  if (context)
 9056    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
 9057  REAL(MD2Update)(context, data, len);
 9058  if (context)
 9059    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
 9060}
 9061
 9062INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
 9063  void *ctx;
 9064  COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
 9065  if (context)
 9066    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
 9067  REAL(MD2Final)(digest, context);
 9068  if (digest)
 9069    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
 9070}
 9071
 9072INTERCEPTOR(char *, MD2End, void *context, char *buf) {
 9073  void *ctx;
 9074  COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
 9075  if (context)
 9076    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
 9077  char *ret = REAL(MD2End)(context, buf);
 9078  if (ret)
 9079    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
 9080  return ret;
 9081}
 9082
 9083INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
 9084  void *ctx;
 9085  COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
 9086  if (filename)
 9087    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
 9088  char *ret = REAL(MD2File)(filename, buf);
 9089  if (ret)
 9090    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
 9091  return ret;
 9092}
 9093
 9094INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
 9095            char *buf) {
 9096  void *ctx;
 9097  COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
 9098  if (data && len > 0)
 9099    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
 9100  char *ret = REAL(MD2Data)(data, len, buf);
 9101  if (ret)
 9102    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
 9103  return ret;
 9104}
 9105
 9106#define INIT_MD2                                                               \
 9107  COMMON_INTERCEPT_FUNCTION(MD2Init);                                          \
 9108  COMMON_INTERCEPT_FUNCTION(MD2Update);                                        \
 9109  COMMON_INTERCEPT_FUNCTION(MD2Final);                                         \
 9110  COMMON_INTERCEPT_FUNCTION(MD2End);                                           \
 9111  COMMON_INTERCEPT_FUNCTION(MD2File);                                          \
 9112  COMMON_INTERCEPT_FUNCTION(MD2Data)
 9113#else
 9114#define INIT_MD2
 9115#endif
 9116
 9117#if SANITIZER_INTERCEPT_VIS
 9118INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
 9119  void *ctx;
 9120  COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
 9121  char *end = REAL(vis)(dst, c, flag, nextc);
 9122  // dst is NULL terminated and end points to the NULL char
 9123  if (dst && end)
 9124    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
 9125  return end;
 9126}
 9127INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
 9128  void *ctx;
 9129  COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
 9130  char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
 9131  // nvis cannot make sure the dst is NULL terminated
 9132  if (dst && end)
 9133    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
 9134  return end;
 9135}
 9136INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
 9137  void *ctx;
 9138  COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
 9139  if (src)
 9140    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9141  int len = REAL(strvis)(dst, src, flag);
 9142  if (dst)
 9143    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
 9144  return len;
 9145}
 9146INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
 9147  void *ctx;
 9148  COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
 9149  if (src)
 9150    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9151  int len = REAL(stravis)(dst, src, flag);
 9152  if (dst) {
 9153    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
 9154    if (*dst)
 9155      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
 9156  }
 9157  return len;
 9158}
 9159INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
 9160  void *ctx;
 9161  COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
 9162  if (src)
 9163    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9164  int len = REAL(strnvis)(dst, dlen, src, flag);
 9165  // The interface will be valid even if there is no space for NULL char
 9166  if (dst && len > 0)
 9167    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
 9168  return len;
 9169}
 9170INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
 9171  void *ctx;
 9172  COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
 9173  if (src)
 9174    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9175  int ret = REAL(strvisx)(dst, src, len, flag);
 9176  if (dst)
 9177    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9178  return ret;
 9179}
 9180INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
 9181            int flag) {
 9182  void *ctx;
 9183  COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
 9184  if (src)
 9185    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9186  int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
 9187  if (dst && ret >= 0)
 9188    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9189  return ret;
 9190}
 9191INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
 9192            int flag, int *cerr_ptr) {
 9193  void *ctx;
 9194  COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
 9195  if (src)
 9196    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9197  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
 9198  // according to the implementation
 9199  if (cerr_ptr)
 9200    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
 9201  int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
 9202  if (dst && ret >= 0)
 9203    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9204  if (cerr_ptr)
 9205    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
 9206  return ret;
 9207}
 9208INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
 9209            const char *extra) {
 9210  void *ctx;
 9211  COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
 9212  if (extra)
 9213    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9214  char *end = REAL(svis)(dst, c, flag, nextc, extra);
 9215  if (dst && end)
 9216    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
 9217  return end;
 9218}
 9219INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
 9220            const char *extra) {
 9221  void *ctx;
 9222  COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
 9223  if (extra)
 9224    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9225  char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
 9226  if (dst && end)
 9227    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
 9228                                   Min((SIZE_T)(end - dst + 1), dlen));
 9229  return end;
 9230}
 9231INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
 9232            const char *extra) {
 9233  void *ctx;
 9234  COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
 9235  if (src)
 9236    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9237  if (extra)
 9238    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9239  int len = REAL(strsvis)(dst, src, flag, extra);
 9240  if (dst)
 9241    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
 9242  return len;
 9243}
 9244INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
 9245            const char *extra) {
 9246  void *ctx;
 9247  COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
 9248  if (src)
 9249    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9250  if (extra)
 9251    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9252  int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
 9253  // The interface will be valid even if there is no space for NULL char
 9254  if (dst && len >= 0)
 9255    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
 9256  return len;
 9257}
 9258INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
 9259            const char *extra) {
 9260  void *ctx;
 9261  COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
 9262  if (src)
 9263    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9264  if (extra)
 9265    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9266  int ret = REAL(strsvisx)(dst, src, len, flag, extra);
 9267  if (dst)
 9268    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9269  return ret;
 9270}
 9271INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
 9272            int flag, const char *extra) {
 9273  void *ctx;
 9274  COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
 9275  if (src)
 9276    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9277  if (extra)
 9278    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9279  int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
 9280  if (dst && ret >= 0)
 9281    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9282  return ret;
 9283}
 9284INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
 9285            SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
 9286  void *ctx;
 9287  COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
 9288                           cerr_ptr);
 9289  if (src)
 9290    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
 9291  if (extra)
 9292    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
 9293  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
 9294  // according to the implementation
 9295  if (cerr_ptr)
 9296    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
 9297  int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
 9298  if (dst && ret >= 0)
 9299    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9300  if (cerr_ptr)
 9301    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
 9302  return ret;
 9303}
 9304INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
 9305  void *ctx;
 9306  COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
 9307  if (astate)
 9308    COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
 9309  int ret = REAL(unvis)(cp, c, astate, flag);
 9310  if (ret == unvis_valid || ret == unvis_validpush) {
 9311    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
 9312  }
 9313  return ret;
 9314}
 9315INTERCEPTOR(int, strunvis, char *dst, const char *src) {
 9316  void *ctx;
 9317  COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
 9318  if (src)
 9319    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9320  int ret = REAL(strunvis)(dst, src);
 9321  if (ret != -1)
 9322    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9323  return ret;
 9324}
 9325INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
 9326  void *ctx;
 9327  COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
 9328  if (src)
 9329    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9330  int ret = REAL(strnunvis)(dst, dlen, src);
 9331  if (ret != -1)
 9332    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9333  return ret;
 9334}
 9335INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
 9336  void *ctx;
 9337  COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
 9338  if (src)
 9339    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9340  int ret = REAL(strunvisx)(dst, src, flag);
 9341  if (ret != -1)
 9342    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9343  return ret;
 9344}
 9345INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
 9346            int flag) {
 9347  void *ctx;
 9348  COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
 9349  if (src)
 9350    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
 9351  int ret = REAL(strnunvisx)(dst, dlen, src, flag);
 9352  if (ret != -1)
 9353    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
 9354  return ret;
 9355}
 9356#define INIT_VIS                                                               \
 9357  COMMON_INTERCEPT_FUNCTION(vis);                                              \
 9358  COMMON_INTERCEPT_FUNCTION(nvis);                                             \
 9359  COMMON_INTERCEPT_FUNCTION(strvis);                                           \
 9360  COMMON_INTERCEPT_FUNCTION(stravis);                                          \
 9361  COMMON_INTERCEPT_FUNCTION(strnvis);                                          \
 9362  COMMON_INTERCEPT_FUNCTION(strvisx);                                          \
 9363  COMMON_INTERCEPT_FUNCTION(strnvisx);                                         \
 9364  COMMON_INTERCEPT_FUNCTION(strenvisx);                                        \
 9365  COMMON_INTERCEPT_FUNCTION(svis);                                             \
 9366  COMMON_INTERCEPT_FUNCTION(snvis);                                            \
 9367  COMMON_INTERCEPT_FUNCTION(strsvis);                                          \
 9368  COMMON_INTERCEPT_FUNCTION(strsnvis);                                         \
 9369  COMMON_INTERCEPT_FUNCTION(strsvisx);                                         \
 9370  COMMON_INTERCEPT_FUNCTION(strsnvisx);                                        \
 9371  COMMON_INTERCEPT_FUNCTION(strsenvisx);                                       \
 9372  COMMON_INTERCEPT_FUNCTION(unvis);                                            \
 9373  COMMON_INTERCEPT_FUNCTION(strunvis);                                         \
 9374  COMMON_INTERCEPT_FUNCTION(strnunvis);                                        \
 9375  COMMON_INTERCEPT_FUNCTION(strunvisx);                                        \
 9376  COMMON_INTERCEPT_FUNCTION(strnunvisx)
 9377#else
 9378#define INIT_VIS
 9379#endif
 9380
 9381#if SANITIZER_INTERCEPT_CDB
 9382INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
 9383  void *ctx;
 9384  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
 9385  if (path)
 9386    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 9387  struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
 9388  if (cdbr)
 9389    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
 9390  return cdbr;
 9391}
 9392
 9393INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
 9394  int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
 9395  void *ctx;
 9396  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
 9397    cookie);
 9398  if (base && size)
 9399    COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
 9400  struct __sanitizer_cdbr *cdbr =
 9401    REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
 9402  if (cdbr)
 9403    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
 9404  return cdbr;
 9405}
 9406
 9407INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
 9408  void *ctx;
 9409  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
 9410  if (cdbr)
 9411    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
 9412  return REAL(cdbr_entries)(cdbr);
 9413}
 9414
 9415INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
 9416            const void **data, SIZE_T *datalen) {
 9417  void *ctx;
 9418  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
 9419  if (cdbr)
 9420    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
 9421  int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
 9422  if (!ret) {
 9423    if (data)
 9424      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
 9425    if (datalen)
 9426      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
 9427    if (data && datalen)
 9428      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
 9429  }
 9430  return ret;
 9431}
 9432
 9433INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
 9434            SIZE_T keylen, const void **data, SIZE_T *datalen) {
 9435  void *ctx;
 9436  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
 9437  if (cdbr)
 9438    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
 9439  if (key)
 9440    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
 9441  int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
 9442  if (!ret) {
 9443    if (data)
 9444      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
 9445    if (datalen)
 9446      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
 9447    if (data && datalen)
 9448      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
 9449  }
 9450  return ret;
 9451}
 9452
 9453INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
 9454  void *ctx;
 9455  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
 9456  if (cdbr)
 9457    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
 9458  REAL(cdbr_close)(cdbr);
 9459}
 9460
 9461INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
 9462  void *ctx;
 9463  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
 9464  struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
 9465  if (ret)
 9466    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
 9467  return ret;
 9468}
 9469
 9470INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
 9471  SIZE_T keylen, const void *data, SIZE_T datalen) {
 9472  void *ctx;
 9473  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
 9474  if (cdbw)
 9475    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
 9476  if (data && datalen)
 9477    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
 9478  if (key && keylen)
 9479    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
 9480  int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
 9481  if (!ret && cdbw)
 9482    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
 9483  return ret;
 9484}
 9485
 9486INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
 9487  SIZE_T datalen, u32 *index) {
 9488  void *ctx;
 9489  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
 9490  if (cdbw)
 9491    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
 9492  if (data && datalen)
 9493    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
 9494  int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
 9495  if (!ret) {
 9496    if (index)
 9497      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
 9498    if (cdbw)
 9499      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
 9500  }
 9501  return ret;
 9502}
 9503
 9504INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
 9505  SIZE_T keylen, u32 index) {
 9506  void *ctx;
 9507  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
 9508  if (cdbw)
 9509    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
 9510  if (key && keylen)
 9511    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
 9512  int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
 9513  if (!ret && cdbw)
 9514    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
 9515  return ret;
 9516}
 9517
 9518INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
 9519  const char descr[16], u32 (*seedgen)(void)) {
 9520  void *ctx;
 9521  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
 9522  COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
 9523  if (cdbw)
 9524    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
 9525  if (descr)
 9526    COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
 9527  if (seedgen)
 9528    COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
 9529  int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
 9530  if (!ret) {
 9531    if (cdbw)
 9532      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
 9533    if (output >= 0)
 9534      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
 9535  }
 9536  return ret;
 9537}
 9538
 9539INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
 9540  void *ctx;
 9541  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
 9542  if (cdbw)
 9543    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
 9544  REAL(cdbw_close)(cdbw);
 9545}
 9546
 9547#define INIT_CDB \
 9548  COMMON_INTERCEPT_FUNCTION(cdbr_open); \
 9549  COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
 9550  COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
 9551  COMMON_INTERCEPT_FUNCTION(cdbr_get); \
 9552  COMMON_INTERCEPT_FUNCTION(cdbr_find); \
 9553  COMMON_INTERCEPT_FUNCTION(cdbr_close); \
 9554  COMMON_INTERCEPT_FUNCTION(cdbw_open); \
 9555  COMMON_INTERCEPT_FUNCTION(cdbw_put); \
 9556  COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
 9557  COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
 9558  COMMON_INTERCEPT_FUNCTION(cdbw_output); \
 9559  COMMON_INTERCEPT_FUNCTION(cdbw_close)
 9560#else
 9561#define INIT_CDB
 9562#endif
 9563
 9564#if SANITIZER_INTERCEPT_GETFSENT
 9565INTERCEPTOR(void *, getfsent) {
 9566  void *ctx;
 9567  COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
 9568  void *ret = REAL(getfsent)();
 9569  if (ret)
 9570    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
 9571  return ret;
 9572}
 9573
 9574INTERCEPTOR(void *, getfsspec, const char *spec) {
 9575  void *ctx;
 9576  COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
 9577  if (spec)
 9578    COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1);
 9579  void *ret = REAL(getfsspec)(spec);
 9580  if (ret)
 9581    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
 9582  return ret;
 9583}
 9584
 9585INTERCEPTOR(void *, getfsfile, const char *file) {
 9586  void *ctx;
 9587  COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
 9588  if (file)
 9589    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
 9590  void *ret = REAL(getfsfile)(file);
 9591  if (ret)
 9592    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
 9593  return ret;
 9594}
 9595
 9596#define INIT_GETFSENT \
 9597  COMMON_INTERCEPT_FUNCTION(getfsent); \
 9598  COMMON_INTERCEPT_FUNCTION(getfsspec); \
 9599  COMMON_INTERCEPT_FUNCTION(getfsfile);
 9600#else
 9601#define INIT_GETFSENT
 9602#endif
 9603
 9604#if SANITIZER_INTERCEPT_ARC4RANDOM
 9605INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
 9606  void *ctx;
 9607  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
 9608  REAL(arc4random_buf)(buf, len);
 9609  if (buf && len)
 9610    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
 9611}
 9612
 9613INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
 9614  void *ctx;
 9615  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
 9616  if (dat && datlen)
 9617    COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
 9618  REAL(arc4random_addrandom)(dat, datlen);
 9619}
 9620
 9621#define INIT_ARC4RANDOM \
 9622  COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
 9623  COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
 9624#else
 9625#define INIT_ARC4RANDOM
 9626#endif
 9627
 9628#if SANITIZER_INTERCEPT_POPEN
 9629INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
 9630  void *ctx;
 9631  COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
 9632  if (command)
 9633    COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1);
 9634  if (type)
 9635    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
 9636  __sanitizer_FILE *res = REAL(popen)(command, type);
 9637  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
 9638  if (res) unpoison_file(res);
 9639  return res;
 9640}
 9641#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
 9642#else
 9643#define INIT_POPEN
 9644#endif
 9645
 9646#if SANITIZER_INTERCEPT_POPENVE
 9647INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
 9648            char *const *argv, char *const *envp, const char *type) {
 9649  void *ctx;
 9650  COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
 9651  if (path)
 9652    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
 9653  if (argv) {
 9654    for (char *const *pa = argv; ; ++pa) {
 9655      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
 9656      if (!*pa)
 9657        break;
 9658      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
 9659    }
 9660  }
 9661  if (envp) {
 9662    for (char *const *pa = envp; ; ++pa) {
 9663      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
 9664      if (!*pa)
 9665        break;
 9666      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
 9667    }
 9668  }
 9669  if (type)
 9670    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
 9671  __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
 9672  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
 9673  if (res) unpoison_file(res);
 9674  return res;
 9675}
 9676#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
 9677#else
 9678#define INIT_POPENVE
 9679#endif
 9680
 9681#if SANITIZER_INTERCEPT_PCLOSE
 9682INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
 9683  void *ctx;
 9684  COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
 9685  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
 9686  const FileMetadata *m = GetInterceptorMetadata(fp);
 9687  int res = REAL(pclose)(fp);
 9688  if (m) {
 9689    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
 9690    DeleteInterceptorMetadata(fp);
 9691  }
 9692  return res;
 9693}
 9694#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
 9695#else
 9696#define INIT_PCLOSE
 9697#endif
 9698
 9699#if SANITIZER_INTERCEPT_FUNOPEN
 9700typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
 9701typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
 9702typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
 9703typedef int (*funopen_closefn)(void *cookie);
 9704
 9705struct WrappedFunopenCookie {
 9706  void *real_cookie;
 9707  funopen_readfn real_read;
 9708  funopen_writefn real_write;
 9709  funopen_seekfn real_seek;
 9710  funopen_closefn real_close;
 9711};
 9712
 9713static int wrapped_funopen_read(void *cookie, char *buf, int len) {
 9714  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9715  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
 9716  funopen_readfn real_read = wrapped_cookie->real_read;
 9717  return real_read(wrapped_cookie->real_cookie, buf, len);
 9718}
 9719
 9720static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
 9721  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9722  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
 9723  funopen_writefn real_write = wrapped_cookie->real_write;
 9724  return real_write(wrapped_cookie->real_cookie, buf, len);
 9725}
 9726
 9727static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
 9728  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9729  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
 9730  funopen_seekfn real_seek = wrapped_cookie->real_seek;
 9731  return real_seek(wrapped_cookie->real_cookie, offset, whence);
 9732}
 9733
 9734static int wrapped_funopen_close(void *cookie) {
 9735  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 9736  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
 9737  funopen_closefn real_close = wrapped_cookie->real_close;
 9738  int res = real_close(wrapped_cookie->real_cookie);
 9739  InternalFree(wrapped_cookie);
 9740  return res;
 9741}
 9742
 9743INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
 9744            funopen_writefn writefn, funopen_seekfn seekfn,
 9745            funopen_closefn closefn) {
 9746  void *ctx;
 9747  COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
 9748                           closefn);
 9749
 9750  WrappedFunopenCookie *wrapped_cookie =
 9751      (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
 9752  wrapped_cookie->real_cookie = cookie;
 9753  wrapped_cookie->real_read = readfn;
 9754  wrapped_cookie->real_write = writefn;
 9755  wrapped_cookie->real_seek = seekfn;
 9756  wrapped_cookie->real_close = closefn;
 9757
 9758  __sanitizer_FILE *res =
 9759      REAL(funopen)(wrapped_cookie,
 9760                    readfn  ? wrapped_funopen_read  : nullptr,
 9761                    writefn ? wrapped_funopen_write : nullptr,
 9762                    seekfn  ? wrapped_funopen_seek  : nullptr,
 9763                    closefn ? wrapped_funopen_close : nullptr);
 9764  if (res)
 9765    unpoison_file(res);
 9766  return res;
 9767}
 9768#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
 9769#else
 9770#define INIT_FUNOPEN
 9771#endif
 9772
 9773#if SANITIZER_INTERCEPT_FUNOPEN2
 9774typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
 9775typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
 9776typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
 9777typedef int (*funopen2_flushfn)(void *cookie);
 9778typedef int (*funopen2_closefn)(void *cookie);
 9779
 9780struct WrappedFunopen2Cookie {
 9781  void *real_cookie;
 9782  funopen2_readfn real_read;
 9783  funopen2_writefn real_write;
 9784  funopen2_seekfn real_seek;
 9785  funopen2_flushfn real_flush;
 9786  funopen2_closefn real_close;
 9787};
 9788
 9789static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
 9790  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9791  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
 9792  funopen2_readfn real_read = wrapped_cookie->real_read;
 9793  return real_read(wrapped_cookie->real_cookie, buf, len);
 9794}
 9795
 9796static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
 9797                                      SIZE_T len) {
 9798  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9799  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
 9800  funopen2_writefn real_write = wrapped_cookie->real_write;
 9801  return real_write(wrapped_cookie->real_cookie, buf, len);
 9802}
 9803
 9804static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
 9805  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
 9806  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
 9807  funopen2_seekfn real_seek = wrapped_cookie->real_seek;
 9808  return real_seek(wrapped_cookie->real_cookie, offset, whence);
 9809}
 9810
 9811static int wrapped_funopen2_flush(void *cookie) {
 9812  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 9813  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
 9814  funopen2_flushfn real_flush = wrapped_cookie->real_flush;
 9815  return real_flush(wrapped_cookie->real_cookie);
 9816}
 9817
 9818static int wrapped_funopen2_close(void *cookie) {
 9819  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
 9820  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
 9821  funopen2_closefn real_close = wrapped_cookie->real_close;
 9822  int res = real_close(wrapped_cookie->real_cookie);
 9823  InternalFree(wrapped_cookie);
 9824  return res;
 9825}
 9826
 9827INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
 9828            funopen2_writefn writefn, funopen2_seekfn seekfn,
 9829            funopen2_flushfn flushfn, funopen2_closefn closefn) {
 9830  void *ctx;
 9831  COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
 9832                           flushfn, closefn);
 9833
 9834  WrappedFunopen2Cookie *wrapped_cookie =
 9835      (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
 9836  wrapped_cookie->real_cookie = cookie;
 9837  wrapped_cookie->real_read = readfn;
 9838  wrapped_cookie->real_write = writefn;
 9839  wrapped_cookie->real_seek = seekfn;
 9840  wrapped_cookie->real_flush = flushfn;
 9841  wrapped_cookie->real_close = closefn;
 9842
 9843  __sanitizer_FILE *res =
 9844      REAL(funopen2)(wrapped_cookie,
 9845                     readfn  ? wrapped_funopen2_read  : nullptr,
 9846                     writefn ? wrapped_funopen2_write : nullptr,
 9847                     seekfn  ? wrapped_funopen2_seek  : nullptr,
 9848                     flushfn ? wrapped_funopen2_flush : nullptr,
 9849                     closefn ? wrapped_funopen2_close : nullptr);
 9850  if (res)
 9851    unpoison_file(res);
 9852  return res;
 9853}
 9854#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
 9855#else
 9856#define INIT_FUNOPEN2
 9857#endif
 9858
 9859#if SANITIZER_INTERCEPT_FDEVNAME
 9860INTERCEPTOR(char *, fdevname,  int fd) {
 9861  void *ctx;
 9862  COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
 9863  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 9864  char *name = REAL(fdevname)(fd);
 9865  if (name) {
 9866    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
 9867    if (fd > 0)
 9868      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 9869  }
 9870  return name;
 9871}
 9872
 9873INTERCEPTOR(char *, fdevname_r,  int fd, char *buf, SIZE_T len) {
 9874  void *ctx;
 9875  COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
 9876  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
 9877  char *name = REAL(fdevname_r)(fd, buf, len);
 9878  if (name && buf && len > 0) {
 9879    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
 9880    if (fd > 0)
 9881      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
 9882  }
 9883  return name;
 9884}
 9885
 9886#define INIT_FDEVNAME \
 9887  COMMON_INTERCEPT_FUNCTION(fdevname); \
 9888  COMMON_INTERCEPT_FUNCTION(fdevname_r);
 9889#else
 9890#define INIT_FDEVNAME
 9891#endif
 9892
 9893#if SANITIZER_INTERCEPT_GETUSERSHELL
 9894INTERCEPTOR(char *, getusershell,) {
 9895  void *ctx;
 9896  COMMON_INTERCEPTOR_ENTER(ctx, getusershell,);
 9897  char *res = REAL(getusershell)();
 9898  if (res)
 9899    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 9900  return res;
 9901}
 9902
 9903#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
 9904#else
 9905#define INIT_GETUSERSHELL
 9906#endif
 9907
 9908#if SANITIZER_INTERCEPT_SL_INIT
 9909INTERCEPTOR(void *, sl_init) {
 9910  void *ctx;
 9911  COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
 9912  void *res = REAL(sl_init)();
 9913  if (res)
 9914    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
 9915  return res;
 9916}
 9917
 9918INTERCEPTOR(int, sl_add, void *sl, char *item) {
 9919  void *ctx;
 9920  COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
 9921  if (sl)
 9922    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
 9923  if (item)
 9924    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
 9925  int res = REAL(sl_add)(sl, item);
 9926  if (!res)
 9927    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
 9928  return res;
 9929}
 9930
 9931INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
 9932  void *ctx;
 9933  COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
 9934  if (sl)
 9935    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
 9936  if (item)
 9937    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
 9938  char *res = REAL(sl_find)(sl, item);
 9939  if (res)
 9940    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
 9941  return res;
 9942}
 9943
 9944INTERCEPTOR(void, sl_free, void *sl, int freeall) {
 9945  void *ctx;
 9946  COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
 9947  if (sl)
 9948    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
 9949  REAL(sl_free)(sl, freeall);
 9950}
 9951
 9952#define INIT_SL_INIT                  \
 9953  COMMON_INTERCEPT_FUNCTION(sl_init); \
 9954  COMMON_INTERCEPT_FUNCTION(sl_add);  \
 9955  COMMON_INTERCEPT_FUNCTION(sl_find); \
 9956  COMMON_INTERCEPT_FUNCTION(sl_free);
 9957#else
 9958#define INIT_SL_INIT
 9959#endif
 9960
 9961#if SANITIZER_INTERCEPT_GETRANDOM
 9962INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
 9963  void *ctx;
 9964  COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);
 9965  // If GRND_NONBLOCK is set in the flags, it is non blocking.
 9966  static const int grnd_nonblock = 1;
 9967  SSIZE_T n;
 9968  if ((flags & grnd_nonblock))
 9969    n = REAL(getrandom)(buf, buflen, flags);
 9970  else
 9971    n = COMMON_INTERCEPTOR_BLOCK_REAL(getrandom)(buf, buflen, flags);
 9972  if (n > 0) {
 9973    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);
 9974  }
 9975  return n;
 9976}
 9977#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)
 9978#else
 9979#define INIT_GETRANDOM
 9980#endif
 9981
 9982#if SANITIZER_INTERCEPT_GETENTROPY
 9983INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
 9984  void *ctx;
 9985  COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);
 9986  int r = REAL(getentropy)(buf, buflen);
 9987  if (r == 0) {
 9988    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
 9989  }
 9990  return r;
 9991}
 9992#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)
 9993#else
 9994#define INIT_GETENTROPY
 9995#endif
 9996
 9997#if SANITIZER_INTERCEPT_QSORT_R
 9998typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
 9999struct qsort_r_compar_params {
10000  SIZE_T size;
10001  qsort_r_compar_f compar;
10002  void *arg;
10003};
10004static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
10005  qsort_r_compar_params *params = (qsort_r_compar_params *)arg;
10006  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10007  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size);
10008  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size);
10009  return params->compar(a, b, params->arg);
10010}
10011
10012INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
10013            qsort_r_compar_f compar, void *arg) {
10014  void *ctx;
10015  COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
10016  // Run the comparator over all array elements to detect any memory issues.
10017  if (nmemb > 1) {
10018    for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10019      void *p = (void *)((char *)base + i * size);
10020      void *q = (void *)((char *)base + (i + 1) * size);
10021      COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10022      compar(p, q, arg);
10023    }
10024  }
10025  qsort_r_compar_params params = {size, compar, arg};
10026  REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, &params);
10027  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10028}
10029#  define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
10030#else
10031#  define INIT_QSORT_R
10032#endif
10033
10034#if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R
10035INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10036            qsort_r_compar_f compar) {
10037  void *ctx;
10038  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10039  WRAP(qsort_r)(base, nmemb, size, compar, nullptr);
10040}
10041#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10042#elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R
10043// Glibc qsort uses a temporary buffer allocated either on stack or on heap.
10044// Poisoned memory from there may get copied into the comparator arguments,
10045// where it needs to be dealt with. But even that is not enough - the results of
10046// the sort may be copied into the input/output array based on the results of
10047// the comparator calls, but directly from the temp memory, bypassing the
10048// unpoisoning done in wrapped_qsort_compar. We deal with this by, again,
10049// unpoisoning the entire array after the sort is done.
10050//
10051// We can not check that the entire array is initialized at the beginning. IMHO,
10052// it's fine for parts of the sorted objects to contain uninitialized memory,
10053// ex. as padding in structs.
10054typedef int (*qsort_compar_f)(const void *, const void *);
10055static THREADLOCAL qsort_compar_f qsort_compar;
10056static THREADLOCAL SIZE_T qsort_size;
10057static int wrapped_qsort_compar(const void *a, const void *b) {
10058  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10059  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);
10060  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);
10061  return qsort_compar(a, b);
10062}
10063
10064INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10065            qsort_compar_f compar) {
10066  void *ctx;
10067  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10068  // Run the comparator over all array elements to detect any memory issues.
10069  if (nmemb > 1) {
10070    for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10071      void *p = (void *)((char *)base + i * size);
10072      void *q = (void *)((char *)base + (i + 1) * size);
10073      COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10074      compar(p, q);
10075    }
10076  }
10077  qsort_compar_f old_compar = qsort_compar;
10078  SIZE_T old_size = qsort_size;
10079  // Handle qsort() implementations that recurse using an
10080  // interposable function call:
10081  bool already_wrapped = compar == wrapped_qsort_compar;
10082  if (already_wrapped) {
10083    // This case should only happen if the qsort() implementation calls itself
10084    // using a preemptible function call (e.g. the FreeBSD libc version).
10085    // Check that the size and comparator arguments are as expected.
10086    CHECK_NE(compar, qsort_compar);
10087    CHECK_EQ(qsort_size, size);
10088  } else {
10089    qsort_compar = compar;
10090    qsort_size = size;
10091  }
10092  REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);
10093  if (!already_wrapped) {
10094    qsort_compar = old_compar;
10095    qsort_size = old_size;
10096  }
10097  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10098}
10099#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10100#else
10101#  define INIT_QSORT
10102#endif
10103
10104#if SANITIZER_INTERCEPT_BSEARCH
10105typedef int (*bsearch_compar_f)(const void *, const void *);
10106struct bsearch_compar_params {
10107  const void *key;
10108  bsearch_compar_f compar;
10109};
10110
10111static int wrapped_bsearch_compar(const void *key, const void *b) {
10112  const bsearch_compar_params *params = (const bsearch_compar_params *)key;
10113  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10114  return params->compar(params->key, b);
10115}
10116
10117INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb,
10118            SIZE_T size, bsearch_compar_f compar) {
10119  void *ctx;
10120  COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar);
10121  bsearch_compar_params params = {key, compar};
10122  return REAL(bsearch)(&params, base, nmemb, size, wrapped_bsearch_compar);
10123}
10124#  define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch)
10125#else
10126#  define INIT_BSEARCH
10127#endif
10128
10129#if SANITIZER_INTERCEPT_SIGALTSTACK
10130INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
10131  void *ctx;
10132  COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);
10133  int r = REAL(sigaltstack)(ss, oss);
10134  if (r == 0 && oss != nullptr) {
10135    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);
10136  }
10137  return r;
10138}
10139#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)
10140#else
10141#define INIT_SIGALTSTACK
10142#endif
10143
10144#if SANITIZER_INTERCEPT_PROCCTL
10145INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) {
10146   void *ctx;
10147   COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data);
10148   static const int PROC_REAP_ACQUIRE = 2;
10149   static const int PROC_REAP_RELEASE = 3;
10150   static const int PROC_REAP_STATUS = 4;
10151   static const int PROC_REAP_GETPIDS = 5;
10152   static const int PROC_REAP_KILL = 6;
10153   if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) {
10154     COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int));
10155   } else {
10156     // reap_acquire/reap_release bears no arguments.
10157     if (cmd > PROC_REAP_RELEASE) {
10158       unsigned int reapsz;
10159       switch (cmd) {
10160       case PROC_REAP_STATUS:
10161         reapsz = struct_procctl_reaper_status_sz;
10162         break;
10163       case PROC_REAP_GETPIDS:
10164         reapsz = struct_procctl_reaper_pids_sz;
10165         break;
10166       case PROC_REAP_KILL:
10167         reapsz = struct_procctl_reaper_kill_sz;
10168         break;
10169       }
10170       COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz);
10171     }
10172   }
10173   return REAL(procctl)(idtype, id, cmd, data);
10174}
10175#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl)
10176#else
10177#define INIT_PROCCTL
10178#endif
10179
10180#if SANITIZER_INTERCEPT_UNAME
10181INTERCEPTOR(int, uname, struct utsname *utsname) {
10182#if SANITIZER_LINUX
10183  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
10184    return internal_uname(utsname);
10185#endif
10186  void *ctx;
10187  COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);
10188  int res = REAL(uname)(utsname);
10189  if (!res)
10190    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10191                                   __sanitizer::struct_utsname_sz);
10192  return res;
10193}
10194#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)
10195#else
10196#define INIT_UNAME
10197#endif
10198
10199#if SANITIZER_INTERCEPT___XUNAME
10200// FreeBSD's <sys/utsname.h> define uname() as
10201// static __inline int uname(struct utsname *name) {
10202//   return __xuname(SYS_NMLN, (void*)name);
10203// }
10204INTERCEPTOR(int, __xuname, int size, void *utsname) {
10205  void *ctx;
10206  COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);
10207  int res = REAL(__xuname)(size, utsname);
10208  if (!res)
10209    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10210                                   __sanitizer::struct_utsname_sz);
10211  return res;
10212}
10213#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)
10214#else
10215#define INIT___XUNAME
10216#endif
10217
10218#if SANITIZER_INTERCEPT_ARGP_PARSE
10219INTERCEPTOR(int, argp_parse, const struct argp *argp, int argc, char **argv,
10220            unsigned flags, int *arg_index, void *input) {
10221  void *ctx;
10222  COMMON_INTERCEPTOR_ENTER(ctx, argp_parse, argp, argc, argv, flags, arg_index,
10223                           input);
10224  for (int i = 0; i < argc; i++)
10225    COMMON_INTERCEPTOR_READ_RANGE(ctx, argv[i], internal_strlen(argv[i]) + 1);
10226  int res = REAL(argp_parse)(argp, argc, argv, flags, arg_index, input);
10227  if (!res && arg_index)
10228    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg_index, sizeof(int));
10229  return res;
10230}
10231
10232#define INIT_ARGP_PARSE COMMON_INTERCEPT_FUNCTION(argp_parse);
10233#else
10234#define INIT_ARGP_PARSE
10235#endif
10236
10237#if SANITIZER_INTERCEPT_CPUSET_GETAFFINITY
10238INTERCEPTOR(int, cpuset_getaffinity, int level, int which, __int64_t id, SIZE_T cpusetsize, __sanitizer_cpuset_t *mask) {
10239  void *ctx;
10240  COMMON_INTERCEPTOR_ENTER(ctx, cpuset_getaffinity, level, which, id, cpusetsize, mask);
10241  int res = REAL(cpuset_getaffinity)(level, which, id, cpusetsize, mask);
10242  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
10243  return res;
10244}
10245#define INIT_CPUSET_GETAFFINITY COMMON_INTERCEPT_FUNCTION(cpuset_getaffinity);
10246#else
10247#define INIT_CPUSET_GETAFFINITY
10248#endif
10249
10250#if SANITIZER_INTERCEPT_PREADV2
10251INTERCEPTOR(SSIZE_T, preadv2, int fd, __sanitizer_iovec *iov, int iovcnt,
10252            OFF_T offset, int flags) {
10253  void *ctx;
10254  COMMON_INTERCEPTOR_ENTER(ctx, preadv2, fd, iov, iovcnt, offset, flags);
10255  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10256  SSIZE_T res = REAL(preadv2)(fd, iov, iovcnt, offset, flags);
10257  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
10258  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
10259  return res;
10260}
10261#define INIT_PREADV2 COMMON_INTERCEPT_FUNCTION(preadv2)
10262#else
10263#define INIT_PREADV2
10264#endif
10265
10266#if SANITIZER_INTERCEPT_PWRITEV2
10267INTERCEPTOR(SSIZE_T, pwritev2, int fd, __sanitizer_iovec *iov, int iovcnt,
10268            OFF_T offset, int flags) {
10269  void *ctx;
10270  COMMON_INTERCEPTOR_ENTER(ctx, pwritev2, fd, iov, iovcnt, offset, flags);
10271  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10272  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
10273  SSIZE_T res = REAL(pwritev2)(fd, iov, iovcnt, offset, flags);
10274  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
10275  return res;
10276}
10277#define INIT_PWRITEV2 COMMON_INTERCEPT_FUNCTION(pwritev2)
10278#else
10279#define INIT_PWRITEV2
10280#endif
10281
10282#if SANITIZER_INTERCEPT_FREADLINK
10283INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {
10284  void *ctx;
10285  COMMON_INTERCEPTOR_ENTER(ctx, freadlink, fd, buf, bufsiz);
10286  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10287  SSIZE_T res = REAL(freadlink)(fd, buf, bufsiz);
10288  if (res > 0)
10289    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
10290  if (res >= 0 && fd > 0)
10291    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
10292  return res;
10293}
10294#  define INIT_FREADLINK COMMON_INTERCEPT_FUNCTION(freadlink)
10295#else
10296#  define INIT_FREADLINK
10297#endif
10298
10299#if SANITIZER_INTERCEPT_GETSERVENT_R || SANITIZER_INTERCEPT_GETSERVBYNAME_R || \
10300    SANITIZER_INTERCEPT_GETSERVBYPORT_R
10301
10302UNUSED static void HandleGetServentReentrantResult(
10303    void *ctx, int res, struct __sanitizer_servent *result_buf, char *buf,
10304    SIZE_T buflen, struct __sanitizer_servent **result) {
10305  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)result, sizeof(void *));
10306  if (res)
10307    return;
10308  if (*result) {
10309    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)*result,
10310                                   sizeof(__sanitizer_servent));
10311    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
10312  }
10313}
10314
10315#endif
10316
10317#if SANITIZER_INTERCEPT_GETSERVENT_R
10318INTERCEPTOR(int, getservent_r, struct __sanitizer_servent *result_buf,
10319            char *buf, SIZE_T buflen, struct __sanitizer_servent **result) {
10320  void *ctx;
10321  COMMON_INTERCEPTOR_ENTER(ctx, getservent_r, result_buf, buf, buflen, result);
10322  int res = REAL(getservent_r)(result_buf, buf, buflen, result);
10323  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10324  return res;
10325}
10326#  define INIT_GETSERVENT_R COMMON_INTERCEPT_FUNCTION(getservent_r)
10327#else
10328#  define INIT_GETSERVENT_R
10329#endif
10330
10331#if SANITIZER_INTERCEPT_GETSERVBYNAME_R
10332INTERCEPTOR(int, getservbyname_r, const char *name, const char *proto,
10333            struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10334            struct __sanitizer_servent **result) {
10335  void *ctx;
10336  COMMON_INTERCEPTOR_ENTER(ctx, getservbyname_r, name, proto, result_buf, buf,
10337                           buflen, result);
10338  COMMON_INTERCEPTOR_READ_STRING(ctx, name, internal_strlen(name));
10339  int res = REAL(getservbyname_r)(name, proto, result_buf, buf, buflen, result);
10340  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10341  return res;
10342}
10343#  define INIT_GETSERVBYNAME_R COMMON_INTERCEPT_FUNCTION(getservbyname_r)
10344#else
10345#  define INIT_GETSERVBYNAME_R
10346#endif
10347
10348#if SANITIZER_INTERCEPT_GETSERVBYPORT_R
10349INTERCEPTOR(int, getservbyport_r, int port, const char *proto,
10350            struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,
10351            struct __sanitizer_servent **result) {
10352  void *ctx;
10353  COMMON_INTERCEPTOR_ENTER(ctx, getservbyport_r, port, proto, result_buf, buf,
10354                           buflen, result);
10355  int res = REAL(getservbyport_r)(port, proto, result_buf, buf, buflen, result);
10356  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);
10357  return res;
10358}
10359#  define INIT_GETSERVBYPORT_R COMMON_INTERCEPT_FUNCTION(getservbyport_r)
10360#else
10361#  define INIT_GETSERVBYPORT_R
10362#endif
10363
10364#include "sanitizer_common_interceptors_netbsd_compat.inc"
10365
10366namespace __sanitizer {
10367void InitializeMemintrinsicInterceptors();
10368}  // namespace __sanitizer
10369
10370static void InitializeCommonInterceptors() {
10371#if SI_POSIX
10372  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
10373  interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();
10374#endif
10375
10376  __sanitizer::InitializeMemintrinsicInterceptors();
10377
10378  INIT_MMAP;
10379  INIT_MMAP64;
10380  INIT_TEXTDOMAIN;
10381  INIT_STRLEN;
10382  INIT_STRNLEN;
10383  INIT_STRNDUP;
10384  INIT___STRNDUP;
10385  INIT_STRCMP;
10386  INIT_STRNCMP;
10387  INIT_STRCASECMP;
10388  INIT_STRNCASECMP;
10389  INIT_STRSTR;
10390  INIT_STRCASESTR;
10391  INIT_STRCHR;
10392  INIT_STRCHRNUL;
10393  INIT_STRRCHR;
10394  INIT_STRSPN;
10395  INIT_STRTOK;
10396  INIT_STRPBRK;
10397  INIT_STRXFRM;
10398  INIT___STRXFRM_L;
10399  INIT_MEMCHR;
10400  INIT_MEMCMP;
10401  INIT_BCMP;
10402  INIT_MEMRCHR;
10403  INIT_MEMMEM;
10404  INIT_READ;
10405  INIT_FREAD;
10406  INIT_PREAD;
10407  INIT_PREAD64;
10408  INIT_READV;
10409  INIT_PREADV;
10410  INIT_PREADV64;
10411  INIT_WRITE;
10412  INIT_FWRITE;
10413  INIT_PWRITE;
10414  INIT_PWRITE64;
10415  INIT_WRITEV;
10416  INIT_PWRITEV;
10417  INIT_PWRITEV64;
10418  INIT_FGETS;
10419  INIT_FPUTS;
10420  INIT_PUTS;
10421  INIT_PRCTL;
10422  INIT_LOCALTIME_AND_FRIENDS;
10423  INIT_STRPTIME;
10424  INIT_SCANF;
10425  INIT_ISOC99_SCANF;
10426  INIT_PRINTF;
10427  INIT_PRINTF_L;
10428  INIT_ISOC99_PRINTF;
10429  INIT_SETPROCTITLE;
10430  INIT_FREXP;
10431  INIT_FREXPF;
10432  INIT_FREXPL;
10433  INIT_GETPWNAM_AND_FRIENDS;
10434  INIT_GETPWNAM_R_AND_FRIENDS;
10435  INIT_GETPWENT;
10436  INIT_FGETPWENT;
10437  INIT_GETPWENT_R;
10438  INIT_FGETPWENT_R;
10439  INIT_FGETGRENT_R;
10440  INIT_SETPWENT;
10441  INIT_CLOCK_GETTIME;
10442  INIT_CLOCK_GETCPUCLOCKID;
10443  INIT_TIMER_CREATE;
10444  INIT_GETITIMER;
10445  INIT_TIME;
10446  INIT_TIMESPEC_GET;
10447  INIT_GLOB;
10448  INIT_GLOB64;
10449  INIT___B64_TO;
10450  INIT_DN_COMP_EXPAND;
10451  INIT_POSIX_SPAWN;
10452  INIT_WAIT;
10453  INIT_WAIT4;
10454  INIT_INET;
10455  INIT_PTHREAD_GETSCHEDPARAM;
10456  INIT_GETADDRINFO;
10457  INIT_GETNAMEINFO;
10458  INIT_GETSOCKNAME;
10459  INIT_GETHOSTBYNAME;
10460  INIT_GETHOSTBYNAME2;
10461  INIT_GETHOSTBYNAME_R;
10462  INIT_GETHOSTBYNAME2_R;
10463  INIT_GETHOSTBYADDR_R;
10464  INIT_GETHOSTENT_R;
10465  INIT_GETSOCKOPT;
10466  INIT_ACCEPT;
10467  INIT_ACCEPT4;
10468  INIT_PACCEPT;
10469  INIT_MODF;
10470  INIT_RECVMSG;
10471  INIT_SENDMSG;
10472  INIT_RECVMMSG;
10473  INIT_SENDMMSG;
10474  INIT_SYSMSG;
10475  INIT_GETPEERNAME;
10476  INIT_IOCTL;
10477  INIT_INET_ATON;
10478  INIT_SYSINFO;
10479  INIT_READDIR;
10480  INIT_READDIR64;
10481  INIT_PTRACE;
10482  INIT_SETLOCALE;
10483  INIT_GETCWD;
10484  INIT_GET_CURRENT_DIR_NAME;
10485  INIT_STRTOIMAX;
10486  INIT_STRTOIMAX_C23;
10487  INIT_MBSTOWCS;
10488  INIT_MBSNRTOWCS;
10489  INIT_WCSTOMBS;
10490  INIT_WCSNRTOMBS;
10491  INIT_WCRTOMB;
10492  INIT_WCTOMB;
10493  INIT_TCGETATTR;
10494  INIT_REALPATH;
10495  INIT_CANONICALIZE_FILE_NAME;
10496  INIT_CONFSTR;
10497  INIT_SCHED_GETAFFINITY;
10498  INIT_SCHED_GETPARAM;
10499  INIT_STRERROR;
10500  INIT_STRERROR_R;
10501  INIT_XPG_STRERROR_R;
10502  INIT_SCANDIR;
10503  INIT_SCANDIR64;
10504  INIT_GETGROUPS;
10505  INIT_POLL;
10506  INIT_PPOLL;
10507  INIT_WORDEXP;
10508  INIT_SIGWAIT;
10509  INIT_SIGWAITINFO;
10510  INIT_SIGTIMEDWAIT;
10511  INIT_SIGSETOPS;
10512  INIT_SIGSET_LOGICOPS;
10513  INIT_SIGPENDING;
10514  INIT_SIGPROCMASK;
10515  INIT_PTHREAD_SIGMASK;
10516  INIT_BACKTRACE;
10517  INIT__EXIT;
10518  INIT___LIBC_THR_SETCANCELSTATE;
10519  INIT_GETMNTENT;
10520  INIT_GETMNTENT_R;
10521  INIT_STATFS;
10522  INIT_STATFS64;
10523  INIT_STATVFS;
10524  INIT_STATVFS64;
10525  INIT_INITGROUPS;
10526  INIT_ETHER_NTOA_ATON;
10527  INIT_ETHER_HOST;
10528  INIT_ETHER_R;
10529  INIT_SHMCTL;
10530  INIT_RANDOM_R;
10531  INIT_PTHREAD_ATTR_GET;
10532  INIT_PTHREAD_ATTR_GET_SCHED;
10533  INIT_PTHREAD_ATTR_GETINHERITSCHED;
10534  INIT_PTHREAD_ATTR_GETAFFINITY_NP;
10535  INIT_PTHREAD_GETAFFINITY_NP;
10536  INIT_PTHREAD_MUTEXATTR_GETPSHARED;
10537  INIT_PTHREAD_MUTEXATTR_GETTYPE;
10538  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
10539  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
10540  INIT_PTHREAD_MUTEXATTR_GETROBUST;
10541  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
10542  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
10543  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
10544  INIT_PTHREAD_CONDATTR_GETPSHARED;
10545  INIT_PTHREAD_CONDATTR_GETCLOCK;
10546  INIT_PTHREAD_BARRIERATTR_GETPSHARED;
10547  INIT_TMPNAM;
10548  INIT_TMPNAM_R;
10549  INIT_PTSNAME;
10550  INIT_PTSNAME_R;
10551  INIT_TTYNAME;
10552  INIT_TTYNAME_R;
10553  INIT_TEMPNAM;
10554  INIT_PTHREAD_SETNAME_NP;
10555  INIT_PTHREAD_GETNAME_NP;
10556  INIT_SINCOS;
10557  INIT_REMQUO;
10558  INIT_REMQUOL;
10559  INIT_LGAMMA;
10560  INIT_LGAMMAL;
10561  INIT_LGAMMA_R;
10562  INIT_LGAMMAL_R;
10563  INIT_DRAND48_R;
10564  INIT_RAND_R;
10565  INIT_GETLINE;
10566  INIT_ICONV;
10567  INIT_TIMES;
10568  INIT_TLS_GET_ADDR;
10569  INIT_LISTXATTR;
10570  INIT_GETXATTR;
10571  INIT_GETRESID;
10572  INIT_GETIFADDRS;
10573  INIT_IF_INDEXTONAME;
10574  INIT_CAPGET;
10575  INIT_FTIME;
10576  INIT_XDR;
10577  INIT_XDRREC_LINUX;
10578  INIT_TSEARCH;
10579  INIT_LIBIO_INTERNALS;
10580  INIT_FOPEN;
10581  INIT_FOPEN64;
10582  INIT_FLOPEN;
10583  INIT_OPEN_MEMSTREAM;
10584  INIT_OBSTACK;
10585  INIT_FFLUSH;
10586  INIT_FCLOSE;
10587  INIT_DLOPEN_DLCLOSE;
10588  INIT_GETPASS;
10589  INIT_TIMERFD;
10590  INIT_MLOCKX;
10591  INIT_FOPENCOOKIE;
10592  INIT_SEM;
10593  INIT_PTHREAD_SETCANCEL;
10594  INIT_MINCORE;
10595  INIT_PROCESS_VM_READV;
10596  INIT_CTERMID;
10597  INIT_CTERMID_R;
10598  INIT_RECV_RECVFROM;
10599  INIT_SEND_SENDTO;
10600  INIT_STAT;
10601  INIT_STAT64;
10602  INIT_EVENTFD_READ_WRITE;
10603  INIT_LSTAT;
10604  INIT_LSTAT64;
10605  INIT___XSTAT;
10606  INIT___XSTAT64;
10607  INIT___LXSTAT;
10608  INIT___LXSTAT64;
10609  // FIXME: add other *stat interceptors.
10610  INIT_UTMP;
10611  INIT_UTMPX;
10612  INIT_GETLOADAVG;
10613  INIT_WCSLEN;
10614  INIT_WCSCAT;
10615  INIT_WCSDUP;
10616  INIT_WCSXFRM;
10617  INIT___WCSXFRM_L;
10618  INIT_ACCT;
10619  INIT_USER_FROM_UID;
10620  INIT_UID_FROM_USER;
10621  INIT_GROUP_FROM_GID;
10622  INIT_GID_FROM_GROUP;
10623  INIT_ACCESS;
10624  INIT_FACCESSAT;
10625  INIT_GETGROUPLIST;
10626  INIT_GETGROUPMEMBERSHIP;
10627  INIT_READLINK;
10628  INIT_READLINKAT;
10629  INIT_NAME_TO_HANDLE_AT;
10630  INIT_OPEN_BY_HANDLE_AT;
10631  INIT_STRLCPY;
10632  INIT_DEVNAME;
10633  INIT_DEVNAME_R;
10634  INIT_FGETLN;
10635  INIT_STRMODE;
10636  INIT_TTYENT;
10637  INIT_PROTOENT;
10638  INIT_PROTOENT_R;
10639  INIT_NETENT;
10640  INIT_GETMNTINFO;
10641  INIT_MI_VECTOR_HASH;
10642  INIT_SETVBUF;
10643  INIT_GETVFSSTAT;
10644  INIT_REGEX;
10645  INIT_REGEXSUB;
10646  INIT_FTS;
10647  INIT_SYSCTL;
10648  INIT_ASYSCTL;
10649  INIT_SYSCTLGETMIBINFO;
10650  INIT_NL_LANGINFO;
10651  INIT_MODCTL;
10652  INIT_STRTONUM;
10653  INIT_FPARSELN;
10654  INIT_STATVFS1;
10655  INIT_STRTOI;
10656  INIT_CAPSICUM;
10657  INIT_SHA1;
10658  INIT_MD4;
10659  INIT_RMD160;
10660  INIT_FSEEK;
10661  INIT_MD2;
10662  INIT_VIS;
10663  INIT_CDB;
10664  INIT_GETFSENT;
10665  INIT_ARC4RANDOM;
10666  INIT_POPEN;
10667  INIT_POPENVE;
10668  INIT_PCLOSE;
10669  INIT_FUNOPEN;
10670  INIT_FUNOPEN2;
10671  INIT_FDEVNAME;
10672  INIT_GETUSERSHELL;
10673  INIT_SL_INIT;
10674  INIT_GETRANDOM;
10675  INIT_GETENTROPY;
10676  INIT_QSORT;
10677  INIT_QSORT_R;
10678  INIT_BSEARCH;
10679  INIT_SIGALTSTACK;
10680  INIT_PROCCTL
10681  INIT_UNAME;
10682  INIT___XUNAME;
10683  INIT_ARGP_PARSE;
10684  INIT_CPUSET_GETAFFINITY;
10685  INIT_PREADV2;
10686  INIT_PWRITEV2;
10687  INIT_FREADLINK;
10688
10689  INIT___PRINTF_CHK;
10690  INIT_GETSERVENT_R;
10691  INIT_GETSERVBYNAME_R;
10692  INIT_GETSERVBYPORT_R;
10693}