sanitizer_common_interceptors.inc revision e4f9f8a1296768a7a6b6646a3b241a379f4a5e15
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2//
3//                     The LLVM Compiler Infrastructure
4//
5// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
7//
8//===----------------------------------------------------------------------===//
9//
10// Common function interceptors for tools like AddressSanitizer,
11// ThreadSanitizer, MemorySanitizer, etc.
12//
13// This file should be included into the tool's interceptor file,
14// which has to define it's own macros:
15//   COMMON_INTERCEPTOR_ENTER
16//   COMMON_INTERCEPTOR_READ_RANGE
17//   COMMON_INTERCEPTOR_WRITE_RANGE
18//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
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_EXIT
24//   COMMON_INTERCEPTOR_MUTEX_LOCK
25//   COMMON_INTERCEPTOR_MUTEX_UNLOCK
26//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
27//===----------------------------------------------------------------------===//
28#include "interception/interception.h"
29#include "sanitizer_platform_interceptors.h"
30
31#include <stdarg.h>
32
33#if SANITIZER_WINDOWS
34#define va_copy(dst, src) ((dst) = (src))
35#endif // _WIN32
36
37#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
38#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {}
39#endif
40
41#ifndef COMMON_INTERCEPTOR_FD_ACCESS
42#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
43#endif
44
45#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
46#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
47#endif
48
49#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
50#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
51#endif
52
53#if SANITIZER_INTERCEPT_STRCMP
54static inline int CharCmpX(unsigned char c1, unsigned char c2) {
55  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
56}
57
58INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
59  void *ctx;
60  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
61  unsigned char c1, c2;
62  uptr i;
63  for (i = 0; ; i++) {
64    c1 = (unsigned char)s1[i];
65    c2 = (unsigned char)s2[i];
66    if (c1 != c2 || c1 == '\0') break;
67  }
68  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
69  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
70  return CharCmpX(c1, c2);
71}
72
73INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
74  void *ctx;
75  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
76  unsigned char c1 = 0, c2 = 0;
77  uptr i;
78  for (i = 0; i < size; i++) {
79    c1 = (unsigned char)s1[i];
80    c2 = (unsigned char)s2[i];
81    if (c1 != c2 || c1 == '\0') break;
82  }
83  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
84  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
85  return CharCmpX(c1, c2);
86}
87
88#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp)
89#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp)
90#else
91#define INIT_STRCMP
92#define INIT_STRNCMP
93#endif
94
95#if SANITIZER_INTERCEPT_STRCASECMP
96static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
97  int c1_low = ToLower(c1);
98  int c2_low = ToLower(c2);
99  return c1_low - c2_low;
100}
101
102INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
103  void *ctx;
104  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
105  unsigned char c1 = 0, c2 = 0;
106  uptr i;
107  for (i = 0; ; i++) {
108    c1 = (unsigned char)s1[i];
109    c2 = (unsigned char)s2[i];
110    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
111      break;
112  }
113  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
114  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
115  return CharCaseCmp(c1, c2);
116}
117
118INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
119  void *ctx;
120  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
121  unsigned char c1 = 0, c2 = 0;
122  uptr i;
123  for (i = 0; i < n; i++) {
124    c1 = (unsigned char)s1[i];
125    c2 = (unsigned char)s2[i];
126    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
127      break;
128  }
129  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
130  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
131  return CharCaseCmp(c1, c2);
132}
133
134#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
135#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
136#else
137#define INIT_STRCASECMP
138#define INIT_STRNCASECMP
139#endif
140
141#if SANITIZER_INTERCEPT_FREXP
142INTERCEPTOR(double, frexp, double x, int *exp) {
143  void *ctx;
144  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
145  double res = REAL(frexp)(x, exp);
146  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
147  return res;
148}
149
150#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
151#else
152#define INIT_FREXP
153#endif // SANITIZER_INTERCEPT_FREXP
154
155#if SANITIZER_INTERCEPT_FREXPF_FREXPL
156INTERCEPTOR(float, frexpf, float x, int *exp) {
157  void *ctx;
158  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
159  float res = REAL(frexpf)(x, exp);
160  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
161  return res;
162}
163
164INTERCEPTOR(long double, frexpl, long double x, int *exp) {
165  void *ctx;
166  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
167  long double res = REAL(frexpl)(x, exp);
168  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
169  return res;
170}
171
172#define INIT_FREXPF_FREXPL                       \
173  INTERCEPT_FUNCTION(frexpf);                    \
174  INTERCEPT_FUNCTION(frexpl)
175#else
176#define INIT_FREXPF_FREXPL
177#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
178
179#if SI_NOT_WINDOWS
180static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
181                        SIZE_T iovlen, SIZE_T maxlen) {
182  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
183    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
184    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
185    maxlen -= sz;
186  }
187}
188
189static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
190                       SIZE_T iovlen, SIZE_T maxlen) {
191  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
192  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
193    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
194    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
195    maxlen -= sz;
196  }
197}
198#endif
199
200#if SANITIZER_INTERCEPT_READ
201INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
202  void *ctx;
203  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
204  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
205  SSIZE_T res = REAL(read)(fd, ptr, count);
206  if (res > 0)
207    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
208  if (res >= 0 && fd >= 0)
209    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
210  return res;
211}
212#define INIT_READ INTERCEPT_FUNCTION(read)
213#else
214#define INIT_READ
215#endif
216
217#if SANITIZER_INTERCEPT_PREAD
218INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
219  void *ctx;
220  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
221  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
222  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
223  if (res > 0)
224    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
225  if (res >= 0 && fd >= 0)
226    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
227  return res;
228}
229#define INIT_PREAD INTERCEPT_FUNCTION(pread)
230#else
231#define INIT_PREAD
232#endif
233
234#if SANITIZER_INTERCEPT_PREAD64
235INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
236  void *ctx;
237  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
238  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
239  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
240  if (res > 0)
241    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
242  if (res >= 0 && fd >= 0)
243    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
244  return res;
245}
246#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
247#else
248#define INIT_PREAD64
249#endif
250
251#if SANITIZER_INTERCEPT_READV
252INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
253                        int iovcnt) {
254  void *ctx;
255  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
256  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
257  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
258  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
259  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
260  return res;
261}
262#define INIT_READV INTERCEPT_FUNCTION(readv)
263#else
264#define INIT_READV
265#endif
266
267#if SANITIZER_INTERCEPT_PREADV
268INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
269            OFF_T offset) {
270  void *ctx;
271  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
272  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
273  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
274  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
275  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
276  return res;
277}
278#define INIT_PREADV INTERCEPT_FUNCTION(preadv)
279#else
280#define INIT_PREADV
281#endif
282
283#if SANITIZER_INTERCEPT_PREADV64
284INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
285            OFF64_T offset) {
286  void *ctx;
287  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
288  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
289  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
290  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
291  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
292  return res;
293}
294#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64)
295#else
296#define INIT_PREADV64
297#endif
298
299#if SANITIZER_INTERCEPT_WRITE
300INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
301  void *ctx;
302  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
303  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
304  if (fd >= 0)
305    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
306  SSIZE_T res = REAL(write)(fd, ptr, count);
307  // FIXME: this check should be _before_ the call to REAL(write), not after
308  if (res > 0)
309    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
310  return res;
311}
312#define INIT_WRITE INTERCEPT_FUNCTION(write)
313#else
314#define INIT_WRITE
315#endif
316
317#if SANITIZER_INTERCEPT_PWRITE
318INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
319  void *ctx;
320  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
321  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
322  if (fd >= 0)
323    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
324  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
325  if (res > 0)
326    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
327  return res;
328}
329#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
330#else
331#define INIT_PWRITE
332#endif
333
334#if SANITIZER_INTERCEPT_PWRITE64
335INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
336            OFF64_T offset) {
337  void *ctx;
338  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
339  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
340  if (fd >= 0)
341    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
342  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
343  if (res > 0)
344    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
345  return res;
346}
347#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
348#else
349#define INIT_PWRITE64
350#endif
351
352#if SANITIZER_INTERCEPT_WRITEV
353INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
354                        int iovcnt) {
355  void *ctx;
356  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
357  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
358  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
359  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
360  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
361  return res;
362}
363#define INIT_WRITEV INTERCEPT_FUNCTION(writev)
364#else
365#define INIT_WRITEV
366#endif
367
368#if SANITIZER_INTERCEPT_PWRITEV
369INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
370            OFF_T offset) {
371  void *ctx;
372  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
373  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
374  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
375  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
376  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
377  return res;
378}
379#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev)
380#else
381#define INIT_PWRITEV
382#endif
383
384#if SANITIZER_INTERCEPT_PWRITEV64
385INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
386            OFF64_T offset) {
387  void *ctx;
388  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
389  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
390  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
391  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
392  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
393  return res;
394}
395#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
396#else
397#define INIT_PWRITEV64
398#endif
399
400#if SANITIZER_INTERCEPT_PRCTL
401INTERCEPTOR(int, prctl, int option,
402            unsigned long arg2, unsigned long arg3,   // NOLINT
403            unsigned long arg4, unsigned long arg5) { // NOLINT
404  void *ctx;
405  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
406  static const int PR_SET_NAME = 15;
407  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
408  if (option == PR_SET_NAME) {
409    char buff[16];
410    internal_strncpy(buff, (char *)arg2, 15);
411    buff[15] = 0;
412    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
413  }
414  return res;
415}
416#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
417#else
418#define INIT_PRCTL
419#endif // SANITIZER_INTERCEPT_PRCTL
420
421
422#if SANITIZER_INTERCEPT_TIME
423INTERCEPTOR(unsigned long, time, unsigned long *t) {
424  void *ctx;
425  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
426  unsigned long res = REAL(time)(t);
427  if (t && res != (unsigned long)-1) {
428    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
429  }
430  return res;
431}
432#define INIT_TIME                                \
433  INTERCEPT_FUNCTION(time);
434#else
435#define INIT_TIME
436#endif // SANITIZER_INTERCEPT_TIME
437
438#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
439static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
440  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
441  if (tm->tm_zone) {
442    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
443    // can point to shared memory and tsan would report a data race.
444    COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone,
445                                        REAL(strlen(tm->tm_zone)) + 1);
446  }
447}
448INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
449  void *ctx;
450  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
451  __sanitizer_tm *res = REAL(localtime)(timep);
452  if (res) {
453    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
454    unpoison_tm(ctx, res);
455  }
456  return res;
457}
458INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
459  void *ctx;
460  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
461  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
462  if (res) {
463    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
464    unpoison_tm(ctx, res);
465  }
466  return res;
467}
468INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
469  void *ctx;
470  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
471  __sanitizer_tm *res = REAL(gmtime)(timep);
472  if (res) {
473    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
474    unpoison_tm(ctx, res);
475  }
476  return res;
477}
478INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
479  void *ctx;
480  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
481  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
482  if (res) {
483    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
484    unpoison_tm(ctx, res);
485  }
486  return res;
487}
488INTERCEPTOR(char *, ctime, unsigned long *timep) {
489  void *ctx;
490  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
491  char *res = REAL(ctime)(timep);
492  if (res) {
493    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
494    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
495  }
496  return res;
497}
498INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
499  void *ctx;
500  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
501  char *res = REAL(ctime_r)(timep, result);
502  if (res) {
503    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
504    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
505  }
506  return res;
507}
508INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
509  void *ctx;
510  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
511  char *res = REAL(asctime)(tm);
512  if (res) {
513    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
514    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
515  }
516  return res;
517}
518INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
519  void *ctx;
520  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
521  char *res = REAL(asctime_r)(tm, result);
522  if (res) {
523    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
524    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
525  }
526  return res;
527}
528#define INIT_LOCALTIME_AND_FRIENDS               \
529  INTERCEPT_FUNCTION(localtime);                 \
530  INTERCEPT_FUNCTION(localtime_r);               \
531  INTERCEPT_FUNCTION(gmtime);                    \
532  INTERCEPT_FUNCTION(gmtime_r);                  \
533  INTERCEPT_FUNCTION(ctime);                     \
534  INTERCEPT_FUNCTION(ctime_r);                   \
535  INTERCEPT_FUNCTION(asctime);                   \
536  INTERCEPT_FUNCTION(asctime_r);
537#else
538#define INIT_LOCALTIME_AND_FRIENDS
539#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
540
541#if SANITIZER_INTERCEPT_STRPTIME
542INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
543  void *ctx;
544  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
545  if (format)
546    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
547  char *res = REAL(strptime)(s, format, tm);
548  if (res) {
549    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s);
550    // Do not call unpoison_tm here, because strptime does not, in fact,
551    // initialize the entire struct tm. For example, tm_zone pointer is left
552    // uninitialized.
553    if (tm)
554      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
555  }
556  return res;
557}
558#define INIT_STRPTIME INTERCEPT_FUNCTION(strptime);
559#else
560#define INIT_STRPTIME
561#endif
562
563
564#if SANITIZER_INTERCEPT_SCANF
565
566#include "sanitizer_common_interceptors_scanf.inc"
567
568#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
569  {                                                                            \
570    void *ctx;                                                                 \
571    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
572    va_list aq;                                                                \
573    va_copy(aq, ap);                                                           \
574    int res = REAL(vname)(__VA_ARGS__);                                        \
575    if (res > 0)                                                               \
576      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
577    va_end(aq);                                                                \
578    return res;                                                                \
579  }
580
581INTERCEPTOR(int, vscanf, const char *format, va_list ap)
582VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
583
584INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
585VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
586
587INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
588VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
589
590#if SANITIZER_INTERCEPT_ISOC99_SCANF
591INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
592VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
593
594INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
595            va_list ap)
596VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
597
598INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
599VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
600#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
601
602#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
603  {                                                                            \
604    void *ctx;                                                                 \
605    va_list ap;                                                                \
606    va_start(ap, format);                                                      \
607    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
608    int res = vname(__VA_ARGS__, ap);                                          \
609    va_end(ap);                                                                \
610    return res;                                                                \
611  }
612
613INTERCEPTOR(int, scanf, const char *format, ...)
614SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
615
616INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
617SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
618
619INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
620SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
621
622#if SANITIZER_INTERCEPT_ISOC99_SCANF
623INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
624SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
625
626INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
627SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
628
629INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
630SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
631#endif
632
633#endif
634
635#if SANITIZER_INTERCEPT_SCANF
636#define INIT_SCANF             \
637  INTERCEPT_FUNCTION(scanf);   \
638  INTERCEPT_FUNCTION(sscanf);  \
639  INTERCEPT_FUNCTION(fscanf);  \
640  INTERCEPT_FUNCTION(vscanf);  \
641  INTERCEPT_FUNCTION(vsscanf); \
642  INTERCEPT_FUNCTION(vfscanf);
643#else
644#define INIT_SCANF
645#endif
646
647#if SANITIZER_INTERCEPT_ISOC99_SCANF
648#define INIT_ISOC99_SCANF               \
649  INTERCEPT_FUNCTION(__isoc99_scanf);   \
650  INTERCEPT_FUNCTION(__isoc99_sscanf);  \
651  INTERCEPT_FUNCTION(__isoc99_fscanf);  \
652  INTERCEPT_FUNCTION(__isoc99_vscanf);  \
653  INTERCEPT_FUNCTION(__isoc99_vsscanf); \
654  INTERCEPT_FUNCTION(__isoc99_vfscanf);
655#else
656#define INIT_ISOC99_SCANF
657#endif
658
659#if SANITIZER_INTERCEPT_IOCTL
660#include "sanitizer_common_interceptors_ioctl.inc"
661INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
662  void *ctx;
663  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
664
665  CHECK(ioctl_initialized);
666
667  // Note: TSan does not use common flags, and they are zero-initialized.
668  // This effectively disables ioctl handling in TSan.
669  if (!common_flags()->handle_ioctl)
670    return REAL(ioctl)(d, request, arg);
671
672  const ioctl_desc *desc = ioctl_lookup(request);
673  if (!desc)
674    Printf("WARNING: unknown ioctl %x\n", request);
675
676  if (desc)
677    ioctl_common_pre(ctx, desc, d, request, arg);
678  int res = REAL(ioctl)(d, request, arg);
679  // FIXME: some ioctls have different return values for success and failure.
680  if (desc && res != -1)
681    ioctl_common_post(ctx, desc, res, d, request, arg);
682  return res;
683}
684#define INIT_IOCTL \
685  ioctl_init();    \
686  INTERCEPT_FUNCTION(ioctl);
687#else
688#define INIT_IOCTL
689#endif
690
691
692#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
693INTERCEPTOR(void *, getpwnam, const char *name) {
694  void *ctx;
695  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
696  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
697  void *res = REAL(getpwnam)(name);
698  if (res != 0)
699    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
700  return res;
701}
702INTERCEPTOR(void *, getpwuid, u32 uid) {
703  void *ctx;
704  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
705  void *res = REAL(getpwuid)(uid);
706  if (res != 0)
707    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
708  return res;
709}
710INTERCEPTOR(void *, getgrnam, const char *name) {
711  void *ctx;
712  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
713  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
714  void *res = REAL(getgrnam)(name);
715  if (res != 0)
716    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
717  return res;
718}
719INTERCEPTOR(void *, getgrgid, u32 gid) {
720  void *ctx;
721  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
722  void *res = REAL(getgrgid)(gid);
723  if (res != 0)
724    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
725  return res;
726}
727#define INIT_GETPWNAM_AND_FRIENDS                  \
728  INTERCEPT_FUNCTION(getpwnam);                    \
729  INTERCEPT_FUNCTION(getpwuid);                    \
730  INTERCEPT_FUNCTION(getgrnam);                    \
731  INTERCEPT_FUNCTION(getgrgid);
732#else
733#define INIT_GETPWNAM_AND_FRIENDS
734#endif
735
736
737#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
738INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
739    char *buf, SIZE_T buflen, void **result) {
740  void *ctx;
741  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
742  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
743  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
744  if (!res) {
745    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
746    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
747  }
748  return res;
749}
750INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
751    char *buf, SIZE_T buflen, void **result) {
752  void *ctx;
753  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
754  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
755  if (!res) {
756    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
757    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
758  }
759  return res;
760}
761INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
762    char *buf, SIZE_T buflen, void **result) {
763  void *ctx;
764  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
765  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
766  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
767  if (!res) {
768    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
769    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
770  }
771  return res;
772}
773INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
774    char *buf, SIZE_T buflen, void **result) {
775  void *ctx;
776  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
777  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
778  if (!res) {
779    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
780    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
781  }
782  return res;
783}
784#define INIT_GETPWNAM_R_AND_FRIENDS                \
785  INTERCEPT_FUNCTION(getpwnam_r);                  \
786  INTERCEPT_FUNCTION(getpwuid_r);                  \
787  INTERCEPT_FUNCTION(getgrnam_r);                  \
788  INTERCEPT_FUNCTION(getgrgid_r);
789#else
790#define INIT_GETPWNAM_R_AND_FRIENDS
791#endif
792
793
794#if SANITIZER_INTERCEPT_CLOCK_GETTIME
795INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
796  void *ctx;
797  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
798  int res = REAL(clock_getres)(clk_id, tp);
799  if (!res && tp) {
800    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
801  }
802  return res;
803}
804INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
805  void *ctx;
806  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
807  int res = REAL(clock_gettime)(clk_id, tp);
808  if (!res) {
809    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
810  }
811  return res;
812}
813INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
814  void *ctx;
815  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
816  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
817  return REAL(clock_settime)(clk_id, tp);
818}
819#define INIT_CLOCK_GETTIME                         \
820  INTERCEPT_FUNCTION(clock_getres);                \
821  INTERCEPT_FUNCTION(clock_gettime);               \
822  INTERCEPT_FUNCTION(clock_settime);
823#else
824#define INIT_CLOCK_GETTIME
825#endif
826
827
828#if SANITIZER_INTERCEPT_GETITIMER
829INTERCEPTOR(int, getitimer, int which, void *curr_value) {
830  void *ctx;
831  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
832  int res = REAL(getitimer)(which, curr_value);
833  if (!res && curr_value) {
834    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
835  }
836  return res;
837}
838INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
839  void *ctx;
840  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
841  if (new_value)
842    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
843  int res = REAL(setitimer)(which, new_value, old_value);
844  if (!res && old_value) {
845    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
846  }
847  return res;
848}
849#define INIT_GETITIMER                             \
850  INTERCEPT_FUNCTION(getitimer);                   \
851  INTERCEPT_FUNCTION(setitimer);
852#else
853#define INIT_GETITIMER
854#endif
855
856#if SANITIZER_INTERCEPT_GLOB
857static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
858  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
859  // +1 for NULL pointer at the end.
860  if (pglob->gl_pathv)
861    COMMON_INTERCEPTOR_WRITE_RANGE(
862        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
863  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
864    char *p = pglob->gl_pathv[i];
865    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
866  }
867}
868
869static THREADLOCAL __sanitizer_glob_t* pglob_copy;
870static THREADLOCAL void* glob_ctx;
871
872static void wrapped_gl_closedir(void *dir) {
873  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
874  pglob_copy->gl_closedir(dir);
875}
876
877static void *wrapped_gl_readdir(void *dir) {
878  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
879  return pglob_copy->gl_readdir(dir);
880}
881
882static void *wrapped_gl_opendir(const char *s) {
883  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1);
884  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
885  return pglob_copy->gl_opendir(s);
886}
887
888static int wrapped_gl_lstat(const char *s, void *st) {
889  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
890  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
891  return pglob_copy->gl_lstat(s, st);
892}
893
894static int wrapped_gl_stat(const char *s, void *st) {
895  COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2);
896  COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1);
897  return pglob_copy->gl_stat(s, st);
898}
899
900INTERCEPTOR(int, glob, const char *pattern, int flags,
901            int (*errfunc)(const char *epath, int eerrno),
902            __sanitizer_glob_t *pglob) {
903  void *ctx;
904  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
905  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
906                                  wrapped_gl_readdir, wrapped_gl_opendir,
907                                  wrapped_gl_lstat, wrapped_gl_stat};
908  if (flags & glob_altdirfunc) {
909    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
910    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
911    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
912    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
913    Swap(pglob->gl_stat, glob_copy.gl_stat);
914    pglob_copy = &glob_copy;
915    glob_ctx = ctx;
916  }
917  int res = REAL(glob)(pattern, flags, errfunc, pglob);
918  if (flags & glob_altdirfunc) {
919    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
920    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
921    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
922    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
923    Swap(pglob->gl_stat, glob_copy.gl_stat);
924  }
925  pglob_copy = 0;
926  glob_ctx = 0;
927  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
928  return res;
929}
930
931INTERCEPTOR(int, glob64, const char *pattern, int flags,
932            int (*errfunc)(const char *epath, int eerrno),
933            __sanitizer_glob_t *pglob) {
934  void *ctx;
935  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
936  __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir,
937                                  wrapped_gl_readdir, wrapped_gl_opendir,
938                                  wrapped_gl_lstat, wrapped_gl_stat};
939  if (flags & glob_altdirfunc) {
940    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
941    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
942    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
943    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
944    Swap(pglob->gl_stat, glob_copy.gl_stat);
945    pglob_copy = &glob_copy;
946    glob_ctx = ctx;
947  }
948  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
949  if (flags & glob_altdirfunc) {
950    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
951    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
952    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
953    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
954    Swap(pglob->gl_stat, glob_copy.gl_stat);
955  }
956  pglob_copy = 0;
957  glob_ctx = 0;
958  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
959  return res;
960}
961#define INIT_GLOB           \
962  INTERCEPT_FUNCTION(glob); \
963  INTERCEPT_FUNCTION(glob64);
964#else  // SANITIZER_INTERCEPT_GLOB
965#define INIT_GLOB
966#endif  // SANITIZER_INTERCEPT_GLOB
967
968#if SANITIZER_INTERCEPT_WAIT
969// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
970// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
971// details.
972INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
973  void *ctx;
974  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
975  int res = REAL(wait)(status);
976  if (res != -1 && status)
977    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
978  return res;
979}
980INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
981  int options) {
982  void *ctx;
983  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
984  int res = REAL(waitid)(idtype, id, infop, options);
985  if (res != -1 && infop)
986    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
987  return res;
988}
989INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
990  void *ctx;
991  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
992  int res = REAL(waitpid)(pid, status, options);
993  if (res != -1 && status)
994    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
995  return res;
996}
997INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
998  void *ctx;
999  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
1000  int res = REAL(wait3)(status, options, rusage);
1001  if (res != -1) {
1002    if (status)
1003      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1004    if (rusage)
1005      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1006  }
1007  return res;
1008}
1009INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
1010  void *ctx;
1011  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
1012  int res = REAL(wait4)(pid, status, options, rusage);
1013  if (res != -1) {
1014    if (status)
1015      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1016    if (rusage)
1017      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1018  }
1019  return res;
1020}
1021#define INIT_WAIT                                \
1022  INTERCEPT_FUNCTION(wait);                      \
1023  INTERCEPT_FUNCTION(waitid);                    \
1024  INTERCEPT_FUNCTION(waitpid);                   \
1025  INTERCEPT_FUNCTION(wait3);                     \
1026  INTERCEPT_FUNCTION(wait4);
1027#else
1028#define INIT_WAIT
1029#endif
1030
1031#if SANITIZER_INTERCEPT_INET
1032INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1033  void *ctx;
1034  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1035  uptr sz = __sanitizer_in_addr_sz(af);
1036  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1037  // FIXME: figure out read size based on the address family.
1038  char *res = REAL(inet_ntop)(af, src, dst, size);
1039  if (res)
1040    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1041  return res;
1042}
1043INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1044  void *ctx;
1045  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
1046  // FIXME: figure out read size based on the address family.
1047  int res = REAL(inet_pton)(af, src, dst);
1048  if (res == 1) {
1049    uptr sz = __sanitizer_in_addr_sz(af);
1050    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1051  }
1052  return res;
1053}
1054#define INIT_INET                                \
1055  INTERCEPT_FUNCTION(inet_ntop);                 \
1056  INTERCEPT_FUNCTION(inet_pton);
1057#else
1058#define INIT_INET
1059#endif
1060
1061#if SANITIZER_INTERCEPT_INET
1062INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1063  void *ctx;
1064  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1065  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
1066  int res = REAL(inet_aton)(cp, dst);
1067  if (res != 0) {
1068    uptr sz = __sanitizer_in_addr_sz(af_inet);
1069    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1070  }
1071  return res;
1072}
1073#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
1074#else
1075#define INIT_INET_ATON
1076#endif
1077
1078#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1079INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1080  void *ctx;
1081  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
1082  int res = REAL(pthread_getschedparam)(thread, policy, param);
1083  if (res == 0) {
1084    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1085    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1086  }
1087  return res;
1088}
1089#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
1090#else
1091#define INIT_PTHREAD_GETSCHEDPARAM
1092#endif
1093
1094#if SANITIZER_INTERCEPT_GETADDRINFO
1095INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1096            struct __sanitizer_addrinfo *hints,
1097            struct __sanitizer_addrinfo **out) {
1098  void *ctx;
1099  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1100  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1101  if (service)
1102    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1103  if (hints)
1104    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
1105  int res = REAL(getaddrinfo)(node, service, hints, out);
1106  if (res == 0 && out) {
1107    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1108    struct __sanitizer_addrinfo *p = *out;
1109    while (p) {
1110      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1111      if (p->ai_addr)
1112        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1113      if (p->ai_canonname)
1114        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1115                                       REAL(strlen)(p->ai_canonname) + 1);
1116      p = p->ai_next;
1117    }
1118  }
1119  return res;
1120}
1121#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
1122#else
1123#define INIT_GETADDRINFO
1124#endif
1125
1126#if SANITIZER_INTERCEPT_GETNAMEINFO
1127INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1128            unsigned hostlen, char *serv, unsigned servlen, int flags) {
1129  void *ctx;
1130  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1131                           serv, servlen, flags);
1132  // FIXME: consider adding READ_RANGE(sockaddr, salen)
1133  // There is padding in in_addr that may make this too noisy
1134  int res =
1135      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1136  if (res == 0) {
1137    if (host && hostlen)
1138      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1139    if (serv && servlen)
1140      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1141  }
1142  return res;
1143}
1144#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo);
1145#else
1146#define INIT_GETNAMEINFO
1147#endif
1148
1149#if SANITIZER_INTERCEPT_GETSOCKNAME
1150INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1151  void *ctx;
1152  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
1153  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1154  int addrlen_in = *addrlen;
1155  int res = REAL(getsockname)(sock_fd, addr, addrlen);
1156  if (res == 0) {
1157    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
1158  }
1159  return res;
1160}
1161#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
1162#else
1163#define INIT_GETSOCKNAME
1164#endif
1165
1166#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1167static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
1168  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
1169  if (h->h_name)
1170    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
1171  char **p = h->h_aliases;
1172  while (*p) {
1173    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
1174    ++p;
1175  }
1176  COMMON_INTERCEPTOR_WRITE_RANGE(
1177      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
1178  p = h->h_addr_list;
1179  while (*p) {
1180    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
1181    ++p;
1182  }
1183  COMMON_INTERCEPTOR_WRITE_RANGE(
1184      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
1185}
1186#endif
1187
1188#if SANITIZER_INTERCEPT_GETHOSTBYNAME
1189INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
1190  void *ctx;
1191  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
1192  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
1193  if (res) write_hostent(ctx, res);
1194  return res;
1195}
1196
1197INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
1198            int type) {
1199  void *ctx;
1200  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
1201  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1202  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1203  if (res) write_hostent(ctx, res);
1204  return res;
1205}
1206
1207INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
1208  void *ctx;
1209  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
1210  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
1211  if (res) write_hostent(ctx, res);
1212  return res;
1213}
1214
1215INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1216  void *ctx;
1217  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1218  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1219  if (res) write_hostent(ctx, res);
1220  return res;
1221}
1222#define INIT_GETHOSTBYNAME           \
1223  INTERCEPT_FUNCTION(gethostent);    \
1224  INTERCEPT_FUNCTION(gethostbyaddr); \
1225  INTERCEPT_FUNCTION(gethostbyname); \
1226  INTERCEPT_FUNCTION(gethostbyname2);
1227#else
1228#define INIT_GETHOSTBYNAME
1229#endif
1230
1231#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1232INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1233            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1234  void *ctx;
1235  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1236                           h_errnop);
1237  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1238  if (res == 0) {
1239    if (result) {
1240      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1241      if (*result) write_hostent(ctx, *result);
1242    }
1243    if (h_errnop)
1244      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1245  }
1246  return res;
1247}
1248
1249INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1250            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1251            __sanitizer_hostent **result, int *h_errnop) {
1252  void *ctx;
1253  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1254                           buflen, result, h_errnop);
1255  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1256  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1257                                  h_errnop);
1258  if (res == 0) {
1259    if (result) {
1260      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1261      if (*result) write_hostent(ctx, *result);
1262    }
1263    if (h_errnop)
1264      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1265  }
1266  return res;
1267}
1268
1269INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1270            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1271            int *h_errnop) {
1272  void *ctx;
1273  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1274                           h_errnop);
1275  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1276  if (res == 0) {
1277    if (result) {
1278      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1279      if (*result) write_hostent(ctx, *result);
1280    }
1281    if (h_errnop)
1282      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1283  }
1284  return res;
1285}
1286
1287INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1288            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1289            __sanitizer_hostent **result, int *h_errnop) {
1290  void *ctx;
1291  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1292                           result, h_errnop);
1293  int res =
1294      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1295  if (res == 0) {
1296    if (result) {
1297      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1298      if (*result) write_hostent(ctx, *result);
1299    }
1300    if (h_errnop)
1301      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1302  }
1303  return res;
1304}
1305#define INIT_GETHOSTBYNAME_R           \
1306  INTERCEPT_FUNCTION(gethostent_r);    \
1307  INTERCEPT_FUNCTION(gethostbyaddr_r); \
1308  INTERCEPT_FUNCTION(gethostbyname_r); \
1309  INTERCEPT_FUNCTION(gethostbyname2_r);
1310#else
1311#define INIT_GETHOSTBYNAME_R
1312#endif
1313
1314#if SANITIZER_INTERCEPT_GETSOCKOPT
1315INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1316            int *optlen) {
1317  void *ctx;
1318  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1319                           optlen);
1320  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1321  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1322  if (res == 0)
1323    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1324  return res;
1325}
1326#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1327#else
1328#define INIT_GETSOCKOPT
1329#endif
1330
1331#if SANITIZER_INTERCEPT_ACCEPT
1332INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1333  void *ctx;
1334  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1335  unsigned addrlen0;
1336  if (addrlen) {
1337    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1338    addrlen0 = *addrlen;
1339  }
1340  int fd2 = REAL(accept)(fd, addr, addrlen);
1341  if (fd2 >= 0) {
1342    if (fd >= 0)
1343      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1344    if (addr && addrlen)
1345      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1346  }
1347  return fd2;
1348}
1349#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
1350#else
1351#define INIT_ACCEPT
1352#endif
1353
1354#if SANITIZER_INTERCEPT_ACCEPT4
1355INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1356  void *ctx;
1357  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1358  unsigned addrlen0;
1359  if (addrlen) {
1360    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1361    addrlen0 = *addrlen;
1362  }
1363  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1364  if (fd2 >= 0) {
1365    if (fd >= 0)
1366      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1367    if (addr && addrlen)
1368      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1369  }
1370  return fd2;
1371}
1372#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
1373#else
1374#define INIT_ACCEPT4
1375#endif
1376
1377#if SANITIZER_INTERCEPT_MODF
1378INTERCEPTOR(double, modf, double x, double *iptr) {
1379  void *ctx;
1380  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1381  double res = REAL(modf)(x, iptr);
1382  if (iptr) {
1383    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1384  }
1385  return res;
1386}
1387INTERCEPTOR(float, modff, float x, float *iptr) {
1388  void *ctx;
1389  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1390  float res = REAL(modff)(x, iptr);
1391  if (iptr) {
1392    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1393  }
1394  return res;
1395}
1396INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1397  void *ctx;
1398  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1399  long double res = REAL(modfl)(x, iptr);
1400  if (iptr) {
1401    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1402  }
1403  return res;
1404}
1405#define INIT_MODF            \
1406  INTERCEPT_FUNCTION(modf);  \
1407  INTERCEPT_FUNCTION(modff); \
1408  INTERCEPT_FUNCTION(modfl);
1409#else
1410#define INIT_MODF
1411#endif
1412
1413#if SANITIZER_INTERCEPT_RECVMSG
1414static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1415                         SSIZE_T maxlen) {
1416  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
1417  if (msg->msg_name && msg->msg_namelen)
1418    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
1419  if (msg->msg_iov && msg->msg_iovlen)
1420    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1421                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
1422  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
1423  if (msg->msg_control && msg->msg_controllen)
1424    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
1425}
1426
1427INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
1428            int flags) {
1429  void *ctx;
1430  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
1431  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
1432  if (res >= 0) {
1433    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1434    if (msg) write_msghdr(ctx, msg, res);
1435  }
1436  return res;
1437}
1438#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
1439#else
1440#define INIT_RECVMSG
1441#endif
1442
1443#if SANITIZER_INTERCEPT_GETPEERNAME
1444INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1445  void *ctx;
1446  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1447  unsigned addr_sz;
1448  if (addrlen) addr_sz = *addrlen;
1449  int res = REAL(getpeername)(sockfd, addr, addrlen);
1450  if (!res && addr && addrlen)
1451    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1452  return res;
1453}
1454#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1455#else
1456#define INIT_GETPEERNAME
1457#endif
1458
1459#if SANITIZER_INTERCEPT_SYSINFO
1460INTERCEPTOR(int, sysinfo, void *info) {
1461  void *ctx;
1462  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1463  int res = REAL(sysinfo)(info);
1464  if (!res && info)
1465    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1466  return res;
1467}
1468#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1469#else
1470#define INIT_SYSINFO
1471#endif
1472
1473#if SANITIZER_INTERCEPT_READDIR
1474INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
1475  void *ctx;
1476  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
1477  __sanitizer_dirent *res = REAL(readdir)(dirp);
1478  if (res)
1479    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1480  return res;
1481}
1482
1483INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
1484            __sanitizer_dirent **result) {
1485  void *ctx;
1486  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1487  int res = REAL(readdir_r)(dirp, entry, result);
1488  if (!res) {
1489    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1490    if (*result)
1491      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1492  }
1493  return res;
1494}
1495
1496#define INIT_READDIR           \
1497  INTERCEPT_FUNCTION(readdir); \
1498  INTERCEPT_FUNCTION(readdir_r);
1499#else
1500#define INIT_READDIR
1501#endif
1502
1503#if SANITIZER_INTERCEPT_READDIR64
1504INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
1505  void *ctx;
1506  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
1507  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
1508  if (res)
1509    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1510  return res;
1511}
1512
1513INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
1514            __sanitizer_dirent64 **result) {
1515  void *ctx;
1516  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1517  int res = REAL(readdir64_r)(dirp, entry, result);
1518  if (!res) {
1519    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1520    if (*result)
1521      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
1522  }
1523  return res;
1524}
1525#define INIT_READDIR64           \
1526  INTERCEPT_FUNCTION(readdir64); \
1527  INTERCEPT_FUNCTION(readdir64_r);
1528#else
1529#define INIT_READDIR64
1530#endif
1531
1532#if SANITIZER_INTERCEPT_PTRACE
1533INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
1534  void *ctx;
1535  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
1536
1537  if (data) {
1538    if (request == ptrace_setregs)
1539      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
1540    else if (request == ptrace_setfpregs)
1541      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1542    else if (request == ptrace_setfpxregs)
1543      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1544    else if (request == ptrace_setsiginfo)
1545      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
1546    else if (request == ptrace_setregset) {
1547      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1548      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
1549    }
1550  }
1551
1552  uptr res = REAL(ptrace)(request, pid, addr, data);
1553
1554  if (!res && data) {
1555    // Note that PEEK* requests assing different meaning to the return value.
1556    // This function does not handle them (nor does it need to).
1557    if (request == ptrace_getregs)
1558      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
1559    else if (request == ptrace_getfpregs)
1560      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1561    else if (request == ptrace_getfpxregs)
1562      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1563    else if (request == ptrace_getsiginfo)
1564      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
1565    else if (request == ptrace_getregset) {
1566      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1567      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
1568    }
1569  }
1570  return res;
1571}
1572
1573#define INIT_PTRACE           \
1574  INTERCEPT_FUNCTION(ptrace);
1575#else
1576#define INIT_PTRACE
1577#endif
1578
1579#if SANITIZER_INTERCEPT_SETLOCALE
1580INTERCEPTOR(char *, setlocale, int category, char *locale) {
1581  void *ctx;
1582  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
1583  if (locale)
1584    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
1585  char *res = REAL(setlocale)(category, locale);
1586  if (res)
1587    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1588  return res;
1589}
1590
1591#define INIT_SETLOCALE           \
1592  INTERCEPT_FUNCTION(setlocale);
1593#else
1594#define INIT_SETLOCALE
1595#endif
1596
1597#if SANITIZER_INTERCEPT_GETCWD
1598INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
1599  void *ctx;
1600  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
1601  char *res = REAL(getcwd)(buf, size);
1602  if (res)
1603    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1604  return res;
1605}
1606#define INIT_GETCWD           \
1607  INTERCEPT_FUNCTION(getcwd);
1608#else
1609#define INIT_GETCWD
1610#endif
1611
1612#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
1613INTERCEPTOR(char *, get_current_dir_name, int fake) {
1614  void *ctx;
1615  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
1616  char *res = REAL(get_current_dir_name)(fake);
1617  if (res)
1618    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1619  return res;
1620}
1621
1622#define INIT_GET_CURRENT_DIR_NAME           \
1623  INTERCEPT_FUNCTION(get_current_dir_name);
1624#else
1625#define INIT_GET_CURRENT_DIR_NAME
1626#endif
1627
1628#if SANITIZER_INTERCEPT_STRTOIMAX
1629INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
1630  void *ctx;
1631  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
1632  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
1633  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1634  return res;
1635}
1636
1637INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
1638  void *ctx;
1639  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
1640  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
1641  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1642  return res;
1643}
1644
1645#define INIT_STRTOIMAX           \
1646  INTERCEPT_FUNCTION(strtoimax); \
1647  INTERCEPT_FUNCTION(strtoumax);
1648#else
1649#define INIT_STRTOIMAX
1650#endif
1651
1652#if SANITIZER_INTERCEPT_MBSTOWCS
1653INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
1654  void *ctx;
1655  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
1656  SIZE_T res = REAL(mbstowcs)(dest, src, len);
1657  if (res != (SIZE_T) - 1 && dest) {
1658    SIZE_T write_cnt = res + (res < len);
1659    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1660  }
1661  return res;
1662}
1663
1664INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
1665            void *ps) {
1666  void *ctx;
1667  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
1668  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1669  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1670  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
1671  if (res != (SIZE_T)(-1) && dest && src) {
1672    // This function, and several others, may or may not write the terminating
1673    // \0 character. They write it iff they clear *src.
1674    SIZE_T write_cnt = res + !*src;
1675    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1676  }
1677  return res;
1678}
1679
1680#define INIT_MBSTOWCS           \
1681  INTERCEPT_FUNCTION(mbstowcs); \
1682  INTERCEPT_FUNCTION(mbsrtowcs);
1683#else
1684#define INIT_MBSTOWCS
1685#endif
1686
1687#if SANITIZER_INTERCEPT_MBSNRTOWCS
1688INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
1689            SIZE_T len, void *ps) {
1690  void *ctx;
1691  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
1692  if (src) {
1693    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1694    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1695  }
1696  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1697  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
1698  if (res != (SIZE_T)(-1) && dest && src) {
1699    SIZE_T write_cnt = res + !*src;
1700    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
1701  }
1702  return res;
1703}
1704
1705#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
1706#else
1707#define INIT_MBSNRTOWCS
1708#endif
1709
1710#if SANITIZER_INTERCEPT_WCSTOMBS
1711INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
1712  void *ctx;
1713  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
1714  SIZE_T res = REAL(wcstombs)(dest, src, len);
1715  if (res != (SIZE_T) - 1 && dest) {
1716    SIZE_T write_cnt = res + (res < len);
1717    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1718  }
1719  return res;
1720}
1721
1722INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
1723            void *ps) {
1724  void *ctx;
1725  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
1726  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1727  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1728  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
1729  if (res != (SIZE_T) - 1 && dest && src) {
1730    SIZE_T write_cnt = res + !*src;
1731    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1732  }
1733  return res;
1734}
1735
1736#define INIT_WCSTOMBS           \
1737  INTERCEPT_FUNCTION(wcstombs); \
1738  INTERCEPT_FUNCTION(wcsrtombs);
1739#else
1740#define INIT_WCSTOMBS
1741#endif
1742
1743#if SANITIZER_INTERCEPT_WCSNRTOMBS
1744INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
1745            SIZE_T len, void *ps) {
1746  void *ctx;
1747  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
1748  if (src) {
1749    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1750    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1751  }
1752  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
1753  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
1754  if (res != (SIZE_T) - 1 && dest && src) {
1755    SIZE_T write_cnt = res + !*src;
1756    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
1757  }
1758  return res;
1759}
1760
1761#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
1762#else
1763#define INIT_WCSNRTOMBS
1764#endif
1765
1766
1767#if SANITIZER_INTERCEPT_TCGETATTR
1768INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
1769  void *ctx;
1770  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
1771  int res = REAL(tcgetattr)(fd, termios_p);
1772  if (!res && termios_p)
1773    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
1774  return res;
1775}
1776
1777#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr);
1778#else
1779#define INIT_TCGETATTR
1780#endif
1781
1782
1783#if SANITIZER_INTERCEPT_REALPATH
1784INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
1785  void *ctx;
1786  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
1787  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1788
1789  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
1790  // version of a versioned symbol. For realpath(), this gives us something
1791  // (called __old_realpath) that does not handle NULL in the second argument.
1792  // Handle it as part of the interceptor.
1793  char *allocated_path = 0;
1794  if (!resolved_path)
1795    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
1796
1797  char *res = REAL(realpath)(path, resolved_path);
1798  if (allocated_path && !res)
1799    WRAP(free)(allocated_path);
1800  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1801  return res;
1802}
1803#define INIT_REALPATH INTERCEPT_FUNCTION(realpath);
1804#else
1805#define INIT_REALPATH
1806#endif
1807
1808#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
1809INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
1810  void *ctx;
1811  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
1812  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
1813  char *res = REAL(canonicalize_file_name)(path);
1814  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1815  return res;
1816}
1817#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name);
1818#else
1819#define INIT_CANONICALIZE_FILE_NAME
1820#endif
1821
1822#if SANITIZER_INTERCEPT_CONFSTR
1823INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
1824  void *ctx;
1825  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
1826  SIZE_T res = REAL(confstr)(name, buf, len);
1827  if (buf && res)
1828    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
1829  return res;
1830}
1831#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr);
1832#else
1833#define INIT_CONFSTR
1834#endif
1835
1836#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
1837INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
1838  void *ctx;
1839  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
1840  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
1841  if (mask && !res)
1842    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
1843  return res;
1844}
1845#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity);
1846#else
1847#define INIT_SCHED_GETAFFINITY
1848#endif
1849
1850#if SANITIZER_INTERCEPT_STRERROR
1851INTERCEPTOR(char *, strerror, int errnum) {
1852  void *ctx;
1853  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
1854  char *res = REAL(strerror)(errnum);
1855  if (res)
1856    COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1857  return res;
1858}
1859#define INIT_STRERROR INTERCEPT_FUNCTION(strerror);
1860#else
1861#define INIT_STRERROR
1862#endif
1863
1864#if SANITIZER_INTERCEPT_STRERROR_R
1865INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
1866  void *ctx;
1867  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
1868  char *res = REAL(strerror_r)(errnum, buf, buflen);
1869  // There are 2 versions of strerror_r:
1870  //  * POSIX version returns 0 on success, negative error code on failure,
1871  //    writes message to buf.
1872  //  * GNU version returns message pointer, which points to either buf or some
1873  //    static storage.
1874  SIZE_T posix_res = (SIZE_T)res;
1875  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
1876    // POSIX version. Spec is not clear on whether buf is NULL-terminated.
1877    // At least on OSX, buf contents are valid even when the call fails.
1878    SIZE_T sz = internal_strnlen(buf, buflen);
1879    if (sz < buflen) ++sz;
1880    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
1881  } else {
1882    // GNU version.
1883    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1884  }
1885  return res;
1886}
1887#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r);
1888#else
1889#define INIT_STRERROR_R
1890#endif
1891
1892#if SANITIZER_INTERCEPT_SCANDIR
1893typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
1894typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
1895                                const struct __sanitizer_dirent **);
1896
1897static THREADLOCAL void *scandir_ctx;
1898static THREADLOCAL scandir_filter_f scandir_filter;
1899static THREADLOCAL scandir_compar_f scandir_compar;
1900
1901static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
1902  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1);
1903  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen);
1904  return scandir_filter(dir);
1905}
1906
1907static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
1908                                  const struct __sanitizer_dirent **b) {
1909  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2);
1910  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a));
1911  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen);
1912  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b));
1913  COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen);
1914  return scandir_compar(a, b);
1915}
1916
1917INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
1918            scandir_filter_f filter, scandir_compar_f compar) {
1919  void *ctx;
1920  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
1921  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
1922  CHECK_EQ(0, scandir_ctx);
1923  scandir_ctx = ctx;
1924  scandir_filter = filter;
1925  scandir_compar = compar;
1926  int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0,
1927                          compar ? wrapped_scandir_compar : 0);
1928  scandir_ctx = 0;
1929  scandir_filter = 0;
1930  scandir_compar = 0;
1931  if (namelist && res > 0) {
1932    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1933    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1934    for (int i = 0; i < res; ++i)
1935      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1936                                     (*namelist)[i]->d_reclen);
1937  }
1938  return res;
1939}
1940#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir);
1941#else
1942#define INIT_SCANDIR
1943#endif
1944
1945#if SANITIZER_INTERCEPT_SCANDIR64
1946typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
1947typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
1948                                  const struct __sanitizer_dirent64 **);
1949
1950static THREADLOCAL void *scandir64_ctx;
1951static THREADLOCAL scandir64_filter_f scandir64_filter;
1952static THREADLOCAL scandir64_compar_f scandir64_compar;
1953
1954static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
1955  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1);
1956  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen);
1957  return scandir64_filter(dir);
1958}
1959
1960static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
1961                                    const struct __sanitizer_dirent64 **b) {
1962  COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2);
1963  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a));
1964  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen);
1965  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b));
1966  COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen);
1967  return scandir64_compar(a, b);
1968}
1969
1970INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
1971            scandir64_filter_f filter, scandir64_compar_f compar) {
1972  void *ctx;
1973  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
1974  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
1975  CHECK_EQ(0, scandir64_ctx);
1976  scandir64_ctx = ctx;
1977  scandir64_filter = filter;
1978  scandir64_compar = compar;
1979  int res =
1980      REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0,
1981                      compar ? wrapped_scandir64_compar : 0);
1982  scandir64_ctx = 0;
1983  scandir64_filter = 0;
1984  scandir64_compar = 0;
1985  if (namelist && res > 0) {
1986    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
1987    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
1988    for (int i = 0; i < res; ++i)
1989      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
1990                                     (*namelist)[i]->d_reclen);
1991  }
1992  return res;
1993}
1994#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64);
1995#else
1996#define INIT_SCANDIR64
1997#endif
1998
1999#if SANITIZER_INTERCEPT_GETGROUPS
2000INTERCEPTOR(int, getgroups, int size, u32 *lst) {
2001  void *ctx;
2002  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
2003  int res = REAL(getgroups)(size, lst);
2004  if (res && lst)
2005    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
2006  return res;
2007}
2008#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups);
2009#else
2010#define INIT_GETGROUPS
2011#endif
2012
2013#if SANITIZER_INTERCEPT_POLL
2014static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
2015                        __sanitizer_nfds_t nfds) {
2016  for (unsigned i = 0; i < nfds; ++i) {
2017    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
2018    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
2019  }
2020}
2021
2022static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
2023                         __sanitizer_nfds_t nfds) {
2024  for (unsigned i = 0; i < nfds; ++i)
2025    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
2026                                   sizeof(fds[i].revents));
2027}
2028
2029INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2030            int timeout) {
2031  void *ctx;
2032  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
2033  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2034  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
2035  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2036  return res;
2037}
2038#define INIT_POLL INTERCEPT_FUNCTION(poll);
2039#else
2040#define INIT_POLL
2041#endif
2042
2043#if SANITIZER_INTERCEPT_PPOLL
2044INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2045            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
2046  void *ctx;
2047  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
2048  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2049  if (timeout_ts)
2050    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
2051  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
2052  int res =
2053      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
2054  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2055  return res;
2056}
2057#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll);
2058#else
2059#define INIT_PPOLL
2060#endif
2061
2062#if SANITIZER_INTERCEPT_WORDEXP
2063INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
2064  void *ctx;
2065  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
2066  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
2067  int res = REAL(wordexp)(s, p, flags);
2068  if (!res && p) {
2069    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2070    if (p->we_wordc)
2071      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
2072                                     sizeof(*p->we_wordv) * p->we_wordc);
2073    for (uptr i = 0; i < p->we_wordc; ++i) {
2074      char *w = p->we_wordv[i];
2075      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
2076    }
2077  }
2078  return res;
2079}
2080#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp);
2081#else
2082#define INIT_WORDEXP
2083#endif
2084
2085#if SANITIZER_INTERCEPT_SIGWAIT
2086INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
2087  void *ctx;
2088  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
2089  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2090  int res = REAL(sigwait)(set, sig);
2091  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
2092  return res;
2093}
2094#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait);
2095#else
2096#define INIT_SIGWAIT
2097#endif
2098
2099#if SANITIZER_INTERCEPT_SIGWAITINFO
2100INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
2101  void *ctx;
2102  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
2103  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2104  int res = REAL(sigwaitinfo)(set, info);
2105  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2106  return res;
2107}
2108#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo);
2109#else
2110#define INIT_SIGWAITINFO
2111#endif
2112
2113#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
2114INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
2115            void *timeout) {
2116  void *ctx;
2117  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
2118  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
2119  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2120  int res = REAL(sigtimedwait)(set, info, timeout);
2121  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2122  return res;
2123}
2124#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait);
2125#else
2126#define INIT_SIGTIMEDWAIT
2127#endif
2128
2129#if SANITIZER_INTERCEPT_SIGSETOPS
2130INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
2131  void *ctx;
2132  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
2133  int res = REAL(sigemptyset)(set);
2134  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2135  return res;
2136}
2137
2138INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
2139  void *ctx;
2140  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
2141  int res = REAL(sigfillset)(set);
2142  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2143  return res;
2144}
2145#define INIT_SIGSETOPS             \
2146  INTERCEPT_FUNCTION(sigemptyset); \
2147  INTERCEPT_FUNCTION(sigfillset);
2148#else
2149#define INIT_SIGSETOPS
2150#endif
2151
2152#if SANITIZER_INTERCEPT_SIGPENDING
2153INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
2154  void *ctx;
2155  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
2156  int res = REAL(sigpending)(set);
2157  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2158  return res;
2159}
2160#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending);
2161#else
2162#define INIT_SIGPENDING
2163#endif
2164
2165#if SANITIZER_INTERCEPT_SIGPROCMASK
2166INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
2167            __sanitizer_sigset_t *oldset) {
2168  void *ctx;
2169  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
2170  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2171  int res = REAL(sigprocmask)(how, set, oldset);
2172  if (!res && oldset)
2173    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
2174  return res;
2175}
2176#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask);
2177#else
2178#define INIT_SIGPROCMASK
2179#endif
2180
2181#if SANITIZER_INTERCEPT_BACKTRACE
2182INTERCEPTOR(int, backtrace, void **buffer, int size) {
2183  void *ctx;
2184  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
2185  int res = REAL(backtrace)(buffer, size);
2186  if (res && buffer)
2187    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
2188  return res;
2189}
2190
2191INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
2192  void *ctx;
2193  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
2194  if (buffer && size)
2195    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
2196  char ** res = REAL(backtrace_symbols)(buffer, size);
2197  if (res && size) {
2198    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
2199    for (int i = 0; i < size; ++i)
2200      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
2201  }
2202  return res;
2203}
2204#define INIT_BACKTRACE           \
2205  INTERCEPT_FUNCTION(backtrace); \
2206  INTERCEPT_FUNCTION(backtrace_symbols);
2207#else
2208#define INIT_BACKTRACE
2209#endif
2210
2211#if SANITIZER_INTERCEPT__EXIT
2212INTERCEPTOR(void, _exit, int status) {
2213  void *ctx;
2214  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
2215  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
2216  if (status == 0)
2217    status = status1;
2218  REAL(_exit)(status);
2219}
2220#define INIT__EXIT INTERCEPT_FUNCTION(_exit);
2221#else
2222#define INIT__EXIT
2223#endif
2224
2225#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
2226INTERCEPTOR(int, pthread_mutex_lock, void *m) {
2227  void *ctx;
2228  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
2229  int res = REAL(pthread_mutex_lock)(m);
2230  if (res == 0)
2231    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2232  return res;
2233}
2234
2235INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
2236  void *ctx;
2237  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
2238  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2239  return REAL(pthread_mutex_unlock)(m);
2240}
2241
2242#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock)
2243#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock)
2244#else
2245#define INIT_PTHREAD_MUTEX_LOCK
2246#define INIT_PTHREAD_MUTEX_UNLOCK
2247#endif
2248
2249#if SANITIZER_INTERCEPT_PTHREAD_COND
2250INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) {
2251  void *ctx;
2252  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m);
2253  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2254  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2255  int res = REAL(pthread_cond_wait)(c, m);
2256  COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2257  return res;
2258}
2259
2260INTERCEPTOR(int, pthread_cond_init, void *c, void *a) {
2261  void *ctx;
2262  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a);
2263  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz);
2264  return REAL(pthread_cond_init)(c, a);
2265}
2266
2267INTERCEPTOR(int, pthread_cond_signal, void *c) {
2268  void *ctx;
2269  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c);
2270  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2271  return REAL(pthread_cond_signal)(c);
2272}
2273
2274INTERCEPTOR(int, pthread_cond_broadcast, void *c) {
2275  void *ctx;
2276  COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c);
2277  COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz);
2278  return REAL(pthread_cond_broadcast)(c);
2279}
2280
2281#define INIT_PTHREAD_COND_WAIT \
2282  INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2)
2283#define INIT_PTHREAD_COND_INIT \
2284  INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2)
2285#define INIT_PTHREAD_COND_SIGNAL \
2286  INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2)
2287#define INIT_PTHREAD_COND_BROADCAST \
2288  INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2)
2289#else
2290#define INIT_PTHREAD_COND_WAIT
2291#define INIT_PTHREAD_COND_INIT
2292#define INIT_PTHREAD_COND_SIGNAL
2293#define INIT_PTHREAD_COND_BROADCAST
2294#endif
2295
2296#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
2297static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
2298  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
2299  if (mnt->mnt_fsname)
2300    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
2301                                   REAL(strlen)(mnt->mnt_fsname) + 1);
2302  if (mnt->mnt_dir)
2303    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
2304                                   REAL(strlen)(mnt->mnt_dir) + 1);
2305  if (mnt->mnt_type)
2306    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
2307                                   REAL(strlen)(mnt->mnt_type) + 1);
2308  if (mnt->mnt_opts)
2309    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
2310                                   REAL(strlen)(mnt->mnt_opts) + 1);
2311}
2312#endif
2313
2314#if SANITIZER_INTERCEPT_GETMNTENT
2315INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
2316  void *ctx;
2317  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
2318  __sanitizer_mntent *res = REAL(getmntent)(fp);
2319  if (res) write_mntent(ctx, res);
2320  return res;
2321}
2322#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent);
2323#else
2324#define INIT_GETMNTENT
2325#endif
2326
2327#if SANITIZER_INTERCEPT_GETMNTENT_R
2328INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
2329            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
2330  void *ctx;
2331  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
2332  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
2333  if (res) write_mntent(ctx, res);
2334  return res;
2335}
2336#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r);
2337#else
2338#define INIT_GETMNTENT_R
2339#endif
2340
2341#if SANITIZER_INTERCEPT_STATFS
2342INTERCEPTOR(int, statfs, char *path, void *buf) {
2343  void *ctx;
2344  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
2345  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2346  int res = REAL(statfs)(path, buf);
2347  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2348  return res;
2349}
2350INTERCEPTOR(int, fstatfs, int fd, void *buf) {
2351  void *ctx;
2352  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
2353  int res = REAL(fstatfs)(fd, buf);
2354  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
2355  return res;
2356}
2357#define INIT_STATFS           \
2358  INTERCEPT_FUNCTION(statfs); \
2359  INTERCEPT_FUNCTION(fstatfs);
2360#else
2361#define INIT_STATFS
2362#endif
2363
2364#if SANITIZER_INTERCEPT_STATFS64
2365INTERCEPTOR(int, statfs64, char *path, void *buf) {
2366  void *ctx;
2367  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
2368  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2369  int res = REAL(statfs64)(path, buf);
2370  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2371  return res;
2372}
2373INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
2374  void *ctx;
2375  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
2376  int res = REAL(fstatfs64)(fd, buf);
2377  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
2378  return res;
2379}
2380#define INIT_STATFS64           \
2381  INTERCEPT_FUNCTION(statfs64); \
2382  INTERCEPT_FUNCTION(fstatfs64);
2383#else
2384#define INIT_STATFS64
2385#endif
2386
2387#if SANITIZER_INTERCEPT_STATVFS
2388INTERCEPTOR(int, statvfs, char *path, void *buf) {
2389  void *ctx;
2390  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
2391  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2392  int res = REAL(statvfs)(path, buf);
2393  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2394  return res;
2395}
2396INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
2397  void *ctx;
2398  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
2399  int res = REAL(fstatvfs)(fd, buf);
2400  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
2401  return res;
2402}
2403#define INIT_STATVFS           \
2404  INTERCEPT_FUNCTION(statvfs); \
2405  INTERCEPT_FUNCTION(fstatvfs);
2406#else
2407#define INIT_STATVFS
2408#endif
2409
2410#if SANITIZER_INTERCEPT_STATVFS64
2411INTERCEPTOR(int, statvfs64, char *path, void *buf) {
2412  void *ctx;
2413  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
2414  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2415  int res = REAL(statvfs64)(path, buf);
2416  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2417  return res;
2418}
2419INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
2420  void *ctx;
2421  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
2422  int res = REAL(fstatvfs64)(fd, buf);
2423  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
2424  return res;
2425}
2426#define INIT_STATVFS64           \
2427  INTERCEPT_FUNCTION(statvfs64); \
2428  INTERCEPT_FUNCTION(fstatvfs64);
2429#else
2430#define INIT_STATVFS64
2431#endif
2432
2433#if SANITIZER_INTERCEPT_INITGROUPS
2434INTERCEPTOR(int, initgroups, char *user, u32 group) {
2435  void *ctx;
2436  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
2437  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
2438  int res = REAL(initgroups)(user, group);
2439  return res;
2440}
2441#define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups);
2442#else
2443#define INIT_INITGROUPS
2444#endif
2445
2446#if SANITIZER_INTERCEPT_ETHER
2447INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
2448  void *ctx;
2449  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
2450  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2451  char *res = REAL(ether_ntoa)(addr);
2452  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2453  return res;
2454}
2455INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
2456  void *ctx;
2457  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
2458  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2459  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
2460  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res));
2461  return res;
2462}
2463INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
2464  void *ctx;
2465  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
2466  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2467  int res = REAL(ether_ntohost)(hostname, addr);
2468  if (!res && hostname)
2469    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2470  return res;
2471}
2472INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
2473  void *ctx;
2474  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
2475  if (hostname)
2476    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2477  int res = REAL(ether_hostton)(hostname, addr);
2478  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2479  return res;
2480}
2481INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
2482            char *hostname) {
2483  void *ctx;
2484  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
2485  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
2486  int res = REAL(ether_line)(line, addr, hostname);
2487  if (!res) {
2488    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2489    if (hostname)
2490      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
2491  }
2492  return res;
2493}
2494#define INIT_ETHER                   \
2495  INTERCEPT_FUNCTION(ether_ntoa);    \
2496  INTERCEPT_FUNCTION(ether_aton);    \
2497  INTERCEPT_FUNCTION(ether_ntohost); \
2498  INTERCEPT_FUNCTION(ether_hostton); \
2499  INTERCEPT_FUNCTION(ether_line);
2500#else
2501#define INIT_ETHER
2502#endif
2503
2504#if SANITIZER_INTERCEPT_ETHER_R
2505INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
2506  void *ctx;
2507  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
2508  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
2509  char *res = REAL(ether_ntoa_r)(addr, buf);
2510  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2511  return res;
2512}
2513INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
2514            __sanitizer_ether_addr *addr) {
2515  void *ctx;
2516  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
2517  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2518  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
2519  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
2520  return res;
2521}
2522#define INIT_ETHER_R                 \
2523  INTERCEPT_FUNCTION(ether_ntoa_r);  \
2524  INTERCEPT_FUNCTION(ether_aton_r);
2525#else
2526#define INIT_ETHER_R
2527#endif
2528
2529#if SANITIZER_INTERCEPT_SHMCTL
2530INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
2531  void *ctx;
2532  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
2533  int res = REAL(shmctl)(shmid, cmd, buf);
2534  if (res >= 0) {
2535    unsigned sz = 0;
2536    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
2537      sz = sizeof(__sanitizer_shmid_ds);
2538    else if (cmd == shmctl_ipc_info)
2539      sz = struct_shminfo_sz;
2540    else if (cmd == shmctl_shm_info)
2541      sz = struct_shm_info_sz;
2542    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2543  }
2544  return res;
2545}
2546#define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl);
2547#else
2548#define INIT_SHMCTL
2549#endif
2550
2551#if SANITIZER_INTERCEPT_RANDOM_R
2552INTERCEPTOR(int, random_r, void *buf, u32 *result) {
2553  void *ctx;
2554  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
2555  int res = REAL(random_r)(buf, result);
2556  if (!res && result)
2557    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2558  return res;
2559}
2560#define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r);
2561#else
2562#define INIT_RANDOM_R
2563#endif
2564
2565#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \
2566    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED
2567#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz)                      \
2568  INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) {   \
2569    void *ctx;                                                      \
2570    COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \
2571    int res = REAL(pthread_attr_get##what)(attr, r);                \
2572    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz);      \
2573    return res;                                                     \
2574  }
2575#endif
2576
2577#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
2578INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
2579INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
2580INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
2581INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
2582INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
2583INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
2584INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
2585  void *ctx;
2586  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
2587  int res = REAL(pthread_attr_getstack)(attr, addr, size);
2588  if (!res) {
2589    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
2590    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
2591  }
2592  return res;
2593}
2594
2595#define INIT_PTHREAD_ATTR_GET                       \
2596  INTERCEPT_FUNCTION(pthread_attr_getdetachstate);  \
2597  INTERCEPT_FUNCTION(pthread_attr_getguardsize);    \
2598  INTERCEPT_FUNCTION(pthread_attr_getschedparam);   \
2599  INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);  \
2600  INTERCEPT_FUNCTION(pthread_attr_getscope);        \
2601  INTERCEPT_FUNCTION(pthread_attr_getstacksize);    \
2602  INTERCEPT_FUNCTION(pthread_attr_getstack);
2603#else
2604#define INIT_PTHREAD_ATTR_GET
2605#endif
2606
2607#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
2608INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
2609
2610#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
2611  INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
2612#else
2613#define INIT_PTHREAD_ATTR_GETINHERITSCHED
2614#endif
2615
2616#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
2617INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
2618            void *cpuset) {
2619  void *ctx;
2620  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
2621                           cpuset);
2622  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
2623  if (!res && cpusetsize && cpuset)
2624    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
2625  return res;
2626}
2627
2628#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
2629  INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
2630#else
2631#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
2632#endif
2633
2634#if SANITIZER_INTERCEPT_TMPNAM
2635INTERCEPTOR(char *, tmpnam, char *s) {
2636  void *ctx;
2637  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
2638  char *res = REAL(tmpnam)(s);
2639  if (res) {
2640    if (s)
2641      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
2642    else
2643      COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2644  }
2645  return res;
2646}
2647#define INIT_TMPNAM INTERCEPT_FUNCTION(tmpnam);
2648#else
2649#define INIT_TMPNAM
2650#endif
2651
2652#if SANITIZER_INTERCEPT_TMPNAM_R
2653INTERCEPTOR(char *, tmpnam_r, char *s) {
2654  void *ctx;
2655  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
2656  char *res = REAL(tmpnam_r)(s);
2657  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
2658  return res;
2659}
2660#define INIT_TMPNAM_R INTERCEPT_FUNCTION(tmpnam_r);
2661#else
2662#define INIT_TMPNAM_R
2663#endif
2664
2665#if SANITIZER_INTERCEPT_TEMPNAM
2666INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
2667  void *ctx;
2668  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
2669  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
2670  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
2671  char *res = REAL(tempnam)(dir, pfx);
2672  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2673  return res;
2674}
2675#define INIT_TEMPNAM INTERCEPT_FUNCTION(tempnam);
2676#else
2677#define INIT_TEMPNAM
2678#endif
2679
2680#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
2681INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
2682  void *ctx;
2683  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
2684  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
2685  return REAL(pthread_setname_np)(thread, name);
2686}
2687#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np);
2688#else
2689#define INIT_PTHREAD_SETNAME_NP
2690#endif
2691
2692#if SANITIZER_INTERCEPT_SINCOS
2693INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
2694  void *ctx;
2695  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
2696  REAL(sincos)(x, sin, cos);
2697  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2698  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2699}
2700INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
2701  void *ctx;
2702  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
2703  REAL(sincosf)(x, sin, cos);
2704  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2705  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2706}
2707INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
2708  void *ctx;
2709  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
2710  REAL(sincosl)(x, sin, cos);
2711  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
2712  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
2713}
2714#define INIT_SINCOS            \
2715  INTERCEPT_FUNCTION(sincos);  \
2716  INTERCEPT_FUNCTION(sincosf); \
2717  INTERCEPT_FUNCTION(sincosl);
2718#else
2719#define INIT_SINCOS
2720#endif
2721
2722#if SANITIZER_INTERCEPT_REMQUO
2723INTERCEPTOR(double, remquo, double x, double y, int *quo) {
2724  void *ctx;
2725  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
2726  double res = REAL(remquo)(x, y, quo);
2727  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2728  return res;
2729}
2730INTERCEPTOR(float, remquof, float x, float y, int *quo) {
2731  void *ctx;
2732  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
2733  float res = REAL(remquof)(x, y, quo);
2734  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2735  return res;
2736}
2737INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
2738  void *ctx;
2739  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
2740  long double res = REAL(remquol)(x, y, quo);
2741  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
2742  return res;
2743}
2744#define INIT_REMQUO            \
2745  INTERCEPT_FUNCTION(remquo);  \
2746  INTERCEPT_FUNCTION(remquof); \
2747  INTERCEPT_FUNCTION(remquol);
2748#else
2749#define INIT_REMQUO
2750#endif
2751
2752#if SANITIZER_INTERCEPT_LGAMMA
2753extern int signgam;
2754INTERCEPTOR(double, lgamma, double x) {
2755  void *ctx;
2756  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
2757  double res = REAL(lgamma)(x);
2758  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2759  return res;
2760}
2761INTERCEPTOR(float, lgammaf, float x) {
2762  void *ctx;
2763  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
2764  float res = REAL(lgammaf)(x);
2765  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2766  return res;
2767}
2768INTERCEPTOR(long double, lgammal, long double x) {
2769  void *ctx;
2770  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
2771  long double res = REAL(lgammal)(x);
2772  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
2773  return res;
2774}
2775#define INIT_LGAMMA            \
2776  INTERCEPT_FUNCTION(lgamma);  \
2777  INTERCEPT_FUNCTION(lgammaf); \
2778  INTERCEPT_FUNCTION(lgammal);
2779#else
2780#define INIT_LGAMMA
2781#endif
2782
2783#if SANITIZER_INTERCEPT_LGAMMA_R
2784INTERCEPTOR(double, lgamma_r, double x, int *signp) {
2785  void *ctx;
2786  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
2787  double res = REAL(lgamma_r)(x, signp);
2788  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2789  return res;
2790}
2791INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
2792  void *ctx;
2793  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
2794  float res = REAL(lgammaf_r)(x, signp);
2795  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2796  return res;
2797}
2798INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
2799  void *ctx;
2800  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
2801  long double res = REAL(lgammal_r)(x, signp);
2802  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
2803  return res;
2804}
2805#define INIT_LGAMMA_R            \
2806  INTERCEPT_FUNCTION(lgamma_r);  \
2807  INTERCEPT_FUNCTION(lgammaf_r); \
2808  INTERCEPT_FUNCTION(lgammal_r);
2809#else
2810#define INIT_LGAMMA_R
2811#endif
2812
2813#if SANITIZER_INTERCEPT_DRAND48_R
2814INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
2815  void *ctx;
2816  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
2817  int res = REAL(drand48_r)(buffer, result);
2818  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2819  return res;
2820}
2821INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
2822  void *ctx;
2823  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
2824  int res = REAL(lrand48_r)(buffer, result);
2825  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2826  return res;
2827}
2828#define INIT_DRAND48_R            \
2829  INTERCEPT_FUNCTION(drand48_r);  \
2830  INTERCEPT_FUNCTION(lrand48_r);
2831#else
2832#define INIT_DRAND48_R
2833#endif
2834
2835#if SANITIZER_INTERCEPT_GETLINE
2836INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
2837  void *ctx;
2838  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
2839  SSIZE_T res = REAL(getline)(lineptr, n, stream);
2840  if (res > 0) {
2841    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
2842    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
2843    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
2844  }
2845  return res;
2846}
2847INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
2848            void *stream) {
2849  void *ctx;
2850  COMMON_INTERCEPTOR_ENTER(ctx, getdelim, lineptr, n, delim, stream);
2851  SSIZE_T res = REAL(getdelim)(lineptr, n, delim, stream);
2852  if (res > 0) {
2853    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
2854    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
2855    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
2856  }
2857  return res;
2858}
2859#define INIT_GETLINE           \
2860  INTERCEPT_FUNCTION(getline); \
2861  INTERCEPT_FUNCTION(getdelim);
2862#else
2863#define INIT_GETLINE
2864#endif
2865
2866#define SANITIZER_COMMON_INTERCEPTORS_INIT \
2867  INIT_STRCMP;                             \
2868  INIT_STRNCMP;                            \
2869  INIT_STRCASECMP;                         \
2870  INIT_STRNCASECMP;                        \
2871  INIT_READ;                               \
2872  INIT_PREAD;                              \
2873  INIT_PREAD64;                            \
2874  INIT_READV;                              \
2875  INIT_PREADV;                             \
2876  INIT_PREADV64;                           \
2877  INIT_WRITE;                              \
2878  INIT_PWRITE;                             \
2879  INIT_PWRITE64;                           \
2880  INIT_WRITEV;                             \
2881  INIT_PWRITEV;                            \
2882  INIT_PWRITEV64;                          \
2883  INIT_PRCTL;                              \
2884  INIT_LOCALTIME_AND_FRIENDS;              \
2885  INIT_STRPTIME;                           \
2886  INIT_SCANF;                              \
2887  INIT_ISOC99_SCANF;                       \
2888  INIT_FREXP;                              \
2889  INIT_FREXPF_FREXPL;                      \
2890  INIT_GETPWNAM_AND_FRIENDS;               \
2891  INIT_GETPWNAM_R_AND_FRIENDS;             \
2892  INIT_CLOCK_GETTIME;                      \
2893  INIT_GETITIMER;                          \
2894  INIT_TIME;                               \
2895  INIT_GLOB;                               \
2896  INIT_WAIT;                               \
2897  INIT_INET;                               \
2898  INIT_PTHREAD_GETSCHEDPARAM;              \
2899  INIT_GETADDRINFO;                        \
2900  INIT_GETNAMEINFO;                        \
2901  INIT_GETSOCKNAME;                        \
2902  INIT_GETHOSTBYNAME;                      \
2903  INIT_GETHOSTBYNAME_R;                    \
2904  INIT_GETSOCKOPT;                         \
2905  INIT_ACCEPT;                             \
2906  INIT_ACCEPT4;                            \
2907  INIT_MODF;                               \
2908  INIT_RECVMSG;                            \
2909  INIT_GETPEERNAME;                        \
2910  INIT_IOCTL;                              \
2911  INIT_INET_ATON;                          \
2912  INIT_SYSINFO;                            \
2913  INIT_READDIR;                            \
2914  INIT_READDIR64;                          \
2915  INIT_PTRACE;                             \
2916  INIT_SETLOCALE;                          \
2917  INIT_GETCWD;                             \
2918  INIT_GET_CURRENT_DIR_NAME;               \
2919  INIT_STRTOIMAX;                          \
2920  INIT_MBSTOWCS;                           \
2921  INIT_MBSNRTOWCS;                         \
2922  INIT_WCSTOMBS;                           \
2923  INIT_WCSNRTOMBS;                         \
2924  INIT_TCGETATTR;                          \
2925  INIT_REALPATH;                           \
2926  INIT_CANONICALIZE_FILE_NAME;             \
2927  INIT_CONFSTR;                            \
2928  INIT_SCHED_GETAFFINITY;                  \
2929  INIT_STRERROR;                           \
2930  INIT_STRERROR_R;                         \
2931  INIT_SCANDIR;                            \
2932  INIT_SCANDIR64;                          \
2933  INIT_GETGROUPS;                          \
2934  INIT_POLL;                               \
2935  INIT_PPOLL;                              \
2936  INIT_WORDEXP;                            \
2937  INIT_SIGWAIT;                            \
2938  INIT_SIGWAITINFO;                        \
2939  INIT_SIGTIMEDWAIT;                       \
2940  INIT_SIGSETOPS;                          \
2941  INIT_SIGPENDING;                         \
2942  INIT_SIGPROCMASK;                        \
2943  INIT_BACKTRACE;                          \
2944  INIT__EXIT;                              \
2945  INIT_PTHREAD_MUTEX_LOCK;                 \
2946  INIT_PTHREAD_MUTEX_UNLOCK;               \
2947  INIT_PTHREAD_COND_WAIT;                  \
2948  INIT_PTHREAD_COND_INIT;                  \
2949  INIT_PTHREAD_COND_SIGNAL;                \
2950  INIT_PTHREAD_COND_BROADCAST;             \
2951  INIT_GETMNTENT;                          \
2952  INIT_GETMNTENT_R;                        \
2953  INIT_STATFS;                             \
2954  INIT_STATFS64;                           \
2955  INIT_STATVFS;                            \
2956  INIT_STATVFS64;                          \
2957  INIT_INITGROUPS;                         \
2958  INIT_ETHER;                              \
2959  INIT_ETHER_R;                            \
2960  INIT_SHMCTL;                             \
2961  INIT_RANDOM_R;                           \
2962  INIT_PTHREAD_ATTR_GET;                   \
2963  INIT_PTHREAD_ATTR_GETINHERITSCHED;       \
2964  INIT_PTHREAD_ATTR_GETAFFINITY_NP;        \
2965  INIT_TMPNAM;                             \
2966  INIT_TMPNAM_R;                           \
2967  INIT_TEMPNAM;                            \
2968  INIT_PTHREAD_SETNAME_NP;                 \
2969  INIT_SINCOS;                             \
2970  INIT_REMQUO;                             \
2971  INIT_LGAMMA;                             \
2972  INIT_LGAMMA_R;                           \
2973  INIT_DRAND48_R;                          \
2974  INIT_GETLINE;                            \
2975/**/
2976