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