sanitizer_common_interceptors.inc revision ff6c9fb3ee83529dc28cd60a3797a8b783f3e892
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#if SANITIZER_INTERCEPT_GLOB
742static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
743  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
744  // +1 for NULL pointer at the end.
745  if (pglob->gl_pathv)
746    COMMON_INTERCEPTOR_WRITE_RANGE(
747        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
748  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
749    char *p = pglob->gl_pathv[i];
750    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
751  }
752}
753
754INTERCEPTOR(int, glob, const char *pattern, int flags,
755            int (*errfunc)(const char *epath, int eerrno),
756            __sanitizer_glob_t *pglob) {
757  void *ctx;
758  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
759  int res = REAL(glob)(pattern, flags, errfunc, pglob);
760  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
761  return res;
762}
763
764INTERCEPTOR(int, glob64, const char *pattern, int flags,
765            int (*errfunc)(const char *epath, int eerrno),
766            __sanitizer_glob_t *pglob) {
767  void *ctx;
768  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
769  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
770  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
771  return res;
772}
773#define INIT_GLOB           \
774  INTERCEPT_FUNCTION(glob); \
775  INTERCEPT_FUNCTION(glob64);
776#else  // SANITIZER_INTERCEPT_GLOB
777#define INIT_GLOB
778#endif  // SANITIZER_INTERCEPT_GLOB
779
780#if SANITIZER_INTERCEPT_WAIT
781// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
782// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
783// details.
784INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
785  void *ctx;
786  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
787  int res = REAL(wait)(status);
788  if (res != -1 && status)
789    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
790  return res;
791}
792INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
793  int options) {
794  void *ctx;
795  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
796  int res = REAL(waitid)(idtype, id, infop, options);
797  if (res != -1 && infop)
798    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
799  return res;
800}
801INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
802  void *ctx;
803  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
804  int res = REAL(waitpid)(pid, status, options);
805  if (res != -1 && status)
806    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
807  return res;
808}
809INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
810  void *ctx;
811  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
812  int res = REAL(wait3)(status, options, rusage);
813  if (res != -1) {
814    if (status)
815      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
816    if (rusage)
817      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
818  }
819  return res;
820}
821INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
822  void *ctx;
823  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
824  int res = REAL(wait4)(pid, status, options, rusage);
825  if (res != -1) {
826    if (status)
827      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
828    if (rusage)
829      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
830  }
831  return res;
832}
833#define INIT_WAIT                                \
834  INTERCEPT_FUNCTION(wait);                      \
835  INTERCEPT_FUNCTION(waitid);                    \
836  INTERCEPT_FUNCTION(waitpid);                   \
837  INTERCEPT_FUNCTION(wait3);                     \
838  INTERCEPT_FUNCTION(wait4);
839#else
840#define INIT_WAIT
841#endif
842
843#if SANITIZER_INTERCEPT_INET
844INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
845  void *ctx;
846  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
847  uptr sz = __sanitizer_in_addr_sz(af);
848  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
849  // FIXME: figure out read size based on the address family.
850  char *res = REAL(inet_ntop)(af, src, dst, size);
851  if (res)
852    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
853  return res;
854}
855INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
856  void *ctx;
857  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
858  // FIXME: figure out read size based on the address family.
859  int res = REAL(inet_pton)(af, src, dst);
860  if (res == 1) {
861    uptr sz = __sanitizer_in_addr_sz(af);
862    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
863  }
864  return res;
865}
866#define INIT_INET                                \
867  INTERCEPT_FUNCTION(inet_ntop);                 \
868  INTERCEPT_FUNCTION(inet_pton);
869#else
870#define INIT_INET
871#endif
872
873#if SANITIZER_INTERCEPT_INET
874INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
875  void *ctx;
876  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
877  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
878  int res = REAL(inet_aton)(cp, dst);
879  if (res != 0) {
880    uptr sz = __sanitizer_in_addr_sz(af_inet);
881    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
882  }
883  return res;
884}
885#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton);
886#else
887#define INIT_INET_ATON
888#endif
889
890#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
891INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
892  void *ctx;
893  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
894  int res = REAL(pthread_getschedparam)(thread, policy, param);
895  if (res == 0) {
896    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
897    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
898  }
899  return res;
900}
901#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam);
902#else
903#define INIT_PTHREAD_GETSCHEDPARAM
904#endif
905
906#if SANITIZER_INTERCEPT_GETADDRINFO
907INTERCEPTOR(int, getaddrinfo, char *node, char *service,
908            struct __sanitizer_addrinfo *hints,
909            struct __sanitizer_addrinfo **out) {
910  void *ctx;
911  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
912  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
913  if (service)
914    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
915  if (hints)
916    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
917  int res = REAL(getaddrinfo)(node, service, hints, out);
918  if (res == 0 && out) {
919    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
920    struct __sanitizer_addrinfo *p = *out;
921    while (p) {
922      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
923      if (p->ai_addr)
924        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
925      if (p->ai_canonname)
926        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
927                                       REAL(strlen)(p->ai_canonname) + 1);
928      p = p->ai_next;
929    }
930  }
931  return res;
932}
933#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo);
934#else
935#define INIT_GETADDRINFO
936#endif
937
938#if SANITIZER_INTERCEPT_GETNAMEINFO
939INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
940            unsigned hostlen, char *serv, unsigned servlen, int flags) {
941  void *ctx;
942  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
943                           serv, servlen, flags);
944  // FIXME: consider adding READ_RANGE(sockaddr, salen)
945  // There is padding in in_addr that may make this too noisy
946  int res =
947      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
948  if (res == 0) {
949    if (host && hostlen)
950      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
951    if (serv && servlen)
952      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
953  }
954  return res;
955}
956#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo);
957#else
958#define INIT_GETNAMEINFO
959#endif
960
961#if SANITIZER_INTERCEPT_GETSOCKNAME
962INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
963  void *ctx;
964  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
965  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
966  int addrlen_in = *addrlen;
967  int res = REAL(getsockname)(sock_fd, addr, addrlen);
968  if (res == 0) {
969    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
970  }
971  return res;
972}
973#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname);
974#else
975#define INIT_GETSOCKNAME
976#endif
977
978#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
979static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
980  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
981  if (h->h_name)
982    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
983  char **p = h->h_aliases;
984  while (*p) {
985    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
986    ++p;
987  }
988  COMMON_INTERCEPTOR_WRITE_RANGE(
989      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
990  p = h->h_addr_list;
991  while (*p) {
992    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
993    ++p;
994  }
995  COMMON_INTERCEPTOR_WRITE_RANGE(
996      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
997}
998#endif
999
1000#if SANITIZER_INTERCEPT_GETHOSTBYNAME
1001INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
1002  void *ctx;
1003  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
1004  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
1005  if (res) write_hostent(ctx, res);
1006  return res;
1007}
1008
1009INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
1010            int type) {
1011  void *ctx;
1012  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
1013  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1014  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1015  if (res) write_hostent(ctx, res);
1016  return res;
1017}
1018
1019INTERCEPTOR(struct __sanitizer_hostent *, gethostent) {
1020  void *ctx;
1021  COMMON_INTERCEPTOR_ENTER(ctx, gethostent);
1022  struct __sanitizer_hostent *res = REAL(gethostent)();
1023  if (res) write_hostent(ctx, res);
1024  return res;
1025}
1026
1027INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1028  void *ctx;
1029  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1030  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1031  if (res) write_hostent(ctx, res);
1032  return res;
1033}
1034#define INIT_GETHOSTBYNAME           \
1035  INTERCEPT_FUNCTION(gethostent);    \
1036  INTERCEPT_FUNCTION(gethostbyaddr); \
1037  INTERCEPT_FUNCTION(gethostbyname); \
1038  INTERCEPT_FUNCTION(gethostbyname2);
1039#else
1040#define INIT_GETHOSTBYNAME
1041#endif
1042
1043#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1044INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1045            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1046  void *ctx;
1047  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1048                           h_errnop);
1049  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1050  if (res == 0) {
1051    if (result) {
1052      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1053      if (*result) write_hostent(ctx, *result);
1054    }
1055    if (h_errnop)
1056      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1057  }
1058  return res;
1059}
1060
1061INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1062            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1063            __sanitizer_hostent **result, int *h_errnop) {
1064  void *ctx;
1065  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1066                           buflen, result, h_errnop);
1067  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1068  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1069                                  h_errnop);
1070  if (res == 0) {
1071    if (result) {
1072      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1073      if (*result) write_hostent(ctx, *result);
1074    }
1075    if (h_errnop)
1076      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1077  }
1078  return res;
1079}
1080
1081INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1082            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1083            int *h_errnop) {
1084  void *ctx;
1085  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1086                           h_errnop);
1087  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1088  if (res == 0) {
1089    if (result) {
1090      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1091      if (*result) write_hostent(ctx, *result);
1092    }
1093    if (h_errnop)
1094      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1095  }
1096  return res;
1097}
1098
1099INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1100            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1101            __sanitizer_hostent **result, int *h_errnop) {
1102  void *ctx;
1103  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1104                           result, h_errnop);
1105  int res =
1106      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1107  if (res == 0) {
1108    if (result) {
1109      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1110      if (*result) write_hostent(ctx, *result);
1111    }
1112    if (h_errnop)
1113      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1114  }
1115  return res;
1116}
1117#define INIT_GETHOSTBYNAME_R           \
1118  INTERCEPT_FUNCTION(gethostent_r);    \
1119  INTERCEPT_FUNCTION(gethostbyaddr_r); \
1120  INTERCEPT_FUNCTION(gethostbyname_r); \
1121  INTERCEPT_FUNCTION(gethostbyname2_r);
1122#else
1123#define INIT_GETHOSTBYNAME_R
1124#endif
1125
1126#if SANITIZER_INTERCEPT_GETSOCKOPT
1127INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1128            int *optlen) {
1129  void *ctx;
1130  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1131                           optlen);
1132  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1133  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1134  if (res == 0)
1135    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1136  return res;
1137}
1138#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt);
1139#else
1140#define INIT_GETSOCKOPT
1141#endif
1142
1143#if SANITIZER_INTERCEPT_ACCEPT
1144INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1145  void *ctx;
1146  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1147  unsigned addrlen0;
1148  if (addrlen) {
1149    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1150    addrlen0 = *addrlen;
1151  }
1152  int fd2 = REAL(accept)(fd, addr, addrlen);
1153  if (fd2 >= 0) {
1154    if (fd >= 0)
1155      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1156    if (addr && addrlen)
1157      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1158  }
1159  return fd2;
1160}
1161#define INIT_ACCEPT INTERCEPT_FUNCTION(accept);
1162#else
1163#define INIT_ACCEPT
1164#endif
1165
1166#if SANITIZER_INTERCEPT_ACCEPT4
1167INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1168  void *ctx;
1169  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1170  unsigned addrlen0;
1171  if (addrlen) {
1172    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1173    addrlen0 = *addrlen;
1174  }
1175  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1176  if (fd2 >= 0) {
1177    if (fd >= 0)
1178      COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1179    if (addr && addrlen)
1180      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1181  }
1182  return fd2;
1183}
1184#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4);
1185#else
1186#define INIT_ACCEPT4
1187#endif
1188
1189#if SANITIZER_INTERCEPT_MODF
1190INTERCEPTOR(double, modf, double x, double *iptr) {
1191  void *ctx;
1192  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
1193  double res = REAL(modf)(x, iptr);
1194  if (iptr) {
1195    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1196  }
1197  return res;
1198}
1199INTERCEPTOR(float, modff, float x, float *iptr) {
1200  void *ctx;
1201  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
1202  float res = REAL(modff)(x, iptr);
1203  if (iptr) {
1204    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1205  }
1206  return res;
1207}
1208INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
1209  void *ctx;
1210  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
1211  long double res = REAL(modfl)(x, iptr);
1212  if (iptr) {
1213    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
1214  }
1215  return res;
1216}
1217#define INIT_MODF            \
1218  INTERCEPT_FUNCTION(modf);  \
1219  INTERCEPT_FUNCTION(modff); \
1220  INTERCEPT_FUNCTION(modfl);
1221#else
1222#define INIT_MODF
1223#endif
1224
1225#if SANITIZER_INTERCEPT_RECVMSG
1226static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
1227                         SSIZE_T maxlen) {
1228  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
1229  if (msg->msg_name)
1230    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name,
1231                                   REAL(strlen)((char *)msg->msg_name) + 1);
1232  if (msg->msg_iov)
1233    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
1234                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
1235  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
1236  if (msg->msg_control)
1237    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
1238}
1239
1240INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
1241            int flags) {
1242  void *ctx;
1243  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
1244  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
1245  if (res >= 0) {
1246    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1247    if (msg) write_msghdr(ctx, msg, res);
1248  }
1249  return res;
1250}
1251#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg);
1252#else
1253#define INIT_RECVMSG
1254#endif
1255
1256#if SANITIZER_INTERCEPT_GETPEERNAME
1257INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
1258  void *ctx;
1259  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
1260  unsigned addr_sz;
1261  if (addrlen) addr_sz = *addrlen;
1262  int res = REAL(getpeername)(sockfd, addr, addrlen);
1263  if (!res && addr && addrlen)
1264    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
1265  return res;
1266}
1267#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername);
1268#else
1269#define INIT_GETPEERNAME
1270#endif
1271
1272#if SANITIZER_INTERCEPT_SYSINFO
1273INTERCEPTOR(int, sysinfo, void *info) {
1274  void *ctx;
1275  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
1276  int res = REAL(sysinfo)(info);
1277  if (!res && info)
1278    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
1279  return res;
1280}
1281#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo);
1282#else
1283#define INIT_SYSINFO
1284#endif
1285
1286#if SANITIZER_INTERCEPT_READDIR
1287INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
1288  void *ctx;
1289  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
1290  __sanitizer_dirent *res = REAL(readdir)(dirp);
1291  if (res)
1292    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1293  return res;
1294}
1295
1296INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
1297            __sanitizer_dirent **result) {
1298  void *ctx;
1299  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
1300  int res = REAL(readdir_r)(dirp, entry, result);
1301  if (!res) {
1302    if (result)
1303      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1304    if (entry)
1305      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
1306  }
1307  return res;
1308}
1309
1310#define INIT_READDIR           \
1311  INTERCEPT_FUNCTION(readdir); \
1312  INTERCEPT_FUNCTION(readdir_r);
1313#else
1314#define INIT_READDIR
1315#endif
1316
1317#if SANITIZER_INTERCEPT_READDIR64
1318INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
1319  void *ctx;
1320  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
1321  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
1322  if (res)
1323    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
1324  return res;
1325}
1326
1327INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
1328            __sanitizer_dirent64 **result) {
1329  void *ctx;
1330  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
1331  int res = REAL(readdir64_r)(dirp, entry, result);
1332  if (!res) {
1333    if (result)
1334      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1335    if (entry)
1336      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen);
1337  }
1338  return res;
1339}
1340#define INIT_READDIR64           \
1341  INTERCEPT_FUNCTION(readdir64); \
1342  INTERCEPT_FUNCTION(readdir64_r);
1343#else
1344#define INIT_READDIR64
1345#endif
1346
1347#if SANITIZER_INTERCEPT_PTRACE
1348INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
1349  void *ctx;
1350  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
1351
1352  if (data) {
1353    if (request == ptrace_setregs)
1354      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
1355    else if (request == ptrace_setfpregs)
1356      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1357    else if (request == ptrace_setfpxregs)
1358      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1359    else if (request == ptrace_setsiginfo)
1360      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
1361    else if (request == ptrace_setregset) {
1362      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1363      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
1364    }
1365  }
1366
1367  uptr res = REAL(ptrace)(request, pid, addr, data);
1368
1369  if (!res && data) {
1370    // Note that PEEK* requests assing different meaning to the return value.
1371    // This function does not handle them (nor does it need to).
1372    if (request == ptrace_getregs)
1373      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
1374    else if (request == ptrace_getfpregs)
1375      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
1376    else if (request == ptrace_getfpxregs)
1377      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
1378    else if (request == ptrace_getsiginfo)
1379      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
1380    else if (request == ptrace_getregset) {
1381      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
1382      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
1383    }
1384  }
1385  return res;
1386}
1387
1388#define INIT_PTRACE           \
1389  INTERCEPT_FUNCTION(ptrace);
1390#else
1391#define INIT_PTRACE
1392#endif
1393
1394#if SANITIZER_INTERCEPT_SETLOCALE
1395INTERCEPTOR(char *, setlocale, int category, char *locale) {
1396  void *ctx;
1397  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
1398  if (locale)
1399    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
1400  char *res = REAL(setlocale)(category, locale);
1401  if (res)
1402    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1403  return res;
1404}
1405
1406#define INIT_SETLOCALE           \
1407  INTERCEPT_FUNCTION(setlocale);
1408#else
1409#define INIT_SETLOCALE
1410#endif
1411
1412#if SANITIZER_INTERCEPT_GETCWD
1413INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
1414  void *ctx;
1415  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
1416  char *res = REAL(getcwd)(buf, size);
1417  if (res)
1418    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1419  return res;
1420}
1421#define INIT_GETCWD           \
1422  INTERCEPT_FUNCTION(getcwd);
1423#else
1424#define INIT_GETCWD
1425#endif
1426
1427#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
1428INTERCEPTOR(char *, get_current_dir_name) {
1429  void *ctx;
1430  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name);
1431  char *res = REAL(get_current_dir_name)();
1432  if (res)
1433    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1434  return res;
1435}
1436
1437#define INIT_GET_CURRENT_DIR_NAME           \
1438  INTERCEPT_FUNCTION(get_current_dir_name);
1439#else
1440#define INIT_GET_CURRENT_DIR_NAME
1441#endif
1442
1443#if SANITIZER_INTERCEPT_STRTOIMAX
1444INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
1445  void *ctx;
1446  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
1447  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
1448  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1449  return res;
1450}
1451
1452INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
1453  void *ctx;
1454  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
1455  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
1456  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
1457  return res;
1458}
1459
1460#define INIT_STRTOIMAX           \
1461  INTERCEPT_FUNCTION(strtoimax); \
1462  INTERCEPT_FUNCTION(strtoumax);
1463#else
1464#define INIT_STRTOIMAX
1465#endif
1466
1467#if SANITIZER_INTERCEPT_MBSTOWCS
1468INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
1469  void *ctx;
1470  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
1471  SIZE_T res = REAL(mbstowcs)(dest, src, len);
1472  if (res != (SIZE_T) - 1 && dest)
1473    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
1474  return res;
1475}
1476
1477INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
1478            void *ps) {
1479  void *ctx;
1480  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
1481  if (src) {
1482    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1483  }
1484  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
1485  if (res != (SIZE_T) - 1 && dest)
1486    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
1487  return res;
1488}
1489
1490#define INIT_MBSTOWCS           \
1491  INTERCEPT_FUNCTION(mbstowcs); \
1492  INTERCEPT_FUNCTION(mbsrtowcs);
1493#else
1494#define INIT_MBSTOWCS
1495#endif
1496
1497#if SANITIZER_INTERCEPT_MBSNRTOWCS
1498
1499INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
1500            SIZE_T len, void *ps) {
1501  void *ctx;
1502  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
1503  if (src) {
1504    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1505    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1506  }
1507  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
1508  if (res != (SIZE_T) - 1 && dest)
1509    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t));
1510  return res;
1511}
1512
1513#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs);
1514#else
1515#define INIT_MBSNRTOWCS
1516#endif
1517
1518#if SANITIZER_INTERCEPT_WCSTOMBS
1519INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
1520  void *ctx;
1521  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
1522  SIZE_T res = REAL(wcstombs)(dest, src, len);
1523  if (res != (SIZE_T) - 1 && dest)
1524    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
1525  return res;
1526}
1527
1528INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
1529            void *ps) {
1530  void *ctx;
1531  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
1532  if (src) {
1533    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1534  }
1535  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
1536  if (res != (SIZE_T) - 1 && dest)
1537    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
1538  return res;
1539}
1540
1541#define INIT_WCSTOMBS           \
1542  INTERCEPT_FUNCTION(wcstombs); \
1543  INTERCEPT_FUNCTION(wcsrtombs);
1544#else
1545#define INIT_WCSTOMBS
1546#endif
1547
1548#if SANITIZER_INTERCEPT_WCSNRTOMBS
1549
1550INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
1551            SIZE_T len, void *ps) {
1552  void *ctx;
1553  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
1554  if (src) {
1555    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
1556    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
1557  }
1558  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
1559  if (res != (SIZE_T) - 1 && dest)
1560    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1);
1561  return res;
1562}
1563
1564#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs);
1565#else
1566#define INIT_WCSNRTOMBS
1567#endif
1568
1569#define SANITIZER_COMMON_INTERCEPTORS_INIT \
1570  INIT_STRCASECMP;                         \
1571  INIT_STRNCASECMP;                        \
1572  INIT_READ;                               \
1573  INIT_PREAD;                              \
1574  INIT_PREAD64;                            \
1575  INIT_READV;                              \
1576  INIT_PREADV;                             \
1577  INIT_PREADV64;                           \
1578  INIT_WRITE;                              \
1579  INIT_PWRITE;                             \
1580  INIT_PWRITE64;                           \
1581  INIT_WRITEV;                             \
1582  INIT_PWRITEV;                            \
1583  INIT_PWRITEV64;                          \
1584  INIT_PRCTL;                              \
1585  INIT_LOCALTIME_AND_FRIENDS;              \
1586  INIT_SCANF;                              \
1587  INIT_FREXP;                              \
1588  INIT_FREXPF_FREXPL;                      \
1589  INIT_GETPWNAM_AND_FRIENDS;               \
1590  INIT_GETPWNAM_R_AND_FRIENDS;             \
1591  INIT_CLOCK_GETTIME;                      \
1592  INIT_GETITIMER;                          \
1593  INIT_TIME;                               \
1594  INIT_GLOB;                               \
1595  INIT_WAIT;                               \
1596  INIT_INET;                               \
1597  INIT_PTHREAD_GETSCHEDPARAM;              \
1598  INIT_GETADDRINFO;                        \
1599  INIT_GETNAMEINFO;                        \
1600  INIT_GETSOCKNAME;                        \
1601  INIT_GETHOSTBYNAME;                      \
1602  INIT_GETHOSTBYNAME_R;                    \
1603  INIT_GETSOCKOPT;                         \
1604  INIT_ACCEPT;                             \
1605  INIT_ACCEPT4;                            \
1606  INIT_MODF;                               \
1607  INIT_RECVMSG;                            \
1608  INIT_GETPEERNAME;                        \
1609  INIT_IOCTL;                              \
1610  INIT_INET_ATON;                          \
1611  INIT_SYSINFO;                            \
1612  INIT_READDIR;                            \
1613  INIT_READDIR64;                          \
1614  INIT_PTRACE;                             \
1615  INIT_SETLOCALE;                          \
1616  INIT_GETCWD;                             \
1617  INIT_GET_CURRENT_DIR_NAME;               \
1618  INIT_STRTOIMAX;                          \
1619  INIT_MBSTOWCS;                           \
1620  INIT_MBSNRTOWCS;                         \
1621  INIT_WCSTOMBS;                           \
1622  INIT_WCSNRTOMBS;
1623