sanitizer_common_interceptors.inc revision 5d71de26cedae3dafc17449fe0182045c0bd20e8
1ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//
3ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//                     The LLVM Compiler Infrastructure
4ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//
5ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// This file is distributed under the University of Illinois Open Source
6ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// License. See LICENSE.TXT for details.
7ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//
8ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//===----------------------------------------------------------------------===//
9ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//
10ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// Common function interceptors for tools like AddressSanitizer,
11ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// ThreadSanitizer, MemorySanitizer, etc.
12ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//
13ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// This file should be included into the tool's interceptor file,
14ef8225444452a1486bd721f3285301fe84643b00Stephen Hines// which has to define it's own macros:
15ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_ENTER
16ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_ENTER_NOIGNORE
17ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_READ_RANGE
18ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_WRITE_RANGE
19ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
20ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_FD_ACQUIRE
21ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_FD_RELEASE
22ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_FD_ACCESS
23ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_SET_THREAD_NAME
24ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_ON_EXIT
25ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_MUTEX_LOCK
26ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_MUTEX_UNLOCK
27ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_MUTEX_REPAIR
28ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
29ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//   COMMON_INTERCEPTOR_HANDLE_RECVMSG
30ef8225444452a1486bd721f3285301fe84643b00Stephen Hines//===----------------------------------------------------------------------===//
31ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "interception/interception.h"
32ef8225444452a1486bd721f3285301fe84643b00Stephen Hines#include "sanitizer_addrhashmap.h"
33#include "sanitizer_placement_new.h"
34#include "sanitizer_platform_interceptors.h"
35#include "sanitizer_tls_get_addr.h"
36
37#include <stdarg.h>
38
39#if SANITIZER_WINDOWS && !defined(va_copy)
40#define va_copy(dst, src) ((dst) = (src))
41#endif // _WIN32
42
43#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
44#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
45#endif
46
47#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
48#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
49#endif
50
51#ifndef COMMON_INTERCEPTOR_FD_ACCESS
52#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
53#endif
54
55#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
56#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
57#endif
58
59#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
60#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
61#endif
62
63#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
64#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
65#endif
66
67#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
68#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
69#endif
70
71#ifndef COMMON_INTERCEPTOR_FILE_OPEN
72#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
73#endif
74
75#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
76#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
77#endif
78
79#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
80#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) {}
81#endif
82
83#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
84#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
85#endif
86
87#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
88#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
89  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
90#endif
91
92struct FileMetadata {
93  // For open_memstream().
94  char **addr;
95  SIZE_T *size;
96};
97
98struct CommonInterceptorMetadata {
99  enum {
100    CIMT_INVALID = 0,
101    CIMT_FILE
102  } type;
103  union {
104    FileMetadata file;
105  };
106};
107
108typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
109
110static MetadataHashMap *interceptor_metadata_map;
111
112#if SI_NOT_WINDOWS
113UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
114                                          const FileMetadata &file) {
115  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
116  CHECK(h.created());
117  h->type = CommonInterceptorMetadata::CIMT_FILE;
118  h->file = file;
119}
120
121UNUSED static const FileMetadata *GetInterceptorMetadata(
122    __sanitizer_FILE *addr) {
123  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
124                            /* remove */ false,
125                            /* create */ false);
126  if (h.exists()) {
127    CHECK(!h.created());
128    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
129    return &h->file;
130  } else {
131    return 0;
132  }
133}
134
135UNUSED static void DeleteInterceptorMetadata(void *addr) {
136  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
137  CHECK(h.exists());
138}
139#endif  // SI_NOT_WINDOWS
140
141#if SANITIZER_INTERCEPT_TEXTDOMAIN
142INTERCEPTOR(char*, textdomain, const char *domainname) {
143  void *ctx;
144  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
145  char* domain = REAL(textdomain)(domainname);
146  if (domain) {
147    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
148  }
149  return domain;
150}
151#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
152#else
153#define INIT_TEXTDOMAIN
154#endif
155
156#if SANITIZER_INTERCEPT_STRCMP
157static inline int CharCmpX(unsigned char c1, unsigned char c2) {
158  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
159}
160
161INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
162  void *ctx;
163  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
164  unsigned char c1, c2;
165  uptr i;
166  for (i = 0;; i++) {
167    c1 = (unsigned char)s1[i];
168    c2 = (unsigned char)s2[i];
169    if (c1 != c2 || c1 == '\0') break;
170  }
171  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
172  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
173  return CharCmpX(c1, c2);
174}
175
176INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
177  void *ctx;
178  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
179  unsigned char c1 = 0, c2 = 0;
180  uptr i;
181  for (i = 0; i < size; i++) {
182    c1 = (unsigned char)s1[i];
183    c2 = (unsigned char)s2[i];
184    if (c1 != c2 || c1 == '\0') break;
185  }
186  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
187  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
188  return CharCmpX(c1, c2);
189}
190
191#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
192#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
193#else
194#define INIT_STRCMP
195#define INIT_STRNCMP
196#endif
197
198#if SANITIZER_INTERCEPT_STRCASECMP
199static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
200  int c1_low = ToLower(c1);
201  int c2_low = ToLower(c2);
202  return c1_low - c2_low;
203}
204
205INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
206  void *ctx;
207  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
208  unsigned char c1 = 0, c2 = 0;
209  uptr i;
210  for (i = 0;; i++) {
211    c1 = (unsigned char)s1[i];
212    c2 = (unsigned char)s2[i];
213    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
214  }
215  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1);
216  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1);
217  return CharCaseCmp(c1, c2);
218}
219
220INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
221  void *ctx;
222  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
223  unsigned char c1 = 0, c2 = 0;
224  uptr i;
225  for (i = 0; i < n; i++) {
226    c1 = (unsigned char)s1[i];
227    c2 = (unsigned char)s2[i];
228    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
229  }
230  COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
231  COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
232  return CharCaseCmp(c1, c2);
233}
234
235#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
236#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
237#else
238#define INIT_STRCASECMP
239#define INIT_STRNCASECMP
240#endif
241
242#if SANITIZER_INTERCEPT_MEMCHR
243INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
244  void *ctx;
245  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
246  void *res = REAL(memchr)(s, c, n);
247  uptr len = res ? (char*)res - (char*)s + 1 : n;
248  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
249  return res;
250}
251
252#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
253#else
254#define INIT_MEMCHR
255#endif
256
257#if SANITIZER_INTERCEPT_MEMRCHR
258INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
259  void *ctx;
260  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
261  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
262  return REAL(memrchr)(s, c, n);
263}
264
265#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
266#else
267#define INIT_MEMRCHR
268#endif
269
270#if SANITIZER_INTERCEPT_FREXP
271INTERCEPTOR(double, frexp, double x, int *exp) {
272  void *ctx;
273  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
274  // Assuming frexp() always writes to |exp|.
275  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
276  double res = REAL(frexp)(x, exp);
277  return res;
278}
279
280#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
281#else
282#define INIT_FREXP
283#endif  // SANITIZER_INTERCEPT_FREXP
284
285#if SANITIZER_INTERCEPT_FREXPF_FREXPL
286INTERCEPTOR(float, frexpf, float x, int *exp) {
287  void *ctx;
288  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
289  // FIXME: under ASan the call below may write to freed memory and corrupt
290  // its metadata. See
291  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
292  float res = REAL(frexpf)(x, exp);
293  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
294  return res;
295}
296
297INTERCEPTOR(long double, frexpl, long double x, int *exp) {
298  void *ctx;
299  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
300  // FIXME: under ASan the call below may write to freed memory and corrupt
301  // its metadata. See
302  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
303  long double res = REAL(frexpl)(x, exp);
304  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
305  return res;
306}
307
308#define INIT_FREXPF_FREXPL           \
309  COMMON_INTERCEPT_FUNCTION(frexpf); \
310  COMMON_INTERCEPT_FUNCTION(frexpl)
311#else
312#define INIT_FREXPF_FREXPL
313#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
314
315#if SI_NOT_WINDOWS
316static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
317                        SIZE_T iovlen, SIZE_T maxlen) {
318  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
319    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
320    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
321    maxlen -= sz;
322  }
323}
324
325static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
326                       SIZE_T iovlen, SIZE_T maxlen) {
327  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
328  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
329    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
330    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
331    maxlen -= sz;
332  }
333}
334#endif
335
336#if SANITIZER_INTERCEPT_READ
337INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
338  void *ctx;
339  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
340  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
341  // FIXME: under ASan the call below may write to freed memory and corrupt
342  // its metadata. See
343  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
344  SSIZE_T res = REAL(read)(fd, ptr, count);
345  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
346  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
347  return res;
348}
349#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
350#else
351#define INIT_READ
352#endif
353
354#if SANITIZER_INTERCEPT_PREAD
355INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
356  void *ctx;
357  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
358  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
359  // FIXME: under ASan the call below may write to freed memory and corrupt
360  // its metadata. See
361  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
362  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
363  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
364  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
365  return res;
366}
367#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
368#else
369#define INIT_PREAD
370#endif
371
372#if SANITIZER_INTERCEPT_PREAD64
373INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
374  void *ctx;
375  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
376  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
377  // FIXME: under ASan the call below may write to freed memory and corrupt
378  // its metadata. See
379  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
380  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
381  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
382  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
383  return res;
384}
385#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
386#else
387#define INIT_PREAD64
388#endif
389
390#if SANITIZER_INTERCEPT_READV
391INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
392                        int iovcnt) {
393  void *ctx;
394  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
395  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
396  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
397  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
398  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
399  return res;
400}
401#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
402#else
403#define INIT_READV
404#endif
405
406#if SANITIZER_INTERCEPT_PREADV
407INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
408            OFF_T offset) {
409  void *ctx;
410  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
411  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
412  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
413  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
414  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
415  return res;
416}
417#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
418#else
419#define INIT_PREADV
420#endif
421
422#if SANITIZER_INTERCEPT_PREADV64
423INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
424            OFF64_T offset) {
425  void *ctx;
426  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
427  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
428  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
429  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
430  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
431  return res;
432}
433#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
434#else
435#define INIT_PREADV64
436#endif
437
438#if SANITIZER_INTERCEPT_WRITE
439INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
440  void *ctx;
441  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
442  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
443  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
444  SSIZE_T res = REAL(write)(fd, ptr, count);
445  // FIXME: this check should be _before_ the call to REAL(write), not after
446  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
447  return res;
448}
449#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
450#else
451#define INIT_WRITE
452#endif
453
454#if SANITIZER_INTERCEPT_PWRITE
455INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
456  void *ctx;
457  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
458  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
459  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
460  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
461  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
462  return res;
463}
464#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
465#else
466#define INIT_PWRITE
467#endif
468
469#if SANITIZER_INTERCEPT_PWRITE64
470INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
471            OFF64_T offset) {
472  void *ctx;
473  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
474  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
475  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
476  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
477  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
478  return res;
479}
480#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
481#else
482#define INIT_PWRITE64
483#endif
484
485#if SANITIZER_INTERCEPT_WRITEV
486INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
487                        int iovcnt) {
488  void *ctx;
489  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
490  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
491  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
492  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
493  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
494  return res;
495}
496#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
497#else
498#define INIT_WRITEV
499#endif
500
501#if SANITIZER_INTERCEPT_PWRITEV
502INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
503            OFF_T offset) {
504  void *ctx;
505  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
506  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
507  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
508  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
509  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
510  return res;
511}
512#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
513#else
514#define INIT_PWRITEV
515#endif
516
517#if SANITIZER_INTERCEPT_PWRITEV64
518INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
519            OFF64_T offset) {
520  void *ctx;
521  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
522  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
523  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
524  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
525  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
526  return res;
527}
528#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
529#else
530#define INIT_PWRITEV64
531#endif
532
533#if SANITIZER_INTERCEPT_PRCTL
534INTERCEPTOR(int, prctl, int option, unsigned long arg2,
535            unsigned long arg3,                        // NOLINT
536            unsigned long arg4, unsigned long arg5) {  // NOLINT
537  void *ctx;
538  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
539  static const int PR_SET_NAME = 15;
540  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
541  if (option == PR_SET_NAME) {
542    char buff[16];
543    internal_strncpy(buff, (char *)arg2, 15);
544    buff[15] = 0;
545    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
546  }
547  return res;
548}
549#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
550#else
551#define INIT_PRCTL
552#endif  // SANITIZER_INTERCEPT_PRCTL
553
554#if SANITIZER_INTERCEPT_TIME
555INTERCEPTOR(unsigned long, time, unsigned long *t) {
556  void *ctx;
557  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
558  unsigned long local_t;
559  unsigned long res = REAL(time)(&local_t);
560  if (t && res != (unsigned long)-1) {
561    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
562    *t = local_t;
563  }
564  return res;
565}
566#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
567#else
568#define INIT_TIME
569#endif  // SANITIZER_INTERCEPT_TIME
570
571#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
572static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
573  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
574  if (tm->tm_zone) {
575    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
576    // can point to shared memory and tsan would report a data race.
577    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
578                                        REAL(strlen(tm->tm_zone)) + 1);
579  }
580}
581INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
582  void *ctx;
583  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
584  __sanitizer_tm *res = REAL(localtime)(timep);
585  if (res) {
586    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
587    unpoison_tm(ctx, res);
588  }
589  return res;
590}
591INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
592  void *ctx;
593  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
594  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
595  if (res) {
596    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
597    unpoison_tm(ctx, res);
598  }
599  return res;
600}
601INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
602  void *ctx;
603  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
604  __sanitizer_tm *res = REAL(gmtime)(timep);
605  if (res) {
606    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
607    unpoison_tm(ctx, res);
608  }
609  return res;
610}
611INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
612  void *ctx;
613  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
614  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
615  if (res) {
616    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
617    unpoison_tm(ctx, res);
618  }
619  return res;
620}
621INTERCEPTOR(char *, ctime, unsigned long *timep) {
622  void *ctx;
623  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
624  // FIXME: under ASan the call below may write to freed memory and corrupt
625  // its metadata. See
626  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
627  char *res = REAL(ctime)(timep);
628  if (res) {
629    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
630    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
631  }
632  return res;
633}
634INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
635  void *ctx;
636  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
637  // FIXME: under ASan the call below may write to freed memory and corrupt
638  // its metadata. See
639  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
640  char *res = REAL(ctime_r)(timep, result);
641  if (res) {
642    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
643    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
644  }
645  return res;
646}
647INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
648  void *ctx;
649  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
650  // FIXME: under ASan the call below may write to freed memory and corrupt
651  // its metadata. See
652  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
653  char *res = REAL(asctime)(tm);
654  if (res) {
655    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
656    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
657  }
658  return res;
659}
660INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
661  void *ctx;
662  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
663  // FIXME: under ASan the call below may write to freed memory and corrupt
664  // its metadata. See
665  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
666  char *res = REAL(asctime_r)(tm, result);
667  if (res) {
668    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
669    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
670  }
671  return res;
672}
673INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
674  void *ctx;
675  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
676  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
677  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
678  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
679  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
680  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
681  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
682  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
683  long res = REAL(mktime)(tm);
684  if (res != -1) unpoison_tm(ctx, tm);
685  return res;
686}
687#define INIT_LOCALTIME_AND_FRIENDS        \
688  COMMON_INTERCEPT_FUNCTION(localtime);   \
689  COMMON_INTERCEPT_FUNCTION(localtime_r); \
690  COMMON_INTERCEPT_FUNCTION(gmtime);      \
691  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
692  COMMON_INTERCEPT_FUNCTION(ctime);       \
693  COMMON_INTERCEPT_FUNCTION(ctime_r);     \
694  COMMON_INTERCEPT_FUNCTION(asctime);     \
695  COMMON_INTERCEPT_FUNCTION(asctime_r);   \
696  COMMON_INTERCEPT_FUNCTION(mktime);
697#else
698#define INIT_LOCALTIME_AND_FRIENDS
699#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
700
701#if SANITIZER_INTERCEPT_STRPTIME
702INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
703  void *ctx;
704  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
705  if (format)
706    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
707  // FIXME: under ASan the call below may write to freed memory and corrupt
708  // its metadata. See
709  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
710  char *res = REAL(strptime)(s, format, tm);
711  if (res) {
712    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s);
713    // Do not call unpoison_tm here, because strptime does not, in fact,
714    // initialize the entire struct tm. For example, tm_zone pointer is left
715    // uninitialized.
716    if (tm) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
717  }
718  return res;
719}
720#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
721#else
722#define INIT_STRPTIME
723#endif
724
725#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
726#include "sanitizer_common_interceptors_format.inc"
727
728#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
729  {                                                                            \
730    void *ctx;                                                                 \
731    va_list ap;                                                                \
732    va_start(ap, format);                                                      \
733    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
734    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
735    va_end(ap);                                                                \
736    return res;                                                                \
737  }
738
739#endif
740
741#if SANITIZER_INTERCEPT_SCANF
742
743#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
744  {                                                                            \
745    void *ctx;                                                                 \
746    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
747    va_list aq;                                                                \
748    va_copy(aq, ap);                                                           \
749    int res = REAL(vname)(__VA_ARGS__);                                        \
750    if (res > 0)                                                               \
751      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
752    va_end(aq);                                                                \
753    return res;                                                                \
754  }
755
756INTERCEPTOR(int, vscanf, const char *format, va_list ap)
757VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
758
759INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
760VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
761
762INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
763VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
764
765#if SANITIZER_INTERCEPT_ISOC99_SCANF
766INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
767VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
768
769INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
770            va_list ap)
771VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
772
773INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
774VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
775#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
776
777INTERCEPTOR(int, scanf, const char *format, ...)
778FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
779
780INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
781FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
782
783INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
784FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
785
786#if SANITIZER_INTERCEPT_ISOC99_SCANF
787INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
788FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
789
790INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
791FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
792
793INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
794FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
795#endif
796
797#endif
798
799#if SANITIZER_INTERCEPT_SCANF
800#define INIT_SCANF                    \
801  COMMON_INTERCEPT_FUNCTION(scanf);   \
802  COMMON_INTERCEPT_FUNCTION(sscanf);  \
803  COMMON_INTERCEPT_FUNCTION(fscanf);  \
804  COMMON_INTERCEPT_FUNCTION(vscanf);  \
805  COMMON_INTERCEPT_FUNCTION(vsscanf); \
806  COMMON_INTERCEPT_FUNCTION(vfscanf);
807#else
808#define INIT_SCANF
809#endif
810
811#if SANITIZER_INTERCEPT_ISOC99_SCANF
812#define INIT_ISOC99_SCANF                      \
813  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
814  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
815  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
816  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
817  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
818  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
819#else
820#define INIT_ISOC99_SCANF
821#endif
822
823#if SANITIZER_INTERCEPT_PRINTF
824
825#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
826  void *ctx;                                                                   \
827  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
828  va_list aq;                                                                  \
829  va_copy(aq, ap);
830
831#define VPRINTF_INTERCEPTOR_RETURN()                                           \
832  va_end(aq);
833
834#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
835  {                                                                            \
836    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
837    if (common_flags()->check_printf)                                          \
838      printf_common(ctx, format, aq);                                          \
839    int res = REAL(vname)(__VA_ARGS__);                                        \
840    VPRINTF_INTERCEPTOR_RETURN();                                              \
841    return res;                                                                \
842  }
843
844// FIXME: under ASan the REAL() call below may write to freed memory and
845// corrupt its metadata. See
846// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
847#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
848  {                                                                            \
849    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
850    if (common_flags()->check_printf) {                                        \
851      printf_common(ctx, format, aq);                                          \
852    }                                                                          \
853    int res = REAL(vname)(str, __VA_ARGS__);                                   \
854    if (res >= 0) {                                                            \
855      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
856    }                                                                          \
857    VPRINTF_INTERCEPTOR_RETURN();                                              \
858    return res;                                                                \
859  }
860
861// FIXME: under ASan the REAL() call below may write to freed memory and
862// corrupt its metadata. See
863// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
864#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
865  {                                                                            \
866    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
867    if (common_flags()->check_printf) {                                        \
868      printf_common(ctx, format, aq);                                          \
869    }                                                                          \
870    int res = REAL(vname)(str, size, __VA_ARGS__);                             \
871    if (res >= 0) {                                                            \
872      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
873    }                                                                          \
874    VPRINTF_INTERCEPTOR_RETURN();                                              \
875    return res;                                                                \
876  }
877
878// FIXME: under ASan the REAL() call below may write to freed memory and
879// corrupt its metadata. See
880// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
881#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
882  {                                                                            \
883    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
884    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
885    if (common_flags()->check_printf) {                                        \
886      printf_common(ctx, format, aq);                                          \
887    }                                                                          \
888    int res = REAL(vname)(strp, __VA_ARGS__);                                  \
889    if (res >= 0) {                                                            \
890      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
891    }                                                                          \
892    VPRINTF_INTERCEPTOR_RETURN();                                              \
893    return res;                                                                \
894  }
895
896INTERCEPTOR(int, vprintf, const char *format, va_list ap)
897VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
898
899INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
900            va_list ap)
901VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
902
903INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
904            va_list ap)
905VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
906
907INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
908VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
909
910INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
911VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
912
913#if SANITIZER_INTERCEPT_ISOC99_PRINTF
914INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
915VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
916
917INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
918            const char *format, va_list ap)
919VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
920
921INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
922            va_list ap)
923VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
924
925INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
926            va_list ap)
927VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
928                          ap)
929
930#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
931
932INTERCEPTOR(int, printf, const char *format, ...)
933FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
934
935INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
936FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
937
938INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
939FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
940
941INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
942FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
943
944INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
945FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
946
947#if SANITIZER_INTERCEPT_ISOC99_PRINTF
948INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
949FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
950
951INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
952            ...)
953FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
954
955INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
956FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
957
958INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
959            const char *format, ...)
960FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
961                        format)
962
963#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
964
965#endif  // SANITIZER_INTERCEPT_PRINTF
966
967#if SANITIZER_INTERCEPT_PRINTF
968#define INIT_PRINTF                     \
969  COMMON_INTERCEPT_FUNCTION(printf);    \
970  COMMON_INTERCEPT_FUNCTION(sprintf);   \
971  COMMON_INTERCEPT_FUNCTION(snprintf);  \
972  COMMON_INTERCEPT_FUNCTION(asprintf);  \
973  COMMON_INTERCEPT_FUNCTION(fprintf);   \
974  COMMON_INTERCEPT_FUNCTION(vprintf);   \
975  COMMON_INTERCEPT_FUNCTION(vsprintf);  \
976  COMMON_INTERCEPT_FUNCTION(vsnprintf); \
977  COMMON_INTERCEPT_FUNCTION(vasprintf); \
978  COMMON_INTERCEPT_FUNCTION(vfprintf);
979#else
980#define INIT_PRINTF
981#endif
982
983#if SANITIZER_INTERCEPT_ISOC99_PRINTF
984#define INIT_ISOC99_PRINTF                       \
985  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
986  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
987  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
988  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
989  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
990  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
991  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
992  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
993#else
994#define INIT_ISOC99_PRINTF
995#endif
996
997#if SANITIZER_INTERCEPT_IOCTL
998#include "sanitizer_common_interceptors_ioctl.inc"
999INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) {
1000  void *ctx;
1001  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1002
1003  CHECK(ioctl_initialized);
1004
1005  // Note: TSan does not use common flags, and they are zero-initialized.
1006  // This effectively disables ioctl handling in TSan.
1007  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1008
1009  const ioctl_desc *desc = ioctl_lookup(request);
1010  ioctl_desc decoded_desc;
1011  if (!desc) {
1012    VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
1013    if (!ioctl_decode(request, &decoded_desc))
1014      Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
1015    else
1016      desc = &decoded_desc;
1017  }
1018
1019  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1020  int res = REAL(ioctl)(d, request, arg);
1021  // FIXME: some ioctls have different return values for success and failure.
1022  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1023  return res;
1024}
1025#define INIT_IOCTL \
1026  ioctl_init();    \
1027  COMMON_INTERCEPT_FUNCTION(ioctl);
1028#else
1029#define INIT_IOCTL
1030#endif
1031
1032#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
1033    SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT
1034static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1035  if (pwd) {
1036    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1037    if (pwd->pw_name)
1038      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
1039                                          REAL(strlen)(pwd->pw_name) + 1);
1040    if (pwd->pw_passwd)
1041      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
1042                                          REAL(strlen)(pwd->pw_passwd) + 1);
1043#if !SANITIZER_ANDROID
1044    if (pwd->pw_gecos)
1045      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
1046                                          REAL(strlen)(pwd->pw_gecos) + 1);
1047#endif
1048#if SANITIZER_MAC
1049    if (pwd->pw_class)
1050      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
1051                                          REAL(strlen)(pwd->pw_class) + 1);
1052#endif
1053    if (pwd->pw_dir)
1054      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
1055                                          REAL(strlen)(pwd->pw_dir) + 1);
1056    if (pwd->pw_shell)
1057      COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
1058                                          REAL(strlen)(pwd->pw_shell) + 1);
1059  }
1060}
1061
1062static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1063  if (grp) {
1064    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1065    if (grp->gr_name)
1066      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
1067                                          REAL(strlen)(grp->gr_name) + 1);
1068    if (grp->gr_passwd)
1069      COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
1070                                          REAL(strlen)(grp->gr_passwd) + 1);
1071    char **p = grp->gr_mem;
1072    for (; *p; ++p) {
1073      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
1074    }
1075    COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
1076                                        (p - grp->gr_mem + 1) * sizeof(*p));
1077  }
1078}
1079#endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
1080        // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT
1081
1082#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1083INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1084  void *ctx;
1085  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1086  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1087  __sanitizer_passwd *res = REAL(getpwnam)(name);
1088  if (res != 0) unpoison_passwd(ctx, res);
1089  return res;
1090}
1091INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1092  void *ctx;
1093  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1094  __sanitizer_passwd *res = REAL(getpwuid)(uid);
1095  if (res != 0) unpoison_passwd(ctx, res);
1096  return res;
1097}
1098INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1099  void *ctx;
1100  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1101  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1102  __sanitizer_group *res = REAL(getgrnam)(name);
1103  if (res != 0) unpoison_group(ctx, res);
1104  return res;
1105}
1106INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1107  void *ctx;
1108  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1109  __sanitizer_group *res = REAL(getgrgid)(gid);
1110  if (res != 0) unpoison_group(ctx, res);
1111  return res;
1112}
1113#define INIT_GETPWNAM_AND_FRIENDS      \
1114  COMMON_INTERCEPT_FUNCTION(getpwnam); \
1115  COMMON_INTERCEPT_FUNCTION(getpwuid); \
1116  COMMON_INTERCEPT_FUNCTION(getgrnam); \
1117  COMMON_INTERCEPT_FUNCTION(getgrgid);
1118#else
1119#define INIT_GETPWNAM_AND_FRIENDS
1120#endif
1121
1122#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1123INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1124            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1125  void *ctx;
1126  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1127  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1128  // FIXME: under ASan the call below may write to freed memory and corrupt
1129  // its metadata. See
1130  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1131  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1132  if (!res) {
1133    if (result && *result) unpoison_passwd(ctx, *result);
1134    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1135  }
1136  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1137  return res;
1138}
1139INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1140            SIZE_T buflen, __sanitizer_passwd **result) {
1141  void *ctx;
1142  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
1143  // FIXME: under ASan the call below may write to freed memory and corrupt
1144  // its metadata. See
1145  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1146  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1147  if (!res) {
1148    if (result && *result) unpoison_passwd(ctx, *result);
1149    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1150  }
1151  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1152  return res;
1153}
1154INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1155            char *buf, SIZE_T buflen, __sanitizer_group **result) {
1156  void *ctx;
1157  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1158  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1159  // FIXME: under ASan the call below may write to freed memory and corrupt
1160  // its metadata. See
1161  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1162  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1163  if (!res) {
1164    if (result && *result) unpoison_group(ctx, *result);
1165    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1166  }
1167  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1168  return res;
1169}
1170INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1171            SIZE_T buflen, __sanitizer_group **result) {
1172  void *ctx;
1173  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
1174  // FIXME: under ASan the call below may write to freed memory and corrupt
1175  // its metadata. See
1176  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1177  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1178  if (!res) {
1179    if (result && *result) unpoison_group(ctx, *result);
1180    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1181  }
1182  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1183  return res;
1184}
1185#define INIT_GETPWNAM_R_AND_FRIENDS      \
1186  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1187  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1188  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1189  COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1190#else
1191#define INIT_GETPWNAM_R_AND_FRIENDS
1192#endif
1193
1194#if SANITIZER_INTERCEPT_GETPWENT
1195INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
1196  void *ctx;
1197  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
1198  __sanitizer_passwd *res = REAL(getpwent)(dummy);
1199  if (res != 0) unpoison_passwd(ctx, res);
1200  return res;
1201}
1202INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
1203  void *ctx;
1204  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
1205  __sanitizer_group *res = REAL(getgrent)(dummy);
1206  if (res != 0) unpoison_group(ctx, res);;
1207  return res;
1208}
1209#define INIT_GETPWENT                  \
1210  COMMON_INTERCEPT_FUNCTION(getpwent); \
1211  COMMON_INTERCEPT_FUNCTION(getgrent);
1212#else
1213#define INIT_GETPWENT
1214#endif
1215
1216#if SANITIZER_INTERCEPT_FGETPWENT
1217INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
1218  void *ctx;
1219  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
1220  __sanitizer_passwd *res = REAL(fgetpwent)(fp);
1221  if (res != 0) unpoison_passwd(ctx, res);
1222  return res;
1223}
1224INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
1225  void *ctx;
1226  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
1227  __sanitizer_group *res = REAL(fgetgrent)(fp);
1228  if (res != 0) unpoison_group(ctx, res);
1229  return res;
1230}
1231#define INIT_FGETPWENT                  \
1232  COMMON_INTERCEPT_FUNCTION(fgetpwent); \
1233  COMMON_INTERCEPT_FUNCTION(fgetgrent);
1234#else
1235#define INIT_FGETPWENT
1236#endif
1237
1238#if SANITIZER_INTERCEPT_GETPWENT_R
1239INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
1240            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1241  void *ctx;
1242  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
1243  // FIXME: under ASan the call below may write to freed memory and corrupt
1244  // its metadata. See
1245  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1246  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
1247  if (!res) {
1248    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1249    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1250  }
1251  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1252  return res;
1253}
1254INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
1255            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1256  void *ctx;
1257  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
1258  // FIXME: under ASan the call below may write to freed memory and corrupt
1259  // its metadata. See
1260  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1261  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
1262  if (!res) {
1263    if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1264    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1265  }
1266  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1267  return res;
1268}
1269INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
1270            __sanitizer_group **pwbufp) {
1271  void *ctx;
1272  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
1273  // FIXME: under ASan the call below may write to freed memory and corrupt
1274  // its metadata. See
1275  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1276  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
1277  if (!res) {
1278    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1279    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1280  }
1281  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1282  return res;
1283}
1284INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
1285            SIZE_T buflen, __sanitizer_group **pwbufp) {
1286  void *ctx;
1287  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
1288  // FIXME: under ASan the call below may write to freed memory and corrupt
1289  // its metadata. See
1290  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1291  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
1292  if (!res) {
1293    if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1294    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1295  }
1296  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1297  return res;
1298}
1299#define INIT_GETPWENT_R                   \
1300  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
1301  COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
1302  COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
1303  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
1304#else
1305#define INIT_GETPWENT_R
1306#endif
1307
1308#if SANITIZER_INTERCEPT_SETPWENT
1309// The only thing these interceptors do is disable any nested interceptors.
1310// These functions may open nss modules and call uninstrumented functions from
1311// them, and we don't want things like strlen() to trigger.
1312INTERCEPTOR(void, setpwent, int dummy) {
1313  void *ctx;
1314  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
1315  REAL(setpwent)(dummy);
1316}
1317INTERCEPTOR(void, endpwent, int dummy) {
1318  void *ctx;
1319  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
1320  REAL(endpwent)(dummy);
1321}
1322INTERCEPTOR(void, setgrent, int dummy) {
1323  void *ctx;
1324  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
1325  REAL(setgrent)(dummy);
1326}
1327INTERCEPTOR(void, endgrent, int dummy) {
1328  void *ctx;
1329  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
1330  REAL(endgrent)(dummy);
1331}
1332#define INIT_SETPWENT                  \
1333  COMMON_INTERCEPT_FUNCTION(setpwent); \
1334  COMMON_INTERCEPT_FUNCTION(endpwent); \
1335  COMMON_INTERCEPT_FUNCTION(setgrent); \
1336  COMMON_INTERCEPT_FUNCTION(endgrent);
1337#else
1338#define INIT_SETPWENT
1339#endif
1340
1341#if SANITIZER_INTERCEPT_CLOCK_GETTIME
1342INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1343  void *ctx;
1344  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
1345  // FIXME: under ASan the call below may write to freed memory and corrupt
1346  // its metadata. See
1347  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1348  int res = REAL(clock_getres)(clk_id, tp);
1349  if (!res && tp) {
1350    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1351  }
1352  return res;
1353}
1354INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1355  void *ctx;
1356  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
1357  // FIXME: under ASan the call below may write to freed memory and corrupt
1358  // its metadata. See
1359  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1360  int res = REAL(clock_gettime)(clk_id, tp);
1361  if (!res) {
1362    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1363  }
1364  return res;
1365}
1366INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1367  void *ctx;
1368  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1369  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1370  return REAL(clock_settime)(clk_id, tp);
1371}
1372#define INIT_CLOCK_GETTIME                  \
1373  COMMON_INTERCEPT_FUNCTION(clock_getres);  \
1374  COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1375  COMMON_INTERCEPT_FUNCTION(clock_settime);
1376#else
1377#define INIT_CLOCK_GETTIME
1378#endif
1379
1380#if SANITIZER_INTERCEPT_GETITIMER
1381INTERCEPTOR(int, getitimer, int which, void *curr_value) {
1382  void *ctx;
1383  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
1384  // FIXME: under ASan the call below may write to freed memory and corrupt
1385  // its metadata. See
1386  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1387  int res = REAL(getitimer)(which, curr_value);
1388  if (!res && curr_value) {
1389    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1390  }
1391  return res;
1392}
1393INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1394  void *ctx;
1395  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
1396  if (new_value)
1397    COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
1398  // FIXME: under ASan the call below may write to freed memory and corrupt
1399  // its metadata. See
1400  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1401  int res = REAL(setitimer)(which, new_value, old_value);
1402  if (!res && old_value) {
1403    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1404  }
1405  return res;
1406}
1407#define INIT_GETITIMER                  \
1408  COMMON_INTERCEPT_FUNCTION(getitimer); \
1409  COMMON_INTERCEPT_FUNCTION(setitimer);
1410#else
1411#define INIT_GETITIMER
1412#endif
1413
1414#if SANITIZER_INTERCEPT_GLOB
1415static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1416  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1417  // +1 for NULL pointer at the end.
1418  if (pglob->gl_pathv)
1419    COMMON_INTERCEPTOR_WRITE_RANGE(
1420        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1421  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1422    char *p = pglob->gl_pathv[i];
1423    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1424  }
1425}
1426
1427static THREADLOCAL __sanitizer_glob_t *pglob_copy;
1428
1429static void wrapped_gl_closedir(void *dir) {
1430  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1431  IndirectExternCall(pglob_copy->gl_closedir)(dir);
1432}
1433
1434static void *wrapped_gl_readdir(void *dir) {
1435  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1436  return IndirectExternCall(pglob_copy->gl_readdir)(dir);
1437}
1438
1439static void *wrapped_gl_opendir(const char *s) {
1440  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1441  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1442  return IndirectExternCall(pglob_copy->gl_opendir)(s);
1443}
1444
1445static int wrapped_gl_lstat(const char *s, void *st) {
1446  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1447  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1448  return IndirectExternCall(pglob_copy->gl_lstat)(s, st);
1449}
1450
1451static int wrapped_gl_stat(const char *s, void *st) {
1452  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1453  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1454  return IndirectExternCall(pglob_copy->gl_stat)(s, st);
1455}
1456
1457INTERCEPTOR(int, glob, const char *pattern, int flags,
1458            int (*errfunc)(const char *epath, int eerrno),
1459            __sanitizer_glob_t *pglob) {
1460  void *ctx;
1461  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
1462  __sanitizer_glob_t glob_copy = {
1463      0,                  0,                   0,
1464      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1465      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1466  if (flags & glob_altdirfunc) {
1467    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1468    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1469    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1470    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1471    Swap(pglob->gl_stat, glob_copy.gl_stat);
1472    pglob_copy = &glob_copy;
1473  }
1474  int res = REAL(glob)(pattern, flags, errfunc, pglob);
1475  if (flags & glob_altdirfunc) {
1476    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1477    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1478    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1479    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1480    Swap(pglob->gl_stat, glob_copy.gl_stat);
1481  }
1482  pglob_copy = 0;
1483  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1484  return res;
1485}
1486
1487INTERCEPTOR(int, glob64, const char *pattern, int flags,
1488            int (*errfunc)(const char *epath, int eerrno),
1489            __sanitizer_glob_t *pglob) {
1490  void *ctx;
1491  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
1492  __sanitizer_glob_t glob_copy = {
1493      0,                  0,                   0,
1494      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1495      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1496  if (flags & glob_altdirfunc) {
1497    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1498    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1499    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1500    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1501    Swap(pglob->gl_stat, glob_copy.gl_stat);
1502    pglob_copy = &glob_copy;
1503  }
1504  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
1505  if (flags & glob_altdirfunc) {
1506    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1507    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1508    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1509    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1510    Swap(pglob->gl_stat, glob_copy.gl_stat);
1511  }
1512  pglob_copy = 0;
1513  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1514  return res;
1515}
1516#define INIT_GLOB                  \
1517  COMMON_INTERCEPT_FUNCTION(glob); \
1518  COMMON_INTERCEPT_FUNCTION(glob64);
1519#else  // SANITIZER_INTERCEPT_GLOB
1520#define INIT_GLOB
1521#endif  // SANITIZER_INTERCEPT_GLOB
1522
1523#if SANITIZER_INTERCEPT_WAIT
1524// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
1525// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
1526// details.
1527INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1528  void *ctx;
1529  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
1530  // FIXME: under ASan the call below may write to freed memory and corrupt
1531  // its metadata. See
1532  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1533  int res = REAL(wait)(status);
1534  if (res != -1 && status)
1535    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1536  return res;
1537}
1538INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
1539                        int options) {
1540  void *ctx;
1541  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
1542  // FIXME: under ASan the call below may write to freed memory and corrupt
1543  // its metadata. See
1544  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1545  int res = REAL(waitid)(idtype, id, infop, options);
1546  if (res != -1 && infop)
1547    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
1548  return res;
1549}
1550INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
1551  void *ctx;
1552  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
1553  // FIXME: under ASan the call below may write to freed memory and corrupt
1554  // its metadata. See
1555  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1556  int res = REAL(waitpid)(pid, status, options);
1557  if (res != -1 && status)
1558    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1559  return res;
1560}
1561INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
1562  void *ctx;
1563  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
1564  // FIXME: under ASan the call below may write to freed memory and corrupt
1565  // its metadata. See
1566  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1567  int res = REAL(wait3)(status, options, rusage);
1568  if (res != -1) {
1569    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1570    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1571  }
1572  return res;
1573}
1574#if SANITIZER_ANDROID
1575INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
1576  void *ctx;
1577  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
1578  // FIXME: under ASan the call below may write to freed memory and corrupt
1579  // its metadata. See
1580  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1581  int res = REAL(__wait4)(pid, status, options, rusage);
1582  if (res != -1) {
1583    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1584    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1585  }
1586  return res;
1587}
1588#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
1589#else
1590INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
1591  void *ctx;
1592  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
1593  // FIXME: under ASan the call below may write to freed memory and corrupt
1594  // its metadata. See
1595  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1596  int res = REAL(wait4)(pid, status, options, rusage);
1597  if (res != -1) {
1598    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1599    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1600  }
1601  return res;
1602}
1603#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
1604#endif  // SANITIZER_ANDROID
1605#define INIT_WAIT                     \
1606  COMMON_INTERCEPT_FUNCTION(wait);    \
1607  COMMON_INTERCEPT_FUNCTION(waitid);  \
1608  COMMON_INTERCEPT_FUNCTION(waitpid); \
1609  COMMON_INTERCEPT_FUNCTION(wait3);
1610#else
1611#define INIT_WAIT
1612#define INIT_WAIT4
1613#endif
1614
1615#if SANITIZER_INTERCEPT_INET
1616INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1617  void *ctx;
1618  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1619  uptr sz = __sanitizer_in_addr_sz(af);
1620  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1621  // FIXME: figure out read size based on the address family.
1622  // FIXME: under ASan the call below may write to freed memory and corrupt
1623  // its metadata. See
1624  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1625  char *res = REAL(inet_ntop)(af, src, dst, size);
1626  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1627  return res;
1628}
1629INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1630  void *ctx;
1631  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
1632  // FIXME: figure out read size based on the address family.
1633  // FIXME: under ASan the call below may write to freed memory and corrupt
1634  // its metadata. See
1635  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1636  int res = REAL(inet_pton)(af, src, dst);
1637  if (res == 1) {
1638    uptr sz = __sanitizer_in_addr_sz(af);
1639    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1640  }
1641  return res;
1642}
1643#define INIT_INET                       \
1644  COMMON_INTERCEPT_FUNCTION(inet_ntop); \
1645  COMMON_INTERCEPT_FUNCTION(inet_pton);
1646#else
1647#define INIT_INET
1648#endif
1649
1650#if SANITIZER_INTERCEPT_INET
1651INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1652  void *ctx;
1653  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1654  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
1655  // FIXME: under ASan the call below may write to freed memory and corrupt
1656  // its metadata. See
1657  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1658  int res = REAL(inet_aton)(cp, dst);
1659  if (res != 0) {
1660    uptr sz = __sanitizer_in_addr_sz(af_inet);
1661    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1662  }
1663  return res;
1664}
1665#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
1666#else
1667#define INIT_INET_ATON
1668#endif
1669
1670#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1671INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1672  void *ctx;
1673  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
1674  // FIXME: under ASan the call below may write to freed memory and corrupt
1675  // its metadata. See
1676  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1677  int res = REAL(pthread_getschedparam)(thread, policy, param);
1678  if (res == 0) {
1679    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1680    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1681  }
1682  return res;
1683}
1684#define INIT_PTHREAD_GETSCHEDPARAM \
1685  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
1686#else
1687#define INIT_PTHREAD_GETSCHEDPARAM
1688#endif
1689
1690#if SANITIZER_INTERCEPT_GETADDRINFO
1691INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1692            struct __sanitizer_addrinfo *hints,
1693            struct __sanitizer_addrinfo **out) {
1694  void *ctx;
1695  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1696  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1697  if (service)
1698    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1699  if (hints)
1700    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
1701  // FIXME: under ASan the call below may write to freed memory and corrupt
1702  // its metadata. See
1703  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1704  int res = REAL(getaddrinfo)(node, service, hints, out);
1705  if (res == 0 && out) {
1706    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1707    struct __sanitizer_addrinfo *p = *out;
1708    while (p) {
1709      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1710      if (p->ai_addr)
1711        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1712      if (p->ai_canonname)
1713        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1714                                       REAL(strlen)(p->ai_canonname) + 1);
1715      p = p->ai_next;
1716    }
1717  }
1718  return res;
1719}
1720#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
1721#else
1722#define INIT_GETADDRINFO
1723#endif
1724
1725#if SANITIZER_INTERCEPT_GETNAMEINFO
1726INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1727            unsigned hostlen, char *serv, unsigned servlen, int flags) {
1728  void *ctx;
1729  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1730                           serv, servlen, flags);
1731  // FIXME: consider adding READ_RANGE(sockaddr, salen)
1732  // There is padding in in_addr that may make this too noisy
1733  // FIXME: under ASan the call below may write to freed memory and corrupt
1734  // its metadata. See
1735  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1736  int res =
1737      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1738  if (res == 0) {
1739    if (host && hostlen)
1740      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1741    if (serv && servlen)
1742      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1743  }
1744  return res;
1745}
1746#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
1747#else
1748#define INIT_GETNAMEINFO
1749#endif
1750
1751#if SANITIZER_INTERCEPT_GETSOCKNAME
1752INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1753  void *ctx;
1754  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
1755  COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1756  int addrlen_in = *addrlen;
1757  // FIXME: under ASan the call below may write to freed memory and corrupt
1758  // its metadata. See
1759  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1760  int res = REAL(getsockname)(sock_fd, addr, addrlen);
1761  if (res == 0) {
1762    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
1763  }
1764  return res;
1765}
1766#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
1767#else
1768#define INIT_GETSOCKNAME
1769#endif
1770
1771#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1772static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
1773  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
1774  if (h->h_name)
1775    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
1776  char **p = h->h_aliases;
1777  while (*p) {
1778    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
1779    ++p;
1780  }
1781  COMMON_INTERCEPTOR_WRITE_RANGE(
1782      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
1783  p = h->h_addr_list;
1784  while (*p) {
1785    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
1786    ++p;
1787  }
1788  COMMON_INTERCEPTOR_WRITE_RANGE(
1789      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
1790}
1791#endif
1792
1793#if SANITIZER_INTERCEPT_GETHOSTBYNAME
1794INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
1795  void *ctx;
1796  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
1797  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
1798  if (res) write_hostent(ctx, res);
1799  return res;
1800}
1801
1802INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
1803            int type) {
1804  void *ctx;
1805  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
1806  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1807  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
1808  if (res) write_hostent(ctx, res);
1809  return res;
1810}
1811
1812INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
1813  void *ctx;
1814  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
1815  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
1816  if (res) write_hostent(ctx, res);
1817  return res;
1818}
1819
1820INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
1821  void *ctx;
1822  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
1823  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
1824  if (res) write_hostent(ctx, res);
1825  return res;
1826}
1827#define INIT_GETHOSTBYNAME                  \
1828  COMMON_INTERCEPT_FUNCTION(gethostent);    \
1829  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
1830  COMMON_INTERCEPT_FUNCTION(gethostbyname); \
1831  COMMON_INTERCEPT_FUNCTION(gethostbyname2);
1832#else
1833#define INIT_GETHOSTBYNAME
1834#endif
1835
1836#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
1837INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
1838            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
1839            int *h_errnop) {
1840  void *ctx;
1841  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
1842                           h_errnop);
1843  // FIXME: under ASan the call below may write to freed memory and corrupt
1844  // its metadata. See
1845  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1846  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
1847  if (result) {
1848    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1849    if (res == 0 && *result) write_hostent(ctx, *result);
1850  }
1851  if (h_errnop)
1852    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1853  return res;
1854}
1855#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
1856#else
1857#define INIT_GETHOSTBYNAME_R
1858#endif
1859
1860#if SANITIZER_INTERCEPT_GETHOSTENT_R
1861INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
1862            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
1863  void *ctx;
1864  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
1865                           h_errnop);
1866  // FIXME: under ASan the call below may write to freed memory and corrupt
1867  // its metadata. See
1868  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1869  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
1870  if (result) {
1871    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1872    if (res == 0 && *result) write_hostent(ctx, *result);
1873  }
1874  if (h_errnop)
1875    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1876  return res;
1877}
1878#define INIT_GETHOSTENT_R                  \
1879  COMMON_INTERCEPT_FUNCTION(gethostent_r);
1880#else
1881#define INIT_GETHOSTENT_R
1882#endif
1883
1884#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
1885INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
1886            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1887            __sanitizer_hostent **result, int *h_errnop) {
1888  void *ctx;
1889  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
1890                           buflen, result, h_errnop);
1891  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
1892  // FIXME: under ASan the call below may write to freed memory and corrupt
1893  // its metadata. See
1894  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1895  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
1896                                  h_errnop);
1897  if (result) {
1898    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1899    if (res == 0 && *result) write_hostent(ctx, *result);
1900  }
1901  if (h_errnop)
1902    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1903  return res;
1904}
1905#define INIT_GETHOSTBYADDR_R                  \
1906  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
1907#else
1908#define INIT_GETHOSTBYADDR_R
1909#endif
1910
1911#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
1912INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
1913            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
1914            __sanitizer_hostent **result, int *h_errnop) {
1915  void *ctx;
1916  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
1917                           result, h_errnop);
1918  // FIXME: under ASan the call below may write to freed memory and corrupt
1919  // its metadata. See
1920  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1921  int res =
1922      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
1923  if (result) {
1924    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1925    if (res == 0 && *result) write_hostent(ctx, *result);
1926  }
1927  if (h_errnop)
1928    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
1929  return res;
1930}
1931#define INIT_GETHOSTBYNAME2_R                  \
1932  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
1933#else
1934#define INIT_GETHOSTBYNAME2_R
1935#endif
1936
1937#if SANITIZER_INTERCEPT_GETSOCKOPT
1938INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
1939            int *optlen) {
1940  void *ctx;
1941  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
1942                           optlen);
1943  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
1944  // FIXME: under ASan the call below may write to freed memory and corrupt
1945  // its metadata. See
1946  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1947  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
1948  if (res == 0)
1949    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
1950  return res;
1951}
1952#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
1953#else
1954#define INIT_GETSOCKOPT
1955#endif
1956
1957#if SANITIZER_INTERCEPT_ACCEPT
1958INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
1959  void *ctx;
1960  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
1961  unsigned addrlen0 = 0;
1962  if (addrlen) {
1963    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1964    addrlen0 = *addrlen;
1965  }
1966  int fd2 = REAL(accept)(fd, addr, addrlen);
1967  if (fd2 >= 0) {
1968    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1969    if (addr && addrlen)
1970      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1971  }
1972  return fd2;
1973}
1974#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
1975#else
1976#define INIT_ACCEPT
1977#endif
1978
1979#if SANITIZER_INTERCEPT_ACCEPT4
1980INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
1981  void *ctx;
1982  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
1983  unsigned addrlen0 = 0;
1984  if (addrlen) {
1985    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
1986    addrlen0 = *addrlen;
1987  }
1988  // FIXME: under ASan the call below may write to freed memory and corrupt
1989  // its metadata. See
1990  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1991  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
1992  if (fd2 >= 0) {
1993    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
1994    if (addr && addrlen)
1995      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
1996  }
1997  return fd2;
1998}
1999#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2000#else
2001#define INIT_ACCEPT4
2002#endif
2003
2004#if SANITIZER_INTERCEPT_MODF
2005INTERCEPTOR(double, modf, double x, double *iptr) {
2006  void *ctx;
2007  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
2008  // FIXME: under ASan the call below may write to freed memory and corrupt
2009  // its metadata. See
2010  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2011  double res = REAL(modf)(x, iptr);
2012  if (iptr) {
2013    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2014  }
2015  return res;
2016}
2017INTERCEPTOR(float, modff, float x, float *iptr) {
2018  void *ctx;
2019  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
2020  // FIXME: under ASan the call below may write to freed memory and corrupt
2021  // its metadata. See
2022  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2023  float res = REAL(modff)(x, iptr);
2024  if (iptr) {
2025    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2026  }
2027  return res;
2028}
2029INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2030  void *ctx;
2031  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
2032  // FIXME: under ASan the call below may write to freed memory and corrupt
2033  // its metadata. See
2034  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2035  long double res = REAL(modfl)(x, iptr);
2036  if (iptr) {
2037    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2038  }
2039  return res;
2040}
2041#define INIT_MODF                   \
2042  COMMON_INTERCEPT_FUNCTION(modf);  \
2043  COMMON_INTERCEPT_FUNCTION(modff); \
2044  COMMON_INTERCEPT_FUNCTION(modfl);
2045#else
2046#define INIT_MODF
2047#endif
2048
2049#if SANITIZER_INTERCEPT_RECVMSG
2050static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2051                         SSIZE_T maxlen) {
2052  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2053  if (msg->msg_name && msg->msg_namelen)
2054    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2055  if (msg->msg_iov && msg->msg_iovlen)
2056    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2057                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
2058  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2059  if (msg->msg_control && msg->msg_controllen)
2060    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
2061}
2062
2063INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
2064            int flags) {
2065  void *ctx;
2066  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
2067  // FIXME: under ASan the call below may write to freed memory and corrupt
2068  // its metadata. See
2069  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2070  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
2071  if (res >= 0) {
2072    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2073    if (msg) {
2074      write_msghdr(ctx, msg, res);
2075      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
2076    }
2077  }
2078  return res;
2079}
2080#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
2081#else
2082#define INIT_RECVMSG
2083#endif
2084
2085#if SANITIZER_INTERCEPT_GETPEERNAME
2086INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2087  void *ctx;
2088  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2089  unsigned addr_sz;
2090  if (addrlen) addr_sz = *addrlen;
2091  // FIXME: under ASan the call below may write to freed memory and corrupt
2092  // its metadata. See
2093  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2094  int res = REAL(getpeername)(sockfd, addr, addrlen);
2095  if (!res && addr && addrlen)
2096    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2097  return res;
2098}
2099#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2100#else
2101#define INIT_GETPEERNAME
2102#endif
2103
2104#if SANITIZER_INTERCEPT_SYSINFO
2105INTERCEPTOR(int, sysinfo, void *info) {
2106  void *ctx;
2107  // FIXME: under ASan the call below may write to freed memory and corrupt
2108  // its metadata. See
2109  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2110  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2111  int res = REAL(sysinfo)(info);
2112  if (!res && info)
2113    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2114  return res;
2115}
2116#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2117#else
2118#define INIT_SYSINFO
2119#endif
2120
2121#if SANITIZER_INTERCEPT_READDIR
2122INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2123  void *ctx;
2124  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
2125  // FIXME: under ASan the call below may write to freed memory and corrupt
2126  // its metadata. See
2127  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2128  __sanitizer_dirent *res = REAL(readdir)(dirp);
2129  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2130  return res;
2131}
2132
2133INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
2134            __sanitizer_dirent **result) {
2135  void *ctx;
2136  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
2137  // FIXME: under ASan the call below may write to freed memory and corrupt
2138  // its metadata. See
2139  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2140  int res = REAL(readdir_r)(dirp, entry, result);
2141  if (!res) {
2142    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2143    if (*result)
2144      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2145  }
2146  return res;
2147}
2148
2149#define INIT_READDIR                  \
2150  COMMON_INTERCEPT_FUNCTION(readdir); \
2151  COMMON_INTERCEPT_FUNCTION(readdir_r);
2152#else
2153#define INIT_READDIR
2154#endif
2155
2156#if SANITIZER_INTERCEPT_READDIR64
2157INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2158  void *ctx;
2159  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
2160  // FIXME: under ASan the call below may write to freed memory and corrupt
2161  // its metadata. See
2162  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2163  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2164  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2165  return res;
2166}
2167
2168INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
2169            __sanitizer_dirent64 **result) {
2170  void *ctx;
2171  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
2172  // FIXME: under ASan the call below may write to freed memory and corrupt
2173  // its metadata. See
2174  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2175  int res = REAL(readdir64_r)(dirp, entry, result);
2176  if (!res) {
2177    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2178    if (*result)
2179      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2180  }
2181  return res;
2182}
2183#define INIT_READDIR64                  \
2184  COMMON_INTERCEPT_FUNCTION(readdir64); \
2185  COMMON_INTERCEPT_FUNCTION(readdir64_r);
2186#else
2187#define INIT_READDIR64
2188#endif
2189
2190#if SANITIZER_INTERCEPT_PTRACE
2191INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2192  void *ctx;
2193  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
2194
2195  if (data) {
2196    if (request == ptrace_setregs)
2197      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2198    else if (request == ptrace_setfpregs)
2199      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2200    else if (request == ptrace_setfpxregs)
2201      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2202    else if (request == ptrace_setsiginfo)
2203      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
2204    else if (request == ptrace_setregset) {
2205      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
2206      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len);
2207    }
2208  }
2209
2210  // FIXME: under ASan the call below may write to freed memory and corrupt
2211  // its metadata. See
2212  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2213  uptr res = REAL(ptrace)(request, pid, addr, data);
2214
2215  if (!res && data) {
2216    // Note that PEEK* requests assign different meaning to the return value.
2217    // This function does not handle them (nor does it need to).
2218    if (request == ptrace_getregs)
2219      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2220    else if (request == ptrace_getfpregs)
2221      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2222    else if (request == ptrace_getfpxregs)
2223      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2224    else if (request == ptrace_getsiginfo)
2225      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
2226    else if (request == ptrace_geteventmsg)
2227      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
2228    else if (request == ptrace_getregset) {
2229      __sanitizer_iovec *iov = (__sanitizer_iovec *)data;
2230      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len);
2231    }
2232  }
2233  return res;
2234}
2235
2236#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2237#else
2238#define INIT_PTRACE
2239#endif
2240
2241#if SANITIZER_INTERCEPT_SETLOCALE
2242INTERCEPTOR(char *, setlocale, int category, char *locale) {
2243  void *ctx;
2244  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
2245  if (locale)
2246    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2247  char *res = REAL(setlocale)(category, locale);
2248  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2249  return res;
2250}
2251
2252#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
2253#else
2254#define INIT_SETLOCALE
2255#endif
2256
2257#if SANITIZER_INTERCEPT_GETCWD
2258INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2259  void *ctx;
2260  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
2261  // FIXME: under ASan the call below may write to freed memory and corrupt
2262  // its metadata. See
2263  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2264  char *res = REAL(getcwd)(buf, size);
2265  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2266  return res;
2267}
2268#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2269#else
2270#define INIT_GETCWD
2271#endif
2272
2273#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
2274INTERCEPTOR(char *, get_current_dir_name, int fake) {
2275  void *ctx;
2276  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
2277  // FIXME: under ASan the call below may write to freed memory and corrupt
2278  // its metadata. See
2279  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2280  char *res = REAL(get_current_dir_name)(fake);
2281  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2282  return res;
2283}
2284
2285#define INIT_GET_CURRENT_DIR_NAME \
2286  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2287#else
2288#define INIT_GET_CURRENT_DIR_NAME
2289#endif
2290
2291#if SANITIZER_INTERCEPT_STRTOIMAX
2292INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2293  void *ctx;
2294  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
2295  // FIXME: under ASan the call below may write to freed memory and corrupt
2296  // its metadata. See
2297  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2298  INTMAX_T res = REAL(strtoimax)(nptr, endptr, base);
2299  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2300  return res;
2301}
2302
2303INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2304  void *ctx;
2305  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
2306  // FIXME: under ASan the call below may write to freed memory and corrupt
2307  // its metadata. See
2308  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2309  INTMAX_T res = REAL(strtoumax)(nptr, endptr, base);
2310  if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2311  return res;
2312}
2313
2314#define INIT_STRTOIMAX                  \
2315  COMMON_INTERCEPT_FUNCTION(strtoimax); \
2316  COMMON_INTERCEPT_FUNCTION(strtoumax);
2317#else
2318#define INIT_STRTOIMAX
2319#endif
2320
2321#if SANITIZER_INTERCEPT_MBSTOWCS
2322INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2323  void *ctx;
2324  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
2325  // FIXME: under ASan the call below may write to freed memory and corrupt
2326  // its metadata. See
2327  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2328  SIZE_T res = REAL(mbstowcs)(dest, src, len);
2329  if (res != (SIZE_T) - 1 && dest) {
2330    SIZE_T write_cnt = res + (res < len);
2331    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2332  }
2333  return res;
2334}
2335
2336INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2337            void *ps) {
2338  void *ctx;
2339  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2340  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2341  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2342  // FIXME: under ASan the call below may write to freed memory and corrupt
2343  // its metadata. See
2344  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2345  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2346  if (res != (SIZE_T)(-1) && dest && src) {
2347    // This function, and several others, may or may not write the terminating
2348    // \0 character. They write it iff they clear *src.
2349    SIZE_T write_cnt = res + !*src;
2350    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2351  }
2352  return res;
2353}
2354
2355#define INIT_MBSTOWCS                  \
2356  COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2357  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2358#else
2359#define INIT_MBSTOWCS
2360#endif
2361
2362#if SANITIZER_INTERCEPT_MBSNRTOWCS
2363INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2364            SIZE_T len, void *ps) {
2365  void *ctx;
2366  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2367  if (src) {
2368    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2369    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2370  }
2371  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2372  // FIXME: under ASan the call below may write to freed memory and corrupt
2373  // its metadata. See
2374  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2375  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2376  if (res != (SIZE_T)(-1) && dest && src) {
2377    SIZE_T write_cnt = res + !*src;
2378    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2379  }
2380  return res;
2381}
2382
2383#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2384#else
2385#define INIT_MBSNRTOWCS
2386#endif
2387
2388#if SANITIZER_INTERCEPT_WCSTOMBS
2389INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2390  void *ctx;
2391  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
2392  // FIXME: under ASan the call below may write to freed memory and corrupt
2393  // its metadata. See
2394  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2395  SIZE_T res = REAL(wcstombs)(dest, src, len);
2396  if (res != (SIZE_T) - 1 && dest) {
2397    SIZE_T write_cnt = res + (res < len);
2398    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2399  }
2400  return res;
2401}
2402
2403INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2404            void *ps) {
2405  void *ctx;
2406  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2407  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2408  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2409  // FIXME: under ASan the call below may write to freed memory and corrupt
2410  // its metadata. See
2411  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2412  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
2413  if (res != (SIZE_T) - 1 && dest && src) {
2414    SIZE_T write_cnt = res + !*src;
2415    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2416  }
2417  return res;
2418}
2419
2420#define INIT_WCSTOMBS                  \
2421  COMMON_INTERCEPT_FUNCTION(wcstombs); \
2422  COMMON_INTERCEPT_FUNCTION(wcsrtombs);
2423#else
2424#define INIT_WCSTOMBS
2425#endif
2426
2427#if SANITIZER_INTERCEPT_WCSNRTOMBS
2428INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
2429            SIZE_T len, void *ps) {
2430  void *ctx;
2431  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
2432  if (src) {
2433    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2434    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2435  }
2436  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2437  // FIXME: under ASan the call below may write to freed memory and corrupt
2438  // its metadata. See
2439  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2440  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
2441  if (res != (SIZE_T) - 1 && dest && src) {
2442    SIZE_T write_cnt = res + !*src;
2443    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2444  }
2445  return res;
2446}
2447
2448#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
2449#else
2450#define INIT_WCSNRTOMBS
2451#endif
2452
2453#if SANITIZER_INTERCEPT_TCGETATTR
2454INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
2455  void *ctx;
2456  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
2457  // FIXME: under ASan the call below may write to freed memory and corrupt
2458  // its metadata. See
2459  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2460  int res = REAL(tcgetattr)(fd, termios_p);
2461  if (!res && termios_p)
2462    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
2463  return res;
2464}
2465
2466#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
2467#else
2468#define INIT_TCGETATTR
2469#endif
2470
2471#if SANITIZER_INTERCEPT_REALPATH
2472INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
2473  void *ctx;
2474  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
2475  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2476
2477  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
2478  // version of a versioned symbol. For realpath(), this gives us something
2479  // (called __old_realpath) that does not handle NULL in the second argument.
2480  // Handle it as part of the interceptor.
2481  char *allocated_path = 0;
2482  if (!resolved_path)
2483    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
2484
2485  char *res = REAL(realpath)(path, resolved_path);
2486  if (allocated_path && !res) WRAP(free)(allocated_path);
2487  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2488  return res;
2489}
2490#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
2491#else
2492#define INIT_REALPATH
2493#endif
2494
2495#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
2496INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
2497  void *ctx;
2498  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
2499  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2500  char *res = REAL(canonicalize_file_name)(path);
2501  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2502  return res;
2503}
2504#define INIT_CANONICALIZE_FILE_NAME \
2505  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
2506#else
2507#define INIT_CANONICALIZE_FILE_NAME
2508#endif
2509
2510#if SANITIZER_INTERCEPT_CONFSTR
2511INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
2512  void *ctx;
2513  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
2514  // FIXME: under ASan the call below may write to freed memory and corrupt
2515  // its metadata. See
2516  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2517  SIZE_T res = REAL(confstr)(name, buf, len);
2518  if (buf && res)
2519    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
2520  return res;
2521}
2522#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
2523#else
2524#define INIT_CONFSTR
2525#endif
2526
2527#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
2528INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
2529  void *ctx;
2530  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
2531  // FIXME: under ASan the call below may write to freed memory and corrupt
2532  // its metadata. See
2533  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2534  int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
2535  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
2536  return res;
2537}
2538#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
2539#else
2540#define INIT_SCHED_GETAFFINITY
2541#endif
2542
2543#if SANITIZER_INTERCEPT_STRERROR
2544INTERCEPTOR(char *, strerror, int errnum) {
2545  void *ctx;
2546  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
2547  char *res = REAL(strerror)(errnum);
2548  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
2549  return res;
2550}
2551#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
2552#else
2553#define INIT_STRERROR
2554#endif
2555
2556#if SANITIZER_INTERCEPT_STRERROR_R
2557INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
2558  void *ctx;
2559  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
2560  // FIXME: under ASan the call below may write to freed memory and corrupt
2561  // its metadata. See
2562  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2563  char *res = REAL(strerror_r)(errnum, buf, buflen);
2564  // There are 2 versions of strerror_r:
2565  //  * POSIX version returns 0 on success, negative error code on failure,
2566  //    writes message to buf.
2567  //  * GNU version returns message pointer, which points to either buf or some
2568  //    static storage.
2569  SIZE_T posix_res = (SIZE_T)res;
2570  if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
2571    // POSIX version. Spec is not clear on whether buf is NULL-terminated.
2572    // At least on OSX, buf contents are valid even when the call fails.
2573    SIZE_T sz = internal_strnlen(buf, buflen);
2574    if (sz < buflen) ++sz;
2575    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2576  } else {
2577    // GNU version.
2578    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2579  }
2580  return res;
2581}
2582#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
2583#else
2584#define INIT_STRERROR_R
2585#endif
2586
2587#if SANITIZER_INTERCEPT_XPG_STRERROR_R
2588INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
2589  void *ctx;
2590  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
2591  // FIXME: under ASan the call below may write to freed memory and corrupt
2592  // its metadata. See
2593  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2594  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
2595  // This version always returns a null-terminated string.
2596  if (buf && buflen)
2597    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2598  return res;
2599}
2600#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
2601#else
2602#define INIT_XPG_STRERROR_R
2603#endif
2604
2605#if SANITIZER_INTERCEPT_SCANDIR
2606typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
2607typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
2608                                const struct __sanitizer_dirent **);
2609
2610static THREADLOCAL scandir_filter_f scandir_filter;
2611static THREADLOCAL scandir_compar_f scandir_compar;
2612
2613static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
2614  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2615  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
2616  return IndirectExternCall(scandir_filter)(dir);
2617}
2618
2619static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
2620                                  const struct __sanitizer_dirent **b) {
2621  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2622  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
2623  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
2624  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
2625  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
2626  return IndirectExternCall(scandir_compar)(a, b);
2627}
2628
2629INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
2630            scandir_filter_f filter, scandir_compar_f compar) {
2631  void *ctx;
2632  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
2633  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2634  scandir_filter = filter;
2635  scandir_compar = compar;
2636  // FIXME: under ASan the call below may write to freed memory and corrupt
2637  // its metadata. See
2638  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2639  int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0,
2640                          compar ? wrapped_scandir_compar : 0);
2641  scandir_filter = 0;
2642  scandir_compar = 0;
2643  if (namelist && res > 0) {
2644    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2645    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2646    for (int i = 0; i < res; ++i)
2647      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2648                                     (*namelist)[i]->d_reclen);
2649  }
2650  return res;
2651}
2652#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
2653#else
2654#define INIT_SCANDIR
2655#endif
2656
2657#if SANITIZER_INTERCEPT_SCANDIR64
2658typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
2659typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
2660                                  const struct __sanitizer_dirent64 **);
2661
2662static THREADLOCAL scandir64_filter_f scandir64_filter;
2663static THREADLOCAL scandir64_compar_f scandir64_compar;
2664
2665static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
2666  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2667  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
2668  return IndirectExternCall(scandir64_filter)(dir);
2669}
2670
2671static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
2672                                    const struct __sanitizer_dirent64 **b) {
2673  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2674  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
2675  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
2676  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
2677  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
2678  return IndirectExternCall(scandir64_compar)(a, b);
2679}
2680
2681INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
2682            scandir64_filter_f filter, scandir64_compar_f compar) {
2683  void *ctx;
2684  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
2685  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2686  scandir64_filter = filter;
2687  scandir64_compar = compar;
2688  // FIXME: under ASan the call below may write to freed memory and corrupt
2689  // its metadata. See
2690  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2691  int res =
2692      REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0,
2693                      compar ? wrapped_scandir64_compar : 0);
2694  scandir64_filter = 0;
2695  scandir64_compar = 0;
2696  if (namelist && res > 0) {
2697    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2698    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2699    for (int i = 0; i < res; ++i)
2700      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2701                                     (*namelist)[i]->d_reclen);
2702  }
2703  return res;
2704}
2705#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
2706#else
2707#define INIT_SCANDIR64
2708#endif
2709
2710#if SANITIZER_INTERCEPT_GETGROUPS
2711INTERCEPTOR(int, getgroups, int size, u32 *lst) {
2712  void *ctx;
2713  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
2714  // FIXME: under ASan the call below may write to freed memory and corrupt
2715  // its metadata. See
2716  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2717  int res = REAL(getgroups)(size, lst);
2718  if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
2719  return res;
2720}
2721#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
2722#else
2723#define INIT_GETGROUPS
2724#endif
2725
2726#if SANITIZER_INTERCEPT_POLL
2727static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
2728                        __sanitizer_nfds_t nfds) {
2729  for (unsigned i = 0; i < nfds; ++i) {
2730    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
2731    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
2732  }
2733}
2734
2735static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
2736                         __sanitizer_nfds_t nfds) {
2737  for (unsigned i = 0; i < nfds; ++i)
2738    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
2739                                   sizeof(fds[i].revents));
2740}
2741
2742INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2743            int timeout) {
2744  void *ctx;
2745  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
2746  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2747  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
2748  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2749  return res;
2750}
2751#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
2752#else
2753#define INIT_POLL
2754#endif
2755
2756#if SANITIZER_INTERCEPT_PPOLL
2757INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
2758            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
2759  void *ctx;
2760  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
2761  if (fds && nfds) read_pollfd(ctx, fds, nfds);
2762  if (timeout_ts)
2763    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
2764  // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
2765  int res =
2766      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
2767  if (fds && nfds) write_pollfd(ctx, fds, nfds);
2768  return res;
2769}
2770#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
2771#else
2772#define INIT_PPOLL
2773#endif
2774
2775#if SANITIZER_INTERCEPT_WORDEXP
2776INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
2777  void *ctx;
2778  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
2779  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
2780  // FIXME: under ASan the call below may write to freed memory and corrupt
2781  // its metadata. See
2782  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2783  int res = REAL(wordexp)(s, p, flags);
2784  if (!res && p) {
2785    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2786    if (p->we_wordc)
2787      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
2788                                     sizeof(*p->we_wordv) * p->we_wordc);
2789    for (uptr i = 0; i < p->we_wordc; ++i) {
2790      char *w = p->we_wordv[i];
2791      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
2792    }
2793  }
2794  return res;
2795}
2796#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
2797#else
2798#define INIT_WORDEXP
2799#endif
2800
2801#if SANITIZER_INTERCEPT_SIGWAIT
2802INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
2803  void *ctx;
2804  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
2805  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2806  // FIXME: under ASan the call below may write to freed memory and corrupt
2807  // its metadata. See
2808  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2809  int res = REAL(sigwait)(set, sig);
2810  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
2811  return res;
2812}
2813#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
2814#else
2815#define INIT_SIGWAIT
2816#endif
2817
2818#if SANITIZER_INTERCEPT_SIGWAITINFO
2819INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
2820  void *ctx;
2821  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
2822  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2823  // FIXME: under ASan the call below may write to freed memory and corrupt
2824  // its metadata. See
2825  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2826  int res = REAL(sigwaitinfo)(set, info);
2827  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2828  return res;
2829}
2830#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
2831#else
2832#define INIT_SIGWAITINFO
2833#endif
2834
2835#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
2836INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
2837            void *timeout) {
2838  void *ctx;
2839  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
2840  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
2841  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2842  // FIXME: under ASan the call below may write to freed memory and corrupt
2843  // its metadata. See
2844  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2845  int res = REAL(sigtimedwait)(set, info, timeout);
2846  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
2847  return res;
2848}
2849#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
2850#else
2851#define INIT_SIGTIMEDWAIT
2852#endif
2853
2854#if SANITIZER_INTERCEPT_SIGSETOPS
2855INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
2856  void *ctx;
2857  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
2858  // FIXME: under ASan the call below may write to freed memory and corrupt
2859  // its metadata. See
2860  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2861  int res = REAL(sigemptyset)(set);
2862  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2863  return res;
2864}
2865
2866INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
2867  void *ctx;
2868  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
2869  // FIXME: under ASan the call below may write to freed memory and corrupt
2870  // its metadata. See
2871  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2872  int res = REAL(sigfillset)(set);
2873  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2874  return res;
2875}
2876#define INIT_SIGSETOPS                    \
2877  COMMON_INTERCEPT_FUNCTION(sigemptyset); \
2878  COMMON_INTERCEPT_FUNCTION(sigfillset);
2879#else
2880#define INIT_SIGSETOPS
2881#endif
2882
2883#if SANITIZER_INTERCEPT_SIGPENDING
2884INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
2885  void *ctx;
2886  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
2887  // FIXME: under ASan the call below may write to freed memory and corrupt
2888  // its metadata. See
2889  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2890  int res = REAL(sigpending)(set);
2891  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
2892  return res;
2893}
2894#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
2895#else
2896#define INIT_SIGPENDING
2897#endif
2898
2899#if SANITIZER_INTERCEPT_SIGPROCMASK
2900INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
2901            __sanitizer_sigset_t *oldset) {
2902  void *ctx;
2903  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
2904  // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
2905  // FIXME: under ASan the call below may write to freed memory and corrupt
2906  // its metadata. See
2907  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2908  int res = REAL(sigprocmask)(how, set, oldset);
2909  if (!res && oldset)
2910    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
2911  return res;
2912}
2913#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
2914#else
2915#define INIT_SIGPROCMASK
2916#endif
2917
2918#if SANITIZER_INTERCEPT_BACKTRACE
2919INTERCEPTOR(int, backtrace, void **buffer, int size) {
2920  void *ctx;
2921  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
2922  // FIXME: under ASan the call below may write to freed memory and corrupt
2923  // its metadata. See
2924  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2925  int res = REAL(backtrace)(buffer, size);
2926  if (res && buffer)
2927    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
2928  return res;
2929}
2930
2931INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
2932  void *ctx;
2933  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
2934  if (buffer && size)
2935    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
2936  // FIXME: under ASan the call below may write to freed memory and corrupt
2937  // its metadata. See
2938  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2939  char **res = REAL(backtrace_symbols)(buffer, size);
2940  if (res && size) {
2941    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
2942    for (int i = 0; i < size; ++i)
2943      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
2944  }
2945  return res;
2946}
2947#define INIT_BACKTRACE                  \
2948  COMMON_INTERCEPT_FUNCTION(backtrace); \
2949  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
2950#else
2951#define INIT_BACKTRACE
2952#endif
2953
2954#if SANITIZER_INTERCEPT__EXIT
2955INTERCEPTOR(void, _exit, int status) {
2956  void *ctx;
2957  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
2958  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
2959  if (status == 0) status = status1;
2960  REAL(_exit)(status);
2961}
2962#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
2963#else
2964#define INIT__EXIT
2965#endif
2966
2967#if SANITIZER_INTERCEPT_PHTREAD_MUTEX
2968INTERCEPTOR(int, pthread_mutex_lock, void *m) {
2969  void *ctx;
2970  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
2971  int res = REAL(pthread_mutex_lock)(m);
2972  if (res == errno_EOWNERDEAD)
2973    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
2974  if (res == 0 || res == errno_EOWNERDEAD)
2975    COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
2976  return res;
2977}
2978
2979INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
2980  void *ctx;
2981  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
2982  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
2983  return REAL(pthread_mutex_unlock)(m);
2984}
2985
2986#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
2987#define INIT_PTHREAD_MUTEX_UNLOCK \
2988  COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
2989#else
2990#define INIT_PTHREAD_MUTEX_LOCK
2991#define INIT_PTHREAD_MUTEX_UNLOCK
2992#endif
2993
2994#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
2995static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
2996  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
2997  if (mnt->mnt_fsname)
2998    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
2999                                   REAL(strlen)(mnt->mnt_fsname) + 1);
3000  if (mnt->mnt_dir)
3001    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
3002                                   REAL(strlen)(mnt->mnt_dir) + 1);
3003  if (mnt->mnt_type)
3004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
3005                                   REAL(strlen)(mnt->mnt_type) + 1);
3006  if (mnt->mnt_opts)
3007    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
3008                                   REAL(strlen)(mnt->mnt_opts) + 1);
3009}
3010#endif
3011
3012#if SANITIZER_INTERCEPT_GETMNTENT
3013INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
3014  void *ctx;
3015  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
3016  __sanitizer_mntent *res = REAL(getmntent)(fp);
3017  if (res) write_mntent(ctx, res);
3018  return res;
3019}
3020#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
3021#else
3022#define INIT_GETMNTENT
3023#endif
3024
3025#if SANITIZER_INTERCEPT_GETMNTENT_R
3026INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
3027            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
3028  void *ctx;
3029  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
3030  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
3031  if (res) write_mntent(ctx, res);
3032  return res;
3033}
3034#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
3035#else
3036#define INIT_GETMNTENT_R
3037#endif
3038
3039#if SANITIZER_INTERCEPT_STATFS
3040INTERCEPTOR(int, statfs, char *path, void *buf) {
3041  void *ctx;
3042  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
3043  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3044  // FIXME: under ASan the call below may write to freed memory and corrupt
3045  // its metadata. See
3046  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3047  int res = REAL(statfs)(path, buf);
3048  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3049  return res;
3050}
3051INTERCEPTOR(int, fstatfs, int fd, void *buf) {
3052  void *ctx;
3053  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
3054  // FIXME: under ASan the call below may write to freed memory and corrupt
3055  // its metadata. See
3056  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3057  int res = REAL(fstatfs)(fd, buf);
3058  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3059  return res;
3060}
3061#define INIT_STATFS                  \
3062  COMMON_INTERCEPT_FUNCTION(statfs); \
3063  COMMON_INTERCEPT_FUNCTION(fstatfs);
3064#else
3065#define INIT_STATFS
3066#endif
3067
3068#if SANITIZER_INTERCEPT_STATFS64
3069INTERCEPTOR(int, statfs64, char *path, void *buf) {
3070  void *ctx;
3071  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
3072  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3073  // FIXME: under ASan the call below may write to freed memory and corrupt
3074  // its metadata. See
3075  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3076  int res = REAL(statfs64)(path, buf);
3077  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3078  return res;
3079}
3080INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
3081  void *ctx;
3082  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
3083  // FIXME: under ASan the call below may write to freed memory and corrupt
3084  // its metadata. See
3085  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3086  int res = REAL(fstatfs64)(fd, buf);
3087  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3088  return res;
3089}
3090#define INIT_STATFS64                  \
3091  COMMON_INTERCEPT_FUNCTION(statfs64); \
3092  COMMON_INTERCEPT_FUNCTION(fstatfs64);
3093#else
3094#define INIT_STATFS64
3095#endif
3096
3097#if SANITIZER_INTERCEPT_STATVFS
3098INTERCEPTOR(int, statvfs, char *path, void *buf) {
3099  void *ctx;
3100  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
3101  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3102  // FIXME: under ASan the call below may write to freed memory and corrupt
3103  // its metadata. See
3104  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3105  int res = REAL(statvfs)(path, buf);
3106  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3107  return res;
3108}
3109INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
3110  void *ctx;
3111  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
3112  // FIXME: under ASan the call below may write to freed memory and corrupt
3113  // its metadata. See
3114  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3115  int res = REAL(fstatvfs)(fd, buf);
3116  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3117  return res;
3118}
3119#define INIT_STATVFS                  \
3120  COMMON_INTERCEPT_FUNCTION(statvfs); \
3121  COMMON_INTERCEPT_FUNCTION(fstatvfs);
3122#else
3123#define INIT_STATVFS
3124#endif
3125
3126#if SANITIZER_INTERCEPT_STATVFS64
3127INTERCEPTOR(int, statvfs64, char *path, void *buf) {
3128  void *ctx;
3129  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
3130  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3131  // FIXME: under ASan the call below may write to freed memory and corrupt
3132  // its metadata. See
3133  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3134  int res = REAL(statvfs64)(path, buf);
3135  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3136  return res;
3137}
3138INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
3139  void *ctx;
3140  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
3141  // FIXME: under ASan the call below may write to freed memory and corrupt
3142  // its metadata. See
3143  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3144  int res = REAL(fstatvfs64)(fd, buf);
3145  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3146  return res;
3147}
3148#define INIT_STATVFS64                  \
3149  COMMON_INTERCEPT_FUNCTION(statvfs64); \
3150  COMMON_INTERCEPT_FUNCTION(fstatvfs64);
3151#else
3152#define INIT_STATVFS64
3153#endif
3154
3155#if SANITIZER_INTERCEPT_INITGROUPS
3156INTERCEPTOR(int, initgroups, char *user, u32 group) {
3157  void *ctx;
3158  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3159  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3160  int res = REAL(initgroups)(user, group);
3161  return res;
3162}
3163#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3164#else
3165#define INIT_INITGROUPS
3166#endif
3167
3168#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
3169INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3170  void *ctx;
3171  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3172  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3173  char *res = REAL(ether_ntoa)(addr);
3174  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3175  return res;
3176}
3177INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3178  void *ctx;
3179  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3180  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3181  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
3182  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3183  return res;
3184}
3185#define INIT_ETHER_NTOA_ATON             \
3186  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
3187  COMMON_INTERCEPT_FUNCTION(ether_aton);
3188#else
3189#define INIT_ETHER_NTOA_ATON
3190#endif
3191
3192#if SANITIZER_INTERCEPT_ETHER_HOST
3193INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3194  void *ctx;
3195  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3196  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3197  // FIXME: under ASan the call below may write to freed memory and corrupt
3198  // its metadata. See
3199  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3200  int res = REAL(ether_ntohost)(hostname, addr);
3201  if (!res && hostname)
3202    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3203  return res;
3204}
3205INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3206  void *ctx;
3207  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3208  if (hostname)
3209    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3210  // FIXME: under ASan the call below may write to freed memory and corrupt
3211  // its metadata. See
3212  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3213  int res = REAL(ether_hostton)(hostname, addr);
3214  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3215  return res;
3216}
3217INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3218            char *hostname) {
3219  void *ctx;
3220  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3221  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
3222  // FIXME: under ASan the call below may write to freed memory and corrupt
3223  // its metadata. See
3224  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3225  int res = REAL(ether_line)(line, addr, hostname);
3226  if (!res) {
3227    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3228    if (hostname)
3229      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3230  }
3231  return res;
3232}
3233#define INIT_ETHER_HOST                     \
3234  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3235  COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3236  COMMON_INTERCEPT_FUNCTION(ether_line);
3237#else
3238#define INIT_ETHER_HOST
3239#endif
3240
3241#if SANITIZER_INTERCEPT_ETHER_R
3242INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3243  void *ctx;
3244  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3245  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3246  // FIXME: under ASan the call below may write to freed memory and corrupt
3247  // its metadata. See
3248  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3249  char *res = REAL(ether_ntoa_r)(addr, buf);
3250  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3251  return res;
3252}
3253INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3254            __sanitizer_ether_addr *addr) {
3255  void *ctx;
3256  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3257  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3258  // FIXME: under ASan the call below may write to freed memory and corrupt
3259  // its metadata. See
3260  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3261  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3262  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3263  return res;
3264}
3265#define INIT_ETHER_R                       \
3266  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3267  COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3268#else
3269#define INIT_ETHER_R
3270#endif
3271
3272#if SANITIZER_INTERCEPT_SHMCTL
3273INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
3274  void *ctx;
3275  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
3276  // FIXME: under ASan the call below may write to freed memory and corrupt
3277  // its metadata. See
3278  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3279  int res = REAL(shmctl)(shmid, cmd, buf);
3280  if (res >= 0) {
3281    unsigned sz = 0;
3282    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3283      sz = sizeof(__sanitizer_shmid_ds);
3284    else if (cmd == shmctl_ipc_info)
3285      sz = struct_shminfo_sz;
3286    else if (cmd == shmctl_shm_info)
3287      sz = struct_shm_info_sz;
3288    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3289  }
3290  return res;
3291}
3292#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
3293#else
3294#define INIT_SHMCTL
3295#endif
3296
3297#if SANITIZER_INTERCEPT_RANDOM_R
3298INTERCEPTOR(int, random_r, void *buf, u32 *result) {
3299  void *ctx;
3300  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
3301  // FIXME: under ASan the call below may write to freed memory and corrupt
3302  // its metadata. See
3303  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3304  int res = REAL(random_r)(buf, result);
3305  if (!res && result)
3306    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3307  return res;
3308}
3309#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3310#else
3311#define INIT_RANDOM_R
3312#endif
3313
3314// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
3315// its metadata. See
3316// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3317#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
3318    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
3319    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
3320    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
3321    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
3322    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
3323#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
3324  INTERCEPTOR(int, fn, void *attr, void *r) {                  \
3325    void *ctx;                                                 \
3326    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
3327    int res = REAL(fn)(attr, r);                               \
3328    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
3329    return res;                                                \
3330  }
3331#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
3332  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
3333#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
3334  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
3335#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
3336  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
3337#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
3338  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
3339#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
3340  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
3341#endif
3342
3343#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3344INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3345INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3346INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3347INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3348INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3349INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3350INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3351  void *ctx;
3352  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
3353  // FIXME: under ASan the call below may write to freed memory and corrupt
3354  // its metadata. See
3355  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3356  int res = REAL(pthread_attr_getstack)(attr, addr, size);
3357  if (!res) {
3358    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3359    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3360  }
3361  return res;
3362}
3363
3364// We may need to call the real pthread_attr_getstack from the run-time
3365// in sanitizer_common, but we don't want to include the interception headers
3366// there. So, just define this function here.
3367namespace __sanitizer {
3368extern "C" {
3369int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
3370  return REAL(pthread_attr_getstack)(attr, addr, size);
3371}
3372}  // extern "C"
3373}  // namespace __sanitizer
3374
3375#define INIT_PTHREAD_ATTR_GET                             \
3376  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
3377  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
3378  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
3379  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
3380  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
3381  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
3382  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
3383#else
3384#define INIT_PTHREAD_ATTR_GET
3385#endif
3386
3387#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
3388INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
3389
3390#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
3391  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
3392#else
3393#define INIT_PTHREAD_ATTR_GETINHERITSCHED
3394#endif
3395
3396#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
3397INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
3398            void *cpuset) {
3399  void *ctx;
3400  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
3401                           cpuset);
3402  // FIXME: under ASan the call below may write to freed memory and corrupt
3403  // its metadata. See
3404  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3405  int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
3406  if (!res && cpusetsize && cpuset)
3407    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
3408  return res;
3409}
3410
3411#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
3412  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
3413#else
3414#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
3415#endif
3416
3417#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
3418INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
3419#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
3420  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
3421#else
3422#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
3423#endif
3424
3425#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
3426INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
3427#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
3428  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
3429#else
3430#define INIT_PTHREAD_MUTEXATTR_GETTYPE
3431#endif
3432
3433#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
3434INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
3435#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
3436  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
3437#else
3438#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
3439#endif
3440
3441#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3442INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
3443#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
3444  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
3445#else
3446#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3447#endif
3448
3449#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
3450INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
3451#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
3452  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
3453#else
3454#define INIT_PTHREAD_MUTEXATTR_GETROBUST
3455#endif
3456
3457#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
3458INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
3459#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
3460  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
3461#else
3462#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
3463#endif
3464
3465#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
3466INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
3467#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
3468  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
3469#else
3470#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
3471#endif
3472
3473#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
3474INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
3475#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
3476  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
3477#else
3478#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
3479#endif
3480
3481#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
3482INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
3483#define INIT_PTHREAD_CONDATTR_GETPSHARED \
3484  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
3485#else
3486#define INIT_PTHREAD_CONDATTR_GETPSHARED
3487#endif
3488
3489#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
3490INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
3491#define INIT_PTHREAD_CONDATTR_GETCLOCK \
3492  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
3493#else
3494#define INIT_PTHREAD_CONDATTR_GETCLOCK
3495#endif
3496
3497#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
3498INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
3499#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
3500  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
3501#else
3502#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
3503#endif
3504
3505#if SANITIZER_INTERCEPT_TMPNAM
3506INTERCEPTOR(char *, tmpnam, char *s) {
3507  void *ctx;
3508  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
3509  char *res = REAL(tmpnam)(s);
3510  if (res) {
3511    if (s)
3512      // FIXME: under ASan the call below may write to freed memory and corrupt
3513      // its metadata. See
3514      // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3515      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3516    else
3517      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3518  }
3519  return res;
3520}
3521#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
3522#else
3523#define INIT_TMPNAM
3524#endif
3525
3526#if SANITIZER_INTERCEPT_TMPNAM_R
3527INTERCEPTOR(char *, tmpnam_r, char *s) {
3528  void *ctx;
3529  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
3530  // FIXME: under ASan the call below may write to freed memory and corrupt
3531  // its metadata. See
3532  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3533  char *res = REAL(tmpnam_r)(s);
3534  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3535  return res;
3536}
3537#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
3538#else
3539#define INIT_TMPNAM_R
3540#endif
3541
3542#if SANITIZER_INTERCEPT_TEMPNAM
3543INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
3544  void *ctx;
3545  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
3546  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
3547  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
3548  char *res = REAL(tempnam)(dir, pfx);
3549  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3550  return res;
3551}
3552#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
3553#else
3554#define INIT_TEMPNAM
3555#endif
3556
3557#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
3558INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
3559  void *ctx;
3560  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
3561  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
3562  return REAL(pthread_setname_np)(thread, name);
3563}
3564#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
3565#else
3566#define INIT_PTHREAD_SETNAME_NP
3567#endif
3568
3569#if SANITIZER_INTERCEPT_SINCOS
3570INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
3571  void *ctx;
3572  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
3573  // FIXME: under ASan the call below may write to freed memory and corrupt
3574  // its metadata. See
3575  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3576  REAL(sincos)(x, sin, cos);
3577  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3578  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3579}
3580INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
3581  void *ctx;
3582  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
3583  // FIXME: under ASan the call below may write to freed memory and corrupt
3584  // its metadata. See
3585  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3586  REAL(sincosf)(x, sin, cos);
3587  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3588  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3589}
3590INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
3591  void *ctx;
3592  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
3593  // FIXME: under ASan the call below may write to freed memory and corrupt
3594  // its metadata. See
3595  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3596  REAL(sincosl)(x, sin, cos);
3597  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3598  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3599}
3600#define INIT_SINCOS                   \
3601  COMMON_INTERCEPT_FUNCTION(sincos);  \
3602  COMMON_INTERCEPT_FUNCTION(sincosf); \
3603  COMMON_INTERCEPT_FUNCTION(sincosl);
3604#else
3605#define INIT_SINCOS
3606#endif
3607
3608#if SANITIZER_INTERCEPT_REMQUO
3609INTERCEPTOR(double, remquo, double x, double y, int *quo) {
3610  void *ctx;
3611  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
3612  // FIXME: under ASan the call below may write to freed memory and corrupt
3613  // its metadata. See
3614  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3615  double res = REAL(remquo)(x, y, quo);
3616  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3617  return res;
3618}
3619INTERCEPTOR(float, remquof, float x, float y, int *quo) {
3620  void *ctx;
3621  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
3622  // FIXME: under ASan the call below may write to freed memory and corrupt
3623  // its metadata. See
3624  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3625  float res = REAL(remquof)(x, y, quo);
3626  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3627  return res;
3628}
3629INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
3630  void *ctx;
3631  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
3632  // FIXME: under ASan the call below may write to freed memory and corrupt
3633  // its metadata. See
3634  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3635  long double res = REAL(remquol)(x, y, quo);
3636  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3637  return res;
3638}
3639#define INIT_REMQUO                   \
3640  COMMON_INTERCEPT_FUNCTION(remquo);  \
3641  COMMON_INTERCEPT_FUNCTION(remquof); \
3642  COMMON_INTERCEPT_FUNCTION(remquol);
3643#else
3644#define INIT_REMQUO
3645#endif
3646
3647#if SANITIZER_INTERCEPT_LGAMMA
3648extern int signgam;
3649INTERCEPTOR(double, lgamma, double x) {
3650  void *ctx;
3651  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
3652  double res = REAL(lgamma)(x);
3653  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3654  return res;
3655}
3656INTERCEPTOR(float, lgammaf, float x) {
3657  void *ctx;
3658  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
3659  float res = REAL(lgammaf)(x);
3660  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3661  return res;
3662}
3663INTERCEPTOR(long double, lgammal, long double x) {
3664  void *ctx;
3665  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
3666  long double res = REAL(lgammal)(x);
3667  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3668  return res;
3669}
3670#define INIT_LGAMMA                   \
3671  COMMON_INTERCEPT_FUNCTION(lgamma);  \
3672  COMMON_INTERCEPT_FUNCTION(lgammaf); \
3673  COMMON_INTERCEPT_FUNCTION(lgammal);
3674#else
3675#define INIT_LGAMMA
3676#endif
3677
3678#if SANITIZER_INTERCEPT_LGAMMA_R
3679INTERCEPTOR(double, lgamma_r, double x, int *signp) {
3680  void *ctx;
3681  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
3682  // FIXME: under ASan the call below may write to freed memory and corrupt
3683  // its metadata. See
3684  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3685  double res = REAL(lgamma_r)(x, signp);
3686  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3687  return res;
3688}
3689INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
3690  void *ctx;
3691  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
3692  // FIXME: under ASan the call below may write to freed memory and corrupt
3693  // its metadata. See
3694  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3695  float res = REAL(lgammaf_r)(x, signp);
3696  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3697  return res;
3698}
3699#define INIT_LGAMMA_R                   \
3700  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
3701  COMMON_INTERCEPT_FUNCTION(lgammaf_r);
3702#else
3703#define INIT_LGAMMA_R
3704#endif
3705
3706#if SANITIZER_INTERCEPT_LGAMMAL_R
3707INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
3708  void *ctx;
3709  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
3710  // FIXME: under ASan the call below may write to freed memory and corrupt
3711  // its metadata. See
3712  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3713  long double res = REAL(lgammal_r)(x, signp);
3714  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
3715  return res;
3716}
3717#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);
3718#else
3719#define INIT_LGAMMAL_R
3720#endif
3721
3722#if SANITIZER_INTERCEPT_DRAND48_R
3723INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
3724  void *ctx;
3725  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
3726  // FIXME: under ASan the call below may write to freed memory and corrupt
3727  // its metadata. See
3728  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3729  int res = REAL(drand48_r)(buffer, result);
3730  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3731  return res;
3732}
3733INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
3734  void *ctx;
3735  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
3736  // FIXME: under ASan the call below may write to freed memory and corrupt
3737  // its metadata. See
3738  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3739  int res = REAL(lrand48_r)(buffer, result);
3740  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3741  return res;
3742}
3743#define INIT_DRAND48_R                  \
3744  COMMON_INTERCEPT_FUNCTION(drand48_r); \
3745  COMMON_INTERCEPT_FUNCTION(lrand48_r);
3746#else
3747#define INIT_DRAND48_R
3748#endif
3749
3750#if SANITIZER_INTERCEPT_RAND_R
3751INTERCEPTOR(int, rand_r, unsigned *seedp) {
3752  void *ctx;
3753  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
3754  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
3755  return REAL(rand_r)(seedp);
3756}
3757#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
3758#else
3759#define INIT_RAND_R
3760#endif
3761
3762#if SANITIZER_INTERCEPT_GETLINE
3763INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
3764  void *ctx;
3765  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
3766  // FIXME: under ASan the call below may write to freed memory and corrupt
3767  // its metadata. See
3768  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3769  SSIZE_T res = REAL(getline)(lineptr, n, stream);
3770  if (res > 0) {
3771    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
3772    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
3773    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
3774  }
3775  return res;
3776}
3777INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
3778            void *stream) {
3779  void *ctx;
3780  COMMON_INTERCEPTOR_ENTER(ctx, __getdelim, lineptr, n, delim, stream);
3781  // FIXME: under ASan the call below may write to freed memory and corrupt
3782  // its metadata. See
3783  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3784  SSIZE_T res = REAL(__getdelim)(lineptr, n, delim, stream);
3785  if (res > 0) {
3786    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
3787    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
3788    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
3789  }
3790  return res;
3791}
3792INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
3793            void *stream) {
3794  return __getdelim(lineptr, n, delim, stream);
3795}
3796#define INIT_GETLINE                     \
3797  COMMON_INTERCEPT_FUNCTION(getline);    \
3798  COMMON_INTERCEPT_FUNCTION(__getdelim); \
3799  COMMON_INTERCEPT_FUNCTION(getdelim);
3800#else
3801#define INIT_GETLINE
3802#endif
3803
3804#if SANITIZER_INTERCEPT_ICONV
3805INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
3806            char **outbuf, SIZE_T *outbytesleft) {
3807  void *ctx;
3808  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
3809                           outbytesleft);
3810  if (inbytesleft)
3811    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
3812  if (inbuf && inbytesleft)
3813    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
3814  if (outbytesleft)
3815    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
3816  void *outbuf_orig = outbuf ? *outbuf : 0;
3817  // FIXME: under ASan the call below may write to freed memory and corrupt
3818  // its metadata. See
3819  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3820  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
3821  if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
3822    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
3823    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
3824  }
3825  return res;
3826}
3827#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
3828#else
3829#define INIT_ICONV
3830#endif
3831
3832#if SANITIZER_INTERCEPT_TIMES
3833INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
3834  void *ctx;
3835  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
3836  // FIXME: under ASan the call below may write to freed memory and corrupt
3837  // its metadata. See
3838  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3839  __sanitizer_clock_t res = REAL(times)(tms);
3840  if (res != (__sanitizer_clock_t)-1 && tms)
3841    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
3842  return res;
3843}
3844#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
3845#else
3846#define INIT_TIMES
3847#endif
3848
3849#if SANITIZER_INTERCEPT_TLS_GET_ADDR
3850#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
3851INTERCEPTOR(void *, __tls_get_addr, void *arg) {
3852  void *ctx;
3853  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
3854  void *res = REAL(__tls_get_addr)(arg);
3855  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res);
3856  if (dtv) {
3857    // New DTLS block has been allocated.
3858    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
3859  }
3860  return res;
3861}
3862#else
3863#define INIT_TLS_GET_ADDR
3864#endif
3865
3866#if SANITIZER_INTERCEPT_LISTXATTR
3867INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
3868  void *ctx;
3869  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
3870  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3871  // FIXME: under ASan the call below may write to freed memory and corrupt
3872  // its metadata. See
3873  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3874  SSIZE_T res = REAL(listxattr)(path, list, size);
3875  // Here and below, size == 0 is a special case where nothing is written to the
3876  // buffer, and res contains the desired buffer size.
3877  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
3878  return res;
3879}
3880INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
3881  void *ctx;
3882  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
3883  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3884  // FIXME: under ASan the call below may write to freed memory and corrupt
3885  // its metadata. See
3886  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3887  SSIZE_T res = REAL(llistxattr)(path, list, size);
3888  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
3889  return res;
3890}
3891INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
3892  void *ctx;
3893  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
3894  // FIXME: under ASan the call below may write to freed memory and corrupt
3895  // its metadata. See
3896  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3897  SSIZE_T res = REAL(flistxattr)(fd, list, size);
3898  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
3899  return res;
3900}
3901#define INIT_LISTXATTR                   \
3902  COMMON_INTERCEPT_FUNCTION(listxattr);  \
3903  COMMON_INTERCEPT_FUNCTION(llistxattr); \
3904  COMMON_INTERCEPT_FUNCTION(flistxattr);
3905#else
3906#define INIT_LISTXATTR
3907#endif
3908
3909#if SANITIZER_INTERCEPT_GETXATTR
3910INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
3911            SIZE_T size) {
3912  void *ctx;
3913  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
3914  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3915  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
3916  // FIXME: under ASan the call below may write to freed memory and corrupt
3917  // its metadata. See
3918  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3919  SSIZE_T res = REAL(getxattr)(path, name, value, size);
3920  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
3921  return res;
3922}
3923INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
3924            SIZE_T size) {
3925  void *ctx;
3926  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
3927  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3928  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
3929  // FIXME: under ASan the call below may write to freed memory and corrupt
3930  // its metadata. See
3931  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3932  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
3933  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
3934  return res;
3935}
3936INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
3937            SIZE_T size) {
3938  void *ctx;
3939  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
3940  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
3941  // FIXME: under ASan the call below may write to freed memory and corrupt
3942  // its metadata. See
3943  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3944  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
3945  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
3946  return res;
3947}
3948#define INIT_GETXATTR                   \
3949  COMMON_INTERCEPT_FUNCTION(getxattr);  \
3950  COMMON_INTERCEPT_FUNCTION(lgetxattr); \
3951  COMMON_INTERCEPT_FUNCTION(fgetxattr);
3952#else
3953#define INIT_GETXATTR
3954#endif
3955
3956#if SANITIZER_INTERCEPT_GETRESID
3957INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
3958  void *ctx;
3959  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
3960  // FIXME: under ASan the call below may write to freed memory and corrupt
3961  // its metadata. See
3962  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3963  int res = REAL(getresuid)(ruid, euid, suid);
3964  if (res >= 0) {
3965    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
3966    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
3967    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
3968  }
3969  return res;
3970}
3971INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
3972  void *ctx;
3973  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
3974  // FIXME: under ASan the call below may write to freed memory and corrupt
3975  // its metadata. See
3976  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3977  int res = REAL(getresgid)(rgid, egid, sgid);
3978  if (res >= 0) {
3979    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
3980    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
3981    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
3982  }
3983  return res;
3984}
3985#define INIT_GETRESID                   \
3986  COMMON_INTERCEPT_FUNCTION(getresuid); \
3987  COMMON_INTERCEPT_FUNCTION(getresgid);
3988#else
3989#define INIT_GETRESID
3990#endif
3991
3992#if SANITIZER_INTERCEPT_GETIFADDRS
3993// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
3994// intercept freeifaddrs(). If that ceases to be the case, we might need to
3995// intercept it to poison the memory again.
3996INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
3997  void *ctx;
3998  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
3999  // FIXME: under ASan the call below may write to freed memory and corrupt
4000  // its metadata. See
4001  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4002  int res = REAL(getifaddrs)(ifap);
4003  if (res == 0 && ifap) {
4004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
4005    __sanitizer_ifaddrs *p = *ifap;
4006    while (p) {
4007      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
4008      if (p->ifa_name)
4009        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
4010                                       REAL(strlen)(p->ifa_name) + 1);
4011      if (p->ifa_addr)
4012        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
4013      if (p->ifa_netmask)
4014        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
4015      // On Linux this is a union, but the other member also points to a
4016      // struct sockaddr, so the following is sufficient.
4017      if (p->ifa_dstaddr)
4018        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
4019      // FIXME(smatveev): Unpoison p->ifa_data as well.
4020      p = p->ifa_next;
4021    }
4022  }
4023  return res;
4024}
4025#define INIT_GETIFADDRS                  \
4026  COMMON_INTERCEPT_FUNCTION(getifaddrs);
4027#else
4028#define INIT_GETIFADDRS
4029#endif
4030
4031#if SANITIZER_INTERCEPT_IF_INDEXTONAME
4032INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
4033  void *ctx;
4034  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
4035  // FIXME: under ASan the call below may write to freed memory and corrupt
4036  // its metadata. See
4037  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4038  char *res = REAL(if_indextoname)(ifindex, ifname);
4039  if (res && ifname)
4040    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4041  return res;
4042}
4043INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
4044  void *ctx;
4045  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
4046  if (ifname)
4047    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4048  return REAL(if_nametoindex)(ifname);
4049}
4050#define INIT_IF_INDEXTONAME                  \
4051  COMMON_INTERCEPT_FUNCTION(if_indextoname); \
4052  COMMON_INTERCEPT_FUNCTION(if_nametoindex);
4053#else
4054#define INIT_IF_INDEXTONAME
4055#endif
4056
4057#if SANITIZER_INTERCEPT_CAPGET
4058INTERCEPTOR(int, capget, void *hdrp, void *datap) {
4059  void *ctx;
4060  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
4061  if (hdrp)
4062    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4063  // FIXME: under ASan the call below may write to freed memory and corrupt
4064  // its metadata. See
4065  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4066  int res = REAL(capget)(hdrp, datap);
4067  if (res == 0 && datap)
4068    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
4069  // We can also return -1 and write to hdrp->version if the version passed in
4070  // hdrp->version is unsupported. But that's not a trivial condition to check,
4071  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
4072  return res;
4073}
4074INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
4075  void *ctx;
4076  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
4077  if (hdrp)
4078    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4079  if (datap)
4080    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
4081  return REAL(capset)(hdrp, datap);
4082}
4083#define INIT_CAPGET                  \
4084  COMMON_INTERCEPT_FUNCTION(capget); \
4085  COMMON_INTERCEPT_FUNCTION(capset);
4086#else
4087#define INIT_CAPGET
4088#endif
4089
4090#if SANITIZER_INTERCEPT_AEABI_MEM
4091DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr);
4092DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr);
4093DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
4094
4095INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
4096  return WRAP(memmove)(to, from, size);
4097}
4098INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
4099  return WRAP(memmove)(to, from, size);
4100}
4101INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
4102  return WRAP(memmove)(to, from, size);
4103}
4104INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
4105  return WRAP(memcpy)(to, from, size);
4106}
4107INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
4108  return WRAP(memcpy)(to, from, size);
4109}
4110INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
4111  return WRAP(memcpy)(to, from, size);
4112}
4113// Note the argument order.
4114INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
4115  return WRAP(memset)(block, c, size);
4116}
4117INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
4118  return WRAP(memset)(block, c, size);
4119}
4120INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
4121  return WRAP(memset)(block, c, size);
4122}
4123INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
4124  return WRAP(memset)(block, 0, size);
4125}
4126INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
4127  return WRAP(memset)(block, 0, size);
4128}
4129INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
4130  return WRAP(memset)(block, 0, size);
4131}
4132#define INIT_AEABI_MEM                         \
4133  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
4134  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
4135  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
4136  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
4137  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
4138  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
4139  COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
4140  COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
4141  COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
4142  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
4143  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
4144  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
4145#else
4146#define INIT_AEABI_MEM
4147#endif  // SANITIZER_INTERCEPT_AEABI_MEM
4148
4149#if SANITIZER_INTERCEPT___BZERO
4150DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
4151
4152INTERCEPTOR(void *, __bzero, void *block, uptr size) {
4153  return WRAP(memset)(block, 0, size);
4154}
4155#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
4156#else
4157#define INIT___BZERO
4158#endif  // SANITIZER_INTERCEPT___BZERO
4159
4160#if SANITIZER_INTERCEPT_FTIME
4161INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
4162  void *ctx;
4163  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
4164  // FIXME: under ASan the call below may write to freed memory and corrupt
4165  // its metadata. See
4166  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4167  int res = REAL(ftime)(tp);
4168  if (tp)
4169    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
4170  return res;
4171}
4172#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
4173#else
4174#define INIT_FTIME
4175#endif  // SANITIZER_INTERCEPT_FTIME
4176
4177#if SANITIZER_INTERCEPT_XDR
4178INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
4179            unsigned size, int op) {
4180  void *ctx;
4181  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
4182  // FIXME: under ASan the call below may write to freed memory and corrupt
4183  // its metadata. See
4184  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4185  REAL(xdrmem_create)(xdrs, addr, size, op);
4186  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4187  if (op == __sanitizer_XDR_ENCODE) {
4188    // It's not obvious how much data individual xdr_ routines write.
4189    // Simply unpoison the entire target buffer in advance.
4190    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
4191  }
4192}
4193
4194INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
4195  void *ctx;
4196  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
4197  // FIXME: under ASan the call below may write to freed memory and corrupt
4198  // its metadata. See
4199  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4200  REAL(xdrstdio_create)(xdrs, file, op);
4201  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4202}
4203
4204// FIXME: under ASan the call below may write to freed memory and corrupt
4205// its metadata. See
4206// https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4207#define XDR_INTERCEPTOR(F, T)                             \
4208  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
4209    void *ctx;                                            \
4210    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
4211    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
4212      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
4213    int res = REAL(F)(xdrs, p);                           \
4214    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
4215      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
4216    return res;                                           \
4217  }
4218
4219XDR_INTERCEPTOR(xdr_short, short)
4220XDR_INTERCEPTOR(xdr_u_short, unsigned short)
4221XDR_INTERCEPTOR(xdr_int, int)
4222XDR_INTERCEPTOR(xdr_u_int, unsigned)
4223XDR_INTERCEPTOR(xdr_long, long)
4224XDR_INTERCEPTOR(xdr_u_long, unsigned long)
4225XDR_INTERCEPTOR(xdr_hyper, long long)
4226XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
4227XDR_INTERCEPTOR(xdr_longlong_t, long long)
4228XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
4229XDR_INTERCEPTOR(xdr_int8_t, u8)
4230XDR_INTERCEPTOR(xdr_uint8_t, u8)
4231XDR_INTERCEPTOR(xdr_int16_t, u16)
4232XDR_INTERCEPTOR(xdr_uint16_t, u16)
4233XDR_INTERCEPTOR(xdr_int32_t, u32)
4234XDR_INTERCEPTOR(xdr_uint32_t, u32)
4235XDR_INTERCEPTOR(xdr_int64_t, u64)
4236XDR_INTERCEPTOR(xdr_uint64_t, u64)
4237XDR_INTERCEPTOR(xdr_quad_t, long long)
4238XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
4239XDR_INTERCEPTOR(xdr_bool, bool)
4240XDR_INTERCEPTOR(xdr_enum, int)
4241XDR_INTERCEPTOR(xdr_char, char)
4242XDR_INTERCEPTOR(xdr_u_char, unsigned char)
4243XDR_INTERCEPTOR(xdr_float, float)
4244XDR_INTERCEPTOR(xdr_double, double)
4245
4246// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
4247// wrapstring, sizeof
4248
4249INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
4250            unsigned maxsize) {
4251  void *ctx;
4252  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
4253  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4254    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4255    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
4256    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
4257  }
4258  // FIXME: under ASan the call below may write to freed memory and corrupt
4259  // its metadata. See
4260  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4261  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
4262  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
4263    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4264    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
4265    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
4266  }
4267  return res;
4268}
4269
4270INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
4271            unsigned maxsize) {
4272  void *ctx;
4273  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
4274  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4275    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4276    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4277  }
4278  // FIXME: under ASan the call below may write to freed memory and corrupt
4279  // its metadata. See
4280  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4281  int res = REAL(xdr_string)(xdrs, p, maxsize);
4282  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
4283    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4284    if (res && *p)
4285      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4286  }
4287  return res;
4288}
4289
4290#define INIT_XDR                               \
4291  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
4292  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
4293  COMMON_INTERCEPT_FUNCTION(xdr_short);        \
4294  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
4295  COMMON_INTERCEPT_FUNCTION(xdr_int);          \
4296  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
4297  COMMON_INTERCEPT_FUNCTION(xdr_long);         \
4298  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
4299  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
4300  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
4301  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
4302  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
4303  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
4304  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
4305  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
4306  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
4307  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
4308  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
4309  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
4310  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
4311  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
4312  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
4313  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
4314  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
4315  COMMON_INTERCEPT_FUNCTION(xdr_char);         \
4316  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
4317  COMMON_INTERCEPT_FUNCTION(xdr_float);        \
4318  COMMON_INTERCEPT_FUNCTION(xdr_double);       \
4319  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
4320  COMMON_INTERCEPT_FUNCTION(xdr_string);
4321#else
4322#define INIT_XDR
4323#endif  // SANITIZER_INTERCEPT_XDR
4324
4325#if SANITIZER_INTERCEPT_TSEARCH
4326INTERCEPTOR(void *, tsearch, void *key, void **rootp,
4327            int (*compar)(const void *, const void *)) {
4328  void *ctx;
4329  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
4330  // FIXME: under ASan the call below may write to freed memory and corrupt
4331  // its metadata. See
4332  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4333  void *res = REAL(tsearch)(key, rootp, compar);
4334  if (res && *(void **)res == key)
4335    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
4336  return res;
4337}
4338#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
4339#else
4340#define INIT_TSEARCH
4341#endif
4342
4343#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
4344    SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4345void unpoison_file(__sanitizer_FILE *fp) {
4346#if SANITIZER_HAS_STRUCT_FILE
4347  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
4348  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
4349    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
4350                                        fp->_IO_read_end - fp->_IO_read_base);
4351#endif  // SANITIZER_HAS_STRUCT_FILE
4352}
4353#endif
4354
4355#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
4356// These guys are called when a .c source is built with -O2.
4357INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
4358  void *ctx;
4359  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
4360  int res = REAL(__uflow)(fp);
4361  unpoison_file(fp);
4362  return res;
4363}
4364INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
4365  void *ctx;
4366  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
4367  int res = REAL(__underflow)(fp);
4368  unpoison_file(fp);
4369  return res;
4370}
4371INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
4372  void *ctx;
4373  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
4374  int res = REAL(__overflow)(fp, ch);
4375  unpoison_file(fp);
4376  return res;
4377}
4378INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
4379  void *ctx;
4380  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
4381  int res = REAL(__wuflow)(fp);
4382  unpoison_file(fp);
4383  return res;
4384}
4385INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
4386  void *ctx;
4387  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
4388  int res = REAL(__wunderflow)(fp);
4389  unpoison_file(fp);
4390  return res;
4391}
4392INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
4393  void *ctx;
4394  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
4395  int res = REAL(__woverflow)(fp, ch);
4396  unpoison_file(fp);
4397  return res;
4398}
4399#define INIT_LIBIO_INTERNALS               \
4400  COMMON_INTERCEPT_FUNCTION(__uflow);      \
4401  COMMON_INTERCEPT_FUNCTION(__underflow);  \
4402  COMMON_INTERCEPT_FUNCTION(__overflow);   \
4403  COMMON_INTERCEPT_FUNCTION(__wuflow);     \
4404  COMMON_INTERCEPT_FUNCTION(__wunderflow); \
4405  COMMON_INTERCEPT_FUNCTION(__woverflow);
4406#else
4407#define INIT_LIBIO_INTERNALS
4408#endif
4409
4410#if SANITIZER_INTERCEPT_FOPEN
4411INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
4412  void *ctx;
4413  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
4414  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4415  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4416  __sanitizer_FILE *res = REAL(fopen)(path, mode);
4417  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4418  if (res) unpoison_file(res);
4419  return res;
4420}
4421INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
4422  void *ctx;
4423  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
4424  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4425  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
4426  if (res) unpoison_file(res);
4427  return res;
4428}
4429INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
4430            __sanitizer_FILE *fp) {
4431  void *ctx;
4432  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
4433  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4434  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4435  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4436  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
4437  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4438  if (res) unpoison_file(res);
4439  return res;
4440}
4441#define INIT_FOPEN                   \
4442  COMMON_INTERCEPT_FUNCTION(fopen);  \
4443  COMMON_INTERCEPT_FUNCTION(fdopen); \
4444  COMMON_INTERCEPT_FUNCTION(freopen);
4445#else
4446#define INIT_FOPEN
4447#endif
4448
4449#if SANITIZER_INTERCEPT_FOPEN64
4450INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
4451  void *ctx;
4452  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
4453  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4454  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4455  __sanitizer_FILE *res = REAL(fopen64)(path, mode);
4456  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4457  if (res) unpoison_file(res);
4458  return res;
4459}
4460INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
4461            __sanitizer_FILE *fp) {
4462  void *ctx;
4463  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
4464  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4465  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4466  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4467  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
4468  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4469  if (res) unpoison_file(res);
4470  return res;
4471}
4472#define INIT_FOPEN64                  \
4473  COMMON_INTERCEPT_FUNCTION(fopen64); \
4474  COMMON_INTERCEPT_FUNCTION(freopen64);
4475#else
4476#define INIT_FOPEN64
4477#endif
4478
4479#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4480INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
4481  void *ctx;
4482  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
4483  // FIXME: under ASan the call below may write to freed memory and corrupt
4484  // its metadata. See
4485  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4486  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
4487  if (res) {
4488    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4489    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4490    unpoison_file(res);
4491    FileMetadata file = {ptr, sizeloc};
4492    SetInterceptorMetadata(res, file);
4493  }
4494  return res;
4495}
4496INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
4497            SIZE_T *sizeloc) {
4498  void *ctx;
4499  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
4500  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
4501  if (res) {
4502    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4503    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4504    unpoison_file(res);
4505    FileMetadata file = {(char **)ptr, sizeloc};
4506    SetInterceptorMetadata(res, file);
4507  }
4508  return res;
4509}
4510INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
4511            const char *mode) {
4512  void *ctx;
4513  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
4514  // FIXME: under ASan the call below may write to freed memory and corrupt
4515  // its metadata. See
4516  // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4517  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
4518  if (res) unpoison_file(res);
4519  return res;
4520}
4521#define INIT_OPEN_MEMSTREAM                   \
4522  COMMON_INTERCEPT_FUNCTION(open_memstream);  \
4523  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
4524  COMMON_INTERCEPT_FUNCTION(fmemopen);
4525#else
4526#define INIT_OPEN_MEMSTREAM
4527#endif
4528
4529#if SANITIZER_INTERCEPT_OBSTACK
4530static void initialize_obstack(__sanitizer_obstack *obstack) {
4531  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
4532  if (obstack->chunk)
4533    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
4534                                        sizeof(*obstack->chunk));
4535}
4536
4537INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
4538            int align, void *(*alloc_fn)(uptr arg, uptr sz),
4539            void (*free_fn)(uptr arg, void *p)) {
4540  void *ctx;
4541  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
4542                           free_fn);
4543  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
4544  if (res) initialize_obstack(obstack);
4545  return res;
4546}
4547INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
4548            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
4549  void *ctx;
4550  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
4551                           free_fn);
4552  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
4553  if (res) initialize_obstack(obstack);
4554  return res;
4555}
4556INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
4557  void *ctx;
4558  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
4559  REAL(_obstack_newchunk)(obstack, length);
4560  if (obstack->chunk)
4561    COMMON_INTERCEPTOR_INITIALIZE_RANGE(
4562        obstack->chunk, obstack->next_free - (char *)obstack->chunk);
4563}
4564#define INIT_OBSTACK                           \
4565  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
4566  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
4567  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
4568#else
4569#define INIT_OBSTACK
4570#endif
4571
4572#if SANITIZER_INTERCEPT_FFLUSH
4573INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
4574  void *ctx;
4575  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
4576  int res = REAL(fflush)(fp);
4577  // FIXME: handle fp == NULL
4578  if (fp) {
4579    const FileMetadata *m = GetInterceptorMetadata(fp);
4580    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4581  }
4582  return res;
4583}
4584#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
4585#else
4586#define INIT_FFLUSH
4587#endif
4588
4589#if SANITIZER_INTERCEPT_FCLOSE
4590INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
4591  void *ctx;
4592  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
4593  if (fp) {
4594    COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4595    const FileMetadata *m = GetInterceptorMetadata(fp);
4596    if (m) {
4597      COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4598      DeleteInterceptorMetadata(fp);
4599    }
4600  }
4601  return REAL(fclose)(fp);
4602}
4603#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
4604#else
4605#define INIT_FCLOSE
4606#endif
4607
4608#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
4609INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
4610  void *ctx;
4611  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
4612  void *res = REAL(dlopen)(filename, flag);
4613  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
4614  return res;
4615}
4616
4617INTERCEPTOR(int, dlclose, void *handle) {
4618  void *ctx;
4619  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
4620  int res = REAL(dlclose)(handle);
4621  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
4622  return res;
4623}
4624#define INIT_DLOPEN_DLCLOSE          \
4625  COMMON_INTERCEPT_FUNCTION(dlopen); \
4626  COMMON_INTERCEPT_FUNCTION(dlclose);
4627#else
4628#define INIT_DLOPEN_DLCLOSE
4629#endif
4630
4631static void InitializeCommonInterceptors() {
4632  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
4633  interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
4634
4635  INIT_TEXTDOMAIN;
4636  INIT_STRCMP;
4637  INIT_STRNCMP;
4638  INIT_STRCASECMP;
4639  INIT_STRNCASECMP;
4640  INIT_MEMCHR;
4641  INIT_MEMRCHR;
4642  INIT_READ;
4643  INIT_PREAD;
4644  INIT_PREAD64;
4645  INIT_READV;
4646  INIT_PREADV;
4647  INIT_PREADV64;
4648  INIT_WRITE;
4649  INIT_PWRITE;
4650  INIT_PWRITE64;
4651  INIT_WRITEV;
4652  INIT_PWRITEV;
4653  INIT_PWRITEV64;
4654  INIT_PRCTL;
4655  INIT_LOCALTIME_AND_FRIENDS;
4656  INIT_STRPTIME;
4657  INIT_SCANF;
4658  INIT_ISOC99_SCANF;
4659  INIT_PRINTF;
4660  INIT_ISOC99_PRINTF;
4661  INIT_FREXP;
4662  INIT_FREXPF_FREXPL;
4663  INIT_GETPWNAM_AND_FRIENDS;
4664  INIT_GETPWNAM_R_AND_FRIENDS;
4665  INIT_GETPWENT;
4666  INIT_FGETPWENT;
4667  INIT_GETPWENT_R;
4668  INIT_SETPWENT;
4669  INIT_CLOCK_GETTIME;
4670  INIT_GETITIMER;
4671  INIT_TIME;
4672  INIT_GLOB;
4673  INIT_WAIT;
4674  INIT_WAIT4;
4675  INIT_INET;
4676  INIT_PTHREAD_GETSCHEDPARAM;
4677  INIT_GETADDRINFO;
4678  INIT_GETNAMEINFO;
4679  INIT_GETSOCKNAME;
4680  INIT_GETHOSTBYNAME;
4681  INIT_GETHOSTBYNAME_R;
4682  INIT_GETHOSTBYNAME2_R;
4683  INIT_GETHOSTBYADDR_R;
4684  INIT_GETHOSTENT_R;
4685  INIT_GETSOCKOPT;
4686  INIT_ACCEPT;
4687  INIT_ACCEPT4;
4688  INIT_MODF;
4689  INIT_RECVMSG;
4690  INIT_GETPEERNAME;
4691  INIT_IOCTL;
4692  INIT_INET_ATON;
4693  INIT_SYSINFO;
4694  INIT_READDIR;
4695  INIT_READDIR64;
4696  INIT_PTRACE;
4697  INIT_SETLOCALE;
4698  INIT_GETCWD;
4699  INIT_GET_CURRENT_DIR_NAME;
4700  INIT_STRTOIMAX;
4701  INIT_MBSTOWCS;
4702  INIT_MBSNRTOWCS;
4703  INIT_WCSTOMBS;
4704  INIT_WCSNRTOMBS;
4705  INIT_TCGETATTR;
4706  INIT_REALPATH;
4707  INIT_CANONICALIZE_FILE_NAME;
4708  INIT_CONFSTR;
4709  INIT_SCHED_GETAFFINITY;
4710  INIT_STRERROR;
4711  INIT_STRERROR_R;
4712  INIT_XPG_STRERROR_R;
4713  INIT_SCANDIR;
4714  INIT_SCANDIR64;
4715  INIT_GETGROUPS;
4716  INIT_POLL;
4717  INIT_PPOLL;
4718  INIT_WORDEXP;
4719  INIT_SIGWAIT;
4720  INIT_SIGWAITINFO;
4721  INIT_SIGTIMEDWAIT;
4722  INIT_SIGSETOPS;
4723  INIT_SIGPENDING;
4724  INIT_SIGPROCMASK;
4725  INIT_BACKTRACE;
4726  INIT__EXIT;
4727  INIT_PTHREAD_MUTEX_LOCK;
4728  INIT_PTHREAD_MUTEX_UNLOCK;
4729  INIT_GETMNTENT;
4730  INIT_GETMNTENT_R;
4731  INIT_STATFS;
4732  INIT_STATFS64;
4733  INIT_STATVFS;
4734  INIT_STATVFS64;
4735  INIT_INITGROUPS;
4736  INIT_ETHER_NTOA_ATON;
4737  INIT_ETHER_HOST;
4738  INIT_ETHER_R;
4739  INIT_SHMCTL;
4740  INIT_RANDOM_R;
4741  INIT_PTHREAD_ATTR_GET;
4742  INIT_PTHREAD_ATTR_GETINHERITSCHED;
4743  INIT_PTHREAD_ATTR_GETAFFINITY_NP;
4744  INIT_PTHREAD_MUTEXATTR_GETPSHARED;
4745  INIT_PTHREAD_MUTEXATTR_GETTYPE;
4746  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
4747  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
4748  INIT_PTHREAD_MUTEXATTR_GETROBUST;
4749  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
4750  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
4751  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
4752  INIT_PTHREAD_CONDATTR_GETPSHARED;
4753  INIT_PTHREAD_CONDATTR_GETCLOCK;
4754  INIT_PTHREAD_BARRIERATTR_GETPSHARED;
4755  INIT_TMPNAM;
4756  INIT_TMPNAM_R;
4757  INIT_TEMPNAM;
4758  INIT_PTHREAD_SETNAME_NP;
4759  INIT_SINCOS;
4760  INIT_REMQUO;
4761  INIT_LGAMMA;
4762  INIT_LGAMMA_R;
4763  INIT_LGAMMAL_R;
4764  INIT_DRAND48_R;
4765  INIT_RAND_R;
4766  INIT_GETLINE;
4767  INIT_ICONV;
4768  INIT_TIMES;
4769  INIT_TLS_GET_ADDR;
4770  INIT_LISTXATTR;
4771  INIT_GETXATTR;
4772  INIT_GETRESID;
4773  INIT_GETIFADDRS;
4774  INIT_IF_INDEXTONAME;
4775  INIT_CAPGET;
4776  INIT_AEABI_MEM;
4777  INIT___BZERO;
4778  INIT_FTIME;
4779  INIT_XDR;
4780  INIT_TSEARCH;
4781  INIT_LIBIO_INTERNALS;
4782  INIT_FOPEN;
4783  INIT_FOPEN64;
4784  INIT_OPEN_MEMSTREAM;
4785  INIT_OBSTACK;
4786  INIT_FFLUSH;
4787  INIT_FCLOSE;
4788  INIT_DLOPEN_DLCLOSE;
4789}
4790