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