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