brintos

brintos / llvm-project-archived public Read only

0
0
Text · 369.9 KiB · b10ce7f Raw
10720 lines · plain
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-exception6//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_ENTER15//   COMMON_INTERCEPTOR_ENTER_NOIGNORE16//   COMMON_INTERCEPTOR_READ_RANGE17//   COMMON_INTERCEPTOR_WRITE_RANGE18//   COMMON_INTERCEPTOR_INITIALIZE_RANGE19//   COMMON_INTERCEPTOR_DIR_ACQUIRE20//   COMMON_INTERCEPTOR_FD_ACQUIRE21//   COMMON_INTERCEPTOR_FD_RELEASE22//   COMMON_INTERCEPTOR_FD_ACCESS23//   COMMON_INTERCEPTOR_SET_THREAD_NAME24//   COMMON_INTERCEPTOR_DLOPEN25//   COMMON_INTERCEPTOR_ON_EXIT26//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME27//   COMMON_INTERCEPTOR_HANDLE_RECVMSG28//   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED29//   COMMON_INTERCEPTOR_MMAP_IMPL30//   COMMON_INTERCEPTOR_MUNMAP_IMPL31//   COMMON_INTERCEPTOR_COPY_STRING32//   COMMON_INTERCEPTOR_STRNDUP_IMPL33//   COMMON_INTERCEPTOR_STRERROR34//===----------------------------------------------------------------------===//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_HOOKS49#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#else53#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)54#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)55 56#endif  // SANITIZER_INTERCEPTOR_HOOKS57 58#if SANITIZER_WINDOWS && !defined(va_copy)59#define va_copy(dst, src) ((dst) = (src))60#endif // _WIN3261 62#if SANITIZER_FREEBSD63#define pthread_setname_np pthread_set_name_np64#define inet_aton __inet_aton65#define inet_pton __inet_pton66#define iconv __bsd_iconv67#endif68 69#if SANITIZER_NETBSD70#define clock_getres __clock_getres5071#define clock_gettime __clock_gettime5072#define clock_settime __clock_settime5073#define ctime __ctime5074#define ctime_r __ctime_r5075#define devname __devname5076#define fgetpos __fgetpos5077#define fsetpos __fsetpos5078#define fstatvfs __fstatvfs9079#define fstatvfs1 __fstatvfs19080#define fts_children __fts_children6081#define fts_close __fts_close6082#define fts_open __fts_open6083#define fts_read __fts_read6084#define fts_set __fts_set6085#define getitimer __getitimer5086#define getmntinfo __getmntinfo9087#define getpwent __getpwent5088#define getpwnam __getpwnam5089#define getpwnam_r __getpwnam_r5090#define getpwuid __getpwuid5091#define getpwuid_r __getpwuid_r5092#define getutent __getutent5093#define getutxent __getutxent5094#define getutxid __getutxid5095#define getutxline __getutxline5096#define getvfsstat __getvfsstat9097#define pututxline __pututxline5098#define glob __glob3099#define gmtime __gmtime50100#define gmtime_r __gmtime_r50101#define localtime __locatime50102#define localtime_r __localtime_r50103#define mktime __mktime50104#define lstat __lstat50105#define opendir __opendir30106#define readdir __readdir30107#define readdir_r __readdir_r30108#define scandir __scandir30109#define setitimer __setitimer50110#define setlocale __setlocale50111#define shmctl __shmctl50112#define sigaltstack __sigaltstack14113#define sigemptyset __sigemptyset14114#define sigfillset __sigfillset14115#define sigpending __sigpending14116#define sigprocmask __sigprocmask14117#define sigtimedwait __sigtimedwait50118#define stat __stat50119#define statvfs __statvfs90120#define statvfs1 __statvfs190121#define time __time50122#define times __times13123#define unvis __unvis50124#define wait3 __wait350125#define wait4 __wait450126extern const unsigned short *_ctype_tab_;127extern const short *_toupper_tab_;128extern const short *_tolower_tab_;129#endif130 131#if SANITIZER_LINUX && SANITIZER_SPARC32132// On 32-bit Linux/sparc64, double and long double are identical and glibc133// uses a __nldbl_ (no long double) prefix for various stdio functions.134#  define __isoc23_fscanf __nldbl___isoc23_fscanf135#  define __isoc23_scanf __nldbl___isoc23_scanf136#  define __isoc23_sscanf __nldbl___isoc23_sscanf137#  define __isoc23_vfscanf __nldbl___isoc23_vfscanf138#  define __isoc23_vscanf __nldbl___isoc23_vscanf139#  define __isoc23_vsscanf __nldbl___isoc23_vsscanf140#  define __isoc99_fscanf __nldbl___isoc99_fscanf141#  define __isoc99_scanf __nldbl___isoc99_scanf142#  define __isoc99_sscanf __nldbl___isoc99_sscanf143#  define __isoc99_vfscanf __nldbl___isoc99_vfscanf144#  define __isoc99_vscanf __nldbl___isoc99_vscanf145#  define __isoc99_vsscanf __nldbl___isoc99_vsscanf146#  define asprintf __nldbl_asprintf147#  define fprintf __nldbl_fprintf148#  define fscanf __nldbl_fscanf149#  define printf __nldbl_printf150#  define scanf __nldbl_scanf151#  define snprintf __nldbl_snprintf152#  define sprintf __nldbl_sprintf153#  define sscanf __nldbl_sscanf154#  define vasprintf __nldbl_vasprintf155#  define vfprintf __nldbl_vfprintf156#  define vfscanf __nldbl_vfscanf157#  define vprintf __nldbl_vprintf158#  define vscanf __nldbl_vscanf159#  define vsnprintf __nldbl_vsnprintf160#  define vsprintf __nldbl_vsprintf161#  define vsscanf __nldbl_vsscanf162#endif163 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 the167// time-related functions that take 64-bit time_t values.  See168// https://musl.libc.org/time64.html169#define adjtime __adjtime64170#define adjtimex __adjtimex_time64171#define aio_suspend __aio_suspend_time64172#define clock_adjtime __clock_adjtime64173#define clock_getres __clock_getres_time64174#define clock_gettime __clock_gettime64175#define clock_nanosleep __clock_nanosleep_time64176#define clock_settime __clock_settime64177#define cnd_timedwait __cnd_timedwait_time64178#define ctime __ctime64179#define ctime_r __ctime64_r180#define difftime __difftime64181#define dlsym __dlsym_time64182#define fstatat __fstatat_time64183#define fstat __fstat_time64184#define ftime __ftime64185#define futimens __futimens_time64186#define futimesat __futimesat_time64187#define futimes __futimes_time64188#define getitimer __getitimer_time64189#define getrusage __getrusage_time64190#define gettimeofday __gettimeofday_time64191#define gmtime __gmtime64192#define gmtime_r __gmtime64_r193#define localtime __localtime64194#define localtime_r __localtime64_r195#define lstat __lstat_time64196#define lutimes __lutimes_time64197#define mktime __mktime64198#define mq_timedreceive __mq_timedreceive_time64199#define mq_timedsend __mq_timedsend_time64200#define mtx_timedlock __mtx_timedlock_time64201#define nanosleep __nanosleep_time64202#define ppoll __ppoll_time64203#define pselect __pselect_time64204#define pthread_cond_timedwait __pthread_cond_timedwait_time64205#define pthread_mutex_timedlock __pthread_mutex_timedlock_time64206#define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock_time64207#define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock_time64208#define pthread_timedjoin_np __pthread_timedjoin_np_time64209#define recvmmsg __recvmmsg_time64210#define sched_rr_get_interval __sched_rr_get_interval_time64211#define select __select_time64212#define semtimedop __semtimedop_time64213#define sem_timedwait __sem_timedwait_time64214#define setitimer __setitimer_time64215#define settimeofday __settimeofday_time64216#define sigtimedwait __sigtimedwait_time64217#define stat __stat_time64218#define stime __stime64219#define thrd_sleep __thrd_sleep_time64220#define timegm __timegm_time64221#define timerfd_gettime __timerfd_gettime64222#define timerfd_settime __timerfd_settime64223#define timer_gettime __timer_gettime64224#define timer_settime __timer_settime64225#define timespec_get __timespec_get_time64226#define time __time64227#define utimensat __utimensat_time64228#define utimes __utimes_time64229#define utime __utime64230#define wait3 __wait3_time64231#define wait4 __wait4_time64232#endif233 234#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE235#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}236#endif237 238#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM239#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}240#endif241 242#ifndef COMMON_INTERCEPTOR_FD_ACCESS243#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}244#endif245 246#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG247#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))248#endif249 250#ifndef COMMON_INTERCEPTOR_FILE_OPEN251#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}252#endif253 254#ifndef COMMON_INTERCEPTOR_FILE_CLOSE255#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}256#endif257 258#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED259#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}260#endif261 262#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED263#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}264#endif265 266#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE267#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \268  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)269#endif270 271#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED272#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)273#endif274 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_DLOPEN280#define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \281  ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); })282#endif283 284#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE285#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;286#endif287 288#ifndef COMMON_INTERCEPTOR_ACQUIRE289#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}290#endif291 292#ifndef COMMON_INTERCEPTOR_RELEASE293#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}294#endif295 296#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START297#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}298#endif299 300#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END301#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}302#endif303 304#ifdef SANITIZER_NLDBL_VERSION305#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \306    COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)307#else308#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \309    COMMON_INTERCEPT_FUNCTION(fn)310#endif311 312#if SANITIZER_GLIBC313// If we could not find the versioned symbol, fall back to an unversioned314// lookup. This is needed to work around a GLibc bug that causes dlsym315// 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 the319// 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#else325#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \326  COMMON_INTERCEPT_FUNCTION(fn)327#endif328 329#ifndef COMMON_INTERCEPTOR_MMAP_IMPL330#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#endif334 335#ifndef COMMON_INTERCEPTOR_MUNMAP_IMPL336#define COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz) \337  { return REAL(munmap)(addr, sz); }338#endif339 340#ifndef COMMON_INTERCEPTOR_COPY_STRING341#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}342#endif343 344#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL345#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#endif359 360#ifndef COMMON_INTERCEPTOR_STRERROR361#define COMMON_INTERCEPTOR_STRERROR() {}362#endif363 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_FILE374  } type;375  union {376    FileMetadata file;377  };378};379 380#if SI_POSIX381typedef 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_POSIX412 413#if SANITIZER_INTERCEPT_STRLEN414INTERCEPTOR(SIZE_T, strlen, const char *s) {415  // Sometimes strlen is called prior to InitializeCommonInterceptors,416  // in which case the REAL(strlen) typically used in417  // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here418  // 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#else430#define INIT_STRLEN431#endif432 433#if SANITIZER_INTERCEPT_STRNLEN434INTERCEPTOR(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#else444#define INIT_STRNLEN445#endif446 447#if SANITIZER_INTERCEPT_STRNDUP448INTERCEPTOR(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#else454#define INIT_STRNDUP455#endif // SANITIZER_INTERCEPT_STRNDUP456 457#if SANITIZER_INTERCEPT___STRNDUP458INTERCEPTOR(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#else464#define INIT___STRNDUP465#endif // SANITIZER_INTERCEPT___STRNDUP466 467#if SANITIZER_INTERCEPT_TEXTDOMAIN468INTERCEPTOR(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#else480#define INIT_TEXTDOMAIN481#endif482 483#if SANITIZER_INTERCEPT_STRCMP || SANITIZER_INTERCEPT_MEMCMP484[[maybe_unused]] static inline int CharCmpX(unsigned char c1,485                                            unsigned char c2) {486  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;487}488#endif489 490#if SANITIZER_INTERCEPT_STRCMP491DECLARE_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#else547#define INIT_STRCMP548#define INIT_STRNCMP549#endif550 551#if SANITIZER_INTERCEPT_STRCASECMP552static 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#else610#define INIT_STRCASECMP611#define INIT_STRNCASECMP612#endif613 614#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR615static 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#endif623 624#if SANITIZER_INTERCEPT_STRSTR625 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#else644#define INIT_STRSTR645#endif646 647#if SANITIZER_INTERCEPT_STRCASESTR648 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#else665#define INIT_STRCASESTR666#endif667 668#if SANITIZER_INTERCEPT_STRTOK669 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 argument678    // string on the first call (strtok saves this string in a static buffer679    // 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 the689    // whole string on the first call. Instead, we check the result string690    // which is guaranteed to be a NULL-terminated substring of the first691    // argument. We also conservatively check one character of str and the692    // 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 was702      // 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#else711#define INIT_STRTOK712#endif713 714#if SANITIZER_INTERCEPT_MEMMEM715DECLARE_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#else735#define INIT_MEMMEM736#endif  // SANITIZER_INTERCEPT_MEMMEM737 738#if SANITIZER_INTERCEPT_STRCHR739INTERCEPTOR(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#else754#define INIT_STRCHR755#endif756 757#if SANITIZER_INTERCEPT_STRCHRNUL758INTERCEPTOR(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#else769#define INIT_STRCHRNUL770#endif771 772#if SANITIZER_INTERCEPT_STRRCHR773INTERCEPTOR(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#else784#define INIT_STRRCHR785#endif786 787#if SANITIZER_INTERCEPT_STRSPN788INTERCEPTOR(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#else814#define INIT_STRSPN815#endif816 817#if SANITIZER_INTERCEPT_STRPBRK818INTERCEPTOR(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#else832#define INIT_STRPBRK833#endif834 835#if SANITIZER_INTERCEPT_MEMCMP836DECLARE_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 are847      // 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#else885#define INIT_MEMCMP886#endif887 888#if SANITIZER_INTERCEPT_BCMP889INTERCEPTOR(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#else899#define INIT_BCMP900#endif901 902#if SANITIZER_INTERCEPT_MEMCHR903INTERCEPTOR(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_WINDOWS909  void *res;910  if (REAL(memchr)) {911    res = REAL(memchr)(s, c, n);912  } else {913    res = internal_memchr(s, c, n);914  }915#else916  void *res = REAL(memchr)(s, c, n);917#endif918  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#else925#define INIT_MEMCHR926#endif927 928#if SANITIZER_INTERCEPT_MEMRCHR929INTERCEPTOR(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#else938#define INIT_MEMRCHR939#endif940 941#if SANITIZER_INTERCEPT_FREXP942INTERCEPTOR(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#else954#define INIT_FREXP955#endif  // SANITIZER_INTERCEPT_FREXP956 957#if SANITIZER_INTERCEPT_FREXPF958INTERCEPTOR(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#else969#  define INIT_FREXPF970#endif971 972#if SANITIZER_INTERCEPT_FREXPL973INTERCEPTOR(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#else984#  define INIT_FREXPL985#endif986 987#if SI_POSIX988static 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#endif1007 1008#if SANITIZER_INTERCEPT_READ1009INTERCEPTOR(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 corrupt1014  // its metadata. See1015  // 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#else1023#define INIT_READ1024#endif1025 1026#if SANITIZER_INTERCEPT_FREAD1027INTERCEPTOR(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 corrupt1032  // its metadata. See1033  // 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#else1040#define INIT_FREAD1041#endif1042 1043#if SANITIZER_INTERCEPT_PREAD1044INTERCEPTOR(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 corrupt1049  // its metadata. See1050  // 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#else1058#define INIT_PREAD1059#endif1060 1061#if SANITIZER_INTERCEPT_PREAD641062INTERCEPTOR(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 corrupt1067  // its metadata. See1068  // 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#else1076#define INIT_PREAD641077#endif1078 1079#if SANITIZER_INTERCEPT_READV1080INTERCEPTOR_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#else1092#define INIT_READV1093#endif1094 1095#if SANITIZER_INTERCEPT_PREADV1096INTERCEPTOR(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#else1108#define INIT_PREADV1109#endif1110 1111#if SANITIZER_INTERCEPT_PREADV641112INTERCEPTOR(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#else1125#define INIT_PREADV641126#endif1127 1128#if SANITIZER_INTERCEPT_WRITE1129INTERCEPTOR(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 to1136  // COMMON_INTERCEPTOR_BLOCK_REAL(write), not after1137  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);1138  return res;1139}1140#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)1141#else1142#define INIT_WRITE1143#endif1144 1145#if SANITIZER_INTERCEPT_FWRITE1146INTERCEPTOR(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#else1156#define INIT_FWRITE1157#endif1158 1159#if SANITIZER_INTERCEPT_PWRITE1160INTERCEPTOR(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#else1171#define INIT_PWRITE1172#endif1173 1174#if SANITIZER_INTERCEPT_PWRITE641175INTERCEPTOR(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#else1187#define INIT_PWRITE641188#endif1189 1190#if SANITIZER_INTERCEPT_WRITEV1191INTERCEPTOR_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#else1203#define INIT_WRITEV1204#endif1205 1206#if SANITIZER_INTERCEPT_PWRITEV1207INTERCEPTOR(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#else1219#define INIT_PWRITEV1220#endif1221 1222#if SANITIZER_INTERCEPT_PWRITEV641223INTERCEPTOR(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#else1236#define INIT_PWRITEV641237#endif1238 1239#if SANITIZER_INTERCEPT_FGETS1240INTERCEPTOR(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 corrupt1245  // its metadata. See1246  // 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#else1254#define INIT_FGETS1255#endif1256 1257#if SANITIZER_INTERCEPT_FPUTS1258INTERCEPTOR_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#else1269#define INIT_FPUTS1270#endif1271 1272#if SANITIZER_INTERCEPT_PUTS1273INTERCEPTOR(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#else1284#define INIT_PUTS1285#endif1286 1287#if SANITIZER_INTERCEPT_PRCTL1288 1289#  if defined(__aarch64__)1290// https://llvm.org/docs/PointerAuth.html1291// AArch64 is currently the only architecture with full PAC support.1292// Avoid adding PAC instructions to prevent crashes caused by1293// prctl(PR_PAC_RESET_KEYS, ...). Since PR_PAC_RESET_KEYS resets the1294// authentication key, using the old key afterward will lead to a crash.1295 1296#    if defined(__ARM_FEATURE_BTI_DEFAULT)1297#      define BRANCH_PROTECTION_ATTRIBUTE \1298        __attribute__((target("branch-protection=bti")))1299#    else1300#      define BRANCH_PROTECTION_ATTRIBUTE \1301        __attribute__((target("branch-protection=none")))1302#    endif1303 1304#    define PRCTL_INTERCEPTOR(ret_type, func, ...)                          \1305      DEFINE_REAL(ret_type, func, __VA_ARGS__)                              \1306      DECLARE_WRAPPER(ret_type, func, __VA_ARGS__)                          \1307      extern "C" INTERCEPTOR_ATTRIBUTE BRANCH_PROTECTION_ATTRIBUTE ret_type \1308      WRAP(func)(__VA_ARGS__)1309 1310#  else1311#    define PRCTL_INTERCEPTOR INTERCEPTOR1312#  endif1313 1314PRCTL_INTERCEPTOR(int, prctl, int option, unsigned long arg2,1315                  unsigned long arg3, unsigned long arg4, unsigned long arg5) {1316  void *ctx;1317  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);1318  static const int PR_SET_NAME = 15;1319  static const int PR_GET_NAME = 16;1320  static const int PR_SET_VMA = 0x53564d41;1321  static const int PR_SCHED_CORE = 62;1322  static const int PR_SCHED_CORE_GET = 0;1323  static const int PR_GET_PDEATHSIG = 2;1324 1325#  if !SANITIZER_ANDROID1326  static const int PR_SET_SECCOMP = 22;1327  static const int SECCOMP_MODE_FILTER = 2;1328#  endif1329  if (option == PR_SET_VMA && arg2 == 0UL && arg5 != 0UL) {1330    char *name = (char *)arg5;1331    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);1332  }1333  int res = REAL(prctl)(option, arg2, arg3, arg4, arg5);1334  if (option == PR_SET_NAME) {1335    char buff[16];1336    internal_strncpy(buff, (char *)arg2, 15);1337    buff[15] = 0;1338    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);1339  } else if (res == 0 && option == PR_GET_NAME) {1340    char *name = (char *)arg2;1341    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);1342  } else if (res != -1 && option == PR_SCHED_CORE &&1343             arg2 == PR_SCHED_CORE_GET) {1344    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg5), sizeof(u64));1345  } else if (res != -1 && option == PR_GET_PDEATHSIG) {1346    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg2), sizeof(int));1347#  if SANITIZER_GLIBC1348  } else if (res != -1 && option == PR_SET_SECCOMP &&1349             arg2 == SECCOMP_MODE_FILTER) {1350    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64 *)(arg3), struct_sock_fprog_sz);1351#  endif1352  }1353  return res;1354}1355#  define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)1356#else1357#define INIT_PRCTL1358#endif  // SANITIZER_INTERCEPT_PRCTL1359 1360#if SANITIZER_INTERCEPT_TIME1361INTERCEPTOR(unsigned long, time, unsigned long *t) {1362  void *ctx;1363  COMMON_INTERCEPTOR_ENTER(ctx, time, t);1364  unsigned long local_t;1365  unsigned long res = REAL(time)(&local_t);1366  if (t && res != (unsigned long)-1) {1367    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));1368    *t = local_t;1369  }1370  return res;1371}1372#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);1373#else1374#define INIT_TIME1375#endif  // SANITIZER_INTERCEPT_TIME1376 1377#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS1378static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {1379  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));1380// AIX tm struct does not have tm_zone field.1381#  if !SANITIZER_SOLARIS && !SANITIZER_AIX1382  if (tm->tm_zone) {1383    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone1384    // can point to shared memory and tsan would report a data race.1385    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,1386                                        internal_strlen(tm->tm_zone) + 1);1387  }1388#endif1389}1390INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {1391  void *ctx;1392  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);1393  __sanitizer_tm *res = REAL(localtime)(timep);1394  if (res) {1395    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1396    unpoison_tm(ctx, res);1397  }1398  return res;1399}1400INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {1401  void *ctx;1402  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);1403  __sanitizer_tm *res = REAL(localtime_r)(timep, result);1404  if (res) {1405    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1406    unpoison_tm(ctx, res);1407  }1408  return res;1409}1410INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {1411  void *ctx;1412  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);1413  __sanitizer_tm *res = REAL(gmtime)(timep);1414  if (res) {1415    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1416    unpoison_tm(ctx, res);1417  }1418  return res;1419}1420INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {1421  void *ctx;1422  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);1423  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);1424  if (res) {1425    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1426    unpoison_tm(ctx, res);1427  }1428  return res;1429}1430INTERCEPTOR(char *, ctime, unsigned long *timep) {1431  void *ctx;1432  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);1433  // FIXME: under ASan the call below may write to freed memory and corrupt1434  // its metadata. See1435  // https://github.com/google/sanitizers/issues/321.1436  char *res = REAL(ctime)(timep);1437  if (res) {1438    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1439    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1440  }1441  return res;1442}1443INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {1444  void *ctx;1445  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);1446  // FIXME: under ASan the call below may write to freed memory and corrupt1447  // its metadata. See1448  // https://github.com/google/sanitizers/issues/321.1449  char *res = REAL(ctime_r)(timep, result);1450  if (res) {1451    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));1452    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1453  }1454  return res;1455}1456INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {1457  void *ctx;1458  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);1459  // FIXME: under ASan the call below may write to freed memory and corrupt1460  // its metadata. See1461  // https://github.com/google/sanitizers/issues/321.1462  char *res = REAL(asctime)(tm);1463  if (res) {1464    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));1465    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1466  }1467  return res;1468}1469INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {1470  void *ctx;1471  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);1472  // FIXME: under ASan the call below may write to freed memory and corrupt1473  // its metadata. See1474  // https://github.com/google/sanitizers/issues/321.1475  char *res = REAL(asctime_r)(tm, result);1476  if (res) {1477    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));1478    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);1479  }1480  return res;1481}1482INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {1483  void *ctx;1484  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);1485  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));1486  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));1487  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));1488  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));1489  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));1490  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));1491  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));1492  long res = REAL(mktime)(tm);1493  if (res != -1) unpoison_tm(ctx, tm);1494  return res;1495}1496#define INIT_LOCALTIME_AND_FRIENDS        \1497  COMMON_INTERCEPT_FUNCTION(localtime);   \1498  COMMON_INTERCEPT_FUNCTION(localtime_r); \1499  COMMON_INTERCEPT_FUNCTION(gmtime);      \1500  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \1501  COMMON_INTERCEPT_FUNCTION(ctime);       \1502  COMMON_INTERCEPT_FUNCTION(ctime_r);     \1503  COMMON_INTERCEPT_FUNCTION(asctime);     \1504  COMMON_INTERCEPT_FUNCTION(asctime_r);   \1505  COMMON_INTERCEPT_FUNCTION(mktime);1506#else1507#define INIT_LOCALTIME_AND_FRIENDS1508#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS1509 1510#if SANITIZER_INTERCEPT_STRPTIME1511INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {1512  void *ctx;1513  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);1514  if (format)1515    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);1516  // FIXME: under ASan the call below may write to freed memory and corrupt1517  // its metadata. See1518  // https://github.com/google/sanitizers/issues/321.1519  char *res = REAL(strptime)(s, format, tm);1520  COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);1521  if (res && tm) {1522    // Do not call unpoison_tm here, because strptime does not, in fact,1523    // initialize the entire struct tm. For example, tm_zone pointer is left1524    // uninitialized.1525    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));1526  }1527  return res;1528}1529#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);1530#else1531#define INIT_STRPTIME1532#endif1533 1534#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF1535#include "sanitizer_common_interceptors_format.inc"1536 1537#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \1538  {                                                                            \1539    void *ctx;                                                                 \1540    va_list ap;                                                                \1541    va_start(ap, format);                                                      \1542    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \1543    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \1544    va_end(ap);                                                                \1545    return res;                                                                \1546  }1547 1548#endif1549 1550#if SANITIZER_INTERCEPT_SCANF1551 1552#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \1553  {                                                                            \1554    void *ctx;                                                                 \1555    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \1556    va_list aq;                                                                \1557    va_copy(aq, ap);                                                           \1558    int res = REAL(vname)(__VA_ARGS__);                                        \1559    if (res > 0)                                                               \1560      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \1561    va_end(aq);                                                                \1562    return res;                                                                \1563  }1564 1565INTERCEPTOR(int, vscanf, const char *format, va_list ap)1566VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)1567 1568INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)1569VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)1570 1571INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)1572VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)1573 1574#if SANITIZER_INTERCEPT_ISOC99_SCANF1575INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)1576VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)1577 1578INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,1579            va_list ap)1580VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)1581 1582INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)1583VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)1584 1585INTERCEPTOR(int, __isoc23_vscanf, const char *format, va_list ap)1586VSCANF_INTERCEPTOR_IMPL(__isoc23_vscanf, false, format, ap)1587 1588INTERCEPTOR(int, __isoc23_vsscanf, const char *str, const char *format,1589            va_list ap)1590VSCANF_INTERCEPTOR_IMPL(__isoc23_vsscanf, false, str, format, ap)1591 1592INTERCEPTOR(int, __isoc23_vfscanf, void *stream, const char *format, va_list ap)1593VSCANF_INTERCEPTOR_IMPL(__isoc23_vfscanf, false, stream, format, ap)1594#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF1595 1596INTERCEPTOR(int, scanf, const char *format, ...)1597FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)1598 1599INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)1600FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)1601 1602INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)1603FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)1604 1605#if SANITIZER_INTERCEPT_ISOC99_SCANF1606INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)1607FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)1608 1609INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)1610FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)1611 1612INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)1613FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)1614 1615INTERCEPTOR(int, __isoc23_scanf, const char *format, ...)1616FORMAT_INTERCEPTOR_IMPL(__isoc23_scanf, __isoc23_vscanf, format)1617 1618INTERCEPTOR(int, __isoc23_fscanf, void *stream, const char *format, ...)1619FORMAT_INTERCEPTOR_IMPL(__isoc23_fscanf, __isoc23_vfscanf, stream, format)1620 1621INTERCEPTOR(int, __isoc23_sscanf, const char *str, const char *format, ...)1622FORMAT_INTERCEPTOR_IMPL(__isoc23_sscanf, __isoc23_vsscanf, str, format)1623#endif1624 1625#endif1626 1627#if SANITIZER_INTERCEPT_SCANF1628#define INIT_SCANF                    \1629  COMMON_INTERCEPT_FUNCTION_LDBL(scanf);   \1630  COMMON_INTERCEPT_FUNCTION_LDBL(sscanf);  \1631  COMMON_INTERCEPT_FUNCTION_LDBL(fscanf);  \1632  COMMON_INTERCEPT_FUNCTION_LDBL(vscanf);  \1633  COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \1634  COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);1635#else1636#define INIT_SCANF1637#endif1638 1639#if SANITIZER_INTERCEPT_ISOC99_SCANF1640#define INIT_ISOC99_SCANF                      \1641  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \1642  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \1643  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \1644  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \1645  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \1646  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); \1647  COMMON_INTERCEPT_FUNCTION(__isoc23_scanf);   \1648  COMMON_INTERCEPT_FUNCTION(__isoc23_sscanf);  \1649  COMMON_INTERCEPT_FUNCTION(__isoc23_fscanf);  \1650  COMMON_INTERCEPT_FUNCTION(__isoc23_vscanf);  \1651  COMMON_INTERCEPT_FUNCTION(__isoc23_vsscanf); \1652  COMMON_INTERCEPT_FUNCTION(__isoc23_vfscanf);1653#else1654#define INIT_ISOC99_SCANF1655#endif1656 1657#if SANITIZER_INTERCEPT_PRINTF1658 1659#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \1660  void *ctx;                                                                   \1661  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \1662  va_list aq;                                                                  \1663  va_copy(aq, ap);1664 1665#define VPRINTF_INTERCEPTOR_RETURN()                                           \1666  va_end(aq);1667 1668#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \1669  {                                                                            \1670    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \1671    if (common_flags()->check_printf)                                          \1672      printf_common(ctx, format, aq);                                          \1673    int res = REAL(vname)(__VA_ARGS__);                                        \1674    VPRINTF_INTERCEPTOR_RETURN();                                              \1675    return res;                                                                \1676  }1677 1678// FIXME: under ASan the REAL() call below may write to freed memory and1679// corrupt its metadata. See1680// https://github.com/google/sanitizers/issues/321.1681#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \1682  {                                                                            \1683    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \1684    if (common_flags()->check_printf) {                                        \1685      printf_common(ctx, format, aq);                                          \1686    }                                                                          \1687    int res = REAL(vname)(str, __VA_ARGS__);                                   \1688    if (res >= 0) {                                                            \1689      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \1690    }                                                                          \1691    VPRINTF_INTERCEPTOR_RETURN();                                              \1692    return res;                                                                \1693  }1694 1695// FIXME: under ASan the REAL() call below may write to freed memory and1696// corrupt its metadata. See1697// https://github.com/google/sanitizers/issues/321.1698#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \1699  {                                                                            \1700    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \1701    if (common_flags()->check_printf) {                                        \1702      printf_common(ctx, format, aq);                                          \1703    }                                                                          \1704    int res = REAL(vname)(str, size, __VA_ARGS__);                             \1705    if (res >= 0) {                                                            \1706      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \1707    }                                                                          \1708    VPRINTF_INTERCEPTOR_RETURN();                                              \1709    return res;                                                                \1710  }1711 1712// FIXME: under ASan the REAL() call below may write to freed memory and1713// corrupt its metadata. See1714// https://github.com/google/sanitizers/issues/321.1715#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \1716  {                                                                            \1717    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \1718    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \1719    if (common_flags()->check_printf) {                                        \1720      printf_common(ctx, format, aq);                                          \1721    }                                                                          \1722    int res = REAL(vname)(strp, __VA_ARGS__);                                  \1723    if (res >= 0) {                                                            \1724      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \1725    }                                                                          \1726    VPRINTF_INTERCEPTOR_RETURN();                                              \1727    return res;                                                                \1728  }1729 1730INTERCEPTOR(int, vprintf, const char *format, va_list ap)1731VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)1732 1733INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,1734            va_list ap)1735VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)1736 1737INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,1738            va_list ap)1739VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)1740 1741#if SANITIZER_INTERCEPT___PRINTF_CHK1742INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,1743            SIZE_T size_to, const char *format, va_list ap)1744VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)1745#endif1746 1747#if SANITIZER_INTERCEPT_PRINTF_L1748INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,1749            const char *format, va_list ap)1750VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)1751 1752INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,1753            const char *format, ...)1754FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)1755#endif  // SANITIZER_INTERCEPT_PRINTF_L1756 1757INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)1758VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)1759 1760#if SANITIZER_INTERCEPT___PRINTF_CHK1761INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,1762            const char *format, va_list ap)1763VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)1764#endif1765 1766#  if SANITIZER_INTERCEPT_VASPRINTF1767INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)1768VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)1769#  endif1770 1771#  if SANITIZER_INTERCEPT_ISOC99_PRINTF1772INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)1773VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)1774 1775INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,1776            const char *format, va_list ap)1777VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)1778 1779INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,1780            va_list ap)1781VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)1782 1783INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,1784            va_list ap)1785VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,1786                          ap)1787 1788#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF1789 1790INTERCEPTOR(int, printf, const char *format, ...)1791FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)1792 1793INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)1794FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)1795 1796#if SANITIZER_INTERCEPT___PRINTF_CHK1797INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,1798            const char *format, ...)1799FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)1800#endif1801 1802INTERCEPTOR(int, sprintf, char *str, const char *format, ...)1803FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)1804 1805#if SANITIZER_INTERCEPT___PRINTF_CHK1806INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,1807            const char *format, ...)1808FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)1809#endif1810 1811INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)1812FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)1813 1814#if SANITIZER_INTERCEPT___PRINTF_CHK1815INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,1816            SIZE_T size_to, const char *format, ...)1817FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)1818#endif1819 1820#  if SANITIZER_INTERCEPT_ASPRINTF1821INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)1822FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)1823#  endif1824 1825#  if SANITIZER_INTERCEPT_ISOC99_PRINTF1826INTERCEPTOR(int, __isoc99_printf, const char *format, ...)1827FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)1828 1829INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,1830            ...)1831FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)1832 1833INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)1834FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)1835 1836INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,1837            const char *format, ...)1838FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,1839                        format)1840 1841#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF1842 1843#endif  // SANITIZER_INTERCEPT_PRINTF1844 1845#if SANITIZER_INTERCEPT_PRINTF1846#  define INIT_PRINTF_COMMON                   \1847    COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \1848    COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \1849    COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \1850    COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \1851    COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \1852    COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \1853    COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \1854    COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);1855#  if !SANITIZER_AIX1856// AIX does not have [v]asprintf.1857#    define INIT_PRINTF_EXTRA                   \1858      COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \1859      COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf);1860#  else1861#    define INIT_PRINTF_EXTRA1862#  endif1863#  define INIT_PRINTF INIT_PRINTF_COMMON INIT_PRINTF_EXTRA1864#else1865#define INIT_PRINTF1866#endif1867 1868#if SANITIZER_INTERCEPT___PRINTF_CHK1869#define INIT___PRINTF_CHK                     \1870  COMMON_INTERCEPT_FUNCTION(__sprintf_chk);   \1871  COMMON_INTERCEPT_FUNCTION(__snprintf_chk);  \1872  COMMON_INTERCEPT_FUNCTION(__vsprintf_chk);  \1873  COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \1874  COMMON_INTERCEPT_FUNCTION(__fprintf_chk);1875#else1876#define INIT___PRINTF_CHK1877#endif1878 1879#if SANITIZER_INTERCEPT_PRINTF_L1880#define INIT_PRINTF_L                     \1881  COMMON_INTERCEPT_FUNCTION(snprintf_l);  \1882  COMMON_INTERCEPT_FUNCTION(vsnprintf_l);1883#else1884#define INIT_PRINTF_L1885#endif1886 1887#if SANITIZER_INTERCEPT_ISOC99_PRINTF1888#define INIT_ISOC99_PRINTF                       \1889  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \1890  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \1891  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \1892  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \1893  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \1894  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \1895  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \1896  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);1897#else1898#define INIT_ISOC99_PRINTF1899#endif1900 1901#if SANITIZER_INTERCEPT_SETPROCTITLE1902INTERCEPTOR(void, setproctitle, const char *fmt, ...) {1903  void *ctx;1904  va_list ap;1905  va_start(ap, fmt);1906  COMMON_INTERCEPTOR_ENTER(ctx, setproctitle, fmt, ap);1907  if (common_flags()->check_printf)1908    printf_common(ctx, fmt, ap);1909  REAL(setproctitle)(fmt, ap);1910  va_end(ap);1911}1912#  define INIT_SETPROCTITLE COMMON_INTERCEPT_FUNCTION(setproctitle);1913#else1914#  define INIT_SETPROCTITLE1915#endif1916 1917#if SANITIZER_INTERCEPT_IOCTL1918#include "sanitizer_common_interceptors_ioctl.inc"1919#include "sanitizer_interceptors_ioctl_netbsd.inc"1920INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {1921  // We need a frame pointer, because we call into ioctl_common_[pre|post] which1922  // can trigger a report and we need to be able to unwind through this1923  // function.  On Mac in debug mode we might not have a frame pointer, because1924  // ioctl_common_[pre|post] doesn't get inlined here.1925  ENABLE_FRAME_POINTER;1926 1927  void *ctx;1928  va_list ap;1929  va_start(ap, request);1930  void *arg = va_arg(ap, void *);1931  va_end(ap);1932  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);1933 1934  CHECK(ioctl_initialized);1935 1936  // Note: TSan does not use common flags, and they are zero-initialized.1937  // This effectively disables ioctl handling in TSan.1938  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);1939 1940  // Although request is unsigned long, the rest of the interceptor uses it1941  // as just "unsigned" to save space, because we know that all values fit in1942  // "unsigned" - they are compile-time constants.1943 1944  const ioctl_desc *desc = ioctl_lookup(request);1945  ioctl_desc decoded_desc;1946  if (!desc) {1947    VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request);1948    if (!ioctl_decode(request, &decoded_desc))1949      Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request);1950    else1951      desc = &decoded_desc;1952  }1953 1954  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);1955  int res = REAL(ioctl)(d, request, arg);1956  // FIXME: some ioctls have different return values for success and failure.1957  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);1958  return res;1959}1960#define INIT_IOCTL \1961  ioctl_init();    \1962  COMMON_INTERCEPT_FUNCTION(ioctl);1963#else1964#define INIT_IOCTL1965#endif1966 1967#if SANITIZER_POSIX1968UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {1969  if (pwd) {1970    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));1971    if (pwd->pw_name)1972      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,1973                                     internal_strlen(pwd->pw_name) + 1);1974    if (pwd->pw_passwd)1975      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,1976                                     internal_strlen(pwd->pw_passwd) + 1);1977#if !SANITIZER_ANDROID1978    if (pwd->pw_gecos)1979      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,1980                                     internal_strlen(pwd->pw_gecos) + 1);1981#endif1982#if SANITIZER_APPLE || SANITIZER_FREEBSD || SANITIZER_NETBSD1983    if (pwd->pw_class)1984      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,1985                                     internal_strlen(pwd->pw_class) + 1);1986#endif1987    if (pwd->pw_dir)1988      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,1989                                     internal_strlen(pwd->pw_dir) + 1);1990    if (pwd->pw_shell)1991      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,1992                                     internal_strlen(pwd->pw_shell) + 1);1993  }1994}1995 1996UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {1997  if (grp) {1998    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));1999    if (grp->gr_name)2000      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,2001                                     internal_strlen(grp->gr_name) + 1);2002    if (grp->gr_passwd)2003      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,2004                                     internal_strlen(grp->gr_passwd) + 1);2005    char **p = grp->gr_mem;2006    for (; *p; ++p) {2007      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);2008    }2009    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,2010                                   (p - grp->gr_mem + 1) * sizeof(*p));2011  }2012}2013#endif  // SANITIZER_POSIX2014 2015#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS2016INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {2017  void *ctx;2018  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);2019  if (name)2020    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2021  __sanitizer_passwd *res = REAL(getpwnam)(name);2022  unpoison_passwd(ctx, res);2023  return res;2024}2025INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {2026  void *ctx;2027  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);2028  __sanitizer_passwd *res = REAL(getpwuid)(uid);2029  unpoison_passwd(ctx, res);2030  return res;2031}2032INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {2033  void *ctx;2034  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);2035  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2036  __sanitizer_group *res = REAL(getgrnam)(name);2037  unpoison_group(ctx, res);2038  return res;2039}2040INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {2041  void *ctx;2042  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);2043  __sanitizer_group *res = REAL(getgrgid)(gid);2044  unpoison_group(ctx, res);2045  return res;2046}2047#define INIT_GETPWNAM_AND_FRIENDS      \2048  COMMON_INTERCEPT_FUNCTION(getpwnam); \2049  COMMON_INTERCEPT_FUNCTION(getpwuid); \2050  COMMON_INTERCEPT_FUNCTION(getgrnam); \2051  COMMON_INTERCEPT_FUNCTION(getgrgid);2052#else2053#define INIT_GETPWNAM_AND_FRIENDS2054#endif2055 2056#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS2057INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,2058            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {2059  void *ctx;2060  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);2061  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2062  // FIXME: under ASan the call below may write to freed memory and corrupt2063  // its metadata. See2064  // https://github.com/google/sanitizers/issues/321.2065  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);2066  if (!res && result)2067    unpoison_passwd(ctx, *result);2068  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2069  return res;2070}2071INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,2072            SIZE_T buflen, __sanitizer_passwd **result) {2073  void *ctx;2074  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);2075  // FIXME: under ASan the call below may write to freed memory and corrupt2076  // its metadata. See2077  // https://github.com/google/sanitizers/issues/321.2078  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);2079  if (!res && result)2080    unpoison_passwd(ctx, *result);2081  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2082  return res;2083}2084INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,2085            char *buf, SIZE_T buflen, __sanitizer_group **result) {2086  void *ctx;2087  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);2088  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);2089  // FIXME: under ASan the call below may write to freed memory and corrupt2090  // its metadata. See2091  // https://github.com/google/sanitizers/issues/321.2092  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);2093  if (!res && result)2094    unpoison_group(ctx, *result);2095  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2096  return res;2097}2098INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,2099            SIZE_T buflen, __sanitizer_group **result) {2100  void *ctx;2101  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);2102  // FIXME: under ASan the call below may write to freed memory and corrupt2103  // its metadata. See2104  // https://github.com/google/sanitizers/issues/321.2105  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);2106  if (!res && result)2107    unpoison_group(ctx, *result);2108  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));2109  return res;2110}2111#define INIT_GETPWNAM_R_AND_FRIENDS      \2112  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \2113  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \2114  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \2115  COMMON_INTERCEPT_FUNCTION(getgrgid_r);2116#else2117#define INIT_GETPWNAM_R_AND_FRIENDS2118#endif2119 2120#if SANITIZER_INTERCEPT_GETPWENT2121INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {2122  void *ctx;2123  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);2124  __sanitizer_passwd *res = REAL(getpwent)(dummy);2125  unpoison_passwd(ctx, res);2126  return res;2127}2128INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {2129  void *ctx;2130  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);2131  __sanitizer_group *res = REAL(getgrent)(dummy);2132  unpoison_group(ctx, res);2133  return res;2134}2135#define INIT_GETPWENT                  \2136  COMMON_INTERCEPT_FUNCTION(getpwent); \2137  COMMON_INTERCEPT_FUNCTION(getgrent);2138#else2139#define INIT_GETPWENT2140#endif2141 2142#if SANITIZER_INTERCEPT_FGETPWENT2143INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {2144  void *ctx;2145  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);2146  __sanitizer_passwd *res = REAL(fgetpwent)(fp);2147  unpoison_passwd(ctx, res);2148  return res;2149}2150INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {2151  void *ctx;2152  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);2153  __sanitizer_group *res = REAL(fgetgrent)(fp);2154  unpoison_group(ctx, res);2155  return res;2156}2157#define INIT_FGETPWENT                  \2158  COMMON_INTERCEPT_FUNCTION(fgetpwent); \2159  COMMON_INTERCEPT_FUNCTION(fgetgrent);2160#else2161#define INIT_FGETPWENT2162#endif2163 2164#if SANITIZER_INTERCEPT_GETPWENT_R2165INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,2166            SIZE_T buflen, __sanitizer_passwd **pwbufp) {2167  void *ctx;2168  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);2169  // FIXME: under ASan the call below may write to freed memory and corrupt2170  // its metadata. See2171  // https://github.com/google/sanitizers/issues/321.2172  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);2173  if (!res && pwbufp)2174    unpoison_passwd(ctx, *pwbufp);2175  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2176  return res;2177}2178INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,2179            __sanitizer_group **pwbufp) {2180  void *ctx;2181  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);2182  // FIXME: under ASan the call below may write to freed memory and corrupt2183  // its metadata. See2184  // https://github.com/google/sanitizers/issues/321.2185  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);2186  if (!res && pwbufp)2187    unpoison_group(ctx, *pwbufp);2188  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2189  return res;2190}2191#define INIT_GETPWENT_R                   \2192  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \2193  COMMON_INTERCEPT_FUNCTION(getgrent_r);2194#else2195#define INIT_GETPWENT_R2196#endif2197 2198#if SANITIZER_INTERCEPT_FGETPWENT_R2199INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,2200            SIZE_T buflen, __sanitizer_passwd **pwbufp) {2201  void *ctx;2202  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);2203  // FIXME: under ASan the call below may write to freed memory and corrupt2204  // its metadata. See2205  // https://github.com/google/sanitizers/issues/321.2206  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);2207  if (!res && pwbufp)2208    unpoison_passwd(ctx, *pwbufp);2209  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2210  return res;2211}2212#define INIT_FGETPWENT_R                  \2213  COMMON_INTERCEPT_FUNCTION(fgetpwent_r);2214#else2215#define INIT_FGETPWENT_R2216#endif2217 2218#if SANITIZER_INTERCEPT_FGETGRENT_R2219INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,2220            SIZE_T buflen, __sanitizer_group **pwbufp) {2221  void *ctx;2222  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);2223  // FIXME: under ASan the call below may write to freed memory and corrupt2224  // its metadata. See2225  // https://github.com/google/sanitizers/issues/321.2226  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);2227  if (!res && pwbufp)2228    unpoison_group(ctx, *pwbufp);2229  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));2230  return res;2231}2232#define INIT_FGETGRENT_R                  \2233  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);2234#else2235#define INIT_FGETGRENT_R2236#endif2237 2238#if SANITIZER_INTERCEPT_SETPWENT2239// The only thing these interceptors do is disable any nested interceptors.2240// These functions may open nss modules and call uninstrumented functions from2241// them, and we don't want things like strlen() to trigger.2242INTERCEPTOR(void, setpwent, int dummy) {2243  void *ctx;2244  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);2245  REAL(setpwent)(dummy);2246}2247INTERCEPTOR(void, endpwent, int dummy) {2248  void *ctx;2249  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);2250  REAL(endpwent)(dummy);2251}2252INTERCEPTOR(void, setgrent, int dummy) {2253  void *ctx;2254  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);2255  REAL(setgrent)(dummy);2256}2257INTERCEPTOR(void, endgrent, int dummy) {2258  void *ctx;2259  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);2260  REAL(endgrent)(dummy);2261}2262#define INIT_SETPWENT                  \2263  COMMON_INTERCEPT_FUNCTION(setpwent); \2264  COMMON_INTERCEPT_FUNCTION(endpwent); \2265  COMMON_INTERCEPT_FUNCTION(setgrent); \2266  COMMON_INTERCEPT_FUNCTION(endgrent);2267#else2268#define INIT_SETPWENT2269#endif2270 2271#if SANITIZER_INTERCEPT_CLOCK_GETTIME2272INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {2273  void *ctx;2274  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);2275  // FIXME: under ASan the call below may write to freed memory and corrupt2276  // its metadata. See2277  // https://github.com/google/sanitizers/issues/321.2278  int res = REAL(clock_getres)(clk_id, tp);2279  if (!res && tp) {2280    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);2281  }2282  return res;2283}2284INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {2285  void *ctx;2286  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);2287  // FIXME: under ASan the call below may write to freed memory and corrupt2288  // its metadata. See2289  // https://github.com/google/sanitizers/issues/321.2290  int res = REAL(clock_gettime)(clk_id, tp);2291  if (!res) {2292    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);2293  }2294  return res;2295}2296#if SANITIZER_GLIBC2297namespace __sanitizer {2298extern "C" {2299int real_clock_gettime(u32 clk_id, void *tp) {2300  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)2301    return internal_clock_gettime(clk_id, tp);2302  return REAL(clock_gettime)(clk_id, tp);2303}2304}  // extern "C"2305}  // namespace __sanitizer2306#endif2307INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {2308  void *ctx;2309  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);2310  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);2311  return REAL(clock_settime)(clk_id, tp);2312}2313#define INIT_CLOCK_GETTIME                  \2314  COMMON_INTERCEPT_FUNCTION(clock_getres);  \2315  COMMON_INTERCEPT_FUNCTION(clock_gettime); \2316  COMMON_INTERCEPT_FUNCTION(clock_settime);2317#else2318#define INIT_CLOCK_GETTIME2319#endif2320 2321#if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID2322INTERCEPTOR(int, clock_getcpuclockid, pid_t pid,2323            __sanitizer_clockid_t *clockid) {2324  void *ctx;2325  COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid);2326  int res = REAL(clock_getcpuclockid)(pid, clockid);2327  if (!res && clockid) {2328    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);2329  }2330  return res;2331}2332 2333INTERCEPTOR(int, pthread_getcpuclockid, uptr thread,2334            __sanitizer_clockid_t *clockid) {2335  void *ctx;2336  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid);2337  int res = REAL(pthread_getcpuclockid)(thread, clockid);2338  if (!res && clockid) {2339    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);2340  }2341  return res;2342}2343 2344#define INIT_CLOCK_GETCPUCLOCKID                   \2345  COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid);  \2346  COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid);2347#else2348#define INIT_CLOCK_GETCPUCLOCKID2349#endif2350 2351#if SANITIZER_INTERCEPT_TIMER_CREATE2352INTERCEPTOR(int, timer_create, __sanitizer_clockid_t clockid, void *sevp,2353            __sanitizer_timer_t *timer) {2354  void *ctx;2355  COMMON_INTERCEPTOR_ENTER(ctx, timer_create, clockid, sevp, timer);2356  int res = REAL(timer_create)(clockid, sevp, timer);2357  if (!res && timer) {2358    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, timer, sizeof *timer);2359  }2360  return res;2361}2362 2363INTERCEPTOR(int, timer_delete, __sanitizer_timer_t timer) {2364  void *ctx;2365  COMMON_INTERCEPTOR_ENTER(ctx, timer_delete, timer);2366  int res = REAL(timer_delete)(timer);2367  return res;2368}2369 2370INTERCEPTOR(int, timer_gettime, __sanitizer_timer_t timer,2371            struct __sanitizer_itimerspec *curr_value) {2372  void *ctx;2373  COMMON_INTERCEPTOR_ENTER(ctx, timer_gettime, timer, curr_value);2374  int res = REAL(timer_gettime)(timer, curr_value);2375  if (!res && curr_value) {2376    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, sizeof *curr_value);2377  }2378  return res;2379}2380 2381INTERCEPTOR(int, timer_settime, __sanitizer_timer_t timer, int flags,2382            const struct __sanitizer_itimerspec *new_value,2383            struct __sanitizer_itimerspec *old_value) {2384  void *ctx;2385  COMMON_INTERCEPTOR_ENTER(ctx, timer_settime, timer, flags, new_value,2386                           old_value);2387  int res = REAL(timer_settime)(timer, flags, new_value, old_value);2388  if (!res) {2389    if (new_value)2390      COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, sizeof *new_value);2391    if (old_value)2392      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, sizeof *old_value);2393  }2394  return res;2395}2396 2397#  define INIT_TIMER_CREATE                                                \2398    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_create, "GLIBC_2.3.3");  \2399    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_delete, "GLIBC_2.3.3");  \2400    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_gettime, "GLIBC_2.3.3"); \2401    COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(timer_settime, "GLIBC_2.3.3");2402#else2403#  define INIT_TIMER_CREATE2404#endif2405 2406#if SANITIZER_INTERCEPT_GETITIMER2407INTERCEPTOR(int, getitimer, int which, void *curr_value) {2408  void *ctx;2409  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);2410  // FIXME: under ASan the call below may write to freed memory and corrupt2411  // its metadata. See2412  // https://github.com/google/sanitizers/issues/321.2413  int res = REAL(getitimer)(which, curr_value);2414  if (!res && curr_value) {2415    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);2416  }2417  return res;2418}2419INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {2420  void *ctx;2421  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);2422  if (new_value) {2423    // itimerval can contain padding that may be legitimately uninitialized2424    const struct __sanitizer_itimerval *nv =2425        (const struct __sanitizer_itimerval *)new_value;2426    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,2427                                  sizeof(__sanitizer_time_t));2428    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,2429                                  sizeof(__sanitizer_suseconds_t));2430    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,2431                                  sizeof(__sanitizer_time_t));2432    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,2433                                  sizeof(__sanitizer_suseconds_t));2434  }2435  // FIXME: under ASan the call below may write to freed memory and corrupt2436  // its metadata. See2437  // https://github.com/google/sanitizers/issues/321.2438  int res = REAL(setitimer)(which, new_value, old_value);2439  if (!res && old_value) {2440    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);2441  }2442  return res;2443}2444#define INIT_GETITIMER                  \2445  COMMON_INTERCEPT_FUNCTION(getitimer); \2446  COMMON_INTERCEPT_FUNCTION(setitimer);2447#else2448#define INIT_GETITIMER2449#endif2450 2451#if SANITIZER_INTERCEPT_TIMESPEC_GET2452INTERCEPTOR(int, timespec_get, struct __sanitizer_timespec *ts, int base) {2453  void *ctx;2454  COMMON_INTERCEPTOR_ENTER(ctx, timespec_get, ts, base);2455  // We don't yet know if ts is addressable, so we use our own scratch buffer2456  struct __sanitizer_timespec ts_local;2457  int res = REAL(timespec_get)(&ts_local, base);2458  if (res) {2459    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ts,2460                                   sizeof(struct __sanitizer_timespec));2461    internal_memcpy(ts, &ts_local, sizeof(struct __sanitizer_timespec));2462  }2463  return res;2464}2465#  define INIT_TIMESPEC_GET COMMON_INTERCEPT_FUNCTION(timespec_get);2466#else2467#  define INIT_TIMESPEC_GET2468#endif2469 2470#if SANITIZER_INTERCEPT_GLOB2471static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {2472  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));2473  // +1 for NULL pointer at the end.2474  if (pglob->gl_pathv)2475    COMMON_INTERCEPTOR_WRITE_RANGE(2476        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));2477  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {2478    char *p = pglob->gl_pathv[i];2479    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);2480  }2481}2482 2483#if SANITIZER_SOLARIS2484INTERCEPTOR(int, glob, const char *pattern, int flags,2485            int (*errfunc)(const char *epath, int eerrno),2486            __sanitizer_glob_t *pglob) {2487  void *ctx;2488  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);2489  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2490  int res = REAL(glob)(pattern, flags, errfunc, pglob);2491  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2492  return res;2493}2494#else2495static THREADLOCAL __sanitizer_glob_t *pglob_copy;2496 2497static void wrapped_gl_closedir(void *dir) {2498  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2499  pglob_copy->gl_closedir(dir);2500}2501 2502static void *wrapped_gl_readdir(void *dir) {2503  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2504  return pglob_copy->gl_readdir(dir);2505}2506 2507static void *wrapped_gl_opendir(const char *s) {2508  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);2509  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2510  return pglob_copy->gl_opendir(s);2511}2512 2513static int wrapped_gl_lstat(const char *s, void *st) {2514  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);2515  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2516  return pglob_copy->gl_lstat(s, st);2517}2518 2519static int wrapped_gl_stat(const char *s, void *st) {2520  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);2521  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);2522  return pglob_copy->gl_stat(s, st);2523}2524 2525static const __sanitizer_glob_t kGlobCopy = {2526      0,                  0,                   0,2527      0,                  wrapped_gl_closedir, wrapped_gl_readdir,2528      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};2529 2530INTERCEPTOR(int, glob, const char *pattern, int flags,2531            int (*errfunc)(const char *epath, int eerrno),2532            __sanitizer_glob_t *pglob) {2533  void *ctx;2534  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);2535  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2536  __sanitizer_glob_t glob_copy;2537  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));2538  if (flags & glob_altdirfunc) {2539    Swap(pglob->gl_closedir, glob_copy.gl_closedir);2540    Swap(pglob->gl_readdir, glob_copy.gl_readdir);2541    Swap(pglob->gl_opendir, glob_copy.gl_opendir);2542    Swap(pglob->gl_lstat, glob_copy.gl_lstat);2543    Swap(pglob->gl_stat, glob_copy.gl_stat);2544    pglob_copy = &glob_copy;2545  }2546  int res = REAL(glob)(pattern, flags, errfunc, pglob);2547  if (flags & glob_altdirfunc) {2548    Swap(pglob->gl_closedir, glob_copy.gl_closedir);2549    Swap(pglob->gl_readdir, glob_copy.gl_readdir);2550    Swap(pglob->gl_opendir, glob_copy.gl_opendir);2551    Swap(pglob->gl_lstat, glob_copy.gl_lstat);2552    Swap(pglob->gl_stat, glob_copy.gl_stat);2553  }2554  pglob_copy = 0;2555  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2556  return res;2557}2558#endif  // SANITIZER_SOLARIS2559#define INIT_GLOB                  \2560  COMMON_INTERCEPT_FUNCTION(glob);2561#else  // SANITIZER_INTERCEPT_GLOB2562#define INIT_GLOB2563#endif  // SANITIZER_INTERCEPT_GLOB2564 2565#if SANITIZER_INTERCEPT_GLOB642566INTERCEPTOR(int, glob64, const char *pattern, int flags,2567            int (*errfunc)(const char *epath, int eerrno),2568            __sanitizer_glob_t *pglob) {2569  void *ctx;2570  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);2571  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);2572  __sanitizer_glob_t glob_copy;2573  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));2574  if (flags & glob_altdirfunc) {2575    Swap(pglob->gl_closedir, glob_copy.gl_closedir);2576    Swap(pglob->gl_readdir, glob_copy.gl_readdir);2577    Swap(pglob->gl_opendir, glob_copy.gl_opendir);2578    Swap(pglob->gl_lstat, glob_copy.gl_lstat);2579    Swap(pglob->gl_stat, glob_copy.gl_stat);2580    pglob_copy = &glob_copy;2581  }2582  int res = REAL(glob64)(pattern, flags, errfunc, pglob);2583  if (flags & glob_altdirfunc) {2584    Swap(pglob->gl_closedir, glob_copy.gl_closedir);2585    Swap(pglob->gl_readdir, glob_copy.gl_readdir);2586    Swap(pglob->gl_opendir, glob_copy.gl_opendir);2587    Swap(pglob->gl_lstat, glob_copy.gl_lstat);2588    Swap(pglob->gl_stat, glob_copy.gl_stat);2589  }2590  pglob_copy = 0;2591  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);2592  return res;2593}2594#define INIT_GLOB64                \2595  COMMON_INTERCEPT_FUNCTION(glob64);2596#else  // SANITIZER_INTERCEPT_GLOB642597#define INIT_GLOB642598#endif  // SANITIZER_INTERCEPT_GLOB642599 2600#if SANITIZER_INTERCEPT___B64_TO2601INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,2602            char *target, SIZE_T targsize) {2603  void *ctx;2604  COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);2605  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);2606  int res = REAL(__b64_ntop)(src, srclength, target, targsize);2607  if (res >= 0)2608    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);2609  return res;2610}2611INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {2612  void *ctx;2613  COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);2614  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);2615  int res = REAL(__b64_pton)(src, target, targsize);2616  if (res >= 0)2617    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);2618  return res;2619}2620#define INIT___B64_TO                      \2621    COMMON_INTERCEPT_FUNCTION(__b64_ntop); \2622    COMMON_INTERCEPT_FUNCTION(__b64_pton);2623#else  // SANITIZER_INTERCEPT___B64_TO2624#define INIT___B64_TO2625#endif  // SANITIZER_INTERCEPT___B64_TO2626 2627#if SANITIZER_INTERCEPT_DN_COMP_EXPAND2628#  if __GLIBC_PREREQ(2, 34)2629// Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf2630#    define DN_COMP_INTERCEPTOR_NAME dn_comp2631#    define DN_EXPAND_INTERCEPTOR_NAME dn_expand2632#  else2633#    define DN_COMP_INTERCEPTOR_NAME __dn_comp2634#    define DN_EXPAND_INTERCEPTOR_NAME __dn_expand2635#  endif2636INTERCEPTOR(int, DN_COMP_INTERCEPTOR_NAME, unsigned char *exp_dn,2637            unsigned char *comp_dn, int length, unsigned char **dnptrs,2638            unsigned char **lastdnptr) {2639  void *ctx;2640  COMMON_INTERCEPTOR_ENTER(ctx, DN_COMP_INTERCEPTOR_NAME, exp_dn, comp_dn,2641                           length, dnptrs, lastdnptr);2642  int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs,2643                                           lastdnptr);2644  if (res >= 0) {2645    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, comp_dn, res);2646    if (dnptrs && lastdnptr) {2647      unsigned char **p = dnptrs;2648      for (; p != lastdnptr && *p; ++p)2649        ;2650      if (p != lastdnptr)2651        ++p;2652      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dnptrs, (p - dnptrs) * sizeof(*p));2653    }2654  }2655  return res;2656}2657INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base,2658            unsigned char const *end, unsigned char const *src, char *dest,2659            int space) {2660  void *ctx;2661  COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src,2662                           dest, space);2663  // TODO: add read check if __dn_comp intercept added2664  int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);2665  if (res >= 0)2666    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1);2667  return res;2668}2669#  define INIT_DN_COMP_EXPAND                            \2670    COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \2671    COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME);2672#else  // SANITIZER_INTERCEPT_DN_COMP_EXPAND2673#  define INIT_DN_COMP_EXPAND2674#endif  // SANITIZER_INTERCEPT_DN_COMP_EXPAND2675 2676#if SANITIZER_INTERCEPT_POSIX_SPAWN2677 2678template <class RealSpawnPtr>2679static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,2680                          const char *file_or_path, const void *file_actions,2681                          const void *attrp, char *const argv[],2682                          char *const envp[]) {2683  COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,2684                                internal_strlen(file_or_path) + 1);2685  if (argv) {2686    for (char *const *s = argv; ; ++s) {2687      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));2688      if (!*s) break;2689      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);2690    }2691  }2692  if (envp) {2693    for (char *const *s = envp; ; ++s) {2694      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));2695      if (!*s) break;2696      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);2697    }2698  }2699  int res =2700      real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);2701  if (res == 0)2702    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));2703  return res;2704}2705INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,2706            const void *file_actions, const void *attrp, char *const argv[],2707            char *const envp[]) {2708  void *ctx;2709  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,2710                           argv, envp);2711  return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,2712                        argv, envp);2713}2714INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,2715            const void *file_actions, const void *attrp, char *const argv[],2716            char *const envp[]) {2717  void *ctx;2718  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,2719                           argv, envp);2720  return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,2721                        argv, envp);2722}2723#  define INIT_POSIX_SPAWN                  \2724    COMMON_INTERCEPT_FUNCTION(posix_spawn); \2725    COMMON_INTERCEPT_FUNCTION(posix_spawnp);2726#else  // SANITIZER_INTERCEPT_POSIX_SPAWN2727#  define INIT_POSIX_SPAWN2728#endif  // SANITIZER_INTERCEPT_POSIX_SPAWN2729 2730#if SANITIZER_INTERCEPT_WAIT2731// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version2732// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for2733// details.2734INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {2735  void *ctx;2736  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);2737  // FIXME: under ASan the call below may write to freed memory and corrupt2738  // its metadata. See2739  // https://github.com/google/sanitizers/issues/321.2740  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait)(status);2741  if (res != -1 && status)2742    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2743  return res;2744}2745// On FreeBSD id_t is always 64-bit wide.2746#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)2747INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,2748                        int options) {2749#else2750INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,2751                        int options) {2752#endif2753  void *ctx;2754  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);2755  // FIXME: under ASan the call below may write to freed memory and corrupt2756  // its metadata. See2757  // https://github.com/google/sanitizers/issues/321.2758  int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitid)(idtype, id, infop, options);2759  if (res != -1 && infop)2760    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);2761  return res;2762}2763INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {2764  void *ctx;2765  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);2766  // FIXME: under ASan the call below may write to freed memory and corrupt2767  // its metadata. See2768  // https://github.com/google/sanitizers/issues/321.2769  int res = COMMON_INTERCEPTOR_BLOCK_REAL(waitpid)(pid, status, options);2770  if (res != -1 && status)2771    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2772  return res;2773}2774INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {2775  void *ctx;2776  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);2777  // FIXME: under ASan the call below may write to freed memory and corrupt2778  // its metadata. See2779  // https://github.com/google/sanitizers/issues/321.2780  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait3)(status, options, rusage);2781  if (res != -1) {2782    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2783    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2784  }2785  return res;2786}2787#if SANITIZER_ANDROID2788INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {2789  void *ctx;2790  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);2791  // FIXME: under ASan the call below may write to freed memory and corrupt2792  // its metadata. See2793  // https://github.com/google/sanitizers/issues/321.2794  int res =2795      COMMON_INTERCEPTOR_BLOCK_REAL(__wait4)(pid, status, options, rusage);2796  if (res != -1) {2797    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2798    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2799  }2800  return res;2801}2802#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);2803#else2804INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {2805  void *ctx;2806  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);2807  // FIXME: under ASan the call below may write to freed memory and corrupt2808  // its metadata. See2809  // https://github.com/google/sanitizers/issues/321.2810  int res = COMMON_INTERCEPTOR_BLOCK_REAL(wait4)(pid, status, options, rusage);2811  if (res != -1) {2812    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));2813    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);2814  }2815  return res;2816}2817#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);2818#endif  // SANITIZER_ANDROID2819#define INIT_WAIT                     \2820  COMMON_INTERCEPT_FUNCTION(wait);    \2821  COMMON_INTERCEPT_FUNCTION(waitid);  \2822  COMMON_INTERCEPT_FUNCTION(waitpid); \2823  COMMON_INTERCEPT_FUNCTION(wait3);2824#else2825#define INIT_WAIT2826#define INIT_WAIT42827#endif2828 2829#if SANITIZER_INTERCEPT_INET2830INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {2831  void *ctx;2832  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);2833  uptr sz = __sanitizer_in_addr_sz(af);2834  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);2835  // FIXME: figure out read size based on the address family.2836  // FIXME: under ASan the call below may write to freed memory and corrupt2837  // its metadata. See2838  // https://github.com/google/sanitizers/issues/321.2839  char *res = REAL(inet_ntop)(af, src, dst, size);2840  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);2841  return res;2842}2843INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {2844  void *ctx;2845  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);2846  COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);2847  // FIXME: figure out read size based on the address family.2848  // FIXME: under ASan the call below may write to freed memory and corrupt2849  // its metadata. See2850  // https://github.com/google/sanitizers/issues/321.2851  int res = REAL(inet_pton)(af, src, dst);2852  if (res == 1) {2853    uptr sz = __sanitizer_in_addr_sz(af);2854    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);2855  }2856  return res;2857}2858#define INIT_INET                       \2859  COMMON_INTERCEPT_FUNCTION(inet_ntop); \2860  COMMON_INTERCEPT_FUNCTION(inet_pton);2861#else2862#define INIT_INET2863#endif2864 2865#if SANITIZER_INTERCEPT_INET2866INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {2867  void *ctx;2868  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);2869  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1);2870  // FIXME: under ASan the call below may write to freed memory and corrupt2871  // its metadata. See2872  // https://github.com/google/sanitizers/issues/321.2873  int res = REAL(inet_aton)(cp, dst);2874  if (res != 0) {2875    uptr sz = __sanitizer_in_addr_sz(af_inet);2876    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);2877  }2878  return res;2879}2880#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);2881#else2882#define INIT_INET_ATON2883#endif2884 2885#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM2886INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {2887  void *ctx;2888  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);2889  // FIXME: under ASan the call below may write to freed memory and corrupt2890  // its metadata. See2891  // https://github.com/google/sanitizers/issues/321.2892  int res = REAL(pthread_getschedparam)(thread, policy, param);2893  if (res == 0) {2894    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));2895    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));2896  }2897  return res;2898}2899#define INIT_PTHREAD_GETSCHEDPARAM \2900  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);2901#else2902#define INIT_PTHREAD_GETSCHEDPARAM2903#endif2904 2905#if SANITIZER_INTERCEPT_GETADDRINFO2906INTERCEPTOR(int, getaddrinfo, char *node, char *service,2907            struct __sanitizer_addrinfo *hints,2908            struct __sanitizer_addrinfo **out) {2909  void *ctx;2910  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);2911  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1);2912  if (service)2913    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1);2914  if (hints)2915    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));2916  // FIXME: under ASan the call below may write to freed memory and corrupt2917  // its metadata. See2918  // https://github.com/google/sanitizers/issues/321.2919  int res = REAL(getaddrinfo)(node, service, hints, out);2920  if (res == 0 && out) {2921    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));2922    struct __sanitizer_addrinfo *p = *out;2923    while (p) {2924      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));2925      if (p->ai_addr)2926        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);2927      if (p->ai_canonname)2928        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,2929                                       internal_strlen(p->ai_canonname) + 1);2930      p = p->ai_next;2931    }2932  }2933  return res;2934}2935#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);2936#else2937#define INIT_GETADDRINFO2938#endif2939 2940#if SANITIZER_INTERCEPT_GETNAMEINFO2941INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,2942            unsigned hostlen, char *serv, unsigned servlen, int flags) {2943  void *ctx;2944  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,2945                           serv, servlen, flags);2946  // FIXME: consider adding READ_RANGE(sockaddr, salen)2947  // There is padding in in_addr that may make this too noisy2948  // FIXME: under ASan the call below may write to freed memory and corrupt2949  // its metadata. See2950  // https://github.com/google/sanitizers/issues/321.2951  int res =2952      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);2953  if (res == 0) {2954    if (host && hostlen)2955      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1);2956    if (serv && servlen)2957      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1);2958  }2959  return res;2960}2961#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);2962#else2963#define INIT_GETNAMEINFO2964#endif2965 2966#if SANITIZER_INTERCEPT_GETSOCKNAME2967INTERCEPTOR(int, getsockname, int sock_fd, void *addr, unsigned *addrlen) {2968  void *ctx;2969  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);2970  unsigned addr_sz;2971  if (addrlen) {2972    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));2973    addr_sz = *addrlen;2974  }2975  // FIXME: under ASan the call below may write to freed memory and corrupt2976  // its metadata. See2977  // https://github.com/google/sanitizers/issues/321.2978  int res = REAL(getsockname)(sock_fd, addr, addrlen);2979  if (!res && addr && addrlen) {2980    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));2981  }2982  return res;2983}2984#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);2985#else2986#define INIT_GETSOCKNAME2987#endif2988 2989#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R2990static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {2991  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));2992  if (h->h_name)2993    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1);2994  char **p = h->h_aliases;2995  while (*p) {2996    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);2997    ++p;2998  }2999  COMMON_INTERCEPTOR_WRITE_RANGE(3000      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));3001  p = h->h_addr_list;3002  while (*p) {3003    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);3004    ++p;3005  }3006  COMMON_INTERCEPTOR_WRITE_RANGE(3007      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));3008}3009#endif3010 3011#if SANITIZER_INTERCEPT_GETHOSTBYNAME3012INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {3013  void *ctx;3014  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);3015  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);3016  if (res) write_hostent(ctx, res);3017  return res;3018}3019 3020INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,3021            int type) {3022  void *ctx;3023  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);3024  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);3025  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);3026  if (res) write_hostent(ctx, res);3027  return res;3028}3029 3030INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {3031  void *ctx;3032  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);3033  struct __sanitizer_hostent *res = REAL(gethostent)(fake);3034  if (res) write_hostent(ctx, res);3035  return res;3036}3037#define INIT_GETHOSTBYNAME                  \3038  COMMON_INTERCEPT_FUNCTION(gethostent);    \3039  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \3040  COMMON_INTERCEPT_FUNCTION(gethostbyname);3041#else3042#define INIT_GETHOSTBYNAME3043#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME3044 3045#if SANITIZER_INTERCEPT_GETHOSTBYNAME23046INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {3047  void *ctx;3048  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);3049  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);3050  if (res) write_hostent(ctx, res);3051  return res;3052}3053#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);3054#else3055#define INIT_GETHOSTBYNAME23056#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME23057 3058#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R3059INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,3060            char *buf, SIZE_T buflen, __sanitizer_hostent **result,3061            int *h_errnop) {3062  void *ctx;3063  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,3064                           h_errnop);3065  // FIXME: under ASan the call below may write to freed memory and corrupt3066  // its metadata. See3067  // https://github.com/google/sanitizers/issues/321.3068  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);3069  if (result) {3070    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3071    if (res == 0 && *result) write_hostent(ctx, *result);3072  }3073  if (h_errnop)3074    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3075  return res;3076}3077#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);3078#else3079#define INIT_GETHOSTBYNAME_R3080#endif3081 3082#if SANITIZER_INTERCEPT_GETHOSTENT_R3083INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,3084            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {3085  void *ctx;3086  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,3087                           h_errnop);3088  // FIXME: under ASan the call below may write to freed memory and corrupt3089  // its metadata. See3090  // https://github.com/google/sanitizers/issues/321.3091  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);3092  if (result) {3093    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3094    if (res == 0 && *result) write_hostent(ctx, *result);3095  }3096  if (h_errnop)3097    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3098  return res;3099}3100#define INIT_GETHOSTENT_R                  \3101  COMMON_INTERCEPT_FUNCTION(gethostent_r);3102#else3103#define INIT_GETHOSTENT_R3104#endif3105 3106#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R3107INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,3108            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,3109            __sanitizer_hostent **result, int *h_errnop) {3110  void *ctx;3111  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,3112                           buflen, result, h_errnop);3113  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);3114  // FIXME: under ASan the call below may write to freed memory and corrupt3115  // its metadata. See3116  // https://github.com/google/sanitizers/issues/321.3117  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,3118                                  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_GETHOSTBYADDR_R                  \3128  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);3129#else3130#define INIT_GETHOSTBYADDR_R3131#endif3132 3133#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R3134INTERCEPTOR(int, gethostbyname2_r, char *name, int af,3135            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,3136            __sanitizer_hostent **result, int *h_errnop) {3137  void *ctx;3138  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,3139                           result, h_errnop);3140  // FIXME: under ASan the call below may write to freed memory and corrupt3141  // its metadata. See3142  // https://github.com/google/sanitizers/issues/321.3143  int res =3144      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);3145  if (result) {3146    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3147    if (res == 0 && *result) write_hostent(ctx, *result);3148  }3149  if (h_errnop)3150    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));3151  return res;3152}3153#define INIT_GETHOSTBYNAME2_R                  \3154  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);3155#else3156#define INIT_GETHOSTBYNAME2_R3157#endif3158 3159#if SANITIZER_INTERCEPT_GETSOCKOPT3160INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,3161            int *optlen) {3162  void *ctx;3163  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,3164                           optlen);3165  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));3166  // FIXME: under ASan the call below may write to freed memory and corrupt3167  // its metadata. See3168  // https://github.com/google/sanitizers/issues/321.3169  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);3170  if (res == 0)3171    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);3172  return res;3173}3174#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);3175#else3176#define INIT_GETSOCKOPT3177#endif3178 3179#if SANITIZER_INTERCEPT_ACCEPT3180INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {3181  void *ctx;3182  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);3183  unsigned addrlen0 = 0;3184  if (addrlen) {3185    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3186    addrlen0 = *addrlen;3187  }3188  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept)(fd, addr, addrlen);3189  if (fd2 >= 0) {3190    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3191    if (addr && addrlen)3192      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3193  }3194  return fd2;3195}3196#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);3197#else3198#define INIT_ACCEPT3199#endif3200 3201#if SANITIZER_INTERCEPT_ACCEPT43202INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {3203  void *ctx;3204  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);3205  unsigned addrlen0 = 0;3206  if (addrlen) {3207    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3208    addrlen0 = *addrlen;3209  }3210  // FIXME: under ASan the call below may write to freed memory and corrupt3211  // its metadata. See3212  // https://github.com/google/sanitizers/issues/321.3213  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(accept4)(fd, addr, addrlen, f);3214  if (fd2 >= 0) {3215    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3216    if (addr && addrlen)3217      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3218  }3219  return fd2;3220}3221#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);3222#else3223#define INIT_ACCEPT43224#endif3225 3226#if SANITIZER_INTERCEPT_PACCEPT3227INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,3228            __sanitizer_sigset_t *set, int f) {3229  void *ctx;3230  COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);3231  unsigned addrlen0 = 0;3232  if (addrlen) {3233    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3234    addrlen0 = *addrlen;3235  }3236  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));3237  int fd2 = COMMON_INTERCEPTOR_BLOCK_REAL(paccept)(fd, addr, addrlen, set, f);3238  if (fd2 >= 0) {3239    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);3240    if (addr && addrlen)3241      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));3242  }3243  return fd2;3244}3245#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);3246#else3247#define INIT_PACCEPT3248#endif3249 3250#if SANITIZER_INTERCEPT_MODF3251INTERCEPTOR(double, modf, double x, double *iptr) {3252  void *ctx;3253  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);3254  // FIXME: under ASan the call below may write to freed memory and corrupt3255  // its metadata. See3256  // https://github.com/google/sanitizers/issues/321.3257  double res = REAL(modf)(x, iptr);3258  if (iptr) {3259    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3260  }3261  return res;3262}3263INTERCEPTOR(float, modff, float x, float *iptr) {3264  void *ctx;3265  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);3266  // FIXME: under ASan the call below may write to freed memory and corrupt3267  // its metadata. See3268  // https://github.com/google/sanitizers/issues/321.3269  float res = REAL(modff)(x, iptr);3270  if (iptr) {3271    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3272  }3273  return res;3274}3275INTERCEPTOR(long double, modfl, long double x, long double *iptr) {3276  void *ctx;3277  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);3278  // FIXME: under ASan the call below may write to freed memory and corrupt3279  // its metadata. See3280  // https://github.com/google/sanitizers/issues/321.3281  long double res = REAL(modfl)(x, iptr);3282  if (iptr) {3283    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));3284  }3285  return res;3286}3287#define INIT_MODF                   \3288  COMMON_INTERCEPT_FUNCTION(modf);  \3289  COMMON_INTERCEPT_FUNCTION(modff); \3290  COMMON_INTERCEPT_FUNCTION_LDBL(modfl);3291#else3292#define INIT_MODF3293#endif3294 3295#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG3296static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,3297                         SSIZE_T maxlen) {3298  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));3299  if (msg->msg_name && msg->msg_namelen)3300    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);3301  if (msg->msg_iov && msg->msg_iovlen)3302    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,3303                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);3304  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);3305  if (msg->msg_control && msg->msg_controllen)3306    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);3307}3308#endif3309 3310#if SANITIZER_INTERCEPT_RECVMSG3311INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,3312            int flags) {3313  void *ctx;3314  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);3315  // FIXME: under ASan the call below may write to freed memory and corrupt3316  // its metadata. See3317  // https://github.com/google/sanitizers/issues/321.3318  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvmsg)(fd, msg, flags);3319  if (res >= 0) {3320    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);3321    if (msg) {3322      write_msghdr(ctx, msg, res);3323      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);3324    }3325  }3326  return res;3327}3328#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);3329#else3330#define INIT_RECVMSG3331#endif3332 3333#if SANITIZER_INTERCEPT_RECVMMSG3334INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,3335            unsigned int vlen, int flags, void *timeout) {3336  void *ctx;3337  COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);3338  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);3339  int res =3340      COMMON_INTERCEPTOR_BLOCK_REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);3341  if (res >= 0) {3342    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);3343    for (int i = 0; i < res; ++i) {3344      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,3345                                     sizeof(msgvec[i].msg_len));3346      write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);3347      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);3348    }3349  }3350  return res;3351}3352#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);3353#else3354#define INIT_RECVMMSG3355#endif3356 3357#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG3358static void read_msghdr_control(void *ctx, void *control, uptr controllen) {3359  const unsigned kCmsgDataOffset =3360      RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));3361 3362  char *p = (char *)control;3363  char *const control_end = p + controllen;3364  while (true) {3365    if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;3366    __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;3367    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));3368 3369    if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;3370 3371    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,3372                                  sizeof(cmsg->cmsg_level));3373    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,3374                                  sizeof(cmsg->cmsg_type));3375 3376    if (cmsg->cmsg_len > kCmsgDataOffset) {3377      char *data = p + kCmsgDataOffset;3378      unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;3379      if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);3380    }3381 3382    p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));3383  }3384}3385 3386static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,3387                        SSIZE_T maxlen) {3388#define R(f) \3389  COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))3390  R(name);3391  R(namelen);3392  R(iov);3393  R(iovlen);3394  R(control);3395  R(controllen);3396  R(flags);3397#undef R3398  if (msg->msg_name && msg->msg_namelen)3399    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);3400  if (msg->msg_iov && msg->msg_iovlen)3401    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,3402                                  sizeof(*msg->msg_iov) * msg->msg_iovlen);3403  read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);3404  if (msg->msg_control && msg->msg_controllen)3405    read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);3406}3407#endif3408 3409#if SANITIZER_INTERCEPT_SENDMSG3410INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,3411            int flags) {3412  void *ctx;3413  COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);3414  if (fd >= 0) {3415    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);3416    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);3417  }3418  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmsg)(fd, msg, flags);3419  if (common_flags()->intercept_send && res >= 0 && msg)3420    read_msghdr(ctx, msg, res);3421  return res;3422}3423#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);3424#else3425#define INIT_SENDMSG3426#endif3427 3428#if SANITIZER_INTERCEPT_SENDMMSG3429INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,3430            unsigned vlen, int flags) {3431  void *ctx;3432  COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);3433  if (fd >= 0) {3434    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);3435    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);3436  }3437  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sendmmsg)(fd, msgvec, vlen, flags);3438  if (res >= 0 && msgvec) {3439    for (int i = 0; i < res; ++i) {3440      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,3441                                     sizeof(msgvec[i].msg_len));3442      if (common_flags()->intercept_send)3443        read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);3444    }3445  }3446  return res;3447}3448#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);3449#else3450#define INIT_SENDMMSG3451#endif3452 3453#if SANITIZER_INTERCEPT_SYSMSG3454INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz,3455            int msgflg) {3456  void *ctx;3457  COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg);3458  if (msgp)3459    COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz);3460  int res = COMMON_INTERCEPTOR_BLOCK_REAL(msgsnd)(msqid, msgp, msgsz, msgflg);3461  return res;3462}3463 3464INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz,3465            long msgtyp, int msgflg) {3466  void *ctx;3467  COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg);3468  SSIZE_T len =3469      COMMON_INTERCEPTOR_BLOCK_REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg);3470  if (len != -1)3471    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len);3472  return len;3473}3474 3475#define INIT_SYSMSG                  \3476  COMMON_INTERCEPT_FUNCTION(msgsnd); \3477  COMMON_INTERCEPT_FUNCTION(msgrcv);3478#else3479#define INIT_SYSMSG3480#endif3481 3482#if SANITIZER_INTERCEPT_GETPEERNAME3483INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {3484  void *ctx;3485  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);3486  unsigned addr_sz;3487  if (addrlen) {3488    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));3489    addr_sz = *addrlen;3490  }3491  // FIXME: under ASan the call below may write to freed memory and corrupt3492  // its metadata. See3493  // https://github.com/google/sanitizers/issues/321.3494  int res = REAL(getpeername)(sockfd, addr, addrlen);3495  if (!res && addr && addrlen) {3496    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));3497  }3498  return res;3499}3500#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);3501#else3502#define INIT_GETPEERNAME3503#endif3504 3505#if SANITIZER_INTERCEPT_SYSINFO3506INTERCEPTOR(int, sysinfo, void *info) {3507  void *ctx;3508  // FIXME: under ASan the call below may write to freed memory and corrupt3509  // its metadata. See3510  // https://github.com/google/sanitizers/issues/321.3511  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);3512  int res = REAL(sysinfo)(info);3513  if (!res && info)3514    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);3515  return res;3516}3517#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);3518#else3519#define INIT_SYSINFO3520#endif3521 3522#if SANITIZER_INTERCEPT_READDIR3523INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {3524  void *ctx;3525  COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);3526  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);3527  __sanitizer_dirent *res = REAL(opendir)(path);3528  if (res)3529    COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);3530  return res;3531}3532 3533INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {3534  void *ctx;3535  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);3536  // FIXME: under ASan the call below may write to freed memory and corrupt3537  // its metadata. See3538  // https://github.com/google/sanitizers/issues/321.3539  __sanitizer_dirent *res = REAL(readdir)(dirp);3540  if (res)3541    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));3542  return res;3543}3544 3545INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,3546            __sanitizer_dirent **result) {3547  void *ctx;3548  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);3549  // FIXME: under ASan the call below may write to freed memory and corrupt3550  // its metadata. See3551  // https://github.com/google/sanitizers/issues/321.3552  int res = REAL(readdir_r)(dirp, entry, result);3553  if (!res) {3554    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3555    if (*result)3556      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));3557  }3558  return res;3559}3560 3561#define INIT_READDIR                  \3562  COMMON_INTERCEPT_FUNCTION(opendir); \3563  COMMON_INTERCEPT_FUNCTION(readdir); \3564  COMMON_INTERCEPT_FUNCTION(readdir_r);3565#else3566#define INIT_READDIR3567#endif3568 3569#if SANITIZER_INTERCEPT_READDIR643570INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {3571  void *ctx;3572  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);3573  // FIXME: under ASan the call below may write to freed memory and corrupt3574  // its metadata. See3575  // https://github.com/google/sanitizers/issues/321.3576  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);3577  if (res)3578    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer_dirsiz(res));3579  return res;3580}3581 3582INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,3583            __sanitizer_dirent64 **result) {3584  void *ctx;3585  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);3586  // FIXME: under ASan the call below may write to freed memory and corrupt3587  // its metadata. See3588  // https://github.com/google/sanitizers/issues/321.3589  int res = REAL(readdir64_r)(dirp, entry, result);3590  if (!res) {3591    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));3592    if (*result)3593      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, __sanitizer_dirsiz(*result));3594  }3595  return res;3596}3597#define INIT_READDIR64                  \3598  COMMON_INTERCEPT_FUNCTION(readdir64); \3599  COMMON_INTERCEPT_FUNCTION(readdir64_r);3600#else3601#define INIT_READDIR643602#endif3603 3604#if SANITIZER_INTERCEPT_PTRACE3605INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {3606  void *ctx;3607  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);3608  __sanitizer_iovec local_iovec;3609 3610  void *data_arg = ptrace_data_arg(request, addr, data);3611  if (data_arg) {3612    if (request == ptrace_setregs) {3613      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, struct_user_regs_struct_sz);3614    } else if (request == ptrace_setfpregs) {3615      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3616                                    struct_user_fpregs_struct_sz);3617    } else if (request == ptrace_setfpxregs) {3618      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3619                                    struct_user_fpxregs_struct_sz);3620    } else if (request == ptrace_setvfpregs) {3621      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg,3622                                    struct_user_vfpregs_struct_sz);3623    } else if (request == ptrace_setsiginfo) {3624      COMMON_INTERCEPTOR_READ_RANGE(ctx, data_arg, siginfo_t_sz);3625 3626      // Some kernel might zero the iovec::iov_base in case of invalid3627      // write access.  In this case copy the invalid address for further3628      // inspection.3629    } else if (request == ptrace_setregset || request == ptrace_getregset) {3630      __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;3631      COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));3632      local_iovec = *iovec;3633      if (request == ptrace_setregset)3634        COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);3635    }3636  }3637 3638  // FIXME: under ASan the call below may write to freed memory and corrupt3639  // its metadata. See3640  // https://github.com/google/sanitizers/issues/321.3641  uptr res = REAL(ptrace)(request, pid, addr, data);3642 3643  if (!res && data_arg) {3644    // Note that PEEK* requests assign different meaning to the return value.3645    // This function does not handle them (nor does it need to).3646    if (request == ptrace_getregs) {3647      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, struct_user_regs_struct_sz);3648    } else if (request == ptrace_getfpregs) {3649      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3650                                     struct_user_fpregs_struct_sz);3651    } else if (request == ptrace_getfpxregs) {3652      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3653                                     struct_user_fpxregs_struct_sz);3654    } else if (request == ptrace_getvfpregs) {3655      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg,3656                                     struct_user_vfpregs_struct_sz);3657    } else if (request == ptrace_getsiginfo) {3658      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, siginfo_t_sz);3659    } else if (request == ptrace_geteventmsg) {3660      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data_arg, sizeof(unsigned long));3661    } else if (request == ptrace_getregset) {3662      __sanitizer_iovec *iovec = (__sanitizer_iovec *)data_arg;3663      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));3664      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,3665                                     local_iovec.iov_len);3666    }3667  }3668  return res;3669}3670 3671#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);3672#else3673#define INIT_PTRACE3674#endif3675 3676#if SANITIZER_INTERCEPT_SETLOCALE3677static void unpoison_ctype_arrays(void *ctx) {3678#if SANITIZER_NETBSD3679  // These arrays contain 256 regular elements in unsigned char range + 1 EOF3680  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));3681  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));3682  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));3683#endif3684}3685 3686INTERCEPTOR(char *, setlocale, int category, char *locale) {3687  void *ctx;3688  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);3689  if (locale)3690    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1);3691  char *res = REAL(setlocale)(category, locale);3692  if (res) {3693    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);3694    unpoison_ctype_arrays(ctx);3695  }3696  return res;3697}3698 3699#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);3700#else3701#define INIT_SETLOCALE3702#endif3703 3704#if SANITIZER_INTERCEPT_GETCWD3705INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {3706  void *ctx;3707  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);3708  // FIXME: under ASan the call below may write to freed memory and corrupt3709  // its metadata. See3710  // https://github.com/google/sanitizers/issues/321.3711  char *res = REAL(getcwd)(buf, size);3712  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);3713  return res;3714}3715#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);3716#else3717#define INIT_GETCWD3718#endif3719 3720#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME3721INTERCEPTOR(char *, get_current_dir_name, int fake) {3722  void *ctx;3723  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);3724  // FIXME: under ASan the call below may write to freed memory and corrupt3725  // its metadata. See3726  // https://github.com/google/sanitizers/issues/321.3727  char *res = REAL(get_current_dir_name)(fake);3728  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);3729  return res;3730}3731 3732#define INIT_GET_CURRENT_DIR_NAME \3733  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);3734#else3735#define INIT_GET_CURRENT_DIR_NAME3736#endif3737 3738UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {3739  CHECK(endptr);3740  if (nptr == *endptr) {3741    // No digits were found at strtol call, we need to find out the last3742    // symbol accessed by strtoll on our own.3743    // We get this symbol by skipping leading blanks and optional +/- sign.3744    while (IsSpace(*nptr)) nptr++;3745    if (*nptr == '+' || *nptr == '-') nptr++;3746    *endptr = const_cast<char *>(nptr);3747  }3748  CHECK(*endptr >= nptr);3749}3750 3751UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,3752                             char **endptr, char *real_endptr, int base) {3753  if (endptr) {3754    *endptr = real_endptr;3755    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));3756  }3757  // If base has unsupported value, strtol can exit with EINVAL3758  // without reading any characters. So do additional checks only3759  // if base is valid.3760  bool is_valid_base = (base == 0) || (2 <= base && base <= 36);3761  if (is_valid_base) {3762    FixRealStrtolEndptr(nptr, &real_endptr);3763  }3764  COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?3765                                 (real_endptr - nptr) + 1 : 0);3766}3767 3768#if SANITIZER_INTERCEPT_STRTOIMAX3769template <typename Fn>3770static ALWAYS_INLINE auto StrtoimaxImpl(void *ctx, Fn real, const char *nptr,3771                                        char **endptr, int base)3772    -> decltype(real(nullptr, nullptr, 0)) {3773  char *real_endptr;3774  auto res = real(nptr, &real_endptr, base);3775  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);3776  return res;3777}3778 3779INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {3780  void *ctx;3781  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);3782  return StrtoimaxImpl(ctx, REAL(strtoimax), nptr, endptr, base);3783}3784INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {3785  void *ctx;3786  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);3787  return StrtoimaxImpl(ctx, REAL(strtoumax), nptr, endptr, base);3788}3789 3790#define INIT_STRTOIMAX                  \3791  COMMON_INTERCEPT_FUNCTION(strtoimax); \3792  COMMON_INTERCEPT_FUNCTION(strtoumax);3793#else3794#define INIT_STRTOIMAX3795#endif3796 3797#if SANITIZER_INTERCEPT_STRTOIMAX && SANITIZER_GLIBC3798INTERCEPTOR(INTMAX_T, __isoc23_strtoimax, const char *nptr, char **endptr, int base) {3799  void *ctx;3800  COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoimax, nptr, endptr, base);3801  return StrtoimaxImpl(ctx, REAL(__isoc23_strtoimax), nptr, endptr, base);3802}3803INTERCEPTOR(UINTMAX_T, __isoc23_strtoumax, const char *nptr, char **endptr, int base) {3804  void *ctx;3805  COMMON_INTERCEPTOR_ENTER(ctx, __isoc23_strtoumax, nptr, endptr, base);3806  return StrtoimaxImpl(ctx, REAL(__isoc23_strtoumax), nptr, endptr, base);3807}3808 3809#  define INIT_STRTOIMAX_C23                       \3810    COMMON_INTERCEPT_FUNCTION(__isoc23_strtoimax); \3811    COMMON_INTERCEPT_FUNCTION(__isoc23_strtoumax);3812#else3813#  define INIT_STRTOIMAX_C233814#endif3815 3816#if SANITIZER_INTERCEPT_MBSTOWCS3817INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {3818  void *ctx;3819  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);3820  // FIXME: under ASan the call below may write to freed memory and corrupt3821  // its metadata. See3822  // https://github.com/google/sanitizers/issues/321.3823  SIZE_T res = REAL(mbstowcs)(dest, src, len);3824  if (res != (SIZE_T) - 1 && dest) {3825    SIZE_T write_cnt = res + (res < len);3826    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3827  }3828  return res;3829}3830 3831INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,3832            void *ps) {3833  void *ctx;3834  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);3835  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3836  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3837  // FIXME: under ASan the call below may write to freed memory and corrupt3838  // its metadata. See3839  // https://github.com/google/sanitizers/issues/321.3840  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);3841  if (res != (SIZE_T)(-1) && dest && src) {3842    // This function, and several others, may or may not write the terminating3843    // \0 character. They write it iff they clear *src.3844    SIZE_T write_cnt = res + !*src;3845    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3846  }3847  return res;3848}3849 3850#define INIT_MBSTOWCS                  \3851  COMMON_INTERCEPT_FUNCTION(mbstowcs); \3852  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);3853#else3854#define INIT_MBSTOWCS3855#endif3856 3857#if SANITIZER_INTERCEPT_MBSNRTOWCS3858INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,3859            SIZE_T len, void *ps) {3860  void *ctx;3861  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);3862  if (src) {3863    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3864    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);3865  }3866  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3867  // FIXME: under ASan the call below may write to freed memory and corrupt3868  // its metadata. See3869  // https://github.com/google/sanitizers/issues/321.3870  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);3871  if (res != (SIZE_T)(-1) && dest && src) {3872    SIZE_T write_cnt = res + !*src;3873    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));3874  }3875  return res;3876}3877 3878#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);3879#else3880#define INIT_MBSNRTOWCS3881#endif3882 3883#if SANITIZER_INTERCEPT_WCSTOMBS3884INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {3885  void *ctx;3886  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);3887  // FIXME: under ASan the call below may write to freed memory and corrupt3888  // its metadata. See3889  // https://github.com/google/sanitizers/issues/321.3890  SIZE_T res = REAL(wcstombs)(dest, src, len);3891  if (res != (SIZE_T) - 1 && dest) {3892    SIZE_T write_cnt = res + (res < len);3893    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3894  }3895  return res;3896}3897 3898INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,3899            void *ps) {3900  void *ctx;3901  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);3902  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3903  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3904  // FIXME: under ASan the call below may write to freed memory and corrupt3905  // its metadata. See3906  // https://github.com/google/sanitizers/issues/321.3907  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);3908  if (res != (SIZE_T) - 1 && dest && src) {3909    SIZE_T write_cnt = res + !*src;3910    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3911  }3912  return res;3913}3914 3915#define INIT_WCSTOMBS                  \3916  COMMON_INTERCEPT_FUNCTION(wcstombs); \3917  COMMON_INTERCEPT_FUNCTION(wcsrtombs);3918#else3919#define INIT_WCSTOMBS3920#endif3921 3922#if SANITIZER_INTERCEPT_WCSNRTOMBS3923INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,3924            SIZE_T len, void *ps) {3925  void *ctx;3926  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);3927  if (src) {3928    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));3929    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);3930  }3931  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3932  // FIXME: under ASan the call below may write to freed memory and corrupt3933  // its metadata. See3934  // https://github.com/google/sanitizers/issues/321.3935  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);3936  if (res != ((SIZE_T)-1) && dest && src) {3937    SIZE_T write_cnt = res + !*src;3938    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);3939  }3940  return res;3941}3942 3943#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);3944#else3945#define INIT_WCSNRTOMBS3946#endif3947 3948 3949#if SANITIZER_INTERCEPT_WCRTOMB3950INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {3951  void *ctx;3952  COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);3953  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);3954 3955  if (!dest)3956    return REAL(wcrtomb)(dest, src, ps);3957 3958  char local_dest[32];3959  SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);3960  if (res != ((SIZE_T)-1)) {3961    CHECK_LE(res, sizeof(local_dest));3962    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);3963    internal_memcpy(dest, local_dest, res);3964  }3965  return res;3966}3967 3968#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);3969#else3970#define INIT_WCRTOMB3971#endif3972 3973#if SANITIZER_INTERCEPT_WCTOMB3974INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {3975  void *ctx;3976  COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);3977  if (!dest)3978    return REAL(wctomb)(dest, src);3979 3980  char local_dest[32];3981  int res = REAL(wctomb)(local_dest, src);3982  if (res != -1) {3983    CHECK_LE(res, sizeof(local_dest));3984    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);3985    internal_memcpy(dest, local_dest, res);3986  }3987  return res;3988}3989 3990#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);3991#else3992#define INIT_WCTOMB3993#endif3994 3995#if SANITIZER_INTERCEPT_TCGETATTR3996INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {3997  void *ctx;3998  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);3999  // FIXME: under ASan the call below may write to freed memory and corrupt4000  // its metadata. See4001  // https://github.com/google/sanitizers/issues/321.4002  int res = REAL(tcgetattr)(fd, termios_p);4003  if (!res && termios_p)4004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);4005  return res;4006}4007 4008#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);4009#else4010#define INIT_TCGETATTR4011#endif4012 4013#if SANITIZER_INTERCEPT_REALPATH4014INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {4015  void *ctx;4016  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);4017  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4018 4019  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest4020  // version of a versioned symbol. For realpath(), this gives us something4021  // (called __old_realpath) that does not handle NULL in the second argument.4022  // Handle it as part of the interceptor.4023  char *allocated_path = nullptr;4024  if (!resolved_path)4025    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);4026 4027  char *res = REAL(realpath)(path, resolved_path);4028  if (allocated_path && !res)4029    WRAP(free)(allocated_path);4030  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4031  return res;4032}4033#  define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);4034#else4035#define INIT_REALPATH4036#endif4037 4038#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME4039INTERCEPTOR(char *, canonicalize_file_name, const char *path) {4040  void *ctx;4041  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);4042  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4043  char *res = REAL(canonicalize_file_name)(path);4044  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4045  return res;4046}4047#define INIT_CANONICALIZE_FILE_NAME \4048  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);4049#else4050#define INIT_CANONICALIZE_FILE_NAME4051#endif4052 4053#if SANITIZER_INTERCEPT_CONFSTR4054INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {4055  void *ctx;4056  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);4057  // FIXME: under ASan the call below may write to freed memory and corrupt4058  // its metadata. See4059  // https://github.com/google/sanitizers/issues/321.4060  SIZE_T res = REAL(confstr)(name, buf, len);4061  if (buf && res)4062    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);4063  return res;4064}4065#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);4066#else4067#define INIT_CONFSTR4068#endif4069 4070#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY4071INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {4072  void *ctx;4073  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);4074  // FIXME: under ASan the call below may write to freed memory and corrupt4075  // its metadata. See4076  // https://github.com/google/sanitizers/issues/321.4077  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);4078  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);4079  return res;4080}4081#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);4082#else4083#define INIT_SCHED_GETAFFINITY4084#endif4085 4086#if SANITIZER_INTERCEPT_SCHED_GETPARAM4087INTERCEPTOR(int, sched_getparam, int pid, void *param) {4088  void *ctx;4089  COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);4090  int res = REAL(sched_getparam)(pid, param);4091  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);4092  return res;4093}4094#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);4095#else4096#define INIT_SCHED_GETPARAM4097#endif4098 4099#if SANITIZER_INTERCEPT_STRERROR4100INTERCEPTOR(char *, strerror, int errnum) {4101  void *ctx;4102  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);4103  COMMON_INTERCEPTOR_STRERROR();4104  char *res = REAL(strerror)(errnum);4105  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4106  return res;4107}4108#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);4109#else4110#define INIT_STRERROR4111#endif4112 4113#if SANITIZER_INTERCEPT_STRERROR_R4114// There are 2 versions of strerror_r:4115//  * POSIX version returns 0 on success, negative error code on failure,4116//    writes message to buf.4117//  * GNU version returns message pointer, which points to either buf or some4118//    static storage.4119#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \4120    SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD ||                 \4121    SANITIZER_FREEBSD4122// POSIX version. Spec is not clear on whether buf is NULL-terminated.4123// At least on OSX, buf contents are valid even when the call fails.4124INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {4125  void *ctx;4126  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);4127  // FIXME: under ASan the call below may write to freed memory and corrupt4128  // its metadata. See4129  // https://github.com/google/sanitizers/issues/321.4130  int res = REAL(strerror_r)(errnum, buf, buflen);4131 4132  SIZE_T sz = internal_strnlen(buf, buflen);4133  if (sz < buflen) ++sz;4134  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);4135  return res;4136}4137#else4138// GNU version.4139INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {4140  void *ctx;4141  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);4142  // FIXME: under ASan the call below may write to freed memory and corrupt4143  // its metadata. See4144  // https://github.com/google/sanitizers/issues/321.4145  char *res = REAL(strerror_r)(errnum, buf, buflen);4146  if (res == buf)4147    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4148  else4149    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4150  return res;4151}4152#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||4153       //SANITIZER_APPLE4154#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);4155#else4156#define INIT_STRERROR_R4157#endif4158 4159#if SANITIZER_INTERCEPT_XPG_STRERROR_R4160INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {4161  void *ctx;4162  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);4163  // FIXME: under ASan the call below may write to freed memory and corrupt4164  // its metadata. See4165  // https://github.com/google/sanitizers/issues/321.4166  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);4167  // This version always returns a null-terminated string.4168  if (buf && buflen)4169    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);4170  return res;4171}4172#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);4173#else4174#define INIT_XPG_STRERROR_R4175#endif4176 4177#if SANITIZER_INTERCEPT_SCANDIR4178typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);4179typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,4180                                const struct __sanitizer_dirent **);4181 4182static THREADLOCAL scandir_filter_f scandir_filter;4183static THREADLOCAL scandir_compar_f scandir_compar;4184 4185static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {4186  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);4187  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));4188  return scandir_filter(dir);4189}4190 4191static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,4192                                  const struct __sanitizer_dirent **b) {4193  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);4194  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));4195  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));4196  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));4197  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));4198  return scandir_compar(a, b);4199}4200 4201INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,4202            scandir_filter_f filter, scandir_compar_f compar) {4203  void *ctx;4204  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);4205  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);4206  scandir_filter = filter;4207  scandir_compar = compar;4208  // FIXME: under ASan the call below may write to freed memory and corrupt4209  // its metadata. See4210  // https://github.com/google/sanitizers/issues/321.4211  int res = REAL(scandir)(dirp, namelist,4212                          filter ? wrapped_scandir_filter : nullptr,4213                          compar ? wrapped_scandir_compar : nullptr);4214  scandir_filter = nullptr;4215  scandir_compar = nullptr;4216  if (namelist && res > 0) {4217    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));4218    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);4219    for (int i = 0; i < res; ++i)4220      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],4221                                     __sanitizer_dirsiz((*namelist)[i]));4222  }4223  return res;4224}4225#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);4226#else4227#define INIT_SCANDIR4228#endif4229 4230#if SANITIZER_INTERCEPT_SCANDIR644231typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);4232typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,4233                                  const struct __sanitizer_dirent64 **);4234 4235static THREADLOCAL scandir64_filter_f scandir64_filter;4236static THREADLOCAL scandir64_compar_f scandir64_compar;4237 4238static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {4239  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);4240  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, __sanitizer_dirsiz(dir));4241  return scandir64_filter(dir);4242}4243 4244static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,4245                                    const struct __sanitizer_dirent64 **b) {4246  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);4247  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));4248  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, __sanitizer_dirsiz(*a));4249  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));4250  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, __sanitizer_dirsiz(*b));4251  return scandir64_compar(a, b);4252}4253 4254INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,4255            scandir64_filter_f filter, scandir64_compar_f compar) {4256  void *ctx;4257  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);4258  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);4259  scandir64_filter = filter;4260  scandir64_compar = compar;4261  // FIXME: under ASan the call below may write to freed memory and corrupt4262  // its metadata. See4263  // https://github.com/google/sanitizers/issues/321.4264  int res =4265      REAL(scandir64)(dirp, namelist,4266                      filter ? wrapped_scandir64_filter : nullptr,4267                      compar ? wrapped_scandir64_compar : nullptr);4268  scandir64_filter = nullptr;4269  scandir64_compar = nullptr;4270  if (namelist && res > 0) {4271    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));4272    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);4273    for (int i = 0; i < res; ++i)4274      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],4275                                     __sanitizer_dirsiz((*namelist)[i]));4276  }4277  return res;4278}4279#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);4280#else4281#define INIT_SCANDIR644282#endif4283 4284#if SANITIZER_INTERCEPT_GETGROUPS4285INTERCEPTOR(int, getgroups, int size, u32 *lst) {4286  void *ctx;4287  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);4288  // FIXME: under ASan the call below may write to freed memory and corrupt4289  // its metadata. See4290  // https://github.com/google/sanitizers/issues/321.4291  int res = REAL(getgroups)(size, lst);4292  if (res >= 0 && lst && size > 0)4293    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));4294  return res;4295}4296#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);4297#else4298#define INIT_GETGROUPS4299#endif4300 4301#if SANITIZER_INTERCEPT_POLL4302static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,4303                        __sanitizer_nfds_t nfds) {4304  for (unsigned i = 0; i < nfds; ++i) {4305    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));4306    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));4307  }4308}4309 4310static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,4311                         __sanitizer_nfds_t nfds) {4312  for (unsigned i = 0; i < nfds; ++i)4313    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,4314                                   sizeof(fds[i].revents));4315}4316 4317INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,4318            int timeout) {4319  void *ctx;4320  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);4321  if (fds && nfds) read_pollfd(ctx, fds, nfds);4322  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);4323  if (fds && nfds) write_pollfd(ctx, fds, nfds);4324  return res;4325}4326#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);4327#else4328#define INIT_POLL4329#endif4330 4331#if SANITIZER_INTERCEPT_PPOLL4332INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,4333            void *timeout_ts, __sanitizer_sigset_t *sigmask) {4334  void *ctx;4335  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);4336  if (fds && nfds) read_pollfd(ctx, fds, nfds);4337  if (timeout_ts)4338    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);4339  if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));4340  int res =4341      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);4342  if (fds && nfds) write_pollfd(ctx, fds, nfds);4343  return res;4344}4345#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);4346#else4347#define INIT_PPOLL4348#endif4349 4350#if SANITIZER_INTERCEPT_WORDEXP4351INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {4352  void *ctx;4353  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);4354  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);4355  // FIXME: under ASan the call below may write to freed memory and corrupt4356  // its metadata. See4357  // https://github.com/google/sanitizers/issues/321.4358  int res = REAL(wordexp)(s, p, flags);4359  if (!res && p) {4360    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));4361    uptr we_wordc =4362        ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc;4363    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,4364                                   sizeof(*p->we_wordv) * (we_wordc + 1));4365    for (uptr i = 0; i < we_wordc; ++i) {4366      char *w = p->we_wordv[i];4367      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);4368    }4369  }4370  return res;4371}4372#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);4373#else4374#define INIT_WORDEXP4375#endif4376 4377#if SANITIZER_INTERCEPT_SIGWAIT4378INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {4379  void *ctx;4380  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);4381  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4382  // FIXME: under ASan the call below may write to freed memory and corrupt4383  // its metadata. See4384  // https://github.com/google/sanitizers/issues/321.4385  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);4386  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));4387  return res;4388}4389#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);4390#else4391#define INIT_SIGWAIT4392#endif4393 4394#if SANITIZER_INTERCEPT_SIGWAITINFO4395INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {4396  void *ctx;4397  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);4398  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4399  // FIXME: under ASan the call below may write to freed memory and corrupt4400  // its metadata. See4401  // https://github.com/google/sanitizers/issues/321.4402  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);4403  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);4404  return res;4405}4406#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);4407#else4408#define INIT_SIGWAITINFO4409#endif4410 4411#if SANITIZER_INTERCEPT_SIGTIMEDWAIT4412INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,4413            void *timeout) {4414  void *ctx;4415  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);4416  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);4417  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4418  // FIXME: under ASan the call below may write to freed memory and corrupt4419  // its metadata. See4420  // https://github.com/google/sanitizers/issues/321.4421  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);4422  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);4423  return res;4424}4425#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);4426#else4427#define INIT_SIGTIMEDWAIT4428#endif4429 4430#if SANITIZER_INTERCEPT_SIGSETOPS4431INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {4432  void *ctx;4433  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);4434  // FIXME: under ASan the call below may write to freed memory and corrupt4435  // its metadata. See4436  // https://github.com/google/sanitizers/issues/321.4437  int res = REAL(sigemptyset)(set);4438  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4439  return res;4440}4441 4442INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {4443  void *ctx;4444  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);4445  // FIXME: under ASan the call below may write to freed memory and corrupt4446  // its metadata. See4447  // https://github.com/google/sanitizers/issues/321.4448  int res = REAL(sigfillset)(set);4449  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4450  return res;4451}4452#define INIT_SIGSETOPS                    \4453  COMMON_INTERCEPT_FUNCTION(sigemptyset); \4454  COMMON_INTERCEPT_FUNCTION(sigfillset);4455#else4456#define INIT_SIGSETOPS4457#endif4458 4459#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS4460INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,4461            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {4462  void *ctx;4463  COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);4464  if (src1)4465    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));4466  if (src2)4467    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));4468  int res = REAL(sigandset)(dst, src1, src2);4469  if (!res && dst)4470    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));4471  return res;4472}4473 4474INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,4475            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {4476  void *ctx;4477  COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);4478  if (src1)4479    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));4480  if (src2)4481    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));4482  int res = REAL(sigorset)(dst, src1, src2);4483  if (!res && dst)4484    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));4485  return res;4486}4487#define INIT_SIGSET_LOGICOPS                    \4488  COMMON_INTERCEPT_FUNCTION(sigandset);   \4489  COMMON_INTERCEPT_FUNCTION(sigorset);4490#else4491#define INIT_SIGSET_LOGICOPS4492#endif4493 4494#if SANITIZER_INTERCEPT_SIGPENDING4495INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {4496  void *ctx;4497  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);4498  // FIXME: under ASan the call below may write to freed memory and corrupt4499  // its metadata. See4500  // https://github.com/google/sanitizers/issues/321.4501  int res = REAL(sigpending)(set);4502  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));4503  return res;4504}4505#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);4506#else4507#define INIT_SIGPENDING4508#endif4509 4510#if SANITIZER_INTERCEPT_SIGPROCMASK4511INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,4512            __sanitizer_sigset_t *oldset) {4513  void *ctx;4514  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);4515  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4516  // FIXME: under ASan the call below may write to freed memory and corrupt4517  // its metadata. See4518  // https://github.com/google/sanitizers/issues/321.4519  int res = REAL(sigprocmask)(how, set, oldset);4520  if (!res && oldset)4521    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));4522  return res;4523}4524#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);4525#else4526#define INIT_SIGPROCMASK4527#endif4528 4529#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK4530INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,4531            __sanitizer_sigset_t *oldset) {4532  void *ctx;4533  COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);4534  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));4535  // FIXME: under ASan the call below may write to freed memory and corrupt4536  // its metadata. See4537  // https://github.com/google/sanitizers/issues/321.4538  int res = REAL(pthread_sigmask)(how, set, oldset);4539  if (!res && oldset)4540    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));4541  return res;4542}4543#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);4544#else4545#define INIT_PTHREAD_SIGMASK4546#endif4547 4548#if SANITIZER_INTERCEPT_BACKTRACE4549INTERCEPTOR(int, backtrace, void **buffer, int size) {4550  void *ctx;4551  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);4552  // 'buffer' might be freed memory, hence it is unsafe to directly call4553  // REAL(backtrace)(buffer, size). Instead, we use our own known-good4554  // scratch buffer.4555  void **scratch = (void**)InternalAlloc(sizeof(void*) * size);4556  int res = REAL(backtrace)(scratch, size);4557  if (res && buffer) {4558    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));4559    internal_memcpy(buffer, scratch, res * sizeof(*buffer));4560  }4561  InternalFree(scratch);4562  return res;4563}4564 4565INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {4566  void *ctx;4567  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);4568  if (buffer && size)4569    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));4570  // The COMMON_INTERCEPTOR_READ_RANGE above ensures that 'buffer' is4571  // valid for reading.4572  char **res = REAL(backtrace_symbols)(buffer, size);4573  if (res && size) {4574    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));4575    for (int i = 0; i < size; ++i)4576      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1);4577  }4578  return res;4579}4580#define INIT_BACKTRACE                  \4581  COMMON_INTERCEPT_FUNCTION(backtrace); \4582  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);4583#else4584#define INIT_BACKTRACE4585#endif4586 4587#if SANITIZER_INTERCEPT__EXIT4588INTERCEPTOR(void, _exit, int status) {4589  void *ctx;4590  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);4591  COMMON_INTERCEPTOR_USER_CALLBACK_START();4592  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);4593  COMMON_INTERCEPTOR_USER_CALLBACK_END();4594  if (status == 0) status = status1;4595  REAL(_exit)(status);4596}4597#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);4598#else4599#define INIT__EXIT4600#endif4601 4602#if SANITIZER_INTERCEPT___LIBC_MUTEX4603INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)4604ALIAS(WRAP(pthread_setcancelstate));4605 4606#define INIT___LIBC_THR_SETCANCELSTATE \4607  COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)4608#else4609#define INIT___LIBC_THR_SETCANCELSTATE4610#endif4611 4612#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R4613static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {4614  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));4615  if (mnt->mnt_fsname)4616    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,4617                                   internal_strlen(mnt->mnt_fsname) + 1);4618  if (mnt->mnt_dir)4619    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,4620                                   internal_strlen(mnt->mnt_dir) + 1);4621  if (mnt->mnt_type)4622    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,4623                                   internal_strlen(mnt->mnt_type) + 1);4624  if (mnt->mnt_opts)4625    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,4626                                   internal_strlen(mnt->mnt_opts) + 1);4627}4628#endif4629 4630#if SANITIZER_INTERCEPT_GETMNTENT4631INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {4632  void *ctx;4633  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);4634  __sanitizer_mntent *res = REAL(getmntent)(fp);4635  if (res) write_mntent(ctx, res);4636  return res;4637}4638#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);4639#else4640#define INIT_GETMNTENT4641#endif4642 4643#if SANITIZER_INTERCEPT_GETMNTENT_R4644INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,4645            __sanitizer_mntent *mntbuf, char *buf, int buflen) {4646  void *ctx;4647  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);4648  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);4649  if (res) write_mntent(ctx, res);4650  return res;4651}4652#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);4653#else4654#define INIT_GETMNTENT_R4655#endif4656 4657#if SANITIZER_INTERCEPT_STATFS4658INTERCEPTOR(int, statfs, char *path, void *buf) {4659  void *ctx;4660  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);4661  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4662  // FIXME: under ASan the call below may write to freed memory and corrupt4663  // its metadata. See4664  // https://github.com/google/sanitizers/issues/321.4665  int res = REAL(statfs)(path, buf);4666  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);4667  return res;4668}4669INTERCEPTOR(int, fstatfs, int fd, void *buf) {4670  void *ctx;4671  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);4672  // FIXME: under ASan the call below may write to freed memory and corrupt4673  // its metadata. See4674  // https://github.com/google/sanitizers/issues/321.4675  int res = REAL(fstatfs)(fd, buf);4676  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);4677  return res;4678}4679#define INIT_STATFS                  \4680  COMMON_INTERCEPT_FUNCTION(statfs); \4681  COMMON_INTERCEPT_FUNCTION(fstatfs);4682#else4683#define INIT_STATFS4684#endif4685 4686#if SANITIZER_INTERCEPT_STATFS644687INTERCEPTOR(int, statfs64, char *path, void *buf) {4688  void *ctx;4689  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);4690  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4691  // FIXME: under ASan the call below may write to freed memory and corrupt4692  // its metadata. See4693  // https://github.com/google/sanitizers/issues/321.4694  int res = REAL(statfs64)(path, buf);4695  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);4696  return res;4697}4698INTERCEPTOR(int, fstatfs64, int fd, void *buf) {4699  void *ctx;4700  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);4701  // FIXME: under ASan the call below may write to freed memory and corrupt4702  // its metadata. See4703  // https://github.com/google/sanitizers/issues/321.4704  int res = REAL(fstatfs64)(fd, buf);4705  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);4706  return res;4707}4708#define INIT_STATFS64                  \4709  COMMON_INTERCEPT_FUNCTION(statfs64); \4710  COMMON_INTERCEPT_FUNCTION(fstatfs64);4711#else4712#define INIT_STATFS644713#endif4714 4715#if SANITIZER_INTERCEPT_STATVFS4716INTERCEPTOR(int, statvfs, char *path, void *buf) {4717  void *ctx;4718  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);4719  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4720  // FIXME: under ASan the call below may write to freed memory and corrupt4721  // its metadata. See4722  // https://github.com/google/sanitizers/issues/321.4723  int res = REAL(statvfs)(path, buf);4724  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);4725  return res;4726}4727INTERCEPTOR(int, fstatvfs, int fd, void *buf) {4728  void *ctx;4729  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);4730  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);4731  // FIXME: under ASan the call below may write to freed memory and corrupt4732  // its metadata. See4733  // https://github.com/google/sanitizers/issues/321.4734  int res = REAL(fstatvfs)(fd, buf);4735  if (!res) {4736    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);4737    if (fd >= 0)4738      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);4739  }4740  return res;4741}4742#define INIT_STATVFS                  \4743  COMMON_INTERCEPT_FUNCTION(statvfs); \4744  COMMON_INTERCEPT_FUNCTION(fstatvfs);4745#else4746#define INIT_STATVFS4747#endif4748 4749#if SANITIZER_INTERCEPT_STATVFS644750INTERCEPTOR(int, statvfs64, char *path, void *buf) {4751  void *ctx;4752  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);4753  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);4754  // FIXME: under ASan the call below may write to freed memory and corrupt4755  // its metadata. See4756  // https://github.com/google/sanitizers/issues/321.4757  int res = REAL(statvfs64)(path, buf);4758  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);4759  return res;4760}4761INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {4762  void *ctx;4763  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);4764  // FIXME: under ASan the call below may write to freed memory and corrupt4765  // its metadata. See4766  // https://github.com/google/sanitizers/issues/321.4767  int res = REAL(fstatvfs64)(fd, buf);4768  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);4769  return res;4770}4771#define INIT_STATVFS64                  \4772  COMMON_INTERCEPT_FUNCTION(statvfs64); \4773  COMMON_INTERCEPT_FUNCTION(fstatvfs64);4774#else4775#define INIT_STATVFS644776#endif4777 4778#if SANITIZER_INTERCEPT_INITGROUPS4779INTERCEPTOR(int, initgroups, char *user, u32 group) {4780  void *ctx;4781  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);4782  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1);4783  int res = REAL(initgroups)(user, group);4784  return res;4785}4786#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);4787#else4788#define INIT_INITGROUPS4789#endif4790 4791#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON4792INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {4793  void *ctx;4794  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);4795  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4796  char *res = REAL(ether_ntoa)(addr);4797  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);4798  return res;4799}4800INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {4801  void *ctx;4802  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);4803  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);4804  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);4805  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));4806  return res;4807}4808#define INIT_ETHER_NTOA_ATON             \4809  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \4810  COMMON_INTERCEPT_FUNCTION(ether_aton);4811#else4812#define INIT_ETHER_NTOA_ATON4813#endif4814 4815#if SANITIZER_INTERCEPT_ETHER_HOST4816INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {4817  void *ctx;4818  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);4819  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4820  // FIXME: under ASan the call below may write to freed memory and corrupt4821  // its metadata. See4822  // https://github.com/google/sanitizers/issues/321.4823  int res = REAL(ether_ntohost)(hostname, addr);4824  if (!res && hostname)4825    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4826  return res;4827}4828INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {4829  void *ctx;4830  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);4831  if (hostname)4832    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4833  // FIXME: under ASan the call below may write to freed memory and corrupt4834  // its metadata. See4835  // https://github.com/google/sanitizers/issues/321.4836  int res = REAL(ether_hostton)(hostname, addr);4837  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4838  return res;4839}4840INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,4841            char *hostname) {4842  void *ctx;4843  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);4844  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1);4845  // FIXME: under ASan the call below may write to freed memory and corrupt4846  // its metadata. See4847  // https://github.com/google/sanitizers/issues/321.4848  int res = REAL(ether_line)(line, addr, hostname);4849  if (!res) {4850    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4851    if (hostname)4852      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);4853  }4854  return res;4855}4856#define INIT_ETHER_HOST                     \4857  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \4858  COMMON_INTERCEPT_FUNCTION(ether_hostton); \4859  COMMON_INTERCEPT_FUNCTION(ether_line);4860#else4861#define INIT_ETHER_HOST4862#endif4863 4864#if SANITIZER_INTERCEPT_ETHER_R4865INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {4866  void *ctx;4867  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);4868  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));4869  // FIXME: under ASan the call below may write to freed memory and corrupt4870  // its metadata. See4871  // https://github.com/google/sanitizers/issues/321.4872  char *res = REAL(ether_ntoa_r)(addr, buf);4873  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);4874  return res;4875}4876INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,4877            __sanitizer_ether_addr *addr) {4878  void *ctx;4879  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);4880  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);4881  // FIXME: under ASan the call below may write to freed memory and corrupt4882  // its metadata. See4883  // https://github.com/google/sanitizers/issues/321.4884  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);4885  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));4886  return res;4887}4888#define INIT_ETHER_R                       \4889  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \4890  COMMON_INTERCEPT_FUNCTION(ether_aton_r);4891#else4892#define INIT_ETHER_R4893#endif4894 4895#if SANITIZER_INTERCEPT_SHMCTL4896INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {4897  void *ctx;4898  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);4899  // FIXME: under ASan the call below may write to freed memory and corrupt4900  // its metadata. See4901  // https://github.com/google/sanitizers/issues/321.4902  int res = REAL(shmctl)(shmid, cmd, buf);4903  if (res >= 0) {4904    unsigned sz = 0;4905    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)4906      sz = sizeof(__sanitizer_shmid_ds);4907    else if (cmd == shmctl_ipc_info)4908      sz = struct_shminfo_sz;4909    else if (cmd == shmctl_shm_info)4910      sz = struct_shm_info_sz;4911    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);4912  }4913  return res;4914}4915#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);4916#else4917#define INIT_SHMCTL4918#endif4919 4920#if SANITIZER_INTERCEPT_RANDOM_R4921INTERCEPTOR(int, random_r, void *buf, u32 *result) {4922  void *ctx;4923  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);4924  // FIXME: under ASan the call below may write to freed memory and corrupt4925  // its metadata. See4926  // https://github.com/google/sanitizers/issues/321.4927  int res = REAL(random_r)(buf, result);4928  if (!res && result)4929    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));4930  return res;4931}4932#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);4933#else4934#define INIT_RANDOM_R4935#endif4936 4937// FIXME: under ASan the REAL() call below may write to freed memory and corrupt4938// its metadata. See4939// https://github.com/google/sanitizers/issues/321.4940#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \4941    SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED ||        \4942    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \4943    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \4944    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \4945    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \4946    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET4947#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \4948  INTERCEPTOR(int, fn, void *attr, void *r) {                  \4949    void *ctx;                                                 \4950    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \4951    int res = REAL(fn)(attr, r);                               \4952    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \4953    return res;                                                \4954  }4955#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \4956  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)4957#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \4958  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)4959#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \4960  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)4961#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \4962  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)4963#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \4964  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)4965#endif4966 4967#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET4968INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))4969INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))4970INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))4971INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))4972INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {4973  void *ctx;4974  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);4975  // FIXME: under ASan the call below may write to freed memory and corrupt4976  // its metadata. See4977  // https://github.com/google/sanitizers/issues/321.4978  int res = REAL(pthread_attr_getstack)(attr, addr, size);4979  if (!res) {4980    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));4981    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));4982  }4983  return res;4984}4985 4986// We may need to call the real pthread_attr_getstack from the run-time4987// in sanitizer_common, but we don't want to include the interception headers4988// there. So, just define this function here.4989namespace __sanitizer {4990extern "C" {4991int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {4992  return REAL(pthread_attr_getstack)(attr, addr, size);4993}4994}  // extern "C"4995}  // namespace __sanitizer4996 4997#define INIT_PTHREAD_ATTR_GET                             \4998  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \4999  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \5000  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \5001  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \5002  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);5003#else5004#define INIT_PTHREAD_ATTR_GET5005#endif5006 5007#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED5008INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)5009INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))5010 5011#define INIT_PTHREAD_ATTR_GET_SCHED                      \5012  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \5013  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);5014#else5015#define INIT_PTHREAD_ATTR_GET_SCHED5016#endif5017 5018#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED5019INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))5020 5021#define INIT_PTHREAD_ATTR_GETINHERITSCHED \5022  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);5023#else5024#define INIT_PTHREAD_ATTR_GETINHERITSCHED5025#endif5026 5027#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP5028INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,5029            void *cpuset) {5030  void *ctx;5031  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,5032                           cpuset);5033  // FIXME: under ASan the call below may write to freed memory and corrupt5034  // its metadata. See5035  // https://github.com/google/sanitizers/issues/321.5036  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);5037  if (!res && cpusetsize && cpuset)5038    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);5039  return res;5040}5041 5042#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \5043  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);5044#else5045#define INIT_PTHREAD_ATTR_GETAFFINITY_NP5046#endif5047 5048#if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP5049INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize,5050            void *cpuset) {5051  void *ctx;5052  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize,5053                           cpuset);5054  // FIXME: under ASan the call below may write to freed memory and corrupt5055  // its metadata. See5056  // https://github.com/google/sanitizers/issues/321.5057  int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset);5058  if (!res && cpusetsize && cpuset)5059    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);5060  return res;5061}5062 5063#define INIT_PTHREAD_GETAFFINITY_NP \5064  COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np);5065#else5066#define INIT_PTHREAD_GETAFFINITY_NP5067#endif5068 5069#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED5070INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))5071#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \5072  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);5073#else5074#define INIT_PTHREAD_MUTEXATTR_GETPSHARED5075#endif5076 5077#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE5078INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))5079#define INIT_PTHREAD_MUTEXATTR_GETTYPE \5080  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);5081#else5082#define INIT_PTHREAD_MUTEXATTR_GETTYPE5083#endif5084 5085#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL5086INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))5087#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \5088  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);5089#else5090#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL5091#endif5092 5093#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING5094INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))5095#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \5096  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);5097#else5098#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING5099#endif5100 5101#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST5102INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))5103#define INIT_PTHREAD_MUTEXATTR_GETROBUST \5104  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);5105#else5106#define INIT_PTHREAD_MUTEXATTR_GETROBUST5107#endif5108 5109#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP5110INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))5111#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \5112  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);5113#else5114#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP5115#endif5116 5117#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED5118INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))5119#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \5120  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);5121#else5122#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED5123#endif5124 5125#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP5126INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))5127#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \5128  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);5129#else5130#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP5131#endif5132 5133#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED5134INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))5135#define INIT_PTHREAD_CONDATTR_GETPSHARED \5136  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);5137#else5138#define INIT_PTHREAD_CONDATTR_GETPSHARED5139#endif5140 5141#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK5142INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))5143#define INIT_PTHREAD_CONDATTR_GETCLOCK \5144  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);5145#else5146#define INIT_PTHREAD_CONDATTR_GETCLOCK5147#endif5148 5149#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED5150INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android5151#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \5152  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);5153#else5154#define INIT_PTHREAD_BARRIERATTR_GETPSHARED5155#endif5156 5157#if SANITIZER_INTERCEPT_TMPNAM5158INTERCEPTOR(char *, tmpnam, char *s) {5159  void *ctx;5160  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);5161  char *res = REAL(tmpnam)(s);5162  if (res) {5163    if (s)5164      // FIXME: under ASan the call below may write to freed memory and corrupt5165      // its metadata. See5166      // https://github.com/google/sanitizers/issues/321.5167      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);5168    else5169      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5170  }5171  return res;5172}5173#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);5174#else5175#define INIT_TMPNAM5176#endif5177 5178#if SANITIZER_INTERCEPT_TMPNAM_R5179INTERCEPTOR(char *, tmpnam_r, char *s) {5180  void *ctx;5181  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);5182  // FIXME: under ASan the call below may write to freed memory and corrupt5183  // its metadata. See5184  // https://github.com/google/sanitizers/issues/321.5185  char *res = REAL(tmpnam_r)(s);5186  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);5187  return res;5188}5189#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);5190#else5191#define INIT_TMPNAM_R5192#endif5193 5194#if SANITIZER_INTERCEPT_PTSNAME5195INTERCEPTOR(char *, ptsname, int fd) {5196  void *ctx;5197  COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);5198  char *res = REAL(ptsname)(fd);5199  if (res != nullptr)5200    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5201  return res;5202}5203#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);5204#else5205#define INIT_PTSNAME5206#endif5207 5208#if SANITIZER_INTERCEPT_PTSNAME_R5209INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {5210  void *ctx;5211  COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);5212  int res = REAL(ptsname_r)(fd, name, namesize);5213  if (res == 0)5214    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);5215  return res;5216}5217#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);5218#else5219#define INIT_PTSNAME_R5220#endif5221 5222#if SANITIZER_INTERCEPT_TTYNAME5223INTERCEPTOR(char *, ttyname, int fd) {5224  void *ctx;5225  COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);5226  char *res = REAL(ttyname)(fd);5227  if (res != nullptr)5228    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5229  return res;5230}5231#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);5232#else5233#define INIT_TTYNAME5234#endif5235 5236#if SANITIZER_INTERCEPT_TTYNAME_R5237INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {5238  void *ctx;5239  COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);5240  int res = REAL(ttyname_r)(fd, name, namesize);5241  if (res == 0)5242    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);5243  return res;5244}5245#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);5246#else5247#define INIT_TTYNAME_R5248#endif5249 5250#if SANITIZER_INTERCEPT_TEMPNAM5251INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {5252  void *ctx;5253  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);5254  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1);5255  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1);5256  char *res = REAL(tempnam)(dir, pfx);5257  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);5258  return res;5259}5260#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);5261#else5262#define INIT_TEMPNAM5263#endif5264 5265#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD5266INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {5267  void *ctx;5268  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);5269  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);5270  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);5271  return REAL(pthread_setname_np)(thread, name);5272}5273#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);5274#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD5275INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {5276  void *ctx;5277  char newname[32]; // PTHREAD_MAX_NAMELEN_NP=325278  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);5279  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);5280  internal_snprintf(newname, sizeof(newname), name, arg);5281  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);5282  return REAL(pthread_setname_np)(thread, name, arg);5283}5284#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);5285#else5286#define INIT_PTHREAD_SETNAME_NP5287#endif5288 5289#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP5290INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {5291  void *ctx;5292  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);5293  int res = REAL(pthread_getname_np)(thread, name, len);5294  if (!res)5295    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);5296  return res;5297}5298#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);5299#else5300#define INIT_PTHREAD_GETNAME_NP5301#endif5302 5303#if SANITIZER_INTERCEPT_SINCOS5304INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {5305  void *ctx;5306  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);5307  // FIXME: under ASan the call below may write to freed memory and corrupt5308  // its metadata. See5309  // https://github.com/google/sanitizers/issues/321.5310  REAL(sincos)(x, sin, cos);5311  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5312  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5313}5314INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {5315  void *ctx;5316  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);5317  // FIXME: under ASan the call below may write to freed memory and corrupt5318  // its metadata. See5319  // https://github.com/google/sanitizers/issues/321.5320  REAL(sincosf)(x, sin, cos);5321  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5322  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5323}5324INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {5325  void *ctx;5326  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);5327  // FIXME: under ASan the call below may write to freed memory and corrupt5328  // its metadata. See5329  // https://github.com/google/sanitizers/issues/321.5330  REAL(sincosl)(x, sin, cos);5331  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));5332  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));5333}5334#define INIT_SINCOS                   \5335  COMMON_INTERCEPT_FUNCTION(sincos);  \5336  COMMON_INTERCEPT_FUNCTION(sincosf); \5337  COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);5338#else5339#define INIT_SINCOS5340#endif5341 5342#if SANITIZER_INTERCEPT_REMQUO5343INTERCEPTOR(double, remquo, double x, double y, int *quo) {5344  void *ctx;5345  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);5346  // FIXME: under ASan the call below may write to freed memory and corrupt5347  // its metadata. See5348  // https://github.com/google/sanitizers/issues/321.5349  double res = REAL(remquo)(x, y, quo);5350  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5351  return res;5352}5353INTERCEPTOR(float, remquof, float x, float y, int *quo) {5354  void *ctx;5355  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);5356  // FIXME: under ASan the call below may write to freed memory and corrupt5357  // its metadata. See5358  // https://github.com/google/sanitizers/issues/321.5359  float res = REAL(remquof)(x, y, quo);5360  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5361  return res;5362}5363#define INIT_REMQUO                   \5364  COMMON_INTERCEPT_FUNCTION(remquo);  \5365  COMMON_INTERCEPT_FUNCTION(remquof);5366#else5367#define INIT_REMQUO5368#endif5369 5370#if SANITIZER_INTERCEPT_REMQUOL5371INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {5372  void *ctx;5373  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);5374  // FIXME: under ASan the call below may write to freed memory and corrupt5375  // its metadata. See5376  // https://github.com/google/sanitizers/issues/321.5377  long double res = REAL(remquol)(x, y, quo);5378  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));5379  return res;5380}5381#define INIT_REMQUOL                  \5382  COMMON_INTERCEPT_FUNCTION_LDBL(remquol);5383#else5384#define INIT_REMQUOL5385#endif5386 5387#if SANITIZER_INTERCEPT_LGAMMA5388extern int signgam;5389INTERCEPTOR(double, lgamma, double x) {5390  void *ctx;5391  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);5392  double res = REAL(lgamma)(x);5393  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5394  return res;5395}5396INTERCEPTOR(float, lgammaf, float x) {5397  void *ctx;5398  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);5399  float res = REAL(lgammaf)(x);5400  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5401  return res;5402}5403#define INIT_LGAMMA                   \5404  COMMON_INTERCEPT_FUNCTION(lgamma);  \5405  COMMON_INTERCEPT_FUNCTION(lgammaf);5406#else5407#define INIT_LGAMMA5408#endif5409 5410#if SANITIZER_INTERCEPT_LGAMMAL5411INTERCEPTOR(long double, lgammal, long double x) {5412  void *ctx;5413  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);5414  long double res = REAL(lgammal)(x);5415  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));5416  return res;5417}5418#define INIT_LGAMMAL                  \5419  COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);5420#else5421#define INIT_LGAMMAL5422#endif5423 5424#if SANITIZER_INTERCEPT_LGAMMA_R5425INTERCEPTOR(double, lgamma_r, double x, int *signp) {5426  void *ctx;5427  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);5428  // FIXME: under ASan the call below may write to freed memory and corrupt5429  // its metadata. See5430  // https://github.com/google/sanitizers/issues/321.5431  double res = REAL(lgamma_r)(x, signp);5432  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5433  return res;5434}5435INTERCEPTOR(float, lgammaf_r, float x, int *signp) {5436  void *ctx;5437  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);5438  // FIXME: under ASan the call below may write to freed memory and corrupt5439  // its metadata. See5440  // https://github.com/google/sanitizers/issues/321.5441  float res = REAL(lgammaf_r)(x, signp);5442  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5443  return res;5444}5445#define INIT_LGAMMA_R                   \5446  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \5447  COMMON_INTERCEPT_FUNCTION(lgammaf_r);5448#else5449#define INIT_LGAMMA_R5450#endif5451 5452#if SANITIZER_INTERCEPT_LGAMMAL_R5453INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {5454  void *ctx;5455  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);5456  // FIXME: under ASan the call below may write to freed memory and corrupt5457  // its metadata. See5458  // https://github.com/google/sanitizers/issues/321.5459  long double res = REAL(lgammal_r)(x, signp);5460  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));5461  return res;5462}5463#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);5464#else5465#define INIT_LGAMMAL_R5466#endif5467 5468#if SANITIZER_INTERCEPT_DRAND48_R5469INTERCEPTOR(int, drand48_r, void *buffer, double *result) {5470  void *ctx;5471  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);5472  // FIXME: under ASan the call below may write to freed memory and corrupt5473  // its metadata. See5474  // https://github.com/google/sanitizers/issues/321.5475  int res = REAL(drand48_r)(buffer, result);5476  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));5477  return res;5478}5479INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {5480  void *ctx;5481  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);5482  // FIXME: under ASan the call below may write to freed memory and corrupt5483  // its metadata. See5484  // https://github.com/google/sanitizers/issues/321.5485  int res = REAL(lrand48_r)(buffer, result);5486  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));5487  return res;5488}5489#define INIT_DRAND48_R                  \5490  COMMON_INTERCEPT_FUNCTION(drand48_r); \5491  COMMON_INTERCEPT_FUNCTION(lrand48_r);5492#else5493#define INIT_DRAND48_R5494#endif5495 5496#if SANITIZER_INTERCEPT_RAND_R5497INTERCEPTOR(int, rand_r, unsigned *seedp) {5498  void *ctx;5499  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);5500  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));5501  return REAL(rand_r)(seedp);5502}5503#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);5504#else5505#define INIT_RAND_R5506#endif5507 5508#if SANITIZER_INTERCEPT_GETLINE5509INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {5510  void *ctx;5511  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);5512  // FIXME: under ASan the call below may write to freed memory and corrupt5513  // its metadata. See5514  // https://github.com/google/sanitizers/issues/321.5515  SSIZE_T res = REAL(getline)(lineptr, n, stream);5516  if (res > 0) {5517    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));5518    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));5519    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);5520  }5521  return res;5522}5523 5524// FIXME: under ASan the call below may write to freed memory and corrupt its5525// metadata. See5526// https://github.com/google/sanitizers/issues/321.5527#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \5528  {                                                                            \5529    void *ctx;                                                                 \5530    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \5531    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \5532    if (res > 0) {                                                             \5533      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \5534      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \5535      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \5536    }                                                                          \5537    return res;                                                                \5538  }5539 5540INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,5541            void *stream)5542GETDELIM_INTERCEPTOR_IMPL(__getdelim)5543 5544// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor5545// with its own body.5546INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,5547            void *stream)5548GETDELIM_INTERCEPTOR_IMPL(getdelim)5549 5550#define INIT_GETLINE                     \5551  COMMON_INTERCEPT_FUNCTION(getline);    \5552  COMMON_INTERCEPT_FUNCTION(__getdelim); \5553  COMMON_INTERCEPT_FUNCTION(getdelim);5554#else5555#define INIT_GETLINE5556#endif5557 5558#if SANITIZER_INTERCEPT_ICONV5559INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,5560            char **outbuf, SIZE_T *outbytesleft) {5561  void *ctx;5562  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,5563                           outbytesleft);5564  if (inbytesleft)5565    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));5566  if (inbuf && inbytesleft)5567    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);5568  if (outbytesleft)5569    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));5570  void *outbuf_orig = outbuf ? *outbuf : nullptr;5571  // FIXME: under ASan the call below may write to freed memory and corrupt5572  // its metadata. See5573  // https://github.com/google/sanitizers/issues/321.5574  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);5575  if (outbuf && *outbuf > outbuf_orig) {5576    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;5577    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);5578  }5579  return res;5580}5581#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);5582#else5583#define INIT_ICONV5584#endif5585 5586#if SANITIZER_INTERCEPT_TIMES5587INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {5588  void *ctx;5589  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);5590  // FIXME: under ASan the call below may write to freed memory and corrupt5591  // its metadata. See5592  // https://github.com/google/sanitizers/issues/321.5593  __sanitizer_clock_t res = REAL(times)(tms);5594  if (res != (__sanitizer_clock_t)-1 && tms)5595    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);5596  return res;5597}5598#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);5599#else5600#define INIT_TIMES5601#endif5602 5603#if SANITIZER_S390 && \5604    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)5605extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));5606DEFINE_REAL(uptr, __tls_get_offset, void *arg)5607#endif5608 5609#if SANITIZER_INTERCEPT_TLS_GET_ADDR5610#if !SANITIZER_S3905611#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)5612// If you see any crashes around this functions, there are 2 known issues with5613// it: 1. __tls_get_addr can be called with mis-aligned stack due to:5614// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=580665615// 2. It can be called recursively if sanitizer code uses __tls_get_addr5616// to access thread local variables (it should not happen normally,5617// because sanitizers use initial-exec tls model).5618INTERCEPTOR(void *, __tls_get_addr, void *arg) {5619  void *ctx;5620  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);5621  void *res = REAL(__tls_get_addr)(arg);5622  uptr tls_begin, tls_end;5623  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);5624  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);5625  if (dtv) {5626    // New DTLS block has been allocated.5627    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);5628  }5629  return res;5630}5631#if SANITIZER_PPC5632// On PowerPC, we also need to intercept __tls_get_addr_opt, which has5633// mostly the same semantics as __tls_get_addr, but its presence enables5634// some optimizations in linker (which are safe to ignore here).5635INTERCEPTOR(void *, __tls_get_addr_opt, void *arg) ALIAS(WRAP(__tls_get_addr));5636#endif5637#else // SANITIZER_S3905638// On s390, we have to intercept two functions here:5639// - __tls_get_addr_internal, which is a glibc-internal function that is like5640//   the usual __tls_get_addr, but returns a TP-relative offset instead of5641//   a proper pointer.  It is used by dlsym for TLS symbols.5642// - __tls_get_offset, which is like the above, but also takes a GOT-relative5643//   descriptor offset as an argument instead of a pointer.  GOT address5644//   is passed in r12, so it's necessary to write it in assembly.  This is5645//   the function used by the compiler.5646#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)5647INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {5648  void *ctx;5649  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);5650  uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));5651  uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());5652  void *ptr = reinterpret_cast<void *>(res + tp);5653  uptr tls_begin, tls_end;5654  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);5655  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);5656  if (dtv) {5657    // New DTLS block has been allocated.5658    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);5659  }5660  return res;5661}5662#endif // SANITIZER_S3905663#else5664#define INIT_TLS_GET_ADDR5665#endif5666 5667#if SANITIZER_S390 && \5668    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)5669// We need a hidden symbol aliasing the above, so that we can jump5670// directly to it from the assembly below.5671extern "C" __attribute__((visibility("hidden"))) uptr __tls_get_addr_hidden(5672    void *arg) ALIAS(WRAP(__tls_get_addr_internal));5673extern "C" uptr __tls_get_offset(void *arg);5674extern "C" uptr TRAMPOLINE(__tls_get_offset)(void *arg);5675extern "C" uptr WRAP(__tls_get_offset)(void *arg);5676// Now carefully intercept __tls_get_offset.5677asm(5678  ".text\n"5679// The __intercept_ version has to exist, so that gen_dynamic_list.py5680// exports our symbol.5681  ".weak __tls_get_offset\n"5682  ".set __tls_get_offset, __interceptor___tls_get_offset\n"5683  ".global __interceptor___tls_get_offset\n"5684  ".type __interceptor___tls_get_offset, @function\n"5685  "__interceptor___tls_get_offset:\n"5686#ifdef __s390x__5687  "la %r2, 0(%r2,%r12)\n"5688  "jg __tls_get_addr_hidden\n"5689#else5690  "basr %r3,0\n"5691  "0: la %r2,0(%r2,%r12)\n"5692  "l %r4,1f-0b(%r3)\n"5693  "b 0(%r4,%r3)\n"5694  "1: .long __tls_get_addr_hidden - 0b\n"5695#endif5696  ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"5697// Assembly wrapper to call REAL(__tls_get_offset)(arg)5698  ".type __tls_get_offset_wrapper, @function\n"5699  "__tls_get_offset_wrapper:\n"5700#ifdef __s390x__5701  "sgr %r2,%r12\n"5702#else5703  "sr %r2,%r12\n"5704#endif5705  "br %r3\n"5706  ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"5707);5708#endif5709 5710#if SANITIZER_INTERCEPT_LISTXATTR5711INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {5712  void *ctx;5713  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);5714  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5715  // FIXME: under ASan the call below may write to freed memory and corrupt5716  // its metadata. See5717  // https://github.com/google/sanitizers/issues/321.5718  SSIZE_T res = REAL(listxattr)(path, list, size);5719  // Here and below, size == 0 is a special case where nothing is written to the5720  // buffer, and res contains the desired buffer size.5721  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5722  return res;5723}5724INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {5725  void *ctx;5726  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);5727  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5728  // FIXME: under ASan the call below may write to freed memory and corrupt5729  // its metadata. See5730  // https://github.com/google/sanitizers/issues/321.5731  SSIZE_T res = REAL(llistxattr)(path, list, size);5732  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5733  return res;5734}5735INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {5736  void *ctx;5737  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);5738  // FIXME: under ASan the call below may write to freed memory and corrupt5739  // its metadata. See5740  // https://github.com/google/sanitizers/issues/321.5741  SSIZE_T res = REAL(flistxattr)(fd, list, size);5742  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);5743  return res;5744}5745#define INIT_LISTXATTR                   \5746  COMMON_INTERCEPT_FUNCTION(listxattr);  \5747  COMMON_INTERCEPT_FUNCTION(llistxattr); \5748  COMMON_INTERCEPT_FUNCTION(flistxattr);5749#else5750#define INIT_LISTXATTR5751#endif5752 5753#if SANITIZER_INTERCEPT_GETXATTR5754INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,5755            SIZE_T size) {5756  void *ctx;5757  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);5758  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5759  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5760  // FIXME: under ASan the call below may write to freed memory and corrupt5761  // its metadata. See5762  // https://github.com/google/sanitizers/issues/321.5763  SSIZE_T res = REAL(getxattr)(path, name, value, size);5764  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5765  return res;5766}5767INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,5768            SIZE_T size) {5769  void *ctx;5770  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);5771  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);5772  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5773  // FIXME: under ASan the call below may write to freed memory and corrupt5774  // its metadata. See5775  // https://github.com/google/sanitizers/issues/321.5776  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);5777  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5778  return res;5779}5780INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,5781            SIZE_T size) {5782  void *ctx;5783  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);5784  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);5785  // FIXME: under ASan the call below may write to freed memory and corrupt5786  // its metadata. See5787  // https://github.com/google/sanitizers/issues/321.5788  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);5789  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);5790  return res;5791}5792#define INIT_GETXATTR                   \5793  COMMON_INTERCEPT_FUNCTION(getxattr);  \5794  COMMON_INTERCEPT_FUNCTION(lgetxattr); \5795  COMMON_INTERCEPT_FUNCTION(fgetxattr);5796#else5797#define INIT_GETXATTR5798#endif5799 5800#if SANITIZER_INTERCEPT_GETRESID5801INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {5802  void *ctx;5803  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);5804  // FIXME: under ASan the call below may write to freed memory and corrupt5805  // its metadata. See5806  // https://github.com/google/sanitizers/issues/321.5807  int res = REAL(getresuid)(ruid, euid, suid);5808  if (res >= 0) {5809    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);5810    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);5811    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);5812  }5813  return res;5814}5815INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {5816  void *ctx;5817  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);5818  // FIXME: under ASan the call below may write to freed memory and corrupt5819  // its metadata. See5820  // https://github.com/google/sanitizers/issues/321.5821  int res = REAL(getresgid)(rgid, egid, sgid);5822  if (res >= 0) {5823    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);5824    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);5825    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);5826  }5827  return res;5828}5829#define INIT_GETRESID                   \5830  COMMON_INTERCEPT_FUNCTION(getresuid); \5831  COMMON_INTERCEPT_FUNCTION(getresgid);5832#else5833#define INIT_GETRESID5834#endif5835 5836#if SANITIZER_INTERCEPT_GETIFADDRS5837// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to5838// intercept freeifaddrs(). If that ceases to be the case, we might need to5839// intercept it to poison the memory again.5840INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {5841  void *ctx;5842  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);5843  // FIXME: under ASan the call below may write to freed memory and corrupt5844  // its metadata. See5845  // https://github.com/google/sanitizers/issues/321.5846  int res = REAL(getifaddrs)(ifap);5847  if (res == 0 && ifap) {5848    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));5849    __sanitizer_ifaddrs *p = *ifap;5850    while (p) {5851      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));5852      if (p->ifa_name)5853        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,5854                                       internal_strlen(p->ifa_name) + 1);5855      if (p->ifa_addr)5856        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);5857      if (p->ifa_netmask)5858        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);5859      // On Linux this is a union, but the other member also points to a5860      // struct sockaddr, so the following is sufficient.5861      if (p->ifa_dstaddr)5862        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);5863      // FIXME(smatveev): Unpoison p->ifa_data as well.5864      p = p->ifa_next;5865    }5866  }5867  return res;5868}5869#define INIT_GETIFADDRS                  \5870  COMMON_INTERCEPT_FUNCTION(getifaddrs);5871#else5872#define INIT_GETIFADDRS5873#endif5874 5875#if SANITIZER_INTERCEPT_IF_INDEXTONAME5876INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {5877  void *ctx;5878  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);5879  // FIXME: under ASan the call below may write to freed memory and corrupt5880  // its metadata. See5881  // https://github.com/google/sanitizers/issues/321.5882  char *res = REAL(if_indextoname)(ifindex, ifname);5883  if (res && ifname)5884    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1);5885  return res;5886}5887INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {5888  void *ctx;5889  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);5890  if (ifname)5891    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1);5892  return REAL(if_nametoindex)(ifname);5893}5894#define INIT_IF_INDEXTONAME                  \5895  COMMON_INTERCEPT_FUNCTION(if_indextoname); \5896  COMMON_INTERCEPT_FUNCTION(if_nametoindex);5897#else5898#define INIT_IF_INDEXTONAME5899#endif5900 5901#if SANITIZER_INTERCEPT_CAPGET5902INTERCEPTOR(int, capget, void *hdrp, void *datap) {5903  void *ctx;5904  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);5905  if (hdrp)5906    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);5907  // FIXME: under ASan the call below may write to freed memory and corrupt5908  // its metadata. See5909  // https://github.com/google/sanitizers/issues/321.5910  int res = REAL(capget)(hdrp, datap);5911  if (res == 0 && datap) {5912    unsigned datasz = __user_cap_data_struct_sz(hdrp);5913    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, datasz);5914  }5915  // We can also return -1 and write to hdrp->version if the version passed in5916  // hdrp->version is unsupported. But that's not a trivial condition to check,5917  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.5918  return res;5919}5920INTERCEPTOR(int, capset, void *hdrp, const void *datap) {5921  void *ctx;5922  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);5923  if (hdrp)5924    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);5925  if (datap) {5926    unsigned datasz = __user_cap_data_struct_sz(hdrp);5927    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, datasz);5928  }5929  return REAL(capset)(hdrp, datap);5930}5931#define INIT_CAPGET                  \5932  COMMON_INTERCEPT_FUNCTION(capget); \5933  COMMON_INTERCEPT_FUNCTION(capset);5934#else5935#define INIT_CAPGET5936#endif5937 5938#if SANITIZER_INTERCEPT_FTIME5939INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {5940  void *ctx;5941  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);5942  // FIXME: under ASan the call below may write to freed memory and corrupt5943  // its metadata. See5944  // https://github.com/google/sanitizers/issues/321.5945  int res = REAL(ftime)(tp);5946  if (tp)5947    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));5948  return res;5949}5950#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);5951#else5952#define INIT_FTIME5953#endif  // SANITIZER_INTERCEPT_FTIME5954 5955#if SANITIZER_INTERCEPT_XDR5956INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,5957            unsigned size, int op) {5958  void *ctx;5959  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);5960  // FIXME: under ASan the call below may write to freed memory and corrupt5961  // its metadata. See5962  // https://github.com/google/sanitizers/issues/321.5963  REAL(xdrmem_create)(xdrs, addr, size, op);5964  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));5965  if (op == __sanitizer_XDR_ENCODE) {5966    // It's not obvious how much data individual xdr_ routines write.5967    // Simply unpoison the entire target buffer in advance.5968    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);5969  }5970}5971 5972INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {5973  void *ctx;5974  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);5975  // FIXME: under ASan the call below may write to freed memory and corrupt5976  // its metadata. See5977  // https://github.com/google/sanitizers/issues/321.5978  REAL(xdrstdio_create)(xdrs, file, op);5979  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));5980}5981 5982// FIXME: under ASan the call below may write to freed memory and corrupt5983// its metadata. See5984// https://github.com/google/sanitizers/issues/321.5985#define XDR_INTERCEPTOR(F, T)                             \5986  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \5987    void *ctx;                                            \5988    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \5989    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \5990      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \5991    int res = REAL(F)(xdrs, p);                           \5992    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \5993      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \5994    return res;                                           \5995  }5996 5997XDR_INTERCEPTOR(xdr_short, short)5998XDR_INTERCEPTOR(xdr_u_short, unsigned short)5999XDR_INTERCEPTOR(xdr_int, int)6000XDR_INTERCEPTOR(xdr_u_int, unsigned)6001XDR_INTERCEPTOR(xdr_long, long)6002XDR_INTERCEPTOR(xdr_u_long, unsigned long)6003XDR_INTERCEPTOR(xdr_hyper, long long)6004XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)6005XDR_INTERCEPTOR(xdr_longlong_t, long long)6006XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)6007XDR_INTERCEPTOR(xdr_int8_t, u8)6008XDR_INTERCEPTOR(xdr_uint8_t, u8)6009XDR_INTERCEPTOR(xdr_int16_t, u16)6010XDR_INTERCEPTOR(xdr_uint16_t, u16)6011XDR_INTERCEPTOR(xdr_int32_t, u32)6012XDR_INTERCEPTOR(xdr_uint32_t, u32)6013XDR_INTERCEPTOR(xdr_int64_t, u64)6014XDR_INTERCEPTOR(xdr_uint64_t, u64)6015XDR_INTERCEPTOR(xdr_quad_t, long long)6016XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)6017XDR_INTERCEPTOR(xdr_bool, bool)6018XDR_INTERCEPTOR(xdr_enum, int)6019XDR_INTERCEPTOR(xdr_char, char)6020XDR_INTERCEPTOR(xdr_u_char, unsigned char)6021XDR_INTERCEPTOR(xdr_float, float)6022XDR_INTERCEPTOR(xdr_double, double)6023 6024// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,6025// wrapstring, sizeof6026 6027INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,6028            unsigned maxsize) {6029  void *ctx;6030  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);6031  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {6032    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));6033    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));6034    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);6035  }6036  // FIXME: under ASan the call below may write to freed memory and corrupt6037  // its metadata. See6038  // https://github.com/google/sanitizers/issues/321.6039  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);6040  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {6041    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));6042    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));6043    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);6044  }6045  return res;6046}6047 6048INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,6049            unsigned maxsize) {6050  void *ctx;6051  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);6052  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {6053    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));6054    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1);6055  }6056  // FIXME: under ASan the call below may write to freed memory and corrupt6057  // its metadata. See6058  // https://github.com/google/sanitizers/issues/321.6059  int res = REAL(xdr_string)(xdrs, p, maxsize);6060  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {6061    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));6062    if (res && *p)6063      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);6064  }6065  return res;6066}6067 6068#define INIT_XDR                               \6069  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \6070  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \6071  COMMON_INTERCEPT_FUNCTION(xdr_short);        \6072  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \6073  COMMON_INTERCEPT_FUNCTION(xdr_int);          \6074  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \6075  COMMON_INTERCEPT_FUNCTION(xdr_long);         \6076  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \6077  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \6078  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \6079  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \6080  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \6081  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \6082  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \6083  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \6084  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \6085  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \6086  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \6087  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \6088  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \6089  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \6090  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \6091  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \6092  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \6093  COMMON_INTERCEPT_FUNCTION(xdr_char);         \6094  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \6095  COMMON_INTERCEPT_FUNCTION(xdr_float);        \6096  COMMON_INTERCEPT_FUNCTION(xdr_double);       \6097  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \6098  COMMON_INTERCEPT_FUNCTION(xdr_string);6099#else6100#define INIT_XDR6101#endif  // SANITIZER_INTERCEPT_XDR6102 6103#if SANITIZER_INTERCEPT_XDRREC6104typedef int (*xdrrec_cb)(char*, char*, int);6105struct XdrRecWrapper {6106  char *handle;6107  xdrrec_cb rd, wr;6108};6109typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;6110static XdrRecWrapMap *xdrrec_wrap_map;6111 6112static int xdrrec_wr_wrap(char *handle, char *buf, int count) {6113  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6114  COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);6115  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;6116  return wrap->wr(wrap->handle, buf, count);6117}6118 6119static int xdrrec_rd_wrap(char *handle, char *buf, int count) {6120  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6121  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;6122  return wrap->rd(wrap->handle, buf, count);6123}6124 6125// This doesn't apply to the solaris version as it has a different function6126// signature.6127INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,6128            unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),6129            int (*wr)(char*, char*, int)) {6130  void *ctx;6131  COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,6132                           handle, rd, wr);6133  COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);6134 6135  // We can't allocate a wrapper on the stack, as the handle is used outside6136  // this stack frame. So we put it on the heap, and keep track of it with6137  // the HashMap (keyed by x_private). When we later need to xdr_destroy,6138  // we can index the map, free the wrapper, and then clean the map entry.6139  XdrRecWrapper *wrap_data =6140      (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));6141  wrap_data->handle = handle;6142  wrap_data->rd = rd;6143  wrap_data->wr = wr;6144  if (wr)6145    wr = xdrrec_wr_wrap;6146  if (rd)6147    rd = xdrrec_rd_wrap;6148  handle = (char *)wrap_data;6149 6150  REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);6151  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);6152 6153  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);6154  *wrap = wrap_data;6155}6156 6157// We have to intercept this to be able to free wrapper memory;6158// otherwise it's not necessary.6159INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {6160  void *ctx;6161  COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);6162 6163  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);6164  InternalFree(*wrap);6165  REAL(xdr_destroy)(xdr);6166}6167#define INIT_XDRREC_LINUX \6168  static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \6169  xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \6170  COMMON_INTERCEPT_FUNCTION(xdrrec_create); \6171  COMMON_INTERCEPT_FUNCTION(xdr_destroy);6172#else6173#define INIT_XDRREC_LINUX6174#endif6175 6176#if SANITIZER_INTERCEPT_TSEARCH6177INTERCEPTOR(void *, tsearch, void *key, void **rootp,6178            int (*compar)(const void *, const void *)) {6179  void *ctx;6180  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);6181  // FIXME: under ASan the call below may write to freed memory and corrupt6182  // its metadata. See6183  // https://github.com/google/sanitizers/issues/321.6184  void *res = REAL(tsearch)(key, rootp, compar);6185  if (res && *(void **)res == key)6186    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));6187  return res;6188}6189#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);6190#else6191#define INIT_TSEARCH6192#endif6193 6194#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \6195    SANITIZER_INTERCEPT_OPEN_MEMSTREAM6196void unpoison_file(__sanitizer_FILE *fp) {6197#if SANITIZER_HAS_STRUCT_FILE6198  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));6199#if SANITIZER_NETBSD6200  if (fp->_bf._base && fp->_bf._size > 0)6201    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,6202                                        fp->_bf._size);6203#else6204  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)6205    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,6206                                        fp->_IO_read_end - fp->_IO_read_base);6207  if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)6208    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,6209                                        fp->_IO_write_end - fp->_IO_write_base);6210#endif6211#endif  // SANITIZER_HAS_STRUCT_FILE6212}6213#endif6214 6215#if SANITIZER_INTERCEPT_LIBIO_INTERNALS6216// These guys are called when a .c source is built with -O2.6217INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {6218  void *ctx;6219  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);6220  int res = REAL(__uflow)(fp);6221  unpoison_file(fp);6222  return res;6223}6224INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {6225  void *ctx;6226  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);6227  int res = REAL(__underflow)(fp);6228  unpoison_file(fp);6229  return res;6230}6231INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {6232  void *ctx;6233  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);6234  int res = REAL(__overflow)(fp, ch);6235  unpoison_file(fp);6236  return res;6237}6238INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {6239  void *ctx;6240  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);6241  int res = REAL(__wuflow)(fp);6242  unpoison_file(fp);6243  return res;6244}6245INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {6246  void *ctx;6247  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);6248  int res = REAL(__wunderflow)(fp);6249  unpoison_file(fp);6250  return res;6251}6252INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {6253  void *ctx;6254  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);6255  int res = REAL(__woverflow)(fp, ch);6256  unpoison_file(fp);6257  return res;6258}6259#define INIT_LIBIO_INTERNALS               \6260  COMMON_INTERCEPT_FUNCTION(__uflow);      \6261  COMMON_INTERCEPT_FUNCTION(__underflow);  \6262  COMMON_INTERCEPT_FUNCTION(__overflow);   \6263  COMMON_INTERCEPT_FUNCTION(__wuflow);     \6264  COMMON_INTERCEPT_FUNCTION(__wunderflow); \6265  COMMON_INTERCEPT_FUNCTION(__woverflow);6266#else6267#define INIT_LIBIO_INTERNALS6268#endif6269 6270#if SANITIZER_INTERCEPT_FOPEN6271INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {6272  void *ctx;6273  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);6274  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6275  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6276  __sanitizer_FILE *res = REAL(fopen)(path, mode);6277  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6278  if (res) unpoison_file(res);6279  return res;6280}6281INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {6282  void *ctx;6283  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);6284  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6285  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);6286  if (res) unpoison_file(res);6287  return res;6288}6289INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,6290            __sanitizer_FILE *fp) {6291  void *ctx;6292  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);6293  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6294  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6295  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6296  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);6297  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6298  if (res) unpoison_file(res);6299  return res;6300}6301#define INIT_FOPEN                   \6302  COMMON_INTERCEPT_FUNCTION(fopen);  \6303  COMMON_INTERCEPT_FUNCTION(fdopen); \6304  COMMON_INTERCEPT_FUNCTION(freopen);6305#else6306#define INIT_FOPEN6307#endif6308 6309#if SANITIZER_INTERCEPT_FLOPEN6310INTERCEPTOR(int, flopen, const char *path, int flags, ...) {6311  void *ctx;6312  va_list ap;6313  va_start(ap, flags);6314  u16 mode = static_cast<u16>(va_arg(ap, u32));6315  va_end(ap);6316  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);6317  if (path) {6318    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6319  }6320  return COMMON_INTERCEPTOR_BLOCK_REAL(flopen)(path, flags, mode);6321}6322 6323INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {6324  void *ctx;6325  va_list ap;6326  va_start(ap, flags);6327  u16 mode = static_cast<u16>(va_arg(ap, u32));6328  va_end(ap);6329  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);6330  if (path) {6331    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6332  }6333  return COMMON_INTERCEPTOR_BLOCK_REAL(flopenat)(dirfd, path, flags, mode);6334}6335 6336#define INIT_FLOPEN    \6337  COMMON_INTERCEPT_FUNCTION(flopen); \6338  COMMON_INTERCEPT_FUNCTION(flopenat);6339#else6340#define INIT_FLOPEN6341#endif6342 6343#if SANITIZER_INTERCEPT_FOPEN646344INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {6345  void *ctx;6346  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);6347  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6348  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6349  __sanitizer_FILE *res = REAL(fopen64)(path, mode);6350  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6351  if (res) unpoison_file(res);6352  return res;6353}6354INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,6355            __sanitizer_FILE *fp) {6356  void *ctx;6357  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);6358  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);6359  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);6360  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6361  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);6362  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);6363  if (res) unpoison_file(res);6364  return res;6365}6366#define INIT_FOPEN64                  \6367  COMMON_INTERCEPT_FUNCTION(fopen64); \6368  COMMON_INTERCEPT_FUNCTION(freopen64);6369#else6370#define INIT_FOPEN646371#endif6372 6373#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM6374INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {6375  void *ctx;6376  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);6377  // FIXME: under ASan the call below may write to freed memory and corrupt6378  // its metadata. See6379  // https://github.com/google/sanitizers/issues/321.6380  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);6381  if (res) {6382    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));6383    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));6384    unpoison_file(res);6385    FileMetadata file = {ptr, sizeloc};6386    SetInterceptorMetadata(res, file);6387  }6388  return res;6389}6390INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,6391            SIZE_T *sizeloc) {6392  void *ctx;6393  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);6394  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);6395  if (res) {6396    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));6397    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));6398    unpoison_file(res);6399    FileMetadata file = {(char **)ptr, sizeloc};6400    SetInterceptorMetadata(res, file);6401  }6402  return res;6403}6404INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,6405            const char *mode) {6406  void *ctx;6407  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);6408  // FIXME: under ASan the call below may write to freed memory and corrupt6409  // its metadata. See6410  // https://github.com/google/sanitizers/issues/321.6411  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);6412  if (res) unpoison_file(res);6413  return res;6414}6415#define INIT_OPEN_MEMSTREAM                   \6416  COMMON_INTERCEPT_FUNCTION(open_memstream);  \6417  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \6418  COMMON_INTERCEPT_FUNCTION(fmemopen);6419#else6420#define INIT_OPEN_MEMSTREAM6421#endif6422 6423#if SANITIZER_INTERCEPT_OBSTACK6424static void initialize_obstack(__sanitizer_obstack *obstack) {6425  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));6426  if (obstack->chunk)6427    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,6428                                        sizeof(*obstack->chunk));6429}6430 6431INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,6432            int align, void *(*alloc_fn)(uptr arg, uptr sz),6433            void (*free_fn)(uptr arg, void *p)) {6434  void *ctx;6435  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,6436                           free_fn);6437  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);6438  if (res) initialize_obstack(obstack);6439  return res;6440}6441INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,6442            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {6443  void *ctx;6444  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,6445                           free_fn);6446  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);6447  if (res) initialize_obstack(obstack);6448  return res;6449}6450INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {6451  void *ctx;6452  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);6453  REAL(_obstack_newchunk)(obstack, length);6454  if (obstack->chunk)6455    COMMON_INTERCEPTOR_INITIALIZE_RANGE(6456        obstack->chunk, obstack->next_free - (char *)obstack->chunk);6457}6458#define INIT_OBSTACK                           \6459  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \6460  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \6461  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);6462#else6463#define INIT_OBSTACK6464#endif6465 6466#if SANITIZER_INTERCEPT_FFLUSH6467INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {6468  void *ctx;6469  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);6470  if (fp)6471    unpoison_file(fp);6472  int res = REAL(fflush)(fp);6473  // FIXME: handle fp == NULL6474  if (fp) {6475    const FileMetadata *m = GetInterceptorMetadata(fp);6476    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);6477  }6478  return res;6479}6480#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);6481#else6482#define INIT_FFLUSH6483#endif6484 6485#if SANITIZER_INTERCEPT_FCLOSE6486INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {6487  void *ctx;6488  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);6489  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);6490  const FileMetadata *m = GetInterceptorMetadata(fp);6491  if (fp)6492    unpoison_file(fp);6493  int res = REAL(fclose)(fp);6494  if (m) {6495    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);6496    DeleteInterceptorMetadata(fp);6497  }6498  return res;6499}6500#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);6501#else6502#define INIT_FCLOSE6503#endif6504 6505#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE6506INTERCEPTOR(void*, dlopen, const char *filename, int flag) {6507  void *ctx;6508  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);6509 6510  if (filename) {6511    COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);6512 6513#  if !SANITIZER_DYNAMIC6514    // We care about a very specific use-case: dladdr on6515    // statically-linked ASan may return <main program>6516    // instead of the library.6517    // We therefore only take effect if the sanitizer is statically6518    // linked, and we don't bother canonicalizing paths because6519    // dladdr should return the same address both times (we assume6520    // the user did not canonicalize the result from dladdr).6521    if (common_flags()->test_only_replace_dlopen_main_program) {6522      VPrintf(1, "dlopen interceptor: filename: %s\n", filename);6523 6524      const char *SelfFName = DladdrSelfFName();6525      VPrintf(1, "dlopen interceptor: DladdrSelfFName: %p %s\n",6526              (const void *)SelfFName, SelfFName);6527 6528      if (SelfFName && internal_strcmp(SelfFName, filename) == 0) {6529        // It's possible they copied the string from dladdr, so6530        // we do a string comparison rather than pointer comparison.6531        VPrintf(1, "dlopen interceptor: replacing %s because it matches %s\n",6532                filename, SelfFName);6533        filename = (char *)0;  // RTLD_DEFAULT6534      }6535    }6536#  endif  // !SANITIZER_DYNAMIC6537  }6538 6539  void *res = COMMON_INTERCEPTOR_DLOPEN(filename, flag);6540  Symbolizer::GetOrInit()->InvalidateModuleList();6541  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);6542  return res;6543}6544 6545INTERCEPTOR(int, dlclose, void *handle) {6546  void *ctx;6547  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);6548  int res = REAL(dlclose)(handle);6549  Symbolizer::GetOrInit()->InvalidateModuleList();6550  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();6551  return res;6552}6553#define INIT_DLOPEN_DLCLOSE          \6554  COMMON_INTERCEPT_FUNCTION(dlopen); \6555  COMMON_INTERCEPT_FUNCTION(dlclose);6556#else6557#define INIT_DLOPEN_DLCLOSE6558#endif6559 6560#if SANITIZER_INTERCEPT_GETPASS6561INTERCEPTOR(char *, getpass, const char *prompt) {6562  void *ctx;6563  COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);6564  if (prompt)6565    COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1);6566  char *res = REAL(getpass)(prompt);6567  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1);6568  return res;6569}6570 6571#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);6572#else6573#define INIT_GETPASS6574#endif6575 6576#if SANITIZER_INTERCEPT_TIMERFD6577INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,6578            void *old_value) {6579  void *ctx;6580  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,6581                           old_value);6582  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);6583  int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);6584  if (res != -1 && old_value)6585    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);6586  return res;6587}6588 6589INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {6590  void *ctx;6591  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);6592  int res = REAL(timerfd_gettime)(fd, curr_value);6593  if (res != -1 && curr_value)6594    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);6595  return res;6596}6597#define INIT_TIMERFD                          \6598  COMMON_INTERCEPT_FUNCTION(timerfd_settime); \6599  COMMON_INTERCEPT_FUNCTION(timerfd_gettime);6600#else6601#define INIT_TIMERFD6602#endif6603 6604#if SANITIZER_INTERCEPT_MLOCKX6605// Linux kernel has a bug that leads to kernel deadlock if a process6606// maps TBs of memory and then calls mlock().6607static void MlockIsUnsupported() {6608  static atomic_uint8_t printed;6609  if (atomic_exchange(&printed, 1, memory_order_relaxed))6610    return;6611  VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",6612          SanitizerToolName);6613}6614 6615INTERCEPTOR(int, mlock, const void *addr, usize len) {6616  MlockIsUnsupported();6617  return 0;6618}6619 6620INTERCEPTOR(int, munlock, const void *addr, usize len) {6621  MlockIsUnsupported();6622  return 0;6623}6624 6625INTERCEPTOR(int, mlockall, int flags) {6626  MlockIsUnsupported();6627  return 0;6628}6629 6630INTERCEPTOR(int, munlockall, void) {6631  MlockIsUnsupported();6632  return 0;6633}6634 6635#define INIT_MLOCKX                                                            \6636  COMMON_INTERCEPT_FUNCTION(mlock);                                            \6637  COMMON_INTERCEPT_FUNCTION(munlock);                                          \6638  COMMON_INTERCEPT_FUNCTION(mlockall);                                         \6639  COMMON_INTERCEPT_FUNCTION(munlockall);6640 6641#else6642#define INIT_MLOCKX6643#endif  // SANITIZER_INTERCEPT_MLOCKX6644 6645#if SANITIZER_INTERCEPT_FOPENCOOKIE6646struct WrappedCookie {6647  void *real_cookie;6648  __sanitizer_cookie_io_functions_t real_io_funcs;6649};6650 6651static uptr wrapped_read(void *cookie, char *buf, uptr size) {6652  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6653  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6654  __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;6655  return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;6656}6657 6658static uptr wrapped_write(void *cookie, const char *buf, uptr size) {6659  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6660  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6661  __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;6662  return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;6663}6664 6665static int wrapped_seek(void *cookie, u64 *offset, int whence) {6666  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);6667  COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));6668  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6669  __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;6670  return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)6671                   : -1;6672}6673 6674static int wrapped_close(void *cookie) {6675  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);6676  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;6677  __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;6678  int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;6679  InternalFree(wrapped_cookie);6680  return res;6681}6682 6683INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,6684            __sanitizer_cookie_io_functions_t io_funcs) {6685  void *ctx;6686  COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);6687  WrappedCookie *wrapped_cookie =6688      (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));6689  wrapped_cookie->real_cookie = cookie;6690  wrapped_cookie->real_io_funcs = io_funcs;6691  __sanitizer_FILE *res =6692      REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,6693                                               wrapped_seek, wrapped_close});6694  return res;6695}6696 6697#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);6698#else6699#define INIT_FOPENCOOKIE6700#endif  // SANITIZER_INTERCEPT_FOPENCOOKIE6701 6702#if SANITIZER_INTERCEPT_SEM6703INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {6704  void *ctx;6705  COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);6706  // Workaround a bug in glibc's "old" semaphore implementation by6707  // zero-initializing the sem_t contents. This has to be done here because6708  // interceptors bind to the lowest version before glibc 2.36, hitting the6709  // buggy code path while the non-sanitized build of the same code works fine.6710  REAL(memset)(s, 0, sizeof(*s));6711  int res = REAL(sem_init)(s, pshared, value);6712  return res;6713}6714 6715INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {6716  void *ctx;6717  COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);6718  int res = REAL(sem_destroy)(s);6719  return res;6720}6721 6722INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {6723  void *ctx;6724  COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);6725  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);6726  if (res == 0) {6727    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6728  }6729  return res;6730}6731 6732INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {6733  void *ctx;6734  COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);6735  int res = REAL(sem_trywait)(s);6736  if (res == 0) {6737    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6738  }6739  return res;6740}6741 6742INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {6743  void *ctx;6744  COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);6745  COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);6746  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);6747  if (res == 0) {6748    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6749  }6750  return res;6751}6752 6753INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {6754  void *ctx;6755  COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);6756  COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);6757  int res = REAL(sem_post)(s);6758  return res;6759}6760 6761INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {6762  void *ctx;6763  COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);6764  int res = REAL(sem_getvalue)(s, sval);6765  if (res == 0) {6766    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);6767    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));6768  }6769  return res;6770}6771 6772INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {6773  void *ctx;6774  va_list ap;6775  va_start(ap, oflag);6776  u32 mode = va_arg(ap, u32);6777  u32 value = va_arg(ap, u32);6778  COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);6779  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);6780  __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);6781  if (s)6782    COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));6783  va_end(ap);6784  return s;6785}6786 6787INTERCEPTOR(int, sem_unlink, const char *name) {6788  void *ctx;6789  COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);6790  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);6791  return REAL(sem_unlink)(name);6792}6793 6794#  define INIT_SEM                            \6795    COMMON_INTERCEPT_FUNCTION(sem_init);      \6796    COMMON_INTERCEPT_FUNCTION(sem_destroy);   \6797    COMMON_INTERCEPT_FUNCTION(sem_wait);      \6798    COMMON_INTERCEPT_FUNCTION(sem_trywait);   \6799    COMMON_INTERCEPT_FUNCTION(sem_timedwait); \6800    COMMON_INTERCEPT_FUNCTION(sem_post);      \6801    COMMON_INTERCEPT_FUNCTION(sem_getvalue);  \6802    COMMON_INTERCEPT_FUNCTION(sem_open);      \6803    COMMON_INTERCEPT_FUNCTION(sem_unlink);6804#else6805#  define INIT_SEM6806#endif  // SANITIZER_INTERCEPT_SEM6807 6808#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL6809INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {6810  void *ctx;6811  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);6812  int res = REAL(pthread_setcancelstate)(state, oldstate);6813  if (res == 0 && oldstate != nullptr)6814    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));6815  return res;6816}6817 6818INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {6819  void *ctx;6820  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);6821  int res = REAL(pthread_setcanceltype)(type, oldtype);6822  if (res == 0 && oldtype != nullptr)6823    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));6824  return res;6825}6826#define INIT_PTHREAD_SETCANCEL                                                 \6827  COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \6828  COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);6829#else6830#define INIT_PTHREAD_SETCANCEL6831#endif6832 6833#if SANITIZER_INTERCEPT_MINCORE6834INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {6835  void *ctx;6836  COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);6837  int res = REAL(mincore)(addr, length, vec);6838  if (res == 0) {6839    uptr page_size = GetPageSizeCached();6840    uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;6841    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);6842  }6843  return res;6844}6845#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);6846#else6847#define INIT_MINCORE6848#endif6849 6850#if SANITIZER_INTERCEPT_PROCESS_VM_READV6851INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,6852            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,6853            uptr flags) {6854  void *ctx;6855  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,6856                           remote_iov, riovcnt, flags);6857  SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,6858                                       riovcnt, flags);6859  if (res > 0)6860    write_iovec(ctx, local_iov, liovcnt, res);6861  return res;6862}6863 6864INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,6865            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,6866            uptr flags) {6867  void *ctx;6868  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,6869                           remote_iov, riovcnt, flags);6870  SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,6871                                        riovcnt, flags);6872  if (res > 0)6873    read_iovec(ctx, local_iov, liovcnt, res);6874  return res;6875}6876#define INIT_PROCESS_VM_READV                                                  \6877  COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \6878  COMMON_INTERCEPT_FUNCTION(process_vm_writev);6879#else6880#define INIT_PROCESS_VM_READV6881#endif6882 6883#if SANITIZER_INTERCEPT_CTERMID6884INTERCEPTOR(char *, ctermid, char *s) {6885  void *ctx;6886  COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);6887  char *res = REAL(ctermid)(s);6888  if (res) {6889    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);6890  }6891  return res;6892}6893#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);6894#else6895#define INIT_CTERMID6896#endif6897 6898#if SANITIZER_INTERCEPT_CTERMID_R6899INTERCEPTOR(char *, ctermid_r, char *s) {6900  void *ctx;6901  COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);6902  char *res = REAL(ctermid_r)(s);6903  if (res) {6904    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);6905  }6906  return res;6907}6908#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);6909#else6910#define INIT_CTERMID_R6911#endif6912 6913#if SANITIZER_INTERCEPT_RECV_RECVFROM6914INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {6915  void *ctx;6916  COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);6917  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6918  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recv)(fd, buf, len, flags);6919  if (res > 0) {6920    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));6921  }6922  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);6923  return res;6924}6925 6926INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,6927            void *srcaddr, int *addrlen) {6928  void *ctx;6929  COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,6930                           addrlen);6931  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6932  SIZE_T srcaddr_sz;6933  if (srcaddr) srcaddr_sz = *addrlen;6934  (void)srcaddr_sz;  // prevent "set but not used" warning6935  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(recvfrom)(fd, buf, len, flags,6936                                                        srcaddr, addrlen);6937  if (res > 0)6938    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));6939  if (res >= 0 && srcaddr)6940    COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,6941                                        Min((SIZE_T)*addrlen, srcaddr_sz));6942  return res;6943}6944#define INIT_RECV_RECVFROM          \6945  COMMON_INTERCEPT_FUNCTION(recv);  \6946  COMMON_INTERCEPT_FUNCTION(recvfrom);6947#else6948#define INIT_RECV_RECVFROM6949#endif6950 6951#if SANITIZER_INTERCEPT_SEND_SENDTO6952INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {6953  void *ctx;6954  COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);6955  if (fd >= 0) {6956    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6957    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);6958  }6959  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(send)(fd, buf, len, flags);6960  if (common_flags()->intercept_send && res > 0)6961    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));6962  return res;6963}6964 6965INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,6966            void *dstaddr, int addrlen) {6967  void *ctx;6968  COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);6969  if (fd >= 0) {6970    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6971    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);6972  }6973  // Can't check dstaddr as it may have uninitialized padding at the end.6974  SSIZE_T res = COMMON_INTERCEPTOR_BLOCK_REAL(sendto)(fd, buf, len, flags,6975                                                      dstaddr, addrlen);6976  if (common_flags()->intercept_send && res > 0)6977    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));6978  return res;6979}6980#define INIT_SEND_SENDTO           \6981  COMMON_INTERCEPT_FUNCTION(send); \6982  COMMON_INTERCEPT_FUNCTION(sendto);6983#else6984#define INIT_SEND_SENDTO6985#endif6986 6987#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE6988INTERCEPTOR(int, eventfd_read, int fd, __sanitizer_eventfd_t *value) {6989  void *ctx;6990  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);6991  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);6992  int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_read)(fd, value);6993  if (res == 0) {6994    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));6995    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);6996  }6997  return res;6998}6999INTERCEPTOR(int, eventfd_write, int fd, __sanitizer_eventfd_t value) {7000  void *ctx;7001  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);7002  if (fd >= 0) {7003    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);7004    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);7005  }7006  int res = COMMON_INTERCEPTOR_BLOCK_REAL(eventfd_write)(fd, value);7007  return res;7008}7009#define INIT_EVENTFD_READ_WRITE            \7010  COMMON_INTERCEPT_FUNCTION(eventfd_read); \7011  COMMON_INTERCEPT_FUNCTION(eventfd_write)7012#else7013#define INIT_EVENTFD_READ_WRITE7014#endif7015 7016#if SANITIZER_INTERCEPT_STAT7017INTERCEPTOR(int, stat, const char *path, void *buf) {7018  void *ctx;7019  COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);7020  if (common_flags()->intercept_stat)7021    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7022  int res = REAL(stat)(path, buf);7023  if (!res)7024    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7025  return res;7026}7027#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)7028#else7029#define INIT_STAT7030#endif7031 7032#if SANITIZER_INTERCEPT_STAT647033INTERCEPTOR(int, stat64, const char *path, void *buf) {7034  void *ctx;7035  COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf);7036  if (common_flags()->intercept_stat)7037    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7038  int res = REAL(stat64)(path, buf);7039  if (!res)7040    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7041  return res;7042}7043#define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64)7044#else7045#define INIT_STAT647046#endif7047 7048 7049#if SANITIZER_INTERCEPT_LSTAT7050INTERCEPTOR(int, lstat, const char *path, void *buf) {7051  void *ctx;7052  COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);7053  if (common_flags()->intercept_stat)7054    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7055  int res = REAL(lstat)(path, buf);7056  if (!res)7057    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7058  return res;7059}7060#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)7061#else7062#define INIT_LSTAT7063#endif7064 7065#if SANITIZER_INTERCEPT_STAT647066INTERCEPTOR(int, lstat64, const char *path, void *buf) {7067  void *ctx;7068  COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf);7069  if (common_flags()->intercept_stat)7070    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7071  int res = REAL(lstat64)(path, buf);7072  if (!res)7073    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7074  return res;7075}7076#define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64)7077#else7078#define INIT_LSTAT647079#endif7080 7081#if SANITIZER_INTERCEPT___XSTAT7082INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {7083  void *ctx;7084  COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);7085  if (common_flags()->intercept_stat)7086    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7087  int res = REAL(__xstat)(version, path, buf);7088  if (!res)7089    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7090  return res;7091}7092#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)7093#else7094#define INIT___XSTAT7095#endif7096 7097#if SANITIZER_INTERCEPT___XSTAT647098INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {7099  void *ctx;7100  COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);7101  if (common_flags()->intercept_stat)7102    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7103  int res = REAL(__xstat64)(version, path, buf);7104  if (!res)7105    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7106  return res;7107}7108#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)7109#else7110#define INIT___XSTAT647111#endif7112 7113#if SANITIZER_INTERCEPT___LXSTAT7114INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {7115  void *ctx;7116  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);7117  if (common_flags()->intercept_stat)7118    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7119  int res = REAL(__lxstat)(version, path, buf);7120  if (!res)7121    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);7122  return res;7123}7124#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)7125#else7126#define INIT___LXSTAT7127#endif7128 7129#if SANITIZER_INTERCEPT___LXSTAT647130INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {7131  void *ctx;7132  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);7133  if (common_flags()->intercept_stat)7134    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);7135  int res = REAL(__lxstat64)(version, path, buf);7136  if (!res)7137    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);7138  return res;7139}7140#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)7141#else7142#define INIT___LXSTAT647143#endif7144 7145// FIXME: add other *stat interceptor7146 7147#if SANITIZER_INTERCEPT_UTMP7148INTERCEPTOR(void *, getutent, int dummy) {7149  void *ctx;7150  COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);7151  void *res = REAL(getutent)(dummy);7152  if (res)7153    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7154  return res;7155}7156INTERCEPTOR(void *, getutid, void *ut) {7157  void *ctx;7158  COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);7159  void *res = REAL(getutid)(ut);7160  if (res)7161    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7162  return res;7163}7164INTERCEPTOR(void *, getutline, void *ut) {7165  void *ctx;7166  COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);7167  void *res = REAL(getutline)(ut);7168  if (res)7169    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);7170  return res;7171}7172#define INIT_UTMP                      \7173  COMMON_INTERCEPT_FUNCTION(getutent); \7174  COMMON_INTERCEPT_FUNCTION(getutid);  \7175  COMMON_INTERCEPT_FUNCTION(getutline);7176#else7177#define INIT_UTMP7178#endif7179 7180#if SANITIZER_INTERCEPT_UTMPX7181INTERCEPTOR(void *, getutxent, int dummy) {7182  void *ctx;7183  COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);7184  void *res = REAL(getutxent)(dummy);7185  if (res)7186    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7187  return res;7188}7189INTERCEPTOR(void *, getutxid, void *ut) {7190  void *ctx;7191  COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);7192  void *res = REAL(getutxid)(ut);7193  if (res)7194    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7195  return res;7196}7197INTERCEPTOR(void *, getutxline, void *ut) {7198  void *ctx;7199  COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);7200  void *res = REAL(getutxline)(ut);7201  if (res)7202    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);7203  return res;7204}7205INTERCEPTOR(void *, pututxline, const void *ut) {7206  void *ctx;7207  COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);7208  if (ut)7209    COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);7210  void *res = REAL(pututxline)(ut);7211  if (res)7212    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);7213  return res;7214}7215#define INIT_UTMPX                      \7216  COMMON_INTERCEPT_FUNCTION(getutxent); \7217  COMMON_INTERCEPT_FUNCTION(getutxid);  \7218  COMMON_INTERCEPT_FUNCTION(getutxline); \7219  COMMON_INTERCEPT_FUNCTION(pututxline);7220#else7221#define INIT_UTMPX7222#endif7223 7224#if SANITIZER_INTERCEPT_GETLOADAVG7225INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {7226  void *ctx;7227  COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);7228  int res = REAL(getloadavg)(loadavg, nelem);7229  if (res > 0)7230    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));7231  return res;7232}7233#define INIT_GETLOADAVG                      \7234  COMMON_INTERCEPT_FUNCTION(getloadavg);7235#else7236#define INIT_GETLOADAVG7237#endif7238 7239#if SANITIZER_INTERCEPT_MCHECK_MPROBE7240INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {7241  return 0;7242}7243 7244INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {7245  return 0;7246}7247 7248INTERCEPTOR(int, mprobe, void *ptr) {7249  return 0;7250}7251#endif7252 7253#if SANITIZER_INTERCEPT_WCSLEN7254INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {7255  void *ctx;7256  COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);7257  SIZE_T res = REAL(wcslen)(s);7258  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));7259  return res;7260}7261 7262INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {7263  void *ctx;7264  COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);7265  SIZE_T res = REAL(wcsnlen)(s, n);7266  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));7267  return res;7268}7269#define INIT_WCSLEN                  \7270  COMMON_INTERCEPT_FUNCTION(wcslen); \7271  COMMON_INTERCEPT_FUNCTION(wcsnlen);7272#else7273#define INIT_WCSLEN7274#endif7275 7276#if SANITIZER_INTERCEPT_WCSCAT7277INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {7278  void *ctx;7279  COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);7280  SIZE_T src_size = internal_wcslen(src);7281  SIZE_T dst_size = internal_wcslen(dst);7282  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));7283  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));7284  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,7285                                 (src_size + 1) * sizeof(wchar_t));7286  return REAL(wcscat)(dst, src);7287}7288 7289INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {7290  void *ctx;7291  COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);7292  SIZE_T src_size = internal_wcsnlen(src, n);7293  SIZE_T dst_size = internal_wcslen(dst);7294  COMMON_INTERCEPTOR_READ_RANGE(ctx, src,7295                                Min(src_size + 1, n) * sizeof(wchar_t));7296  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));7297  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,7298                                 (src_size + 1) * sizeof(wchar_t));7299  return REAL(wcsncat)(dst, src, n);7300}7301#define INIT_WCSCAT                  \7302  COMMON_INTERCEPT_FUNCTION(wcscat); \7303  COMMON_INTERCEPT_FUNCTION(wcsncat);7304#else7305#define INIT_WCSCAT7306#endif7307 7308#if SANITIZER_INTERCEPT_WCSDUP7309INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {7310  void *ctx;7311  COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);7312  SIZE_T len = internal_wcslen(s);7313  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));7314  wchar_t *result = REAL(wcsdup)(s);7315  if (result)7316    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));7317  return result;7318}7319 7320#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);7321#else7322#define INIT_WCSDUP7323#endif7324 7325#if SANITIZER_INTERCEPT_STRXFRM7326static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); }7327 7328static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); }7329 7330#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...)             \7331  {                                                                        \7332    void *ctx;                                                             \7333    COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \7334    COMMON_INTERCEPTOR_READ_RANGE(ctx, src,                                \7335                                  sizeof(*src) * (RealStrLen(src) + 1));   \7336    SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__);             \7337    if (res < len)                                                         \7338      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \7339    return res;                                                            \7340  }7341 7342INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {7343  STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);7344}7345 7346INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,7347            void *locale) {7348  STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);7349}7350 7351#define INIT_STRXFRM                  \7352  COMMON_INTERCEPT_FUNCTION(strxfrm); \7353  COMMON_INTERCEPT_FUNCTION(strxfrm_l);7354#else7355#define INIT_STRXFRM7356#endif7357 7358#if SANITIZER_INTERCEPT___STRXFRM_L7359INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,7360            void *locale) {7361  STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);7362}7363 7364#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);7365#else7366#define INIT___STRXFRM_L7367#endif7368 7369#if SANITIZER_INTERCEPT_WCSXFRM7370INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {7371  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);7372}7373 7374INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,7375            void *locale) {7376  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);7377}7378 7379#define INIT_WCSXFRM                  \7380  COMMON_INTERCEPT_FUNCTION(wcsxfrm); \7381  COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);7382#else7383#define INIT_WCSXFRM7384#endif7385 7386#if SANITIZER_INTERCEPT___WCSXFRM_L7387INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,7388            void *locale) {7389  STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);7390}7391 7392#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);7393#else7394#define INIT___WCSXFRM_L7395#endif7396 7397#if SANITIZER_INTERCEPT_ACCT7398INTERCEPTOR(int, acct, const char *file) {7399  void *ctx;7400  COMMON_INTERCEPTOR_ENTER(ctx, acct, file);7401  if (file)7402    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);7403  return REAL(acct)(file);7404}7405#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)7406#else7407#define INIT_ACCT7408#endif7409 7410#if SANITIZER_INTERCEPT_USER_FROM_UID7411INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {7412  void *ctx;7413  const char *user;7414  COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);7415  user = REAL(user_from_uid)(uid, nouser);7416  if (user)7417    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1);7418  return user;7419}7420#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)7421#else7422#define INIT_USER_FROM_UID7423#endif7424 7425#if SANITIZER_INTERCEPT_UID_FROM_USER7426INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {7427  void *ctx;7428  int res;7429  COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);7430  if (name)7431    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7432  res = REAL(uid_from_user)(name, uid);7433  if (uid)7434    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));7435  return res;7436}7437#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)7438#else7439#define INIT_UID_FROM_USER7440#endif7441 7442#if SANITIZER_INTERCEPT_GROUP_FROM_GID7443INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {7444  void *ctx;7445  const char *group;7446  COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);7447  group = REAL(group_from_gid)(gid, nogroup);7448  if (group)7449    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1);7450  return group;7451}7452#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)7453#else7454#define INIT_GROUP_FROM_GID7455#endif7456 7457#if SANITIZER_INTERCEPT_GID_FROM_GROUP7458INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {7459  void *ctx;7460  int res;7461  COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);7462  if (group)7463    COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1);7464  res = REAL(gid_from_group)(group, gid);7465  if (gid)7466    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));7467  return res;7468}7469#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)7470#else7471#define INIT_GID_FROM_GROUP7472#endif7473 7474#if SANITIZER_INTERCEPT_ACCESS7475INTERCEPTOR(int, access, const char *path, int mode) {7476  void *ctx;7477  COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);7478  if (path)7479    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7480  return REAL(access)(path, mode);7481}7482#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)7483#else7484#define INIT_ACCESS7485#endif7486 7487#if SANITIZER_INTERCEPT_FACCESSAT7488INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {7489  void *ctx;7490  COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);7491  if (path)7492    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7493  return REAL(faccessat)(fd, path, mode, flags);7494}7495#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)7496#else7497#define INIT_FACCESSAT7498#endif7499 7500#if SANITIZER_INTERCEPT_GETGROUPLIST7501INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,7502            int *ngroups) {7503  void *ctx;7504  int res;7505  COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);7506  if (name)7507    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7508  if (ngroups)7509    COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));7510  res = REAL(getgrouplist)(name, basegid, groups, ngroups);7511  if (!res && groups && ngroups) {7512    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));7513    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));7514  }7515  return res;7516}7517 7518#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);7519#else7520#define INIT_GETGROUPLIST7521#endif7522 7523#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP7524INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,7525            int maxgrp, int *ngroups) {7526  void *ctx;7527  int res;7528  COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,7529                           maxgrp, ngroups);7530  if (name)7531    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7532  res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);7533  if (!res && groups && ngroups) {7534    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));7535    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));7536  }7537  return res;7538}7539 7540#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);7541#else7542#define INIT_GETGROUPMEMBERSHIP7543#endif7544 7545#if SANITIZER_INTERCEPT_READLINK7546INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {7547  void* ctx;7548  COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);7549  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7550  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);7551  if (res > 0)7552    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);7553  return res;7554}7555 7556#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)7557#else7558#define INIT_READLINK7559#endif7560 7561#if SANITIZER_INTERCEPT_READLINKAT7562INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,7563            SIZE_T bufsiz) {7564  void* ctx;7565  COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);7566  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7567  SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);7568  if (res > 0)7569    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);7570  return res;7571}7572 7573#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)7574#else7575#define INIT_READLINKAT7576#endif7577 7578#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT7579INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,7580            struct file_handle *handle, int *mount_id, int flags) {7581  void* ctx;7582  COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,7583                           mount_id, flags);7584  COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1);7585 7586  __sanitizer_file_handle *sanitizer_handle =7587      reinterpret_cast<__sanitizer_file_handle*>(handle);7588  COMMON_INTERCEPTOR_READ_RANGE(7589      ctx, &sanitizer_handle->handle_bytes,7590      sizeof(sanitizer_handle->handle_bytes));7591 7592  int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);7593  if (!res) {7594    COMMON_INTERCEPTOR_WRITE_RANGE(7595        ctx, &sanitizer_handle->handle_bytes,7596        sizeof(sanitizer_handle->handle_bytes));7597    COMMON_INTERCEPTOR_WRITE_RANGE(7598        ctx, &sanitizer_handle->handle_type,7599        sizeof(sanitizer_handle->handle_type));7600    COMMON_INTERCEPTOR_WRITE_RANGE(7601        ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);7602    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));7603  }7604  return res;7605}7606 7607#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)7608#else7609#define INIT_NAME_TO_HANDLE_AT7610#endif7611 7612#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT7613INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,7614            int flags) {7615  void* ctx;7616  COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);7617 7618  __sanitizer_file_handle *sanitizer_handle =7619      reinterpret_cast<__sanitizer_file_handle*>(handle);7620  COMMON_INTERCEPTOR_READ_RANGE(7621      ctx, &sanitizer_handle->handle_bytes,7622      sizeof(sanitizer_handle->handle_bytes));7623  COMMON_INTERCEPTOR_READ_RANGE(7624      ctx, &sanitizer_handle->handle_type,7625      sizeof(sanitizer_handle->handle_type));7626  COMMON_INTERCEPTOR_READ_RANGE(7627      ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);7628 7629  return COMMON_INTERCEPTOR_BLOCK_REAL(open_by_handle_at)(mount_fd, handle,7630                                                          flags);7631}7632 7633#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)7634#else7635#define INIT_OPEN_BY_HANDLE_AT7636#endif7637 7638#if SANITIZER_INTERCEPT_STRLCPY7639INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {7640  void *ctx;7641  SIZE_T res;7642  COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);7643  if (src) {7644    // Keep strnlen as macro argument, as macro may ignore it.7645    COMMON_INTERCEPTOR_READ_STRING(7646        ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);7647  }7648  res = REAL(strlcpy)(dst, src, size);7649  COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1);7650  return res;7651}7652 7653INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {7654  void *ctx;7655  SIZE_T len = 0;7656  COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);7657  // src is checked in the strlcpy() interceptor7658  if (dst) {7659    len = internal_strnlen(dst, size);7660    COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);7661  }7662  // Reuse the rest of the code in the strlcpy() interceptor7663  return WRAP(strlcpy)(dst + len, src, size - len) + len;7664}7665#define INIT_STRLCPY \7666  COMMON_INTERCEPT_FUNCTION(strlcpy); \7667  COMMON_INTERCEPT_FUNCTION(strlcat);7668#else7669#define INIT_STRLCPY7670#endif7671 7672#if SANITIZER_INTERCEPT_MMAP7673INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,7674            OFF_T off) {7675  void *ctx;7676  if (common_flags()->detect_write_exec)7677    ReportMmapWriteExec(prot, flags);7678  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7679    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);7680  COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);7681  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);7682}7683 7684INTERCEPTOR(int, munmap, void *addr, SIZE_T sz) {7685  void *ctx;7686  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7687    return (int)internal_munmap(addr, sz);7688  COMMON_INTERCEPTOR_ENTER(ctx, munmap, addr, sz);7689  COMMON_INTERCEPTOR_MUNMAP_IMPL(ctx, addr, sz);7690}7691 7692INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {7693  void *ctx;7694  if (common_flags()->detect_write_exec)7695    ReportMmapWriteExec(prot, 0);7696  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7697    return (int)internal_mprotect(addr, sz, prot);7698  COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);7699  MprotectMallocZones(addr, prot);7700  return REAL(mprotect)(addr, sz, prot);7701}7702#define INIT_MMAP                                                              \7703  COMMON_INTERCEPT_FUNCTION(mmap);                                             \7704  COMMON_INTERCEPT_FUNCTION(munmap);                                           \7705  COMMON_INTERCEPT_FUNCTION(mprotect);7706#else7707#define INIT_MMAP7708#endif7709 7710#if SANITIZER_INTERCEPT_MMAP647711INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,7712            OFF64_T off) {7713  void *ctx;7714  if (common_flags()->detect_write_exec)7715    ReportMmapWriteExec(prot, flags);7716  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)7717    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);7718  COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);7719  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);7720}7721#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);7722#else7723#define INIT_MMAP647724#endif7725 7726#if SANITIZER_INTERCEPT_DEVNAME7727INTERCEPTOR(char *, devname, u64 dev, u32 type) {7728  void *ctx;7729  char *name;7730  COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);7731  name = REAL(devname)(dev, type);7732  if (name)7733    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);7734  return name;7735}7736#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);7737#else7738#define INIT_DEVNAME7739#endif7740 7741#if SANITIZER_INTERCEPT_DEVNAME_R7742#if SANITIZER_NETBSD7743#define DEVNAME_R_RETTYPE int7744#define DEVNAME_R_SUCCESS(x) (!(x))7745#else7746#define DEVNAME_R_RETTYPE char*7747#define DEVNAME_R_SUCCESS(x) (x)7748#endif7749INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,7750            uptr len) {7751  void *ctx;7752  COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);7753  DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);7754  if (DEVNAME_R_SUCCESS(res))7755    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1);7756  return res;7757}7758#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);7759#else7760#define INIT_DEVNAME_R7761#endif7762 7763#if SANITIZER_INTERCEPT_FGETLN7764INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {7765  void *ctx;7766  COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);7767  char *str = REAL(fgetln)(stream, len);7768  if (str && len) {7769    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));7770    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);7771  }7772  return str;7773}7774#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)7775#else7776#define INIT_FGETLN7777#endif7778 7779#if SANITIZER_INTERCEPT_STRMODE7780INTERCEPTOR(void, strmode, u32 mode, char *bp) {7781  void *ctx;7782  COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);7783  REAL(strmode)(mode, bp);7784  if (bp)7785    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1);7786}7787#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)7788#else7789#define INIT_STRMODE7790#endif7791 7792#if SANITIZER_INTERCEPT_TTYENT7793INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {7794  void *ctx;7795  COMMON_INTERCEPTOR_ENTER(ctx, getttyent);7796  struct __sanitizer_ttyent *ttyent = REAL(getttyent)();7797  if (ttyent)7798    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);7799  return ttyent;7800}7801INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {7802  void *ctx;7803  COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);7804  if (name)7805    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7806  struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);7807  if (ttyent)7808    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);7809  return ttyent;7810}7811#define INIT_TTYENT \7812  COMMON_INTERCEPT_FUNCTION(getttyent); \7813  COMMON_INTERCEPT_FUNCTION(getttynam);7814#else7815#define INIT_TTYENT7816#endif7817 7818#if SANITIZER_INTERCEPT_TTYENTPATH7819INTERCEPTOR(int, setttyentpath, char *path) {7820  void *ctx;7821  COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);7822  if (path)7823    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);7824  return REAL(setttyentpath)(path);7825}7826#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);7827#else7828#define INIT_TTYENTPATH7829#endif7830 7831#if SANITIZER_INTERCEPT_PROTOENT7832static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {7833  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));7834 7835  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1);7836 7837  SIZE_T pp_size = 1; // One handles the trailing \07838 7839  for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)7840      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1);7841 7842  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, pp_size * sizeof(char *));7843}7844 7845INTERCEPTOR(struct __sanitizer_protoent *, getprotoent,) {7846  void *ctx;7847  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent,);7848  struct __sanitizer_protoent *p = REAL(getprotoent)();7849  if (p)7850    write_protoent(ctx, p);7851  return p;7852}7853 7854INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {7855  void *ctx;7856  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);7857  if (name)7858    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7859  struct __sanitizer_protoent *p = REAL(getprotobyname)(name);7860  if (p)7861    write_protoent(ctx, p);7862  return p;7863}7864 7865INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {7866  void *ctx;7867  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);7868  struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);7869  if (p)7870    write_protoent(ctx, p);7871  return p;7872}7873#define INIT_PROTOENT \7874  COMMON_INTERCEPT_FUNCTION(getprotoent); \7875  COMMON_INTERCEPT_FUNCTION(getprotobyname); \7876  COMMON_INTERCEPT_FUNCTION(getprotobynumber)7877#else7878#define INIT_PROTOENT7879#endif7880 7881#if SANITIZER_INTERCEPT_PROTOENT_R7882INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,7883            char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {7884  void *ctx;7885  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,7886                           result);7887  int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);7888 7889  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7890  if (!res && *result)7891    write_protoent(ctx, *result);7892  return res;7893}7894 7895INTERCEPTOR(int, getprotobyname_r, const char *name,7896            struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,7897            struct __sanitizer_protoent **result) {7898  void *ctx;7899  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,7900                           buflen, result);7901  if (name)7902    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7903  int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);7904 7905  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7906  if (!res && *result)7907    write_protoent(ctx, *result);7908  return res;7909}7910 7911INTERCEPTOR(int, getprotobynumber_r, int num,7912            struct __sanitizer_protoent *result_buf, char *buf,7913            SIZE_T buflen, struct __sanitizer_protoent **result) {7914  void *ctx;7915  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,7916                           buflen, result);7917  int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);7918 7919  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);7920  if (!res && *result)7921    write_protoent(ctx, *result);7922  return res;7923}7924 7925#define INIT_PROTOENT_R \7926  COMMON_INTERCEPT_FUNCTION(getprotoent_r); \7927  COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \7928  COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);7929#else7930#define INIT_PROTOENT_R7931#endif7932 7933#if SANITIZER_INTERCEPT_NETENT7934INTERCEPTOR(struct __sanitizer_netent *, getnetent,) {7935  void *ctx;7936  COMMON_INTERCEPTOR_ENTER(ctx, getnetent,);7937  struct __sanitizer_netent *n = REAL(getnetent)();7938  if (n) {7939    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7940 7941    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7942 7943    SIZE_T nn_size = 1; // One handles the trailing \07944 7945    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7946      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7947 7948    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7949  }7950  return n;7951}7952 7953INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {7954  void *ctx;7955  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);7956  if (name)7957    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);7958  struct __sanitizer_netent *n = REAL(getnetbyname)(name);7959  if (n) {7960    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7961 7962    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7963 7964    SIZE_T nn_size = 1; // One handles the trailing \07965 7966    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7967      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7968 7969    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7970  }7971  return n;7972}7973 7974INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {7975  void *ctx;7976  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);7977  struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);7978  if (n) {7979    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));7980 7981    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);7982 7983    SIZE_T nn_size = 1; // One handles the trailing \07984 7985    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)7986      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);7987 7988    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, nn_size * sizeof(char *));7989  }7990  return n;7991}7992#define INIT_NETENT \7993  COMMON_INTERCEPT_FUNCTION(getnetent); \7994  COMMON_INTERCEPT_FUNCTION(getnetbyname); \7995  COMMON_INTERCEPT_FUNCTION(getnetbyaddr)7996#else7997#define INIT_NETENT7998#endif7999 8000#if SANITIZER_INTERCEPT_GETMNTINFO8001INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {8002  void *ctx;8003  COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);8004  int cnt = REAL(getmntinfo)(mntbufp, flags);8005  if (cnt > 0 && mntbufp) {8006    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));8007    if (*mntbufp)8008#if SANITIZER_NETBSD8009      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);8010#else8011      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);8012#endif8013  }8014  return cnt;8015}8016#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)8017#else8018#define INIT_GETMNTINFO8019#endif8020 8021#if SANITIZER_INTERCEPT_MI_VECTOR_HASH8022INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,8023            u32 hashes[3]) {8024  void *ctx;8025  COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);8026  if (key)8027    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);8028  REAL(mi_vector_hash)(key, len, seed, hashes);8029  if (hashes)8030    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);8031}8032#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)8033#else8034#define INIT_MI_VECTOR_HASH8035#endif8036 8037#if SANITIZER_INTERCEPT_SETVBUF8038INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,8039  SIZE_T size) {8040  void *ctx;8041  COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);8042  int ret = REAL(setvbuf)(stream, buf, mode, size);8043  if (buf)8044    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);8045  if (stream)8046      unpoison_file(stream);8047  return ret;8048}8049 8050INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {8051  void *ctx;8052  COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);8053  REAL(setbuf)(stream, buf);8054  if (buf) {8055    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);8056  }8057  if (stream)8058      unpoison_file(stream);8059}8060 8061INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, SIZE_T size) {8062  void *ctx;8063  COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, size);8064  REAL(setbuffer)(stream, buf, size);8065  if (buf) {8066    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);8067  }8068  if (stream)8069    unpoison_file(stream);8070}8071 8072INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {8073  void *ctx;8074  COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);8075  REAL(setlinebuf)(stream);8076  if (stream)8077    unpoison_file(stream);8078}8079#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \8080    COMMON_INTERCEPT_FUNCTION(setbuf); \8081    COMMON_INTERCEPT_FUNCTION(setbuffer); \8082    COMMON_INTERCEPT_FUNCTION(setlinebuf)8083#else8084#define INIT_SETVBUF8085#endif8086 8087#if SANITIZER_INTERCEPT_GETVFSSTAT8088INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {8089  void *ctx;8090  COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);8091  int ret = REAL(getvfsstat)(buf, bufsize, flags);8092  if (buf && ret > 0)8093    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);8094  return ret;8095}8096#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)8097#else8098#define INIT_GETVFSSTAT8099#endif8100 8101#if SANITIZER_INTERCEPT_REGEX8102INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {8103  void *ctx;8104  COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);8105  if (pattern)8106    COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1);8107  int res = REAL(regcomp)(preg, pattern, cflags);8108  if (preg)8109    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);8110  return res;8111}8112INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,8113            struct __sanitizer_regmatch *pmatch[], int eflags) {8114  void *ctx;8115  COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);8116  if (preg)8117    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8118  if (string)8119    COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1);8120  int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);8121  if (!res && pmatch)8122    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);8123  return res;8124}8125INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,8126            SIZE_T errbuf_size) {8127  void *ctx;8128  COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);8129  if (preg)8130    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8131  SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);8132  if (errbuf)8133    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1);8134  return res;8135}8136INTERCEPTOR(void, regfree, const void *preg) {8137  void *ctx;8138  COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);8139  if (preg)8140    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);8141  REAL(regfree)(preg);8142}8143#define INIT_REGEX                                                             \8144  COMMON_INTERCEPT_FUNCTION(regcomp);                                          \8145  COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4");             \8146  COMMON_INTERCEPT_FUNCTION(regerror);                                         \8147  COMMON_INTERCEPT_FUNCTION(regfree);8148#else8149#define INIT_REGEX8150#endif8151 8152#if SANITIZER_INTERCEPT_REGEXSUB8153INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,8154            const struct __sanitizer_regmatch *rm, const char *str) {8155  void *ctx;8156  COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);8157  if (sub)8158    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);8159  // The implementation demands and hardcodes 10 elements8160  if (rm)8161    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);8162  if (str)8163    COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);8164  SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);8165  if (res > 0 && buf)8166    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);8167  return res;8168}8169INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,8170            const struct __sanitizer_regmatch *rm, const char *sstr) {8171  void *ctx;8172  COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);8173  if (sub)8174    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);8175  // Hardcode 10 elements as this is hardcoded size8176  if (rm)8177    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);8178  if (sstr)8179    COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1);8180  SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);8181  if (res > 0 && buf) {8182    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));8183    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1);8184  }8185  return res;8186}8187 8188#define INIT_REGEXSUB                                                          \8189  COMMON_INTERCEPT_FUNCTION(regnsub);                                          \8190  COMMON_INTERCEPT_FUNCTION(regasub);8191#else8192#define INIT_REGEXSUB8193#endif8194 8195#if SANITIZER_INTERCEPT_FTS8196INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,8197            int (*compar)(void **, void **)) {8198  void *ctx;8199  COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);8200  if (path_argv) {8201    for (char *const *pa = path_argv; ; ++pa) {8202      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));8203      if (!*pa)8204        break;8205      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);8206    }8207  }8208  // TODO(kamil): handle compar callback8209  void *fts = REAL(fts_open)(path_argv, options, compar);8210  if (fts)8211    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);8212  return fts;8213}8214 8215INTERCEPTOR(void *, fts_read, void *ftsp) {8216  void *ctx;8217  COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);8218  if (ftsp)8219    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8220  void *ftsent = REAL(fts_read)(ftsp);8221  if (ftsent)8222    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);8223  return ftsent;8224}8225 8226INTERCEPTOR(void *, fts_children, void *ftsp, int options) {8227  void *ctx;8228  COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);8229  if (ftsp)8230    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8231  void *ftsent = REAL(fts_children)(ftsp, options);8232  if (ftsent)8233    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);8234  return ftsent;8235}8236 8237INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {8238  void *ctx;8239  COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);8240  if (ftsp)8241    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8242  if (f)8243    COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);8244  return REAL(fts_set)(ftsp, f, options);8245}8246 8247INTERCEPTOR(int, fts_close, void *ftsp) {8248  void *ctx;8249  COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);8250  if (ftsp)8251    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);8252  return REAL(fts_close)(ftsp);8253}8254#define INIT_FTS                                                               \8255  COMMON_INTERCEPT_FUNCTION(fts_open);                                         \8256  COMMON_INTERCEPT_FUNCTION(fts_read);                                         \8257  COMMON_INTERCEPT_FUNCTION(fts_children);                                     \8258  COMMON_INTERCEPT_FUNCTION(fts_set);                                          \8259  COMMON_INTERCEPT_FUNCTION(fts_close);8260#else8261#define INIT_FTS8262#endif8263 8264#if SANITIZER_INTERCEPT_SYSCTL8265INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,8266            SIZE_T *oldlenp, void *newp, SIZE_T newlen) {8267  void *ctx;8268  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)8269    return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);8270  COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,8271                           newlen);8272  if (name)8273    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));8274  if (oldlenp)8275    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));8276  if (newp && newlen)8277    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);8278  int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);8279  if (!res) {8280    if (oldlenp) {8281      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));8282      if (oldp)8283        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);8284    }8285  }8286  return res;8287}8288 8289INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,8290            void *newp, SIZE_T newlen) {8291  void *ctx;8292  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)8293    return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);8294  COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,8295                           newlen);8296  if (sname)8297    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8298  if (oldlenp)8299    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));8300  if (newp && newlen)8301    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);8302  int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);8303  if (!res) {8304    if (oldlenp) {8305      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));8306      if (oldp)8307        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);8308    }8309  }8310  return res;8311}8312 8313INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,8314            SIZE_T *namelenp) {8315  void *ctx;8316  COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);8317  if (sname)8318    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8319  if (namelenp)8320    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));8321  int res = REAL(sysctlnametomib)(sname, name, namelenp);8322  if (!res) {8323    if (namelenp) {8324      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));8325      if (name)8326        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));8327    }8328  }8329  return res;8330}8331 8332#define INIT_SYSCTL                        \8333  COMMON_INTERCEPT_FUNCTION(sysctl);       \8334  COMMON_INTERCEPT_FUNCTION(sysctlbyname); \8335  COMMON_INTERCEPT_FUNCTION(sysctlnametomib);8336#else8337#define INIT_SYSCTL8338#endif8339 8340#if SANITIZER_INTERCEPT_ASYSCTL8341INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {8342  void *ctx;8343  COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);8344  if (name)8345    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);8346  void *res = REAL(asysctl)(name, namelen, len);8347  if (res && len) {8348    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8349    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);8350  }8351  return res;8352}8353 8354INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {8355  void *ctx;8356  COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);8357  if (sname)8358    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8359  void *res = REAL(asysctlbyname)(sname, len);8360  if (res && len) {8361    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8362    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);8363  }8364  return res;8365}8366#define INIT_ASYSCTL                           \8367  COMMON_INTERCEPT_FUNCTION(asysctl);          \8368  COMMON_INTERCEPT_FUNCTION(asysctlbyname);8369#else8370#define INIT_ASYSCTL8371#endif8372 8373#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO8374INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,8375            unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,8376            int v) {8377  void *ctx;8378  COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,8379                           csz, rnode, v);8380  if (sname)8381    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);8382  if (namelenp)8383    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));8384  if (csz)8385    COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));8386  // Skip rnode, it's rarely used and not trivial to sanitize8387  // It's also used mostly internally8388  int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);8389  if (!res) {8390    if (namelenp) {8391      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));8392      if (name)8393        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));8394    }8395    if (csz) {8396      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));8397      if (cname)8398        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);8399    }8400  }8401  return res;8402}8403#define INIT_SYSCTLGETMIBINFO                  \8404  COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);8405#else8406#define INIT_SYSCTLGETMIBINFO8407#endif8408 8409#if SANITIZER_INTERCEPT_NL_LANGINFO8410INTERCEPTOR(char *, nl_langinfo, long item) {8411  void *ctx;8412  COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);8413  char *ret = REAL(nl_langinfo)(item);8414  if (ret)8415    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);8416  return ret;8417}8418#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)8419#else8420#define INIT_NL_LANGINFO8421#endif8422 8423#if SANITIZER_INTERCEPT_MODCTL8424INTERCEPTOR(int, modctl, int operation, void *argp) {8425  void *ctx;8426  int ret;8427  COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);8428 8429  if (operation == modctl_load) {8430    if (argp) {8431      __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;8432      COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));8433      if (ml->ml_filename)8434        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,8435                                      internal_strlen(ml->ml_filename) + 1);8436      if (ml->ml_props)8437        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);8438    }8439    ret = REAL(modctl)(operation, argp);8440  } else if (operation == modctl_unload) {8441    if (argp) {8442      const char *name = (const char *)argp;8443      COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);8444    }8445    ret = REAL(modctl)(operation, argp);8446  } else if (operation == modctl_stat) {8447    uptr iov_len;8448    struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;8449    if (iov) {8450      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));8451      iov_len = iov->iov_len;8452    }8453    ret = REAL(modctl)(operation, argp);8454    if (iov)8455      COMMON_INTERCEPTOR_WRITE_RANGE(8456          ctx, iov->iov_base, Min(iov_len,  iov->iov_len));8457  } else if (operation == modctl_exists) {8458    ret = REAL(modctl)(operation, argp);8459  } else {8460    ret = REAL(modctl)(operation, argp);8461  }8462 8463  return ret;8464}8465#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)8466#else8467#define INIT_MODCTL8468#endif8469 8470#if SANITIZER_INTERCEPT_STRTONUM8471INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,8472            long long maxval, const char **errstr) {8473  void *ctx;8474  COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);8475 8476  // TODO(kamil): Implement strtoll as a common inteceptor8477  char *real_endptr;8478  long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);8479  StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);8480 8481  ret = REAL(strtonum)(nptr, minval, maxval, errstr);8482  if (errstr) {8483    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));8484     if (*errstr)8485      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1);8486  }8487  return ret;8488}8489#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)8490#else8491#define INIT_STRTONUM8492#endif8493 8494#if SANITIZER_INTERCEPT_FPARSELN8495INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,8496            SIZE_T *lineno, const char delim[3], int flags) {8497  void *ctx;8498  COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);8499  if (lineno)8500    COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));8501  if (delim)8502    COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);8503  char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);8504  if (ret) {8505    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);8506    if (len)8507      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));8508    if (lineno)8509      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));8510  }8511  return ret;8512}8513#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)8514#else8515#define INIT_FPARSELN8516#endif8517 8518#if SANITIZER_INTERCEPT_STATVFS18519INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {8520  void *ctx;8521  COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);8522  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);8523  int res = REAL(statvfs1)(path, buf, flags);8524  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);8525  return res;8526}8527INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {8528  void *ctx;8529  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);8530  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);8531  int res = REAL(fstatvfs1)(fd, buf, flags);8532  if (!res) {8533    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);8534    if (fd >= 0)8535      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);8536  }8537  return res;8538}8539#define INIT_STATVFS1                  \8540  COMMON_INTERCEPT_FUNCTION(statvfs1);  \8541  COMMON_INTERCEPT_FUNCTION(fstatvfs1);8542#else8543#define INIT_STATVFS18544#endif8545 8546#if SANITIZER_INTERCEPT_STRTOI8547INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,8548            INTMAX_T low, INTMAX_T high, int *rstatus) {8549  void *ctx;8550  COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);8551  char *real_endptr;8552  INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);8553  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);8554  if (rstatus)8555    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));8556  return ret;8557}8558 8559INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,8560            UINTMAX_T low, UINTMAX_T high, int *rstatus) {8561  void *ctx;8562  COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);8563  char *real_endptr;8564  UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);8565  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);8566  if (rstatus)8567    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));8568  return ret;8569}8570#define INIT_STRTOI                                                            \8571  COMMON_INTERCEPT_FUNCTION(strtoi);                                           \8572  COMMON_INTERCEPT_FUNCTION(strtou)8573#else8574#define INIT_STRTOI8575#endif8576 8577#if SANITIZER_INTERCEPT_CAPSICUM8578#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...)          \8579  {                                                                        \8580    void *ctx;                                                             \8581    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, 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_init)(rights, ##__VA_ARGS__);                      \8586    if (ret)                                                               \8587      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));              \8588    return ret;                                                            \8589  }8590 8591#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...)           \8592  {                                                                       \8593    void *ctx;                                                            \8594    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \8595    if (rights)                                                           \8596      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));        \8597    __sanitizer_cap_rights_t *ret =                                       \8598        REAL(cap_rights_set)(rights, ##__VA_ARGS__);                      \8599    if (ret)                                                              \8600      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));             \8601    return ret;                                                           \8602  }8603 8604#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...)         \8605  {                                                                         \8606    void *ctx;                                                              \8607    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \8608    if (rights)                                                             \8609      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));          \8610    __sanitizer_cap_rights_t *ret =                                         \8611        REAL(cap_rights_clear)(rights, ##__VA_ARGS__);                      \8612    if (ret)                                                                \8613      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));               \8614    return ret;                                                             \8615  }8616 8617#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...)        \8618  {                                                                          \8619    void *ctx;                                                               \8620    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \8621    if (rights)                                                              \8622      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));           \8623    return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__);                   \8624  }8625 8626INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,8627            __sanitizer_cap_rights_t *rights) {8628  CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);8629}8630 8631INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,8632            __sanitizer_cap_rights_t *rights) {8633  CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);8634}8635 8636INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,8637            __sanitizer_cap_rights_t *rights) {8638  CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);8639}8640 8641INTERCEPTOR(bool, cap_rights_is_set,8642            __sanitizer_cap_rights_t *rights) {8643  CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);8644}8645 8646INTERCEPTOR(int, cap_rights_limit, int fd,8647            const __sanitizer_cap_rights_t *rights) {8648  void *ctx;8649  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);8650  if (rights)8651    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));8652 8653  return REAL(cap_rights_limit)(fd, rights);8654}8655 8656INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {8657  void *ctx;8658  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);8659  int ret = REAL(cap_rights_get)(fd, rights);8660  if (!ret && rights)8661    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));8662 8663  return ret;8664}8665 8666INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {8667  void *ctx;8668  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);8669  if (rights)8670    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));8671 8672  return REAL(cap_rights_is_valid(rights));8673}8674 8675INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,8676  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {8677  void *ctx;8678  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);8679  if (src)8680    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));8681 8682  __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);8683  if (dst)8684    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));8685 8686  return ret;8687}8688 8689INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,8690  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {8691  void *ctx;8692  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);8693  if (src)8694    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));8695 8696  __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);8697  if (dst)8698    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));8699 8700  return ret;8701}8702 8703INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,8704  const __sanitizer_cap_rights *little) {8705  void *ctx;8706  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);8707  if (little)8708    COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));8709  if (big)8710    COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));8711 8712  return REAL(cap_rights_contains)(big, little);8713}8714 8715INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {8716  void *ctx;8717  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);8718  if (cmds)8719    COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);8720 8721  return REAL(cap_ioctls_limit)(fd, cmds, ncmds);8722}8723 8724INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {8725  void *ctx;8726  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);8727  int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);8728  if (!ret && cmds)8729    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);8730 8731  return ret;8732}8733#define INIT_CAPSICUM                          \8734  COMMON_INTERCEPT_FUNCTION(cap_rights_init); \8735  COMMON_INTERCEPT_FUNCTION(cap_rights_set); \8736  COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \8737  COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \8738  COMMON_INTERCEPT_FUNCTION(cap_rights_get);   \8739  COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \8740  COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \8741  COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \8742  COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \8743  COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \8744  COMMON_INTERCEPT_FUNCTION(cap_ioctls_get);   \8745  COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)8746#else8747#define INIT_CAPSICUM8748#endif8749 8750#if SANITIZER_INTERCEPT_SHA18751INTERCEPTOR(void, SHA1Init, void *context) {8752  void *ctx;8753  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);8754  REAL(SHA1Init)(context);8755  if (context)8756    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);8757}8758INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {8759  void *ctx;8760  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);8761  if (data && len > 0)8762    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8763  if (context)8764    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8765  REAL(SHA1Update)(context, data, len);8766  if (context)8767    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);8768}8769INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {8770  void *ctx;8771  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);8772  if (context)8773    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8774  REAL(SHA1Final)(digest, context);8775  if (digest)8776    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);8777}8778INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {8779  void *ctx;8780  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);8781  if (state)8782    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);8783  if (buffer)8784    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);8785  REAL(SHA1Transform)(state, buffer);8786  if (state)8787    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);8788}8789INTERCEPTOR(char *, SHA1End, void *context, char *buf) {8790  void *ctx;8791  COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);8792  if (context)8793    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);8794  char *ret = REAL(SHA1End)(context, buf);8795  if (ret)8796    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8797  return ret;8798}8799INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {8800  void *ctx;8801  COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);8802  if (filename)8803    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8804  char *ret = REAL(SHA1File)(filename, buf);8805  if (ret)8806    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8807  return ret;8808}8809INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,8810  OFF_T length) {8811  void *ctx;8812  COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);8813  if (filename)8814    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8815  char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);8816  if (ret)8817    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8818  return ret;8819}8820INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {8821  void *ctx;8822  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);8823  if (data)8824    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8825  char *ret = REAL(SHA1Data)(data, len, buf);8826  if (ret)8827    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);8828  return ret;8829}8830#define INIT_SHA1                                                              \8831  COMMON_INTERCEPT_FUNCTION(SHA1Init);                                         \8832  COMMON_INTERCEPT_FUNCTION(SHA1Update);                                       \8833  COMMON_INTERCEPT_FUNCTION(SHA1Final);                                        \8834  COMMON_INTERCEPT_FUNCTION(SHA1Transform);                                    \8835  COMMON_INTERCEPT_FUNCTION(SHA1End);                                          \8836  COMMON_INTERCEPT_FUNCTION(SHA1File);                                         \8837  COMMON_INTERCEPT_FUNCTION(SHA1FileChunk);                                    \8838  COMMON_INTERCEPT_FUNCTION(SHA1Data)8839#else8840#define INIT_SHA18841#endif8842 8843#if SANITIZER_INTERCEPT_MD48844INTERCEPTOR(void, MD4Init, void *context) {8845  void *ctx;8846  COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);8847  REAL(MD4Init)(context);8848  if (context)8849    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);8850}8851 8852INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,8853            unsigned int len) {8854  void *ctx;8855  COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);8856  if (data && len > 0)8857    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8858  if (context)8859    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8860  REAL(MD4Update)(context, data, len);8861  if (context)8862    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);8863}8864 8865INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {8866  void *ctx;8867  COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);8868  if (context)8869    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8870  REAL(MD4Final)(digest, context);8871  if (digest)8872    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);8873}8874 8875INTERCEPTOR(char *, MD4End, void *context, char *buf) {8876  void *ctx;8877  COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);8878  if (context)8879    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);8880  char *ret = REAL(MD4End)(context, buf);8881  if (ret)8882    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8883  return ret;8884}8885 8886INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {8887  void *ctx;8888  COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);8889  if (filename)8890    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8891  char *ret = REAL(MD4File)(filename, buf);8892  if (ret)8893    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8894  return ret;8895}8896 8897INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,8898            char *buf) {8899  void *ctx;8900  COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);8901  if (data && len > 0)8902    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8903  char *ret = REAL(MD4Data)(data, len, buf);8904  if (ret)8905    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);8906  return ret;8907}8908 8909#define INIT_MD4                                                               \8910  COMMON_INTERCEPT_FUNCTION(MD4Init);                                          \8911  COMMON_INTERCEPT_FUNCTION(MD4Update);                                        \8912  COMMON_INTERCEPT_FUNCTION(MD4Final);                                         \8913  COMMON_INTERCEPT_FUNCTION(MD4End);                                           \8914  COMMON_INTERCEPT_FUNCTION(MD4File);                                          \8915  COMMON_INTERCEPT_FUNCTION(MD4Data)8916#else8917#define INIT_MD48918#endif8919 8920#if SANITIZER_INTERCEPT_RMD1608921INTERCEPTOR(void, RMD160Init, void *context) {8922  void *ctx;8923  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);8924  REAL(RMD160Init)(context);8925  if (context)8926    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);8927}8928INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {8929  void *ctx;8930  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);8931  if (data && len > 0)8932    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8933  if (context)8934    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8935  REAL(RMD160Update)(context, data, len);8936  if (context)8937    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);8938}8939INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {8940  void *ctx;8941  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);8942  if (context)8943    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8944  REAL(RMD160Final)(digest, context);8945  if (digest)8946    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);8947}8948INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {8949  void *ctx;8950  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);8951  if (state)8952    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);8953  if (buffer)8954    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);8955  REAL(RMD160Transform)(state, buffer);8956  if (state)8957    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);8958}8959INTERCEPTOR(char *, RMD160End, void *context, char *buf) {8960  void *ctx;8961  COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);8962  if (context)8963    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);8964  char *ret = REAL(RMD160End)(context, buf);8965  if (ret)8966    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8967  return ret;8968}8969INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {8970  void *ctx;8971  COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);8972  if (filename)8973    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8974  char *ret = REAL(RMD160File)(filename, buf);8975  if (ret)8976    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8977  return ret;8978}8979INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,8980  OFF_T length) {8981  void *ctx;8982  COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);8983  if (filename)8984    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);8985  char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);8986  if (ret)8987    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8988  return ret;8989}8990INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {8991  void *ctx;8992  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);8993  if (data && len > 0)8994    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);8995  char *ret = REAL(RMD160Data)(data, len, buf);8996  if (ret)8997    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);8998  return ret;8999}9000#define INIT_RMD160                                                            \9001  COMMON_INTERCEPT_FUNCTION(RMD160Init);                                       \9002  COMMON_INTERCEPT_FUNCTION(RMD160Update);                                     \9003  COMMON_INTERCEPT_FUNCTION(RMD160Final);                                      \9004  COMMON_INTERCEPT_FUNCTION(RMD160Transform);                                  \9005  COMMON_INTERCEPT_FUNCTION(RMD160End);                                        \9006  COMMON_INTERCEPT_FUNCTION(RMD160File);                                       \9007  COMMON_INTERCEPT_FUNCTION(RMD160FileChunk);                                  \9008  COMMON_INTERCEPT_FUNCTION(RMD160Data)9009#else9010#define INIT_RMD1609011#endif9012 9013#if SANITIZER_INTERCEPT_FSEEK9014INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {9015  void *ctx;9016  COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);9017  return REAL(fseek)(stream, offset, whence);9018}9019INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {9020  void *ctx;9021  COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);9022  return REAL(fseeko)(stream, offset, whence);9023}9024INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {9025  void *ctx;9026  COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);9027  return REAL(ftell)(stream);9028}9029INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {9030  void *ctx;9031  COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);9032  return REAL(ftello)(stream);9033}9034INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {9035  void *ctx;9036  COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);9037  return REAL(rewind)(stream);9038}9039INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {9040  void *ctx;9041  COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);9042  int ret = REAL(fgetpos)(stream, pos);9043  if (pos && !ret)9044    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);9045  return ret;9046}9047INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {9048  void *ctx;9049  COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);9050  if (pos)9051    COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);9052  return REAL(fsetpos)(stream, pos);9053}9054#define INIT_FSEEK \9055  COMMON_INTERCEPT_FUNCTION(fseek); \9056  COMMON_INTERCEPT_FUNCTION(fseeko); \9057  COMMON_INTERCEPT_FUNCTION(ftell); \9058  COMMON_INTERCEPT_FUNCTION(ftello); \9059  COMMON_INTERCEPT_FUNCTION(rewind); \9060  COMMON_INTERCEPT_FUNCTION(fgetpos); \9061  COMMON_INTERCEPT_FUNCTION(fsetpos)9062#else9063#define INIT_FSEEK9064#endif9065 9066#if SANITIZER_INTERCEPT_MD29067INTERCEPTOR(void, MD2Init, void *context) {9068  void *ctx;9069  COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);9070  REAL(MD2Init)(context);9071  if (context)9072    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);9073}9074 9075INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,9076            unsigned int len) {9077  void *ctx;9078  COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);9079  if (data && len > 0)9080    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);9081  if (context)9082    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9083  REAL(MD2Update)(context, data, len);9084  if (context)9085    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);9086}9087 9088INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {9089  void *ctx;9090  COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);9091  if (context)9092    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9093  REAL(MD2Final)(digest, context);9094  if (digest)9095    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);9096}9097 9098INTERCEPTOR(char *, MD2End, void *context, char *buf) {9099  void *ctx;9100  COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);9101  if (context)9102    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);9103  char *ret = REAL(MD2End)(context, buf);9104  if (ret)9105    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9106  return ret;9107}9108 9109INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {9110  void *ctx;9111  COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);9112  if (filename)9113    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);9114  char *ret = REAL(MD2File)(filename, buf);9115  if (ret)9116    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9117  return ret;9118}9119 9120INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,9121            char *buf) {9122  void *ctx;9123  COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);9124  if (data && len > 0)9125    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);9126  char *ret = REAL(MD2Data)(data, len, buf);9127  if (ret)9128    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);9129  return ret;9130}9131 9132#define INIT_MD2                                                               \9133  COMMON_INTERCEPT_FUNCTION(MD2Init);                                          \9134  COMMON_INTERCEPT_FUNCTION(MD2Update);                                        \9135  COMMON_INTERCEPT_FUNCTION(MD2Final);                                         \9136  COMMON_INTERCEPT_FUNCTION(MD2End);                                           \9137  COMMON_INTERCEPT_FUNCTION(MD2File);                                          \9138  COMMON_INTERCEPT_FUNCTION(MD2Data)9139#else9140#define INIT_MD29141#endif9142 9143#if SANITIZER_INTERCEPT_VIS9144INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {9145  void *ctx;9146  COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);9147  char *end = REAL(vis)(dst, c, flag, nextc);9148  // dst is NULL terminated and end points to the NULL char9149  if (dst && end)9150    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9151  return end;9152}9153INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {9154  void *ctx;9155  COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);9156  char *end = REAL(nvis)(dst, dlen, c, flag, nextc);9157  // nvis cannot make sure the dst is NULL terminated9158  if (dst && end)9159    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9160  return end;9161}9162INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {9163  void *ctx;9164  COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);9165  if (src)9166    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9167  int len = REAL(strvis)(dst, src, flag);9168  if (dst)9169    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9170  return len;9171}9172INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {9173  void *ctx;9174  COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);9175  if (src)9176    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9177  int len = REAL(stravis)(dst, src, flag);9178  if (dst) {9179    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));9180    if (*dst)9181      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);9182  }9183  return len;9184}9185INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {9186  void *ctx;9187  COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);9188  if (src)9189    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9190  int len = REAL(strnvis)(dst, dlen, src, flag);9191  // The interface will be valid even if there is no space for NULL char9192  if (dst && len > 0)9193    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9194  return len;9195}9196INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {9197  void *ctx;9198  COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);9199  if (src)9200    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9201  int ret = REAL(strvisx)(dst, src, len, flag);9202  if (dst)9203    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9204  return ret;9205}9206INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9207            int flag) {9208  void *ctx;9209  COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);9210  if (src)9211    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9212  int ret = REAL(strnvisx)(dst, dlen, src, len, flag);9213  if (dst && ret >= 0)9214    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9215  return ret;9216}9217INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9218            int flag, int *cerr_ptr) {9219  void *ctx;9220  COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);9221  if (src)9222    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9223  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold9224  // according to the implementation9225  if (cerr_ptr)9226    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));9227  int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);9228  if (dst && ret >= 0)9229    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9230  if (cerr_ptr)9231    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));9232  return ret;9233}9234INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,9235            const char *extra) {9236  void *ctx;9237  COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);9238  if (extra)9239    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9240  char *end = REAL(svis)(dst, c, flag, nextc, extra);9241  if (dst && end)9242    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);9243  return end;9244}9245INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,9246            const char *extra) {9247  void *ctx;9248  COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);9249  if (extra)9250    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9251  char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);9252  if (dst && end)9253    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,9254                                   Min((SIZE_T)(end - dst + 1), dlen));9255  return end;9256}9257INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,9258            const char *extra) {9259  void *ctx;9260  COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);9261  if (src)9262    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9263  if (extra)9264    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9265  int len = REAL(strsvis)(dst, src, flag, extra);9266  if (dst)9267    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9268  return len;9269}9270INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,9271            const char *extra) {9272  void *ctx;9273  COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);9274  if (src)9275    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9276  if (extra)9277    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9278  int len = REAL(strsnvis)(dst, dlen, src, flag, extra);9279  // The interface will be valid even if there is no space for NULL char9280  if (dst && len >= 0)9281    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);9282  return len;9283}9284INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,9285            const char *extra) {9286  void *ctx;9287  COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);9288  if (src)9289    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9290  if (extra)9291    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9292  int ret = REAL(strsvisx)(dst, src, len, flag, extra);9293  if (dst)9294    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9295  return ret;9296}9297INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,9298            int flag, const char *extra) {9299  void *ctx;9300  COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);9301  if (src)9302    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9303  if (extra)9304    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9305  int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);9306  if (dst && ret >= 0)9307    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9308  return ret;9309}9310INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,9311            SIZE_T len, int flag, const char *extra, int *cerr_ptr) {9312  void *ctx;9313  COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,9314                           cerr_ptr);9315  if (src)9316    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);9317  if (extra)9318    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);9319  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold9320  // according to the implementation9321  if (cerr_ptr)9322    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));9323  int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);9324  if (dst && ret >= 0)9325    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9326  if (cerr_ptr)9327    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));9328  return ret;9329}9330INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {9331  void *ctx;9332  COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);9333  if (astate)9334    COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));9335  int ret = REAL(unvis)(cp, c, astate, flag);9336  if (ret == unvis_valid || ret == unvis_validpush) {9337    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));9338  }9339  return ret;9340}9341INTERCEPTOR(int, strunvis, char *dst, const char *src) {9342  void *ctx;9343  COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);9344  if (src)9345    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9346  int ret = REAL(strunvis)(dst, src);9347  if (ret != -1)9348    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9349  return ret;9350}9351INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {9352  void *ctx;9353  COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);9354  if (src)9355    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9356  int ret = REAL(strnunvis)(dst, dlen, src);9357  if (ret != -1)9358    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9359  return ret;9360}9361INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {9362  void *ctx;9363  COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);9364  if (src)9365    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9366  int ret = REAL(strunvisx)(dst, src, flag);9367  if (ret != -1)9368    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9369  return ret;9370}9371INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,9372            int flag) {9373  void *ctx;9374  COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);9375  if (src)9376    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);9377  int ret = REAL(strnunvisx)(dst, dlen, src, flag);9378  if (ret != -1)9379    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);9380  return ret;9381}9382#define INIT_VIS                                                               \9383  COMMON_INTERCEPT_FUNCTION(vis);                                              \9384  COMMON_INTERCEPT_FUNCTION(nvis);                                             \9385  COMMON_INTERCEPT_FUNCTION(strvis);                                           \9386  COMMON_INTERCEPT_FUNCTION(stravis);                                          \9387  COMMON_INTERCEPT_FUNCTION(strnvis);                                          \9388  COMMON_INTERCEPT_FUNCTION(strvisx);                                          \9389  COMMON_INTERCEPT_FUNCTION(strnvisx);                                         \9390  COMMON_INTERCEPT_FUNCTION(strenvisx);                                        \9391  COMMON_INTERCEPT_FUNCTION(svis);                                             \9392  COMMON_INTERCEPT_FUNCTION(snvis);                                            \9393  COMMON_INTERCEPT_FUNCTION(strsvis);                                          \9394  COMMON_INTERCEPT_FUNCTION(strsnvis);                                         \9395  COMMON_INTERCEPT_FUNCTION(strsvisx);                                         \9396  COMMON_INTERCEPT_FUNCTION(strsnvisx);                                        \9397  COMMON_INTERCEPT_FUNCTION(strsenvisx);                                       \9398  COMMON_INTERCEPT_FUNCTION(unvis);                                            \9399  COMMON_INTERCEPT_FUNCTION(strunvis);                                         \9400  COMMON_INTERCEPT_FUNCTION(strnunvis);                                        \9401  COMMON_INTERCEPT_FUNCTION(strunvisx);                                        \9402  COMMON_INTERCEPT_FUNCTION(strnunvisx)9403#else9404#define INIT_VIS9405#endif9406 9407#if SANITIZER_INTERCEPT_CDB9408INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {9409  void *ctx;9410  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);9411  if (path)9412    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);9413  struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);9414  if (cdbr)9415    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));9416  return cdbr;9417}9418 9419INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,9420  int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {9421  void *ctx;9422  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,9423    cookie);9424  if (base && size)9425    COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);9426  struct __sanitizer_cdbr *cdbr =9427    REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);9428  if (cdbr)9429    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));9430  return cdbr;9431}9432 9433INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {9434  void *ctx;9435  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);9436  if (cdbr)9437    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9438  return REAL(cdbr_entries)(cdbr);9439}9440 9441INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,9442            const void **data, SIZE_T *datalen) {9443  void *ctx;9444  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);9445  if (cdbr)9446    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9447  int ret = REAL(cdbr_get)(cdbr, index, data, datalen);9448  if (!ret) {9449    if (data)9450      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));9451    if (datalen)9452      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));9453    if (data && datalen)9454      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);9455  }9456  return ret;9457}9458 9459INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,9460            SIZE_T keylen, const void **data, SIZE_T *datalen) {9461  void *ctx;9462  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);9463  if (cdbr)9464    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9465  if (key)9466    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9467  int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);9468  if (!ret) {9469    if (data)9470      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));9471    if (datalen)9472      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));9473    if (data && datalen)9474      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);9475  }9476  return ret;9477}9478 9479INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {9480  void *ctx;9481  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);9482  if (cdbr)9483    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));9484  REAL(cdbr_close)(cdbr);9485}9486 9487INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {9488  void *ctx;9489  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);9490  struct __sanitizer_cdbw *ret = REAL(cdbw_open)();9491  if (ret)9492    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));9493  return ret;9494}9495 9496INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,9497  SIZE_T keylen, const void *data, SIZE_T datalen) {9498  void *ctx;9499  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);9500  if (cdbw)9501    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9502  if (data && datalen)9503    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);9504  if (key && keylen)9505    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9506  int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);9507  if (!ret && cdbw)9508    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9509  return ret;9510}9511 9512INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,9513  SIZE_T datalen, u32 *index) {9514  void *ctx;9515  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);9516  if (cdbw)9517    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9518  if (data && datalen)9519    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);9520  int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);9521  if (!ret) {9522    if (index)9523      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));9524    if (cdbw)9525      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9526  }9527  return ret;9528}9529 9530INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,9531  SIZE_T keylen, u32 index) {9532  void *ctx;9533  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);9534  if (cdbw)9535    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9536  if (key && keylen)9537    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);9538  int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);9539  if (!ret && cdbw)9540    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9541  return ret;9542}9543 9544INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,9545  const char descr[16], u32 (*seedgen)(void)) {9546  void *ctx;9547  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);9548  COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);9549  if (cdbw)9550    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9551  if (descr)9552    COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));9553  if (seedgen)9554    COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));9555  int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);9556  if (!ret) {9557    if (cdbw)9558      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));9559    if (output >= 0)9560      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);9561  }9562  return ret;9563}9564 9565INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {9566  void *ctx;9567  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);9568  if (cdbw)9569    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));9570  REAL(cdbw_close)(cdbw);9571}9572 9573#define INIT_CDB \9574  COMMON_INTERCEPT_FUNCTION(cdbr_open); \9575  COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \9576  COMMON_INTERCEPT_FUNCTION(cdbr_entries); \9577  COMMON_INTERCEPT_FUNCTION(cdbr_get); \9578  COMMON_INTERCEPT_FUNCTION(cdbr_find); \9579  COMMON_INTERCEPT_FUNCTION(cdbr_close); \9580  COMMON_INTERCEPT_FUNCTION(cdbw_open); \9581  COMMON_INTERCEPT_FUNCTION(cdbw_put); \9582  COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \9583  COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \9584  COMMON_INTERCEPT_FUNCTION(cdbw_output); \9585  COMMON_INTERCEPT_FUNCTION(cdbw_close)9586#else9587#define INIT_CDB9588#endif9589 9590#if SANITIZER_INTERCEPT_GETFSENT9591INTERCEPTOR(void *, getfsent) {9592  void *ctx;9593  COMMON_INTERCEPTOR_ENTER(ctx, getfsent);9594  void *ret = REAL(getfsent)();9595  if (ret)9596    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9597  return ret;9598}9599 9600INTERCEPTOR(void *, getfsspec, const char *spec) {9601  void *ctx;9602  COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);9603  if (spec)9604    COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1);9605  void *ret = REAL(getfsspec)(spec);9606  if (ret)9607    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9608  return ret;9609}9610 9611INTERCEPTOR(void *, getfsfile, const char *file) {9612  void *ctx;9613  COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);9614  if (file)9615    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);9616  void *ret = REAL(getfsfile)(file);9617  if (ret)9618    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);9619  return ret;9620}9621 9622#define INIT_GETFSENT \9623  COMMON_INTERCEPT_FUNCTION(getfsent); \9624  COMMON_INTERCEPT_FUNCTION(getfsspec); \9625  COMMON_INTERCEPT_FUNCTION(getfsfile);9626#else9627#define INIT_GETFSENT9628#endif9629 9630#if SANITIZER_INTERCEPT_ARC4RANDOM9631INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {9632  void *ctx;9633  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);9634  REAL(arc4random_buf)(buf, len);9635  if (buf && len)9636    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);9637}9638 9639INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {9640  void *ctx;9641  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);9642  if (dat && datlen)9643    COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);9644  REAL(arc4random_addrandom)(dat, datlen);9645}9646 9647#define INIT_ARC4RANDOM \9648  COMMON_INTERCEPT_FUNCTION(arc4random_buf); \9649  COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);9650#else9651#define INIT_ARC4RANDOM9652#endif9653 9654#if SANITIZER_INTERCEPT_POPEN9655INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {9656  void *ctx;9657  COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);9658  if (command)9659    COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1);9660  if (type)9661    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);9662  __sanitizer_FILE *res = REAL(popen)(command, type);9663  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);9664  if (res) unpoison_file(res);9665  return res;9666}9667#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)9668#else9669#define INIT_POPEN9670#endif9671 9672#if SANITIZER_INTERCEPT_POPENVE9673INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,9674            char *const *argv, char *const *envp, const char *type) {9675  void *ctx;9676  COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);9677  if (path)9678    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);9679  if (argv) {9680    for (char *const *pa = argv; ; ++pa) {9681      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));9682      if (!*pa)9683        break;9684      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);9685    }9686  }9687  if (envp) {9688    for (char *const *pa = envp; ; ++pa) {9689      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));9690      if (!*pa)9691        break;9692      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);9693    }9694  }9695  if (type)9696    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);9697  __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);9698  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);9699  if (res) unpoison_file(res);9700  return res;9701}9702#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)9703#else9704#define INIT_POPENVE9705#endif9706 9707#if SANITIZER_INTERCEPT_PCLOSE9708INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {9709  void *ctx;9710  COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);9711  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);9712  const FileMetadata *m = GetInterceptorMetadata(fp);9713  int res = REAL(pclose)(fp);9714  if (m) {9715    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);9716    DeleteInterceptorMetadata(fp);9717  }9718  return res;9719}9720#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);9721#else9722#define INIT_PCLOSE9723#endif9724 9725#if SANITIZER_INTERCEPT_FUNOPEN9726typedef int (*funopen_readfn)(void *cookie, char *buf, int len);9727typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);9728typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);9729typedef int (*funopen_closefn)(void *cookie);9730 9731struct WrappedFunopenCookie {9732  void *real_cookie;9733  funopen_readfn real_read;9734  funopen_writefn real_write;9735  funopen_seekfn real_seek;9736  funopen_closefn real_close;9737};9738 9739static int wrapped_funopen_read(void *cookie, char *buf, int len) {9740  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9741  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9742  funopen_readfn real_read = wrapped_cookie->real_read;9743  return real_read(wrapped_cookie->real_cookie, buf, len);9744}9745 9746static int wrapped_funopen_write(void *cookie, const char *buf, int len) {9747  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9748  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9749  funopen_writefn real_write = wrapped_cookie->real_write;9750  return real_write(wrapped_cookie->real_cookie, buf, len);9751}9752 9753static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {9754  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9755  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9756  funopen_seekfn real_seek = wrapped_cookie->real_seek;9757  return real_seek(wrapped_cookie->real_cookie, offset, whence);9758}9759 9760static int wrapped_funopen_close(void *cookie) {9761  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9762  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;9763  funopen_closefn real_close = wrapped_cookie->real_close;9764  int res = real_close(wrapped_cookie->real_cookie);9765  InternalFree(wrapped_cookie);9766  return res;9767}9768 9769INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,9770            funopen_writefn writefn, funopen_seekfn seekfn,9771            funopen_closefn closefn) {9772  void *ctx;9773  COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,9774                           closefn);9775 9776  WrappedFunopenCookie *wrapped_cookie =9777      (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));9778  wrapped_cookie->real_cookie = cookie;9779  wrapped_cookie->real_read = readfn;9780  wrapped_cookie->real_write = writefn;9781  wrapped_cookie->real_seek = seekfn;9782  wrapped_cookie->real_close = closefn;9783 9784  __sanitizer_FILE *res =9785      REAL(funopen)(wrapped_cookie,9786                    readfn  ? wrapped_funopen_read  : nullptr,9787                    writefn ? wrapped_funopen_write : nullptr,9788                    seekfn  ? wrapped_funopen_seek  : nullptr,9789                    closefn ? wrapped_funopen_close : nullptr);9790  if (res)9791    unpoison_file(res);9792  return res;9793}9794#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)9795#else9796#define INIT_FUNOPEN9797#endif9798 9799#if SANITIZER_INTERCEPT_FUNOPEN29800typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);9801typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);9802typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);9803typedef int (*funopen2_flushfn)(void *cookie);9804typedef int (*funopen2_closefn)(void *cookie);9805 9806struct WrappedFunopen2Cookie {9807  void *real_cookie;9808  funopen2_readfn real_read;9809  funopen2_writefn real_write;9810  funopen2_seekfn real_seek;9811  funopen2_flushfn real_flush;9812  funopen2_closefn real_close;9813};9814 9815static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {9816  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9817  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9818  funopen2_readfn real_read = wrapped_cookie->real_read;9819  return real_read(wrapped_cookie->real_cookie, buf, len);9820}9821 9822static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,9823                                      SIZE_T len) {9824  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9825  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9826  funopen2_writefn real_write = wrapped_cookie->real_write;9827  return real_write(wrapped_cookie->real_cookie, buf, len);9828}9829 9830static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {9831  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);9832  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9833  funopen2_seekfn real_seek = wrapped_cookie->real_seek;9834  return real_seek(wrapped_cookie->real_cookie, offset, whence);9835}9836 9837static int wrapped_funopen2_flush(void *cookie) {9838  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9839  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9840  funopen2_flushfn real_flush = wrapped_cookie->real_flush;9841  return real_flush(wrapped_cookie->real_cookie);9842}9843 9844static int wrapped_funopen2_close(void *cookie) {9845  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);9846  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;9847  funopen2_closefn real_close = wrapped_cookie->real_close;9848  int res = real_close(wrapped_cookie->real_cookie);9849  InternalFree(wrapped_cookie);9850  return res;9851}9852 9853INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,9854            funopen2_writefn writefn, funopen2_seekfn seekfn,9855            funopen2_flushfn flushfn, funopen2_closefn closefn) {9856  void *ctx;9857  COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,9858                           flushfn, closefn);9859 9860  WrappedFunopen2Cookie *wrapped_cookie =9861      (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));9862  wrapped_cookie->real_cookie = cookie;9863  wrapped_cookie->real_read = readfn;9864  wrapped_cookie->real_write = writefn;9865  wrapped_cookie->real_seek = seekfn;9866  wrapped_cookie->real_flush = flushfn;9867  wrapped_cookie->real_close = closefn;9868 9869  __sanitizer_FILE *res =9870      REAL(funopen2)(wrapped_cookie,9871                     readfn  ? wrapped_funopen2_read  : nullptr,9872                     writefn ? wrapped_funopen2_write : nullptr,9873                     seekfn  ? wrapped_funopen2_seek  : nullptr,9874                     flushfn ? wrapped_funopen2_flush : nullptr,9875                     closefn ? wrapped_funopen2_close : nullptr);9876  if (res)9877    unpoison_file(res);9878  return res;9879}9880#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)9881#else9882#define INIT_FUNOPEN29883#endif9884 9885#if SANITIZER_INTERCEPT_FDEVNAME9886INTERCEPTOR(char *, fdevname,  int fd) {9887  void *ctx;9888  COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);9889  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);9890  char *name = REAL(fdevname)(fd);9891  if (name) {9892    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);9893    if (fd > 0)9894      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);9895  }9896  return name;9897}9898 9899INTERCEPTOR(char *, fdevname_r,  int fd, char *buf, SIZE_T len) {9900  void *ctx;9901  COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);9902  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);9903  char *name = REAL(fdevname_r)(fd, buf, len);9904  if (name && buf && len > 0) {9905    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);9906    if (fd > 0)9907      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);9908  }9909  return name;9910}9911 9912#define INIT_FDEVNAME \9913  COMMON_INTERCEPT_FUNCTION(fdevname); \9914  COMMON_INTERCEPT_FUNCTION(fdevname_r);9915#else9916#define INIT_FDEVNAME9917#endif9918 9919#if SANITIZER_INTERCEPT_GETUSERSHELL9920INTERCEPTOR(char *, getusershell,) {9921  void *ctx;9922  COMMON_INTERCEPTOR_ENTER(ctx, getusershell,);9923  char *res = REAL(getusershell)();9924  if (res)9925    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);9926  return res;9927}9928 9929#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);9930#else9931#define INIT_GETUSERSHELL9932#endif9933 9934#if SANITIZER_INTERCEPT_SL_INIT9935INTERCEPTOR(void *, sl_init) {9936  void *ctx;9937  COMMON_INTERCEPTOR_ENTER(ctx, sl_init);9938  void *res = REAL(sl_init)();9939  if (res)9940    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);9941  return res;9942}9943 9944INTERCEPTOR(int, sl_add, void *sl, char *item) {9945  void *ctx;9946  COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);9947  if (sl)9948    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9949  if (item)9950    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);9951  int res = REAL(sl_add)(sl, item);9952  if (!res)9953    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9954  return res;9955}9956 9957INTERCEPTOR(char *, sl_find, void *sl, const char *item) {9958  void *ctx;9959  COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);9960  if (sl)9961    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9962  if (item)9963    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);9964  char *res = REAL(sl_find)(sl, item);9965  if (res)9966    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);9967  return res;9968}9969 9970INTERCEPTOR(void, sl_free, void *sl, int freeall) {9971  void *ctx;9972  COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);9973  if (sl)9974    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);9975  REAL(sl_free)(sl, freeall);9976}9977 9978#define INIT_SL_INIT                  \9979  COMMON_INTERCEPT_FUNCTION(sl_init); \9980  COMMON_INTERCEPT_FUNCTION(sl_add);  \9981  COMMON_INTERCEPT_FUNCTION(sl_find); \9982  COMMON_INTERCEPT_FUNCTION(sl_free);9983#else9984#define INIT_SL_INIT9985#endif9986 9987#if SANITIZER_INTERCEPT_GETRANDOM9988INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {9989  void *ctx;9990  COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);9991  // If GRND_NONBLOCK is set in the flags, it is non blocking.9992  static const int grnd_nonblock = 1;9993  SSIZE_T n;9994  if ((flags & grnd_nonblock))9995    n = REAL(getrandom)(buf, buflen, flags);9996  else9997    n = COMMON_INTERCEPTOR_BLOCK_REAL(getrandom)(buf, buflen, flags);9998  if (n > 0) {9999    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);10000  }10001  return n;10002}10003#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)10004#else10005#define INIT_GETRANDOM10006#endif10007 10008#if SANITIZER_INTERCEPT_GETENTROPY10009INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {10010  void *ctx;10011  COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);10012  int r = REAL(getentropy)(buf, buflen);10013  if (r == 0) {10014    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);10015  }10016  return r;10017}10018#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)10019#else10020#define INIT_GETENTROPY10021#endif10022 10023#if SANITIZER_INTERCEPT_QSORT_R10024typedef int (*qsort_r_compar_f)(const void *, const void *, void *);10025struct qsort_r_compar_params {10026  SIZE_T size;10027  qsort_r_compar_f compar;10028  void *arg;10029};10030static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {10031  qsort_r_compar_params *params = (qsort_r_compar_params *)arg;10032  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);10033  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size);10034  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size);10035  return params->compar(a, b, params->arg);10036}10037 10038INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,10039            qsort_r_compar_f compar, void *arg) {10040  void *ctx;10041  COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);10042  // Run the comparator over all array elements to detect any memory issues.10043  if (nmemb > 1) {10044    for (SIZE_T i = 0; i < nmemb - 1; ++i) {10045      void *p = (void *)((char *)base + i * size);10046      void *q = (void *)((char *)base + (i + 1) * size);10047      COMMON_INTERCEPTOR_UNPOISON_PARAM(3);10048      compar(p, q, arg);10049    }10050  }10051  qsort_r_compar_params params = {size, compar, arg};10052  REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, &params);10053  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);10054}10055#  define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)10056#else10057#  define INIT_QSORT_R10058#endif10059 10060#if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R10061INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,10062            qsort_r_compar_f compar) {10063  void *ctx;10064  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);10065  WRAP(qsort_r)(base, nmemb, size, compar, nullptr);10066}10067#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)10068#elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R10069// Glibc qsort uses a temporary buffer allocated either on stack or on heap.10070// Poisoned memory from there may get copied into the comparator arguments,10071// where it needs to be dealt with. But even that is not enough - the results of10072// the sort may be copied into the input/output array based on the results of10073// the comparator calls, but directly from the temp memory, bypassing the10074// unpoisoning done in wrapped_qsort_compar. We deal with this by, again,10075// unpoisoning the entire array after the sort is done.10076//10077// We can not check that the entire array is initialized at the beginning. IMHO,10078// it's fine for parts of the sorted objects to contain uninitialized memory,10079// ex. as padding in structs.10080typedef int (*qsort_compar_f)(const void *, const void *);10081static THREADLOCAL qsort_compar_f qsort_compar;10082static THREADLOCAL SIZE_T qsort_size;10083static int wrapped_qsort_compar(const void *a, const void *b) {10084  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10085  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);10086  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);10087  return qsort_compar(a, b);10088}10089 10090INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,10091            qsort_compar_f compar) {10092  void *ctx;10093  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);10094  // Run the comparator over all array elements to detect any memory issues.10095  if (nmemb > 1) {10096    for (SIZE_T i = 0; i < nmemb - 1; ++i) {10097      void *p = (void *)((char *)base + i * size);10098      void *q = (void *)((char *)base + (i + 1) * size);10099      COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10100      compar(p, q);10101    }10102  }10103  qsort_compar_f old_compar = qsort_compar;10104  SIZE_T old_size = qsort_size;10105  // Handle qsort() implementations that recurse using an10106  // interposable function call:10107  bool already_wrapped = compar == wrapped_qsort_compar;10108  if (already_wrapped) {10109    // This case should only happen if the qsort() implementation calls itself10110    // using a preemptible function call (e.g. the FreeBSD libc version).10111    // Check that the size and comparator arguments are as expected.10112    CHECK_NE(compar, qsort_compar);10113    CHECK_EQ(qsort_size, size);10114  } else {10115    qsort_compar = compar;10116    qsort_size = size;10117  }10118  REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);10119  if (!already_wrapped) {10120    qsort_compar = old_compar;10121    qsort_size = old_size;10122  }10123  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);10124}10125#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)10126#else10127#  define INIT_QSORT10128#endif10129 10130#if SANITIZER_INTERCEPT_BSEARCH10131typedef int (*bsearch_compar_f)(const void *, const void *);10132struct bsearch_compar_params {10133  const void *key;10134  bsearch_compar_f compar;10135};10136 10137static int wrapped_bsearch_compar(const void *key, const void *b) {10138  const bsearch_compar_params *params = (const bsearch_compar_params *)key;10139  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);10140  return params->compar(params->key, b);10141}10142 10143INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb,10144            SIZE_T size, bsearch_compar_f compar) {10145  void *ctx;10146  COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar);10147  bsearch_compar_params params = {key, compar};10148  return REAL(bsearch)(&params, base, nmemb, size, wrapped_bsearch_compar);10149}10150#  define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch)10151#else10152#  define INIT_BSEARCH10153#endif10154 10155#if SANITIZER_INTERCEPT_SIGALTSTACK10156INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {10157  void *ctx;10158  COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);10159  int r = REAL(sigaltstack)(ss, oss);10160  if (r == 0 && oss != nullptr) {10161    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);10162  }10163  return r;10164}10165#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)10166#else10167#define INIT_SIGALTSTACK10168#endif10169 10170#if SANITIZER_INTERCEPT_PROCCTL10171INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) {10172   void *ctx;10173   COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data);10174   static const int PROC_REAP_ACQUIRE = 2;10175   static const int PROC_REAP_RELEASE = 3;10176   static const int PROC_REAP_STATUS = 4;10177   static const int PROC_REAP_GETPIDS = 5;10178   static const int PROC_REAP_KILL = 6;10179   if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) {10180     COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int));10181   } else {10182     // reap_acquire/reap_release bears no arguments.10183     if (cmd > PROC_REAP_RELEASE) {10184       unsigned int reapsz;10185       switch (cmd) {10186       case PROC_REAP_STATUS:10187         reapsz = struct_procctl_reaper_status_sz;10188         break;10189       case PROC_REAP_GETPIDS:10190         reapsz = struct_procctl_reaper_pids_sz;10191         break;10192       case PROC_REAP_KILL:10193         reapsz = struct_procctl_reaper_kill_sz;10194         break;10195       }10196       COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz);10197     }10198   }10199   return REAL(procctl)(idtype, id, cmd, data);10200}10201#define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl)10202#else10203#define INIT_PROCCTL10204#endif10205 10206#if SANITIZER_INTERCEPT_UNAME10207INTERCEPTOR(int, uname, struct utsname *utsname) {10208#if SANITIZER_LINUX10209  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)10210    return internal_uname(utsname);10211#endif10212  void *ctx;10213  COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);10214  int res = REAL(uname)(utsname);10215  if (!res)10216    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,10217                                   __sanitizer::struct_utsname_sz);10218  return res;10219}10220#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)10221#else10222#define INIT_UNAME10223#endif10224 10225#if SANITIZER_INTERCEPT___XUNAME10226// FreeBSD's <sys/utsname.h> define uname() as10227// static __inline int uname(struct utsname *name) {10228//   return __xuname(SYS_NMLN, (void*)name);10229// }10230INTERCEPTOR(int, __xuname, int size, void *utsname) {10231  void *ctx;10232  COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);10233  int res = REAL(__xuname)(size, utsname);10234  if (!res)10235    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,10236                                   __sanitizer::struct_utsname_sz);10237  return res;10238}10239#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)10240#else10241#define INIT___XUNAME10242#endif10243 10244#if SANITIZER_INTERCEPT_ARGP_PARSE10245INTERCEPTOR(int, argp_parse, const struct argp *argp, int argc, char **argv,10246            unsigned flags, int *arg_index, void *input) {10247  void *ctx;10248  COMMON_INTERCEPTOR_ENTER(ctx, argp_parse, argp, argc, argv, flags, arg_index,10249                           input);10250  for (int i = 0; i < argc; i++)10251    COMMON_INTERCEPTOR_READ_RANGE(ctx, argv[i], internal_strlen(argv[i]) + 1);10252  int res = REAL(argp_parse)(argp, argc, argv, flags, arg_index, input);10253  if (!res && arg_index)10254    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg_index, sizeof(int));10255  return res;10256}10257 10258#define INIT_ARGP_PARSE COMMON_INTERCEPT_FUNCTION(argp_parse);10259#else10260#define INIT_ARGP_PARSE10261#endif10262 10263#if SANITIZER_INTERCEPT_CPUSET_GETAFFINITY10264INTERCEPTOR(int, cpuset_getaffinity, int level, int which, __int64_t id, SIZE_T cpusetsize, __sanitizer_cpuset_t *mask) {10265  void *ctx;10266  COMMON_INTERCEPTOR_ENTER(ctx, cpuset_getaffinity, level, which, id, cpusetsize, mask);10267  int res = REAL(cpuset_getaffinity)(level, which, id, cpusetsize, mask);10268  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);10269  return res;10270}10271#define INIT_CPUSET_GETAFFINITY COMMON_INTERCEPT_FUNCTION(cpuset_getaffinity);10272#else10273#define INIT_CPUSET_GETAFFINITY10274#endif10275 10276#if SANITIZER_INTERCEPT_PREADV210277INTERCEPTOR(SSIZE_T, preadv2, int fd, __sanitizer_iovec *iov, int iovcnt,10278            OFF_T offset, int flags) {10279  void *ctx;10280  COMMON_INTERCEPTOR_ENTER(ctx, preadv2, fd, iov, iovcnt, offset, flags);10281  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10282  SSIZE_T res = REAL(preadv2)(fd, iov, iovcnt, offset, flags);10283  if (res > 0) write_iovec(ctx, iov, iovcnt, res);10284  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);10285  return res;10286}10287#define INIT_PREADV2 COMMON_INTERCEPT_FUNCTION(preadv2)10288#else10289#define INIT_PREADV210290#endif10291 10292#if SANITIZER_INTERCEPT_PWRITEV210293INTERCEPTOR(SSIZE_T, pwritev2, int fd, __sanitizer_iovec *iov, int iovcnt,10294            OFF_T offset, int flags) {10295  void *ctx;10296  COMMON_INTERCEPTOR_ENTER(ctx, pwritev2, fd, iov, iovcnt, offset, flags);10297  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10298  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);10299  SSIZE_T res = REAL(pwritev2)(fd, iov, iovcnt, offset, flags);10300  if (res > 0) read_iovec(ctx, iov, iovcnt, res);10301  return res;10302}10303#define INIT_PWRITEV2 COMMON_INTERCEPT_FUNCTION(pwritev2)10304#else10305#define INIT_PWRITEV210306#endif10307 10308#if SANITIZER_INTERCEPT_FREADLINK10309INTERCEPTOR(SSIZE_T, freadlink, int fd, char *buf, SIZE_T bufsiz) {10310  void *ctx;10311  COMMON_INTERCEPTOR_ENTER(ctx, freadlink, fd, buf, bufsiz);10312  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);10313  SSIZE_T res = REAL(freadlink)(fd, buf, bufsiz);10314  if (res > 0)10315    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);10316  if (res >= 0 && fd > 0)10317    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);10318  return res;10319}10320#  define INIT_FREADLINK COMMON_INTERCEPT_FUNCTION(freadlink)10321#else10322#  define INIT_FREADLINK10323#endif10324 10325#if SANITIZER_INTERCEPT_GETSERVENT_R || SANITIZER_INTERCEPT_GETSERVBYNAME_R || \10326    SANITIZER_INTERCEPT_GETSERVBYPORT_R10327 10328UNUSED static void HandleGetServentReentrantResult(10329    void *ctx, int res, struct __sanitizer_servent *result_buf, char *buf,10330    SIZE_T buflen, struct __sanitizer_servent **result) {10331  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)result, sizeof(void *));10332  if (res)10333    return;10334  if (*result) {10335    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (char *)*result,10336                                   sizeof(__sanitizer_servent));10337    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);10338  }10339}10340 10341#endif10342 10343#if SANITIZER_INTERCEPT_GETSERVENT_R10344INTERCEPTOR(int, getservent_r, struct __sanitizer_servent *result_buf,10345            char *buf, SIZE_T buflen, struct __sanitizer_servent **result) {10346  void *ctx;10347  COMMON_INTERCEPTOR_ENTER(ctx, getservent_r, result_buf, buf, buflen, result);10348  int res = REAL(getservent_r)(result_buf, buf, buflen, result);10349  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10350  return res;10351}10352#  define INIT_GETSERVENT_R COMMON_INTERCEPT_FUNCTION(getservent_r)10353#else10354#  define INIT_GETSERVENT_R10355#endif10356 10357#if SANITIZER_INTERCEPT_GETSERVBYNAME_R10358INTERCEPTOR(int, getservbyname_r, const char *name, const char *proto,10359            struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,10360            struct __sanitizer_servent **result) {10361  void *ctx;10362  COMMON_INTERCEPTOR_ENTER(ctx, getservbyname_r, name, proto, result_buf, buf,10363                           buflen, result);10364  COMMON_INTERCEPTOR_READ_STRING(ctx, name, internal_strlen(name));10365  int res = REAL(getservbyname_r)(name, proto, result_buf, buf, buflen, result);10366  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10367  return res;10368}10369#  define INIT_GETSERVBYNAME_R COMMON_INTERCEPT_FUNCTION(getservbyname_r)10370#else10371#  define INIT_GETSERVBYNAME_R10372#endif10373 10374#if SANITIZER_INTERCEPT_GETSERVBYPORT_R10375INTERCEPTOR(int, getservbyport_r, int port, const char *proto,10376            struct __sanitizer_servent *result_buf, char *buf, SIZE_T buflen,10377            struct __sanitizer_servent **result) {10378  void *ctx;10379  COMMON_INTERCEPTOR_ENTER(ctx, getservbyport_r, port, proto, result_buf, buf,10380                           buflen, result);10381  int res = REAL(getservbyport_r)(port, proto, result_buf, buf, buflen, result);10382  HandleGetServentReentrantResult(ctx, res, result_buf, buf, buflen, result);10383  return res;10384}10385#  define INIT_GETSERVBYPORT_R COMMON_INTERCEPT_FUNCTION(getservbyport_r)10386#else10387#  define INIT_GETSERVBYPORT_R10388#endif10389 10390#include "sanitizer_common_interceptors_netbsd_compat.inc"10391 10392namespace __sanitizer {10393void InitializeMemintrinsicInterceptors();10394}  // namespace __sanitizer10395 10396static void InitializeCommonInterceptors() {10397#if SI_POSIX10398  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];10399  interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();10400#endif10401 10402  __sanitizer::InitializeMemintrinsicInterceptors();10403 10404  INIT_MMAP;10405  INIT_MMAP64;10406  INIT_TEXTDOMAIN;10407  INIT_STRLEN;10408  INIT_STRNLEN;10409  INIT_STRNDUP;10410  INIT___STRNDUP;10411  INIT_STRCMP;10412  INIT_STRNCMP;10413  INIT_STRCASECMP;10414  INIT_STRNCASECMP;10415  INIT_STRSTR;10416  INIT_STRCASESTR;10417  INIT_STRCHR;10418  INIT_STRCHRNUL;10419  INIT_STRRCHR;10420  INIT_STRSPN;10421  INIT_STRTOK;10422  INIT_STRPBRK;10423  INIT_STRXFRM;10424  INIT___STRXFRM_L;10425  INIT_MEMCHR;10426  INIT_MEMCMP;10427  INIT_BCMP;10428  INIT_MEMRCHR;10429  INIT_MEMMEM;10430  INIT_READ;10431  INIT_FREAD;10432  INIT_PREAD;10433  INIT_PREAD64;10434  INIT_READV;10435  INIT_PREADV;10436  INIT_PREADV64;10437  INIT_WRITE;10438  INIT_FWRITE;10439  INIT_PWRITE;10440  INIT_PWRITE64;10441  INIT_WRITEV;10442  INIT_PWRITEV;10443  INIT_PWRITEV64;10444  INIT_FGETS;10445  INIT_FPUTS;10446  INIT_PUTS;10447  INIT_PRCTL;10448  INIT_LOCALTIME_AND_FRIENDS;10449  INIT_STRPTIME;10450  INIT_SCANF;10451  INIT_ISOC99_SCANF;10452  INIT_PRINTF;10453  INIT_PRINTF_L;10454  INIT_ISOC99_PRINTF;10455  INIT_SETPROCTITLE;10456  INIT_FREXP;10457  INIT_FREXPF;10458  INIT_FREXPL;10459  INIT_GETPWNAM_AND_FRIENDS;10460  INIT_GETPWNAM_R_AND_FRIENDS;10461  INIT_GETPWENT;10462  INIT_FGETPWENT;10463  INIT_GETPWENT_R;10464  INIT_FGETPWENT_R;10465  INIT_FGETGRENT_R;10466  INIT_SETPWENT;10467  INIT_CLOCK_GETTIME;10468  INIT_CLOCK_GETCPUCLOCKID;10469  INIT_TIMER_CREATE;10470  INIT_GETITIMER;10471  INIT_TIME;10472  INIT_TIMESPEC_GET;10473  INIT_GLOB;10474  INIT_GLOB64;10475  INIT___B64_TO;10476  INIT_DN_COMP_EXPAND;10477  INIT_POSIX_SPAWN;10478  INIT_WAIT;10479  INIT_WAIT4;10480  INIT_INET;10481  INIT_PTHREAD_GETSCHEDPARAM;10482  INIT_GETADDRINFO;10483  INIT_GETNAMEINFO;10484  INIT_GETSOCKNAME;10485  INIT_GETHOSTBYNAME;10486  INIT_GETHOSTBYNAME2;10487  INIT_GETHOSTBYNAME_R;10488  INIT_GETHOSTBYNAME2_R;10489  INIT_GETHOSTBYADDR_R;10490  INIT_GETHOSTENT_R;10491  INIT_GETSOCKOPT;10492  INIT_ACCEPT;10493  INIT_ACCEPT4;10494  INIT_PACCEPT;10495  INIT_MODF;10496  INIT_RECVMSG;10497  INIT_SENDMSG;10498  INIT_RECVMMSG;10499  INIT_SENDMMSG;10500  INIT_SYSMSG;10501  INIT_GETPEERNAME;10502  INIT_IOCTL;10503  INIT_INET_ATON;10504  INIT_SYSINFO;10505  INIT_READDIR;10506  INIT_READDIR64;10507  INIT_PTRACE;10508  INIT_SETLOCALE;10509  INIT_GETCWD;10510  INIT_GET_CURRENT_DIR_NAME;10511  INIT_STRTOIMAX;10512  INIT_STRTOIMAX_C23;10513  INIT_MBSTOWCS;10514  INIT_MBSNRTOWCS;10515  INIT_WCSTOMBS;10516  INIT_WCSNRTOMBS;10517  INIT_WCRTOMB;10518  INIT_WCTOMB;10519  INIT_TCGETATTR;10520  INIT_REALPATH;10521  INIT_CANONICALIZE_FILE_NAME;10522  INIT_CONFSTR;10523  INIT_SCHED_GETAFFINITY;10524  INIT_SCHED_GETPARAM;10525  INIT_STRERROR;10526  INIT_STRERROR_R;10527  INIT_XPG_STRERROR_R;10528  INIT_SCANDIR;10529  INIT_SCANDIR64;10530  INIT_GETGROUPS;10531  INIT_POLL;10532  INIT_PPOLL;10533  INIT_WORDEXP;10534  INIT_SIGWAIT;10535  INIT_SIGWAITINFO;10536  INIT_SIGTIMEDWAIT;10537  INIT_SIGSETOPS;10538  INIT_SIGSET_LOGICOPS;10539  INIT_SIGPENDING;10540  INIT_SIGPROCMASK;10541  INIT_PTHREAD_SIGMASK;10542  INIT_BACKTRACE;10543  INIT__EXIT;10544  INIT___LIBC_THR_SETCANCELSTATE;10545  INIT_GETMNTENT;10546  INIT_GETMNTENT_R;10547  INIT_STATFS;10548  INIT_STATFS64;10549  INIT_STATVFS;10550  INIT_STATVFS64;10551  INIT_INITGROUPS;10552  INIT_ETHER_NTOA_ATON;10553  INIT_ETHER_HOST;10554  INIT_ETHER_R;10555  INIT_SHMCTL;10556  INIT_RANDOM_R;10557  INIT_PTHREAD_ATTR_GET;10558  INIT_PTHREAD_ATTR_GET_SCHED;10559  INIT_PTHREAD_ATTR_GETINHERITSCHED;10560  INIT_PTHREAD_ATTR_GETAFFINITY_NP;10561  INIT_PTHREAD_GETAFFINITY_NP;10562  INIT_PTHREAD_MUTEXATTR_GETPSHARED;10563  INIT_PTHREAD_MUTEXATTR_GETTYPE;10564  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;10565  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;10566  INIT_PTHREAD_MUTEXATTR_GETROBUST;10567  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;10568  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;10569  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;10570  INIT_PTHREAD_CONDATTR_GETPSHARED;10571  INIT_PTHREAD_CONDATTR_GETCLOCK;10572  INIT_PTHREAD_BARRIERATTR_GETPSHARED;10573  INIT_TMPNAM;10574  INIT_TMPNAM_R;10575  INIT_PTSNAME;10576  INIT_PTSNAME_R;10577  INIT_TTYNAME;10578  INIT_TTYNAME_R;10579  INIT_TEMPNAM;10580  INIT_PTHREAD_SETNAME_NP;10581  INIT_PTHREAD_GETNAME_NP;10582  INIT_SINCOS;10583  INIT_REMQUO;10584  INIT_REMQUOL;10585  INIT_LGAMMA;10586  INIT_LGAMMAL;10587  INIT_LGAMMA_R;10588  INIT_LGAMMAL_R;10589  INIT_DRAND48_R;10590  INIT_RAND_R;10591  INIT_GETLINE;10592  INIT_ICONV;10593  INIT_TIMES;10594  INIT_TLS_GET_ADDR;10595  INIT_LISTXATTR;10596  INIT_GETXATTR;10597  INIT_GETRESID;10598  INIT_GETIFADDRS;10599  INIT_IF_INDEXTONAME;10600  INIT_CAPGET;10601  INIT_FTIME;10602  INIT_XDR;10603  INIT_XDRREC_LINUX;10604  INIT_TSEARCH;10605  INIT_LIBIO_INTERNALS;10606  INIT_FOPEN;10607  INIT_FOPEN64;10608  INIT_FLOPEN;10609  INIT_OPEN_MEMSTREAM;10610  INIT_OBSTACK;10611  INIT_FFLUSH;10612  INIT_FCLOSE;10613  INIT_DLOPEN_DLCLOSE;10614  INIT_GETPASS;10615  INIT_TIMERFD;10616  INIT_MLOCKX;10617  INIT_FOPENCOOKIE;10618  INIT_SEM;10619  INIT_PTHREAD_SETCANCEL;10620  INIT_MINCORE;10621  INIT_PROCESS_VM_READV;10622  INIT_CTERMID;10623  INIT_CTERMID_R;10624  INIT_RECV_RECVFROM;10625  INIT_SEND_SENDTO;10626  INIT_STAT;10627  INIT_STAT64;10628  INIT_EVENTFD_READ_WRITE;10629  INIT_LSTAT;10630  INIT_LSTAT64;10631  INIT___XSTAT;10632  INIT___XSTAT64;10633  INIT___LXSTAT;10634  INIT___LXSTAT64;10635  // FIXME: add other *stat interceptors.10636  INIT_UTMP;10637  INIT_UTMPX;10638  INIT_GETLOADAVG;10639  INIT_WCSLEN;10640  INIT_WCSCAT;10641  INIT_WCSDUP;10642  INIT_WCSXFRM;10643  INIT___WCSXFRM_L;10644  INIT_ACCT;10645  INIT_USER_FROM_UID;10646  INIT_UID_FROM_USER;10647  INIT_GROUP_FROM_GID;10648  INIT_GID_FROM_GROUP;10649  INIT_ACCESS;10650  INIT_FACCESSAT;10651  INIT_GETGROUPLIST;10652  INIT_GETGROUPMEMBERSHIP;10653  INIT_READLINK;10654  INIT_READLINKAT;10655  INIT_NAME_TO_HANDLE_AT;10656  INIT_OPEN_BY_HANDLE_AT;10657  INIT_STRLCPY;10658  INIT_DEVNAME;10659  INIT_DEVNAME_R;10660  INIT_FGETLN;10661  INIT_STRMODE;10662  INIT_TTYENT;10663  INIT_PROTOENT;10664  INIT_PROTOENT_R;10665  INIT_NETENT;10666  INIT_GETMNTINFO;10667  INIT_MI_VECTOR_HASH;10668  INIT_SETVBUF;10669  INIT_GETVFSSTAT;10670  INIT_REGEX;10671  INIT_REGEXSUB;10672  INIT_FTS;10673  INIT_SYSCTL;10674  INIT_ASYSCTL;10675  INIT_SYSCTLGETMIBINFO;10676  INIT_NL_LANGINFO;10677  INIT_MODCTL;10678  INIT_STRTONUM;10679  INIT_FPARSELN;10680  INIT_STATVFS1;10681  INIT_STRTOI;10682  INIT_CAPSICUM;10683  INIT_SHA1;10684  INIT_MD4;10685  INIT_RMD160;10686  INIT_FSEEK;10687  INIT_MD2;10688  INIT_VIS;10689  INIT_CDB;10690  INIT_GETFSENT;10691  INIT_ARC4RANDOM;10692  INIT_POPEN;10693  INIT_POPENVE;10694  INIT_PCLOSE;10695  INIT_FUNOPEN;10696  INIT_FUNOPEN2;10697  INIT_FDEVNAME;10698  INIT_GETUSERSHELL;10699  INIT_SL_INIT;10700  INIT_GETRANDOM;10701  INIT_GETENTROPY;10702  INIT_QSORT;10703  INIT_QSORT_R;10704  INIT_BSEARCH;10705  INIT_SIGALTSTACK;10706  INIT_PROCCTL10707  INIT_UNAME;10708  INIT___XUNAME;10709  INIT_ARGP_PARSE;10710  INIT_CPUSET_GETAFFINITY;10711  INIT_PREADV2;10712  INIT_PWRITEV2;10713  INIT_FREADLINK;10714 10715  INIT___PRINTF_CHK;10716  INIT_GETSERVENT_R;10717  INIT_GETSERVBYNAME_R;10718  INIT_GETSERVBYPORT_R;10719}10720