sanitizer_common_interceptors.inc revision a0379b5566f7c04536a313e40c450c6aef4b3ec5
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_FD_ACQUIRE
19//   COMMON_INTERCEPTOR_FD_RELEASE
20//   COMMON_INTERCEPTOR_SET_THREAD_NAME
21//===----------------------------------------------------------------------===//
22#include "interception/interception.h"
23#include "sanitizer_platform_interceptors.h"
24
25#include <stdarg.h>
26
27#if SANITIZER_WINDOWS
28#define va_copy(dst, src) ((dst) = (src))
29#endif // _WIN32
30
31#if SANITIZER_INTERCEPT_STRCASECMP
32static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
33  int c1_low = ToLower(c1);
34  int c2_low = ToLower(c2);
35  return c1_low - c2_low;
36}
37
38INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
39  void *ctx;
40  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
41  unsigned char c1 = 0, c2 = 0;
42  uptr i;
43  for (i = 0; ; i++) {
44    c1 = (unsigned char)s1[i];
45    c2 = (unsigned char)s2[i];
46    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
47      break;
48  }
49  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
50  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
51  return CharCaseCmp(c1, c2);
52}
53
54INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
55  void *ctx;
56  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
57  unsigned char c1 = 0, c2 = 0;
58  uptr i;
59  for (i = 0; i < n; i++) {
60    c1 = (unsigned char)s1[i];
61    c2 = (unsigned char)s2[i];
62    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0')
63      break;
64  }
65  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
66  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
67  return CharCaseCmp(c1, c2);
68}
69
70#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp)
71#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp)
72#else
73#define INIT_STRCASECMP
74#define INIT_STRNCASECMP
75#endif
76
77#if SANITIZER_INTERCEPT_FREXP
78INTERCEPTOR(double, frexp, double x, int *exp) {
79  void *ctx;
80  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
81  double res = REAL(frexp)(x, exp);
82  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
83  return res;
84}
85
86#define INIT_FREXP INTERCEPT_FUNCTION(frexp);
87#else
88#define INIT_FREXP
89#endif // SANITIZER_INTERCEPT_FREXP
90
91#if SANITIZER_INTERCEPT_FREXPF_FREXPL
92INTERCEPTOR(float, frexpf, float x, int *exp) {
93  void *ctx;
94  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
95  float res = REAL(frexpf)(x, exp);
96  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
97  return res;
98}
99
100INTERCEPTOR(long double, frexpl, long double x, int *exp) {
101  void *ctx;
102  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
103  long double res = REAL(frexpl)(x, exp);
104  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
105  return res;
106}
107
108#define INIT_FREXPF_FREXPL                       \
109  INTERCEPT_FUNCTION(frexpf);                    \
110  INTERCEPT_FUNCTION(frexpl)
111#else
112#define INIT_FREXPF_FREXPL
113#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
114
115#if SI_NOT_WINDOWS
116static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
117                        SIZE_T iovlen, SIZE_T maxlen) {
118  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
119    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
120    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
121    maxlen -= sz;
122  }
123}
124
125static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
126                       SIZE_T iovlen, SIZE_T maxlen) {
127  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
128  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
129    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
130    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
131    maxlen -= sz;
132  }
133}
134#endif
135
136#if SANITIZER_INTERCEPT_READ
137INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
138  void *ctx;
139  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
140  SSIZE_T res = REAL(read)(fd, ptr, count);
141  if (res > 0)
142    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
143  if (res >= 0 && fd >= 0)
144    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
145  return res;
146}
147#define INIT_READ INTERCEPT_FUNCTION(read)
148#else
149#define INIT_READ
150#endif
151
152#if SANITIZER_INTERCEPT_PREAD
153INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
154  void *ctx;
155  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
156  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
157  if (res > 0)
158    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
159  if (res >= 0 && fd >= 0)
160    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
161  return res;
162}
163#define INIT_PREAD INTERCEPT_FUNCTION(pread)
164#else
165#define INIT_PREAD
166#endif
167
168#if SANITIZER_INTERCEPT_PREAD64
169INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
170  void *ctx;
171  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
172  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
173  if (res > 0)
174    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
175  if (res >= 0 && fd >= 0)
176    COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
177  return res;
178}
179#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64)
180#else
181#define INIT_PREAD64
182#endif
183
184#if SANITIZER_INTERCEPT_READV
185INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
186                        int iovcnt) {
187  void *ctx;
188  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
189  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
190  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
191  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
192  return res;
193}
194#define INIT_READV INTERCEPT_FUNCTION(readv)
195#else
196#define INIT_READV
197#endif
198
199#if SANITIZER_INTERCEPT_PREADV
200INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
201            OFF_T offset) {
202  void *ctx;
203  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
204  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
205  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
206  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
207  return res;
208}
209#define INIT_PREADV INTERCEPT_FUNCTION(preadv)
210#else
211#define INIT_PREADV
212#endif
213
214#if SANITIZER_INTERCEPT_PREADV64
215INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
216            OFF64_T offset) {
217  void *ctx;
218  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
219  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
220  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
221  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
222  return res;
223}
224#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64)
225#else
226#define INIT_PREADV64
227#endif
228
229#if SANITIZER_INTERCEPT_WRITE
230INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
231  void *ctx;
232  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
233  if (fd >= 0)
234    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
235  SSIZE_T res = REAL(write)(fd, ptr, count);
236  // FIXME: this check should be _before_ the call to REAL(write), not after
237  if (res > 0)
238    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
239  return res;
240}
241#define INIT_WRITE INTERCEPT_FUNCTION(write)
242#else
243#define INIT_WRITE
244#endif
245
246#if SANITIZER_INTERCEPT_PWRITE
247INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
248  void *ctx;
249  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
250  if (fd >= 0)
251    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
252  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
253  if (res > 0)
254    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
255  return res;
256}
257#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite)
258#else
259#define INIT_PWRITE
260#endif
261
262#if SANITIZER_INTERCEPT_PWRITE64
263INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
264            OFF64_T offset) {
265  void *ctx;
266  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
267  if (fd >= 0)
268    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
269  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
270  if (res > 0)
271    COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
272  return res;
273}
274#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64)
275#else
276#define INIT_PWRITE64
277#endif
278
279#if SANITIZER_INTERCEPT_WRITEV
280INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
281                        int iovcnt) {
282  void *ctx;
283  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
284  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
285  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
286  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
287  return res;
288}
289#define INIT_WRITEV INTERCEPT_FUNCTION(writev)
290#else
291#define INIT_WRITEV
292#endif
293
294#if SANITIZER_INTERCEPT_PWRITEV
295INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
296            OFF_T offset) {
297  void *ctx;
298  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
299  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
300  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
301  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
302  return res;
303}
304#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev)
305#else
306#define INIT_PWRITEV
307#endif
308
309#if SANITIZER_INTERCEPT_PWRITEV64
310INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
311            OFF64_T offset) {
312  void *ctx;
313  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
314  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
315  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
316  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
317  return res;
318}
319#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64)
320#else
321#define INIT_PWRITEV64
322#endif
323
324#if SANITIZER_INTERCEPT_PRCTL
325INTERCEPTOR(int, prctl, int option,
326            unsigned long arg2, unsigned long arg3,   // NOLINT
327            unsigned long arg4, unsigned long arg5) { // NOLINT
328  void *ctx;
329  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
330  static const int PR_SET_NAME = 15;
331  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
332  if (option == PR_SET_NAME) {
333    char buff[16];
334    internal_strncpy(buff, (char *)arg2, 15);
335    buff[15] = 0;
336    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
337  }
338  return res;
339}
340#define INIT_PRCTL INTERCEPT_FUNCTION(prctl)
341#else
342#define INIT_PRCTL
343#endif // SANITIZER_INTERCEPT_PRCTL
344
345
346#if SANITIZER_INTERCEPT_TIME
347INTERCEPTOR(unsigned long, time, unsigned long *t) {
348  void *ctx;
349  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
350  unsigned long res = REAL(time)(t);
351  if (t && res != (unsigned long)-1) {
352    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
353  }
354  return res;
355}
356#define INIT_TIME                                \
357  INTERCEPT_FUNCTION(time);
358#else
359#define INIT_TIME
360#endif // SANITIZER_INTERCEPT_TIME
361
362
363#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
364INTERCEPTOR(void *, localtime, unsigned long *timep) {
365  void *ctx;
366  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
367  void *res = REAL(localtime)(timep);
368  if (res) {
369    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
370    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
371  }
372  return res;
373}
374INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) {
375  void *ctx;
376  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
377  void *res = REAL(localtime_r)(timep, result);
378  if (res) {
379    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
380    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
381  }
382  return res;
383}
384INTERCEPTOR(void *, gmtime, unsigned long *timep) {
385  void *ctx;
386  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
387  void *res = REAL(gmtime)(timep);
388  if (res) {
389    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
390    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
391  }
392  return res;
393}
394INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) {
395  void *ctx;
396  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
397  void *res = REAL(gmtime_r)(timep, result);
398  if (res) {
399    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
400    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz);
401  }
402  return res;
403}
404INTERCEPTOR(char *, ctime, unsigned long *timep) {
405  void *ctx;
406  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
407  char *res = REAL(ctime)(timep);
408  if (res) {
409    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
410    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
411  }
412  return res;
413}
414INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
415  void *ctx;
416  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
417  char *res = REAL(ctime_r)(timep, result);
418  if (res) {
419    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
420    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
421  }
422  return res;
423}
424INTERCEPTOR(char *, asctime, void *tm) {
425  void *ctx;
426  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
427  char *res = REAL(asctime)(tm);
428  if (res) {
429    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
430    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
431  }
432  return res;
433}
434INTERCEPTOR(char *, asctime_r, void *tm, char *result) {
435  void *ctx;
436  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
437  char *res = REAL(asctime_r)(tm, result);
438  if (res) {
439    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz);
440    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
441  }
442  return res;
443}
444#define INIT_LOCALTIME_AND_FRIENDS               \
445  INTERCEPT_FUNCTION(localtime);                 \
446  INTERCEPT_FUNCTION(localtime_r);               \
447  INTERCEPT_FUNCTION(gmtime);                    \
448  INTERCEPT_FUNCTION(gmtime_r);                  \
449  INTERCEPT_FUNCTION(ctime);                     \
450  INTERCEPT_FUNCTION(ctime_r);                   \
451  INTERCEPT_FUNCTION(asctime);                   \
452  INTERCEPT_FUNCTION(asctime_r);
453#else
454#define INIT_LOCALTIME_AND_FRIENDS
455#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
456
457#if SANITIZER_INTERCEPT_SCANF
458
459#include "sanitizer_common_interceptors_scanf.inc"
460
461#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
462  {                                                                            \
463    void *ctx;                                                                 \
464    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
465    va_list aq;                                                                \
466    va_copy(aq, ap);                                                           \
467    int res = REAL(vname)(__VA_ARGS__);                                        \
468    if (res > 0)                                                               \
469      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
470    va_end(aq);                                                                \
471    return res;                                                                \
472  }
473
474INTERCEPTOR(int, vscanf, const char *format, va_list ap)
475VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
476
477INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
478VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
479
480INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
481VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
482
483#if SANITIZER_INTERCEPT_ISOC99_SCANF
484INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
485VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
486
487INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
488            va_list ap)
489VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
490
491INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
492VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
493#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
494
495#define SCANF_INTERCEPTOR_IMPL(name, vname, ...)                               \
496  {                                                                            \
497    void *ctx;                                                                 \
498    COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__);                          \
499    va_list ap;                                                                \
500    va_start(ap, format);                                                      \
501    int res = vname(__VA_ARGS__, ap);                                          \
502    va_end(ap);                                                                \
503    return res;                                                                \
504  }
505
506INTERCEPTOR(int, scanf, const char *format, ...)
507SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format)
508
509INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
510SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
511
512INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
513SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
514
515#if SANITIZER_INTERCEPT_ISOC99_SCANF
516INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
517SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
518
519INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
520SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
521
522INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
523SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
524#endif
525
526#define INIT_SCANF                                                             \
527  INTERCEPT_FUNCTION(scanf);                                                   \
528  INTERCEPT_FUNCTION(sscanf);                                                  \
529  INTERCEPT_FUNCTION(fscanf);                                                  \
530  INTERCEPT_FUNCTION(vscanf);                                                  \
531  INTERCEPT_FUNCTION(vsscanf);                                                 \
532  INTERCEPT_FUNCTION(vfscanf);                                                 \
533  INTERCEPT_FUNCTION(__isoc99_scanf);                                          \
534  INTERCEPT_FUNCTION(__isoc99_sscanf);                                         \
535  INTERCEPT_FUNCTION(__isoc99_fscanf);                                         \
536  INTERCEPT_FUNCTION(__isoc99_vscanf);                                         \
537  INTERCEPT_FUNCTION(__isoc99_vsscanf);                                        \
538  INTERCEPT_FUNCTION(__isoc99_vfscanf);
539
540#else
541#define INIT_SCANF
542#endif
543
544
545#if SANITIZER_INTERCEPT_IOCTL
546#include "sanitizer_common_interceptors_ioctl.inc"
547INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
548  void *ctx;
549  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
550
551  CHECK(ioctl_initialized);
552
553  // Note: TSan does not use common flags, and they are zero-initialized.
554  // This effectively disables ioctl handling in TSan.
555  if (!common_flags()->handle_ioctl)
556    return REAL(ioctl)(d, request, arg);
557
558  const ioctl_desc *desc = ioctl_lookup(request);
559  if (!desc)
560    Printf("WARNING: unknown ioctl %x\n", request);
561
562  if (desc)
563    ioctl_common_pre(ctx, desc, d, request, arg);
564  int res = REAL(ioctl)(d, request, arg);
565  // FIXME: some ioctls have different return values for success and failure.
566  if (desc && res != -1)
567    ioctl_common_post(ctx, desc, res, d, request, arg);
568  return res;
569}
570#define INIT_IOCTL \
571  ioctl_init();    \
572  INTERCEPT_FUNCTION(ioctl);
573#else
574#define INIT_IOCTL
575#endif
576
577
578#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
579INTERCEPTOR(void *, getpwnam, const char *name) {
580  void *ctx;
581  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
582  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
583  void *res = REAL(getpwnam)(name);
584  if (res != 0)
585    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
586  return res;
587}
588INTERCEPTOR(void *, getpwuid, u32 uid) {
589  void *ctx;
590  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
591  void *res = REAL(getpwuid)(uid);
592  if (res != 0)
593    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz);
594  return res;
595}
596INTERCEPTOR(void *, getgrnam, const char *name) {
597  void *ctx;
598  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
599  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
600  void *res = REAL(getgrnam)(name);
601  if (res != 0)
602    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
603  return res;
604}
605INTERCEPTOR(void *, getgrgid, u32 gid) {
606  void *ctx;
607  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
608  void *res = REAL(getgrgid)(gid);
609  if (res != 0)
610    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz);
611  return res;
612}
613#define INIT_GETPWNAM_AND_FRIENDS                  \
614  INTERCEPT_FUNCTION(getpwnam);                    \
615  INTERCEPT_FUNCTION(getpwuid);                    \
616  INTERCEPT_FUNCTION(getgrnam);                    \
617  INTERCEPT_FUNCTION(getgrgid);
618#else
619#define INIT_GETPWNAM_AND_FRIENDS
620#endif
621
622
623#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
624INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd,
625    char *buf, SIZE_T buflen, void **result) {
626  void *ctx;
627  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
628  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
629  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
630  if (!res) {
631    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
632    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
633  }
634  return res;
635}
636INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd,
637    char *buf, SIZE_T buflen, void **result) {
638  void *ctx;
639  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
640  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
641  if (!res) {
642    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz);
643    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
644  }
645  return res;
646}
647INTERCEPTOR(int, getgrnam_r, const char *name, void *grp,
648    char *buf, SIZE_T buflen, void **result) {
649  void *ctx;
650  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
651  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
652  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
653  if (!res) {
654    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
655    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
656  }
657  return res;
658}
659INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp,
660    char *buf, SIZE_T buflen, void **result) {
661  void *ctx;
662  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
663  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
664  if (!res) {
665    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz);
666    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
667  }
668  return res;
669}
670#define INIT_GETPWNAM_R_AND_FRIENDS                \
671  INTERCEPT_FUNCTION(getpwnam_r);                  \
672  INTERCEPT_FUNCTION(getpwuid_r);                  \
673  INTERCEPT_FUNCTION(getgrnam_r);                  \
674  INTERCEPT_FUNCTION(getgrgid_r);
675#else
676#define INIT_GETPWNAM_R_AND_FRIENDS
677#endif
678
679
680#if SANITIZER_INTERCEPT_CLOCK_GETTIME
681INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
682  void *ctx;
683  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
684  int res = REAL(clock_getres)(clk_id, tp);
685  if (!res && tp) {
686    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
687  }
688  return res;
689}
690INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
691  void *ctx;
692  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
693  int res = REAL(clock_gettime)(clk_id, tp);
694  if (!res) {
695    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
696  }
697  return res;
698}
699INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
700  void *ctx;
701  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
702  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
703  return REAL(clock_settime)(clk_id, tp);
704}
705#define INIT_CLOCK_GETTIME                         \
706  INTERCEPT_FUNCTION(clock_getres);                \
707  INTERCEPT_FUNCTION(clock_gettime);               \
708  INTERCEPT_FUNCTION(clock_settime);
709#else
710#define INIT_CLOCK_GETTIME
711#endif
712
713
714#if SANITIZER_INTERCEPT_GETITIMER
715INTERCEPTOR(int, getitimer, int which, void *curr_value) {
716  void *ctx;
717  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
718  int res = REAL(getitimer)(which, curr_value);
719  if (!res) {
720    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
721  }
722  return res;
723}
724INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
725  void *ctx;
726  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
727  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
728  int res = REAL(setitimer)(which, new_value, old_value);
729  if (!res && old_value) {
730    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
731  }
732  return res;
733}
734#define INIT_GETITIMER                             \
735  INTERCEPT_FUNCTION(getitimer);                   \
736  INTERCEPT_FUNCTION(setitimer);
737#else
738#define INIT_GETITIMER
739#endif
740
741
742#if SANITIZER_INTERCEPT_GLOB
743struct sanitizer_glob_t {
744  SIZE_T gl_pathc;
745  char **gl_pathv;
746};
747
748static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) {
749  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
750  // +1 for NULL pointer at the end.
751  COMMON_INTERCEPTOR_WRITE_RANGE(
752      ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
753  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
754    char *p = pglob->gl_pathv[i];
755    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
756  }
757}
758
759INTERCEPTOR(int, glob, const char *pattern, int flags,
760            int (*errfunc)(const char *epath, int eerrno),
761            sanitizer_glob_t *pglob) {
762  void *ctx;
763  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
764  int res = REAL(glob)(pattern, flags, errfunc, pglob);
765  if (res == 0)
766    unpoison_glob_t(ctx, pglob);
767  return res;
768}
769
770INTERCEPTOR(int, glob64, const char *pattern, int flags,
771            int (*errfunc)(const char *epath, int eerrno),
772            sanitizer_glob_t *pglob) {
773  void *ctx;
774  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
775  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
776  if (res == 0)
777    unpoison_glob_t(ctx, pglob);
778  return res;
779}
780#define INIT_GLOB                               \
781  INTERCEPT_FUNCTION(glob);                     \
782  INTERCEPT_FUNCTION(glob64);
783#else // SANITIZER_INTERCEPT_GLOB
784#define INIT_GLOB
785#endif // SANITIZER_INTERCEPT_GLOB
786
787
788#if SANITIZER_INTERCEPT_WAIT
789// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
790// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
791// details.
792INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
793  void *ctx;
794  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
795  int res = REAL(wait)(status);
796  if (res != -1 && status)
797    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
798  return res;
799}
800INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
801  int options) {
802  void *ctx;
803  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
804  int res = REAL(waitid)(idtype, id, infop, options);
805  if (res != -1 && infop)
806    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
807  return res;
808}
809INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
810  void *ctx;
811  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
812  int res = REAL(waitpid)(pid, status, options);
813  if (res != -1 && status)
814    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
815  return res;
816}
817INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
818  void *ctx;
819  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
820  int res = REAL(wait3)(status, options, rusage);
821  if (res != -1) {
822    if (status)
823      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
824    if (rusage)
825      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
826  }
827  return res;
828}
829INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
830  void *ctx;
831  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
832  int res = REAL(wait4)(pid, status, options, rusage);
833  if (res != -1) {
834    if (status)
835      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
836    if (rusage)
837      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
838  }
839  return res;
840}
841#define INIT_WAIT                                \
842  INTERCEPT_FUNCTION(wait);                      \
843  INTERCEPT_FUNCTION(waitid);                    \
844  INTERCEPT_FUNCTION(waitpid);                   \
845  INTERCEPT_FUNCTION(wait3);                     \
846  INTERCEPT_FUNCTION(wait4);
847#else
848#define INIT_WAIT
849#endif
850
851#if SANITIZER_INTERCEPT_INET
852INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
853  void *ctx;
854  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
855  uptr sz = __sanitizer_in_addr_sz(af);
856  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
857  // FIXME: figure out read size based on the address family.
858  char *res = REAL(inet_ntop)(af, src, dst, size);
859  if (res)
860    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
861  return res;
862}
863INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
864  void *ctx;
865  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
866  // FIXME: figure out read size based on the address family.
867  int res = REAL(inet_pton)(af, src, dst);
868  if (res == 1) {
869    uptr sz = __sanitizer_in_addr_sz(af);
870    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
871  }
872  return res;
873}
874#define INIT_INET                                \
875  INTERCEPT_FUNCTION(inet_ntop);                 \
876  INTERCEPT_FUNCTION(inet_pton);
877#else
878#define INIT_INET
879#endif
880
881#if SANITIZER_INTERCEPT_INET
882INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
883  void *ctx;
884  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
885  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
886  int res = REAL(inet_aton)(cp, dst);
887  if (res != 0) {
888    uptr sz = __sanitizer_in_addr_sz(af_inet);
889    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
890  }
891  return res;
892}
893#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
894#else
895#define INIT_INET_ATON
896#endif
897
898#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
899INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
900  void *ctx;
901  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
902  int res = REAL(pthread_getschedparam)(thread, policy, param);
903  if (res == 0) {
904    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
905    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
906  }
907  return res;
908}
909#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
910#else
911#define INIT_PTHREAD_GETSCHEDPARAM
912#endif
913
914#if SANITIZER_INTERCEPT_GETADDRINFO
915INTERCEPTOR(int, getaddrinfo, char *node, char *service,
916            struct __sanitizer_addrinfo *hints,
917            struct __sanitizer_addrinfo **out) {
918  void *ctx;
919  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
920  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
921  if (service)
922    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
923  if (hints)
924    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
925  int res = REAL(getaddrinfo)(node, service, hints, out);
926  if (res == 0 && out) {
927    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
928    struct __sanitizer_addrinfo *p = *out;
929    while (p) {
930      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
931      if (p->ai_addr)
932        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
933      if (p->ai_canonname)
934        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
935                                       REAL(strlen)(p->ai_canonname) + 1);
936      p = p->ai_next;
937    }
938  }
939  return res;
940}
941#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
942#else
943#define INIT_GETADDRINFO
944#endif
945
946#if SANITIZER_INTERCEPT_GETSOCKNAME
947INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
948  void *ctx;
949  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
950  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
951  int addrlen_in = *addrlen;
952  int res = REAL(getsockname)(sock_fd, addr, addrlen);
953  if (res == 0) {
954    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
955  }
956  return res;
957}
958#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
959#else
960#define INIT_GETSOCKNAME
961#endif
962
963#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
964static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
965  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
966  if (h->h_name)
967    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
968  char **p = h->h_aliases;
969  while (*p) {
970    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
971    ++p;
972  }
973  COMMON_INTERCEPTOR_WRITE_RANGE(
974      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
975  p = h->h_addr_list;
976  while (*p) {
977    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
978    ++p;
979  }
980  COMMON_INTERCEPTOR_WRITE_RANGE(
981      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
982}
983#endif
984
985#if SANITIZER_INTERCEPT_GETHOSTBYNAME
986INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
987  void *ctx;
988  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
989  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
990  if (res) write_hostent(ctx, res);
991  return res;
992}
993
994INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
995            int type) {
996  void *ctx;
997  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
998  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
999  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1000  if (res) write_hostent(ctx, res);
1001  return res;
1002}
1003
1004INTERCEPTOR(struct __sanitizer_hostent *, gethostent) {
1005  void *ctx;
1006  COMMON_INTERCEPTOR_ENTER(ctx, gethostent);
1007  struct __sanitizer_hostent *res = REAL(gethostent)();
1008  if (res) write_hostent(ctx, res);
1009  return res;
1010}
1011
1012INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1013  void *ctx;
1014  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1015  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1016  if (res) write_hostent(ctx, res);
1017  return res;
1018}
1019#define INIT_GETHOSTBYNAME           \
1020  INTERCEPT_FUNCTION(gethostent);    \
1021  INTERCEPT_FUNCTION(gethostbyaddr); \
1022  INTERCEPT_FUNCTION(gethostbyname); \
1023  INTERCEPT_FUNCTION(gethostbyname2);
1024#else
1025#define INIT_GETHOSTBYNAME
1026#endif
1027
1028#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1029INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1030            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1031  void *ctx;
1032  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1033                           h_errnop);
1034  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1035  if (res == 0) {
1036    if (result) {
1037      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1038      if (*result) write_hostent(ctx, *result);
1039    }
1040    if (h_errnop)
1041      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1042  }
1043  return res;
1044}
1045
1046INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1047            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1048            __sanitizer_hostent **result, int *h_errnop) {
1049  void *ctx;
1050  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1051                           buflen, result, h_errnop);
1052  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1053  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1054                                  h_errnop);
1055  if (res == 0) {
1056    if (result) {
1057      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1058      if (*result) write_hostent(ctx, *result);
1059    }
1060    if (h_errnop)
1061      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1062  }
1063  return res;
1064}
1065
1066INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1067            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1068            int *h_errnop) {
1069  void *ctx;
1070  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1071                           h_errnop);
1072  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1073  if (res == 0) {
1074    if (result) {
1075      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1076      if (*result) write_hostent(ctx, *result);
1077    }
1078    if (h_errnop)
1079      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1080  }
1081  return res;
1082}
1083
1084INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1085            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1086            __sanitizer_hostent **result, int *h_errnop) {
1087  void *ctx;
1088  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1089                           result, h_errnop);
1090  int res =
1091      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1092  if (res == 0) {
1093    if (result) {
1094      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1095      if (*result) write_hostent(ctx, *result);
1096    }
1097    if (h_errnop)
1098      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1099  }
1100  return res;
1101}
1102#define INIT_GETHOSTBYNAME_R           \
1103  INTERCEPT_FUNCTION(gethostent_r);    \
1104  INTERCEPT_FUNCTION(gethostbyaddr_r); \
1105  INTERCEPT_FUNCTION(gethostbyname_r); \
1106  INTERCEPT_FUNCTION(gethostbyname2_r);
1107#else
1108#define INIT_GETHOSTBYNAME_R
1109#endif
1110
1111#if SANITIZER_INTERCEPT_GETSOCKOPT
1112INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1113            int *optlen) {
1114  void *ctx;
1115  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1116                           optlen);
1117  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1118  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1119  if (res == 0)
1120    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1121  return res;
1122}
1123#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1124#else
1125#define INIT_GETSOCKOPT
1126#endif
1127
1128#if SANITIZER_INTERCEPT_ACCEPT
1129INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1130  void *ctx;
1131  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1132  unsigned addrlen0;
1133  if (addrlen) {
1134    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1135    addrlen0 = *addrlen;
1136  }
1137  int fd2 = REAL(accept)(fd, addr, addrlen);
1138  if (fd2 >= 0) {
1139    if (fd >= 0)
1140      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1141    if (addr && addrlen)
1142      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1143  }
1144  return fd2;
1145}
1146#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
1147#else
1148#define INIT_ACCEPT
1149#endif
1150
1151#if SANITIZER_INTERCEPT_ACCEPT4
1152INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1153  void *ctx;
1154  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1155  unsigned addrlen0;
1156  if (addrlen) {
1157    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1158    addrlen0 = *addrlen;
1159  }
1160  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1161  if (fd2 >= 0) {
1162    if (fd >= 0)
1163      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1164    if (addr && addrlen)
1165      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1166  }
1167  return fd2;
1168}
1169#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
1170#else
1171#define INIT_ACCEPT4
1172#endif
1173
1174#if SANITIZER_INTERCEPT_MODF
1175INTERCEPTOR(double, modf, double x, double *iptr) {
1176  void *ctx;
1177  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1178  double res = REAL(modf)(x, iptr);
1179  if (iptr) {
1180    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1181  }
1182  return res;
1183}
1184INTERCEPTOR(float, modff, float x, float *iptr) {
1185  void *ctx;
1186  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1187  float res = REAL(modff)(x, iptr);
1188  if (iptr) {
1189    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1190  }
1191  return res;
1192}
1193INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1194  void *ctx;
1195  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1196  long double res = REAL(modfl)(x, iptr);
1197  if (iptr) {
1198    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1199  }
1200  return res;
1201}
1202#define INIT_MODF            \
1203  INTERCEPT_FUNCTION(modf);  \
1204  INTERCEPT_FUNCTION(modff); \
1205  INTERCEPT_FUNCTION(modfl);
1206#else
1207#define INIT_MODF
1208#endif
1209
1210#if SANITIZER_INTERCEPT_RECVMSG
1211static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1212                         SSIZE_T maxlen) {
1213  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
1214  if (msg->msg_name)
1215    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
1216                                   REAL(strlen)((char *)msg->msg_name) + 1);
1217  if (msg->msg_iov)
1218    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1219                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
1220  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
1221  if (msg->msg_control)
1222    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
1223}
1224
1225INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
1226            int flags) {
1227  void *ctx;
1228  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
1229  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
1230  if (res >= 0) {
1231    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1232    if (msg) write_msghdr(ctx, msg, res);
1233  }
1234  return res;
1235}
1236#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
1237#else
1238#define INIT_RECVMSG
1239#endif
1240
1241#if SANITIZER_INTERCEPT_GETPEERNAME
1242INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1243  void *ctx;
1244  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1245  unsigned addr_sz;
1246  if (addrlen) addr_sz = *addrlen;
1247  int res = REAL(getpeername)(sockfd, addr, addrlen);
1248  if (!res && addr && addrlen)
1249    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1250  return res;
1251}
1252#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1253#else
1254#define INIT_GETPEERNAME
1255#endif
1256
1257#if SANITIZER_INTERCEPT_SYSINFO
1258INTERCEPTOR(int, sysinfo, void *info) {
1259  void *ctx;
1260  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1261  int res = REAL(sysinfo)(info);
1262  if (!res && info)
1263    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1264  return res;
1265}
1266#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1267#else
1268#define INIT_SYSINFO
1269#endif
1270
1271#if SANITIZER_INTERCEPT_READDIR
1272INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
1273  void *ctx;
1274  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
1275  __sanitizer_dirent *res = REAL(readdir)(dirp);
1276  if (res)
1277    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1278  return res;
1279}
1280
1281INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, __sanitizer_dirent **result) {
1282  void *ctx;
1283  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1284  int res = REAL(readdir_r)(dirp, entry, result);
1285  if (!res) {
1286    if (result)
1287      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1288    if (entry)
1289      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
1290  }
1291  return res;
1292}
1293
1294#define INIT_READDIR           \
1295  INTERCEPT_FUNCTION(readdir); \
1296  INTERCEPT_FUNCTION(readdir_r);
1297#else
1298#define INIT_READDIR
1299#endif
1300
1301#if SANITIZER_INTERCEPT_READDIR64
1302INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
1303  void *ctx;
1304  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
1305  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
1306  if (res)
1307    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1308  return res;
1309}
1310
1311INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, __sanitizer_dirent64 **result) {
1312  void *ctx;
1313  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1314  int res = REAL(readdir64_r)(dirp, entry, result);
1315  if (!res) {
1316    if (result)
1317      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1318    if (entry)
1319      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
1320  }
1321  return res;
1322}
1323#define INIT_READDIR64           \
1324  INTERCEPT_FUNCTION(readdir64); \
1325  INTERCEPT_FUNCTION(readdir64_r);
1326#else
1327#define INIT_READDIR64
1328#endif
1329
1330
1331#define SANITIZER_COMMON_INTERCEPTORS_INIT \
1332  INIT_STRCASECMP;                         \
1333  INIT_STRNCASECMP;                        \
1334  INIT_READ;                               \
1335  INIT_PREAD;                              \
1336  INIT_PREAD64;                            \
1337  INIT_READV;                              \
1338  INIT_PREADV;                             \
1339  INIT_PREADV64;                           \
1340  INIT_WRITE;                              \
1341  INIT_PWRITE;                             \
1342  INIT_PWRITE64;                           \
1343  INIT_WRITEV;                             \
1344  INIT_PWRITEV;                            \
1345  INIT_PWRITEV64;                          \
1346  INIT_PRCTL;                              \
1347  INIT_LOCALTIME_AND_FRIENDS;              \
1348  INIT_SCANF;                              \
1349  INIT_FREXP;                              \
1350  INIT_FREXPF_FREXPL;                      \
1351  INIT_GETPWNAM_AND_FRIENDS;               \
1352  INIT_GETPWNAM_R_AND_FRIENDS;             \
1353  INIT_CLOCK_GETTIME;                      \
1354  INIT_GETITIMER;                          \
1355  INIT_TIME;                               \
1356  INIT_GLOB;                               \
1357  INIT_WAIT;                               \
1358  INIT_INET;                               \
1359  INIT_PTHREAD_GETSCHEDPARAM;              \
1360  INIT_GETADDRINFO;                        \
1361  INIT_GETSOCKNAME;                        \
1362  INIT_GETHOSTBYNAME;                      \
1363  INIT_GETHOSTBYNAME_R;                    \
1364  INIT_GETSOCKOPT;                         \
1365  INIT_ACCEPT;                             \
1366  INIT_ACCEPT4;                            \
1367  INIT_MODF;                               \
1368  INIT_RECVMSG;                            \
1369  INIT_GETPEERNAME;                        \
1370  INIT_IOCTL;                              \
1371  INIT_INET_ATON;                          \
1372  INIT_SYSINFO;                            \
1373  INIT_READDIR;                            \
1374  INIT_READDIR64;
1375