PR target/77349
[official-gcc.git] / libsanitizer / sanitizer_common / sanitizer_common_interceptors.inc
blob8223778cac428b054c68b9a4a8a8e6c7fea95610
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_DIR_ACQUIRE
19 //   COMMON_INTERCEPTOR_FD_ACQUIRE
20 //   COMMON_INTERCEPTOR_FD_RELEASE
21 //   COMMON_INTERCEPTOR_FD_ACCESS
22 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
23 //   COMMON_INTERCEPTOR_ON_DLOPEN
24 //   COMMON_INTERCEPTOR_ON_EXIT
25 //   COMMON_INTERCEPTOR_MUTEX_LOCK
26 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
27 //   COMMON_INTERCEPTOR_MUTEX_REPAIR
28 //   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
29 //   COMMON_INTERCEPTOR_HANDLE_RECVMSG
30 //   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
31 //===----------------------------------------------------------------------===//
33 #include "interception/interception.h"
34 #include "sanitizer_addrhashmap.h"
35 #include "sanitizer_placement_new.h"
36 #include "sanitizer_platform_interceptors.h"
37 #include "sanitizer_tls_get_addr.h"
39 #include <stdarg.h>
41 #if SANITIZER_INTERCEPTOR_HOOKS
42 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)                                     \
43   do {                                                                         \
44     if (f)                                                                     \
45       f(__VA_ARGS__);                                                          \
46   } while (false);
47 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)                                  \
48   extern "C" {                                                                 \
49   SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void f(__VA_ARGS__);  \
50   } // extern "C"
51 #else
52 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
53 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
55 #endif  // SANITIZER_INTERCEPTOR_HOOKS
57 #if SANITIZER_WINDOWS && !defined(va_copy)
58 #define va_copy(dst, src) ((dst) = (src))
59 #endif // _WIN32
61 #if SANITIZER_FREEBSD
62 #define pthread_setname_np pthread_set_name_np
63 #define inet_aton __inet_aton
64 #define inet_pton __inet_pton
65 #define iconv __bsd_iconv
66 #endif
68 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
69 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
70 #endif
72 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
73 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
74 #endif
76 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
77 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
78 #endif
80 #ifndef COMMON_INTERCEPTOR_MUTEX_LOCK
81 #define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {}
82 #endif
84 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
85 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
86 #endif
88 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
89 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
90 #endif
92 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
93 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
94 #endif
96 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
97 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
98 #endif
100 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
101 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
102 #endif
104 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
105 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
106 #endif
108 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
109 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
110 #endif
112 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
113 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
114   COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
115 #endif
117 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
118 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
119 #endif
121 #define COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s, len, n)       \
122     COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
123       common_flags()->strict_string_checks ? (len) + 1 : (n) )
125 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
126     COMMON_INTERCEPTOR_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
128 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
129 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) {}
130 #endif
132 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
133 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
134 #endif
136 #ifndef COMMON_INTERCEPTOR_ACQUIRE
137 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
138 #endif
140 #ifndef COMMON_INTERCEPTOR_RELEASE
141 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
142 #endif
144 struct FileMetadata {
145   // For open_memstream().
146   char **addr;
147   SIZE_T *size;
150 struct CommonInterceptorMetadata {
151   enum {
152     CIMT_INVALID = 0,
153     CIMT_FILE
154   } type;
155   union {
156     FileMetadata file;
157   };
160 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
162 static MetadataHashMap *interceptor_metadata_map;
164 #if SI_NOT_WINDOWS
165 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
166                                           const FileMetadata &file) {
167   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
168   CHECK(h.created());
169   h->type = CommonInterceptorMetadata::CIMT_FILE;
170   h->file = file;
173 UNUSED static const FileMetadata *GetInterceptorMetadata(
174     __sanitizer_FILE *addr) {
175   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
176                             /* remove */ false,
177                             /* create */ false);
178   if (h.exists()) {
179     CHECK(!h.created());
180     CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
181     return &h->file;
182   } else {
183     return 0;
184   }
187 UNUSED static void DeleteInterceptorMetadata(void *addr) {
188   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
189   CHECK(h.exists());
191 #endif  // SI_NOT_WINDOWS
193 #if SANITIZER_INTERCEPT_TEXTDOMAIN
194 INTERCEPTOR(char*, textdomain, const char *domainname) {
195   void *ctx;
196   COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
197   COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
198   char *domain = REAL(textdomain)(domainname);
199   if (domain) {
200     COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
201   }
202   return domain;
204 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
205 #else
206 #define INIT_TEXTDOMAIN
207 #endif
209 #if SANITIZER_INTERCEPT_STRCMP
210 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
211   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
214 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
215                               const char *s1, const char *s2)
217 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
218   void *ctx;
219   COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
220   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
221                              s2);
222   unsigned char c1, c2;
223   uptr i;
224   for (i = 0;; i++) {
225     c1 = (unsigned char)s1[i];
226     c2 = (unsigned char)s2[i];
227     if (c1 != c2 || c1 == '\0') break;
228   }
229   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
230   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
231   return CharCmpX(c1, c2);
234 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
235                               const char *s1, const char *s2, uptr n)
237 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
238   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
239     return internal_strncmp(s1, s2, size);
240   void *ctx;
241   COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
242   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
243                              s2, size);
244   unsigned char c1 = 0, c2 = 0;
245   uptr i;
246   for (i = 0; i < size; i++) {
247     c1 = (unsigned char)s1[i];
248     c2 = (unsigned char)s2[i];
249     if (c1 != c2 || c1 == '\0') break;
250   }
251   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
252   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
253   return CharCmpX(c1, c2);
256 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
257 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
258 #else
259 #define INIT_STRCMP
260 #define INIT_STRNCMP
261 #endif
263 #if SANITIZER_INTERCEPT_STRCASECMP
264 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
265   int c1_low = ToLower(c1);
266   int c2_low = ToLower(c2);
267   return c1_low - c2_low;
270 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
271   void *ctx;
272   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
273   unsigned char c1 = 0, c2 = 0;
274   uptr i;
275   for (i = 0;; i++) {
276     c1 = (unsigned char)s1[i];
277     c2 = (unsigned char)s2[i];
278     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
279   }
280   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
281   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
282   return CharCaseCmp(c1, c2);
285 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) {
286   void *ctx;
287   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n);
288   unsigned char c1 = 0, c2 = 0;
289   uptr i;
290   for (i = 0; i < n; i++) {
291     c1 = (unsigned char)s1[i];
292     c2 = (unsigned char)s2[i];
293     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
294   }
295   COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n));
296   COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n));
297   return CharCaseCmp(c1, c2);
300 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
301 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
302 #else
303 #define INIT_STRCASECMP
304 #define INIT_STRNCASECMP
305 #endif
307 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
308 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
309                                const char *s2) {
310     uptr len1 = REAL(strlen)(s1);
311     uptr len2 = REAL(strlen)(s2);
312     COMMON_INTERCEPTOR_READ_STRING_OF_LEN(ctx, s1, len1,
313                                           r ? r - s1 + len2 : len1 + 1);
314     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
316 #endif
318 #if SANITIZER_INTERCEPT_STRSTR
319 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
320   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
321     return internal_strstr(s1, s2);
322   void *ctx;
323   COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
324   char *r = REAL(strstr)(s1, s2);
325   if (common_flags()->intercept_strstr)
326     StrstrCheck(ctx, r, s1, s2);
327   return r;
330 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
331 #else
332 #define INIT_STRSTR
333 #endif
335 #if SANITIZER_INTERCEPT_STRCASESTR
336 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
337   void *ctx;
338   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
339   char *r = REAL(strcasestr)(s1, s2);
340   if (common_flags()->intercept_strstr)
341     StrstrCheck(ctx, r, s1, s2);
342   return r;
345 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
346 #else
347 #define INIT_STRCASESTR
348 #endif
350 #if SANITIZER_INTERCEPT_STRSPN
351 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
352   void *ctx;
353   COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
354   SIZE_T r = REAL(strspn)(s1, s2);
355   if (common_flags()->intercept_strspn) {
356     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
357     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
358   }
359   return r;
362 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
363   void *ctx;
364   COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
365   SIZE_T r = REAL(strcspn)(s1, s2);
366   if (common_flags()->intercept_strspn) {
367     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
368     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
369   }
370   return r;
373 #define INIT_STRSPN \
374   COMMON_INTERCEPT_FUNCTION(strspn); \
375   COMMON_INTERCEPT_FUNCTION(strcspn);
376 #else
377 #define INIT_STRSPN
378 #endif
380 #if SANITIZER_INTERCEPT_STRPBRK
381 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
382   void *ctx;
383   COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
384   char *r = REAL(strpbrk)(s1, s2);
385   if (common_flags()->intercept_strpbrk) {
386     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
387     COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
388         r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
389   }
390   return r;
393 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
394 #else
395 #define INIT_STRPBRK
396 #endif
398 #if SANITIZER_INTERCEPT_MEMCMP
400 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
401                               const void *s1, const void *s2, uptr n)
403 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
404   void *ctx;
405   COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
406   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
407     return internal_memcmp(a1, a2, size);
408   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
409                              a2, size);
410   if (common_flags()->intercept_memcmp) {
411     if (common_flags()->strict_memcmp) {
412       // Check the entire regions even if the first bytes of the buffers are
413       // different.
414       COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
415       COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
416       // Fallthrough to REAL(memcmp) below.
417     } else {
418       unsigned char c1 = 0, c2 = 0;
419       const unsigned char *s1 = (const unsigned char*)a1;
420       const unsigned char *s2 = (const unsigned char*)a2;
421       uptr i;
422       for (i = 0; i < size; i++) {
423         c1 = s1[i];
424         c2 = s2[i];
425         if (c1 != c2) break;
426       }
427       COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
428       COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
429       return CharCmpX(c1, c2);
430     }
431   }
432   return REAL(memcmp(a1, a2, size));
435 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
436 #else
437 #define INIT_MEMCMP
438 #endif
440 #if SANITIZER_INTERCEPT_MEMCHR
441 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
442   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
443     return internal_memchr(s, c, n);
444   void *ctx;
445   COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
446   void *res = REAL(memchr)(s, c, n);
447   uptr len = res ? (char *)res - (const char *)s + 1 : n;
448   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
449   return res;
452 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
453 #else
454 #define INIT_MEMCHR
455 #endif
457 #if SANITIZER_INTERCEPT_MEMRCHR
458 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
459   void *ctx;
460   COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
461   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
462   return REAL(memrchr)(s, c, n);
465 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
466 #else
467 #define INIT_MEMRCHR
468 #endif
470 #if SANITIZER_INTERCEPT_FREXP
471 INTERCEPTOR(double, frexp, double x, int *exp) {
472   void *ctx;
473   COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
474   // Assuming frexp() always writes to |exp|.
475   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
476   double res = REAL(frexp)(x, exp);
477   return res;
480 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
481 #else
482 #define INIT_FREXP
483 #endif  // SANITIZER_INTERCEPT_FREXP
485 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
486 INTERCEPTOR(float, frexpf, float x, int *exp) {
487   void *ctx;
488   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
489   // FIXME: under ASan the call below may write to freed memory and corrupt
490   // its metadata. See
491   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
492   float res = REAL(frexpf)(x, exp);
493   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
494   return res;
497 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
498   void *ctx;
499   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
500   // FIXME: under ASan the call below may write to freed memory and corrupt
501   // its metadata. See
502   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
503   long double res = REAL(frexpl)(x, exp);
504   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
505   return res;
508 #define INIT_FREXPF_FREXPL           \
509   COMMON_INTERCEPT_FUNCTION(frexpf); \
510   COMMON_INTERCEPT_FUNCTION(frexpl)
511 #else
512 #define INIT_FREXPF_FREXPL
513 #endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
515 #if SI_NOT_WINDOWS
516 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
517                         SIZE_T iovlen, SIZE_T maxlen) {
518   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
519     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
520     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
521     maxlen -= sz;
522   }
525 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
526                        SIZE_T iovlen, SIZE_T maxlen) {
527   COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
528   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
529     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
530     COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
531     maxlen -= sz;
532   }
534 #endif
536 #if SANITIZER_INTERCEPT_READ
537 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
538   void *ctx;
539   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
540   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
541   // FIXME: under ASan the call below may write to freed memory and corrupt
542   // its metadata. See
543   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
544   SSIZE_T res = REAL(read)(fd, ptr, count);
545   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
546   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
547   return res;
549 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
550 #else
551 #define INIT_READ
552 #endif
554 #if SANITIZER_INTERCEPT_PREAD
555 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
556   void *ctx;
557   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
558   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
559   // FIXME: under ASan the call below may write to freed memory and corrupt
560   // its metadata. See
561   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
562   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
563   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
564   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
565   return res;
567 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
568 #else
569 #define INIT_PREAD
570 #endif
572 #if SANITIZER_INTERCEPT_PREAD64
573 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
574   void *ctx;
575   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
576   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
577   // FIXME: under ASan the call below may write to freed memory and corrupt
578   // its metadata. See
579   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
580   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
581   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
582   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
583   return res;
585 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
586 #else
587 #define INIT_PREAD64
588 #endif
590 #if SANITIZER_INTERCEPT_READV
591 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
592                         int iovcnt) {
593   void *ctx;
594   COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
595   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
596   SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
597   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
598   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
599   return res;
601 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
602 #else
603 #define INIT_READV
604 #endif
606 #if SANITIZER_INTERCEPT_PREADV
607 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
608             OFF_T offset) {
609   void *ctx;
610   COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
611   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
612   SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
613   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
614   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
615   return res;
617 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
618 #else
619 #define INIT_PREADV
620 #endif
622 #if SANITIZER_INTERCEPT_PREADV64
623 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
624             OFF64_T offset) {
625   void *ctx;
626   COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
627   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
628   SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
629   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
630   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
631   return res;
633 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
634 #else
635 #define INIT_PREADV64
636 #endif
638 #if SANITIZER_INTERCEPT_WRITE
639 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
640   void *ctx;
641   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
642   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
643   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
644   SSIZE_T res = REAL(write)(fd, ptr, count);
645   // FIXME: this check should be _before_ the call to REAL(write), not after
646   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
647   return res;
649 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
650 #else
651 #define INIT_WRITE
652 #endif
654 #if SANITIZER_INTERCEPT_PWRITE
655 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
656   void *ctx;
657   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
658   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
659   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
660   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
661   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
662   return res;
664 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
665 #else
666 #define INIT_PWRITE
667 #endif
669 #if SANITIZER_INTERCEPT_PWRITE64
670 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
671             OFF64_T offset) {
672   void *ctx;
673   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
674   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
675   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
676   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
677   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
678   return res;
680 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
681 #else
682 #define INIT_PWRITE64
683 #endif
685 #if SANITIZER_INTERCEPT_WRITEV
686 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
687                         int iovcnt) {
688   void *ctx;
689   COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
690   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
691   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
692   SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
693   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
694   return res;
696 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
697 #else
698 #define INIT_WRITEV
699 #endif
701 #if SANITIZER_INTERCEPT_PWRITEV
702 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
703             OFF_T offset) {
704   void *ctx;
705   COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
706   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
707   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
708   SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
709   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
710   return res;
712 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
713 #else
714 #define INIT_PWRITEV
715 #endif
717 #if SANITIZER_INTERCEPT_PWRITEV64
718 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
719             OFF64_T offset) {
720   void *ctx;
721   COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
722   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
723   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
724   SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
725   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
726   return res;
728 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
729 #else
730 #define INIT_PWRITEV64
731 #endif
733 #if SANITIZER_INTERCEPT_PRCTL
734 INTERCEPTOR(int, prctl, int option, unsigned long arg2,
735             unsigned long arg3,                        // NOLINT
736             unsigned long arg4, unsigned long arg5) {  // NOLINT
737   void *ctx;
738   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
739   static const int PR_SET_NAME = 15;
740   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
741   if (option == PR_SET_NAME) {
742     char buff[16];
743     internal_strncpy(buff, (char *)arg2, 15);
744     buff[15] = 0;
745     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
746   }
747   return res;
749 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
750 #else
751 #define INIT_PRCTL
752 #endif  // SANITIZER_INTERCEPT_PRCTL
754 #if SANITIZER_INTERCEPT_TIME
755 INTERCEPTOR(unsigned long, time, unsigned long *t) {
756   void *ctx;
757   COMMON_INTERCEPTOR_ENTER(ctx, time, t);
758   unsigned long local_t;
759   unsigned long res = REAL(time)(&local_t);
760   if (t && res != (unsigned long)-1) {
761     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
762     *t = local_t;
763   }
764   return res;
766 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
767 #else
768 #define INIT_TIME
769 #endif  // SANITIZER_INTERCEPT_TIME
771 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
772 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
773   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
774   if (tm->tm_zone) {
775     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
776     // can point to shared memory and tsan would report a data race.
777     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
778                                         REAL(strlen(tm->tm_zone)) + 1);
779   }
781 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
782   void *ctx;
783   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
784   __sanitizer_tm *res = REAL(localtime)(timep);
785   if (res) {
786     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
787     unpoison_tm(ctx, res);
788   }
789   return res;
791 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
792   void *ctx;
793   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
794   __sanitizer_tm *res = REAL(localtime_r)(timep, result);
795   if (res) {
796     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
797     unpoison_tm(ctx, res);
798   }
799   return res;
801 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
802   void *ctx;
803   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
804   __sanitizer_tm *res = REAL(gmtime)(timep);
805   if (res) {
806     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
807     unpoison_tm(ctx, res);
808   }
809   return res;
811 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
812   void *ctx;
813   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
814   __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
815   if (res) {
816     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
817     unpoison_tm(ctx, res);
818   }
819   return res;
821 INTERCEPTOR(char *, ctime, unsigned long *timep) {
822   void *ctx;
823   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
824   // FIXME: under ASan the call below may write to freed memory and corrupt
825   // its metadata. See
826   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
827   char *res = REAL(ctime)(timep);
828   if (res) {
829     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
830     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
831   }
832   return res;
834 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
835   void *ctx;
836   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
837   // FIXME: under ASan the call below may write to freed memory and corrupt
838   // its metadata. See
839   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
840   char *res = REAL(ctime_r)(timep, result);
841   if (res) {
842     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
843     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
844   }
845   return res;
847 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
848   void *ctx;
849   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
850   // FIXME: under ASan the call below may write to freed memory and corrupt
851   // its metadata. See
852   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
853   char *res = REAL(asctime)(tm);
854   if (res) {
855     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
856     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
857   }
858   return res;
860 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
861   void *ctx;
862   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
863   // FIXME: under ASan the call below may write to freed memory and corrupt
864   // its metadata. See
865   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
866   char *res = REAL(asctime_r)(tm, result);
867   if (res) {
868     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
869     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
870   }
871   return res;
873 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
874   void *ctx;
875   COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
876   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
877   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
878   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
879   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
880   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
881   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
882   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
883   long res = REAL(mktime)(tm);
884   if (res != -1) unpoison_tm(ctx, tm);
885   return res;
887 #define INIT_LOCALTIME_AND_FRIENDS        \
888   COMMON_INTERCEPT_FUNCTION(localtime);   \
889   COMMON_INTERCEPT_FUNCTION(localtime_r); \
890   COMMON_INTERCEPT_FUNCTION(gmtime);      \
891   COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
892   COMMON_INTERCEPT_FUNCTION(ctime);       \
893   COMMON_INTERCEPT_FUNCTION(ctime_r);     \
894   COMMON_INTERCEPT_FUNCTION(asctime);     \
895   COMMON_INTERCEPT_FUNCTION(asctime_r);   \
896   COMMON_INTERCEPT_FUNCTION(mktime);
897 #else
898 #define INIT_LOCALTIME_AND_FRIENDS
899 #endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
901 #if SANITIZER_INTERCEPT_STRPTIME
902 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
903   void *ctx;
904   COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
905   if (format)
906     COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
907   // FIXME: under ASan the call below may write to freed memory and corrupt
908   // its metadata. See
909   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
910   char *res = REAL(strptime)(s, format, tm);
911   COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
912   if (res && tm) {
913     // Do not call unpoison_tm here, because strptime does not, in fact,
914     // initialize the entire struct tm. For example, tm_zone pointer is left
915     // uninitialized.
916     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
917   }
918   return res;
920 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
921 #else
922 #define INIT_STRPTIME
923 #endif
925 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
926 #include "sanitizer_common_interceptors_format.inc"
928 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
929   {                                                                            \
930     void *ctx;                                                                 \
931     va_list ap;                                                                \
932     va_start(ap, format);                                                      \
933     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
934     int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
935     va_end(ap);                                                                \
936     return res;                                                                \
937   }
939 #endif
941 #if SANITIZER_INTERCEPT_SCANF
943 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
944   {                                                                            \
945     void *ctx;                                                                 \
946     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
947     va_list aq;                                                                \
948     va_copy(aq, ap);                                                           \
949     int res = REAL(vname)(__VA_ARGS__);                                        \
950     if (res > 0)                                                               \
951       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
952     va_end(aq);                                                                \
953     return res;                                                                \
954   }
956 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
957 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
959 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
960 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
962 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
963 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
965 #if SANITIZER_INTERCEPT_ISOC99_SCANF
966 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
967 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
969 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
970             va_list ap)
971 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
973 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
974 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
975 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
977 INTERCEPTOR(int, scanf, const char *format, ...)
978 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
980 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
981 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
983 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
984 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
986 #if SANITIZER_INTERCEPT_ISOC99_SCANF
987 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
988 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
990 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
991 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
993 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
994 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
995 #endif
997 #endif
999 #if SANITIZER_INTERCEPT_SCANF
1000 #define INIT_SCANF                    \
1001   COMMON_INTERCEPT_FUNCTION(scanf);   \
1002   COMMON_INTERCEPT_FUNCTION(sscanf);  \
1003   COMMON_INTERCEPT_FUNCTION(fscanf);  \
1004   COMMON_INTERCEPT_FUNCTION(vscanf);  \
1005   COMMON_INTERCEPT_FUNCTION(vsscanf); \
1006   COMMON_INTERCEPT_FUNCTION(vfscanf);
1007 #else
1008 #define INIT_SCANF
1009 #endif
1011 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1012 #define INIT_ISOC99_SCANF                      \
1013   COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
1014   COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
1015   COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
1016   COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
1017   COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1018   COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1019 #else
1020 #define INIT_ISOC99_SCANF
1021 #endif
1023 #if SANITIZER_INTERCEPT_PRINTF
1025 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
1026   void *ctx;                                                                   \
1027   COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
1028   va_list aq;                                                                  \
1029   va_copy(aq, ap);
1031 #define VPRINTF_INTERCEPTOR_RETURN()                                           \
1032   va_end(aq);
1034 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
1035   {                                                                            \
1036     VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
1037     if (common_flags()->check_printf)                                          \
1038       printf_common(ctx, format, aq);                                          \
1039     int res = REAL(vname)(__VA_ARGS__);                                        \
1040     VPRINTF_INTERCEPTOR_RETURN();                                              \
1041     return res;                                                                \
1042   }
1044 // FIXME: under ASan the REAL() call below may write to freed memory and
1045 // corrupt its metadata. See
1046 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1047 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
1048   {                                                                            \
1049     VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
1050     if (common_flags()->check_printf) {                                        \
1051       printf_common(ctx, format, aq);                                          \
1052     }                                                                          \
1053     int res = REAL(vname)(str, __VA_ARGS__);                                   \
1054     if (res >= 0) {                                                            \
1055       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
1056     }                                                                          \
1057     VPRINTF_INTERCEPTOR_RETURN();                                              \
1058     return res;                                                                \
1059   }
1061 // FIXME: under ASan the REAL() call below may write to freed memory and
1062 // corrupt its metadata. See
1063 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1064 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
1065   {                                                                            \
1066     VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
1067     if (common_flags()->check_printf) {                                        \
1068       printf_common(ctx, format, aq);                                          \
1069     }                                                                          \
1070     int res = REAL(vname)(str, size, __VA_ARGS__);                             \
1071     if (res >= 0) {                                                            \
1072       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
1073     }                                                                          \
1074     VPRINTF_INTERCEPTOR_RETURN();                                              \
1075     return res;                                                                \
1076   }
1078 // FIXME: under ASan the REAL() call below may write to freed memory and
1079 // corrupt its metadata. See
1080 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1081 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
1082   {                                                                            \
1083     VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
1084     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
1085     if (common_flags()->check_printf) {                                        \
1086       printf_common(ctx, format, aq);                                          \
1087     }                                                                          \
1088     int res = REAL(vname)(strp, __VA_ARGS__);                                  \
1089     if (res >= 0) {                                                            \
1090       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
1091     }                                                                          \
1092     VPRINTF_INTERCEPTOR_RETURN();                                              \
1093     return res;                                                                \
1094   }
1096 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1097 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1099 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1100             va_list ap)
1101 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1103 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1104             va_list ap)
1105 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1107 #if SANITIZER_INTERCEPT_PRINTF_L
1108 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1109             const char *format, va_list ap)
1110 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1112 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1113             const char *format, ...)
1114 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1115 #endif  // SANITIZER_INTERCEPT_PRINTF_L
1117 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1118 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1120 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1121 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1123 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1124 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1125 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1127 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1128             const char *format, va_list ap)
1129 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1131 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1132             va_list ap)
1133 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1135 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1136             va_list ap)
1137 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1138                           ap)
1140 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1142 INTERCEPTOR(int, printf, const char *format, ...)
1143 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1145 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1146 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1148 INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT
1149 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT
1151 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1152 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1154 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1155 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1157 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1158 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1159 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1161 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1162             ...)
1163 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1165 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1166 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1168 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1169             const char *format, ...)
1170 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1171                         format)
1173 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1175 #endif  // SANITIZER_INTERCEPT_PRINTF
1177 #if SANITIZER_INTERCEPT_PRINTF
1178 #define INIT_PRINTF                     \
1179   COMMON_INTERCEPT_FUNCTION(printf);    \
1180   COMMON_INTERCEPT_FUNCTION(sprintf);   \
1181   COMMON_INTERCEPT_FUNCTION(snprintf);  \
1182   COMMON_INTERCEPT_FUNCTION(asprintf);  \
1183   COMMON_INTERCEPT_FUNCTION(fprintf);   \
1184   COMMON_INTERCEPT_FUNCTION(vprintf);   \
1185   COMMON_INTERCEPT_FUNCTION(vsprintf);  \
1186   COMMON_INTERCEPT_FUNCTION(vsnprintf); \
1187   COMMON_INTERCEPT_FUNCTION(vasprintf); \
1188   COMMON_INTERCEPT_FUNCTION(vfprintf);
1189 #else
1190 #define INIT_PRINTF
1191 #endif
1193 #if SANITIZER_INTERCEPT_PRINTF_L
1194 #define INIT_PRINTF_L                     \
1195   COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
1196   COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1197 #else
1198 #define INIT_PRINTF_L
1199 #endif
1201 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1202 #define INIT_ISOC99_PRINTF                       \
1203   COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
1204   COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
1205   COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
1206   COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
1207   COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
1208   COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
1209   COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1210   COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1211 #else
1212 #define INIT_ISOC99_PRINTF
1213 #endif
1215 #if SANITIZER_INTERCEPT_IOCTL
1216 #include "sanitizer_common_interceptors_ioctl.inc"
1217 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1218   // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1219   // can trigger a report and we need to be able to unwind through this
1220   // function.  On Mac in debug mode we might not have a frame pointer, because
1221   // ioctl_common_[pre|post] doesn't get inlined here.
1222   ENABLE_FRAME_POINTER;
1224   void *ctx;
1225   va_list ap;
1226   va_start(ap, request);
1227   void *arg = va_arg(ap, void *);
1228   va_end(ap);
1229   COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1231   CHECK(ioctl_initialized);
1233   // Note: TSan does not use common flags, and they are zero-initialized.
1234   // This effectively disables ioctl handling in TSan.
1235   if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1237   // Although request is unsigned long, the rest of the interceptor uses it
1238   // as just "unsigned" to save space, because we know that all values fit in
1239   // "unsigned" - they are compile-time constants.
1241   const ioctl_desc *desc = ioctl_lookup(request);
1242   ioctl_desc decoded_desc;
1243   if (!desc) {
1244     VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
1245     if (!ioctl_decode(request, &decoded_desc))
1246       Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
1247     else
1248       desc = &decoded_desc;
1249   }
1251   if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1252   int res = REAL(ioctl)(d, request, arg);
1253   // FIXME: some ioctls have different return values for success and failure.
1254   if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1255   return res;
1257 #define INIT_IOCTL \
1258   ioctl_init();    \
1259   COMMON_INTERCEPT_FUNCTION(ioctl);
1260 #else
1261 #define INIT_IOCTL
1262 #endif
1264 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \
1265     SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \
1266     SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1267 static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1268   if (pwd) {
1269     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1270     if (pwd->pw_name)
1271       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name,
1272                                           REAL(strlen)(pwd->pw_name) + 1);
1273     if (pwd->pw_passwd)
1274       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd,
1275                                           REAL(strlen)(pwd->pw_passwd) + 1);
1276 #if !SANITIZER_ANDROID
1277     if (pwd->pw_gecos)
1278       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos,
1279                                           REAL(strlen)(pwd->pw_gecos) + 1);
1280 #endif
1281 #if SANITIZER_MAC
1282     if (pwd->pw_class)
1283       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class,
1284                                           REAL(strlen)(pwd->pw_class) + 1);
1285 #endif
1286     if (pwd->pw_dir)
1287       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir,
1288                                           REAL(strlen)(pwd->pw_dir) + 1);
1289     if (pwd->pw_shell)
1290       COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell,
1291                                           REAL(strlen)(pwd->pw_shell) + 1);
1292   }
1295 static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1296   if (grp) {
1297     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1298     if (grp->gr_name)
1299       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name,
1300                                           REAL(strlen)(grp->gr_name) + 1);
1301     if (grp->gr_passwd)
1302       COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd,
1303                                           REAL(strlen)(grp->gr_passwd) + 1);
1304     char **p = grp->gr_mem;
1305     for (; *p; ++p) {
1306       COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1);
1307     }
1308     COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem,
1309                                         (p - grp->gr_mem + 1) * sizeof(*p));
1310   }
1312 #endif  // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS ||
1313         // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT ||
1314         // SANITIZER_INTERCEPT_GETPWENT_R ||
1315         // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1317 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1318 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1319   void *ctx;
1320   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1321   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1322   __sanitizer_passwd *res = REAL(getpwnam)(name);
1323   if (res) unpoison_passwd(ctx, res);
1324   return res;
1326 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1327   void *ctx;
1328   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1329   __sanitizer_passwd *res = REAL(getpwuid)(uid);
1330   if (res) unpoison_passwd(ctx, res);
1331   return res;
1333 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1334   void *ctx;
1335   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1336   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1337   __sanitizer_group *res = REAL(getgrnam)(name);
1338   if (res) unpoison_group(ctx, res);
1339   return res;
1341 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1342   void *ctx;
1343   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1344   __sanitizer_group *res = REAL(getgrgid)(gid);
1345   if (res) unpoison_group(ctx, res);
1346   return res;
1348 #define INIT_GETPWNAM_AND_FRIENDS      \
1349   COMMON_INTERCEPT_FUNCTION(getpwnam); \
1350   COMMON_INTERCEPT_FUNCTION(getpwuid); \
1351   COMMON_INTERCEPT_FUNCTION(getgrnam); \
1352   COMMON_INTERCEPT_FUNCTION(getgrgid);
1353 #else
1354 #define INIT_GETPWNAM_AND_FRIENDS
1355 #endif
1357 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1358 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1359             char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1360   void *ctx;
1361   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1362   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1363   // FIXME: under ASan the call below may write to freed memory and corrupt
1364   // its metadata. See
1365   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1366   int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1367   if (!res) {
1368     if (result && *result) unpoison_passwd(ctx, *result);
1369     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1370   }
1371   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1372   return res;
1374 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1375             SIZE_T buflen, __sanitizer_passwd **result) {
1376   void *ctx;
1377   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
1378   // FIXME: under ASan the call below may write to freed memory and corrupt
1379   // its metadata. See
1380   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1381   int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1382   if (!res) {
1383     if (result && *result) unpoison_passwd(ctx, *result);
1384     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1385   }
1386   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1387   return res;
1389 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1390             char *buf, SIZE_T buflen, __sanitizer_group **result) {
1391   void *ctx;
1392   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1393   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1394   // FIXME: under ASan the call below may write to freed memory and corrupt
1395   // its metadata. See
1396   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1397   int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1398   if (!res) {
1399     if (result && *result) unpoison_group(ctx, *result);
1400     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1401   }
1402   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1403   return res;
1405 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1406             SIZE_T buflen, __sanitizer_group **result) {
1407   void *ctx;
1408   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
1409   // FIXME: under ASan the call below may write to freed memory and corrupt
1410   // its metadata. See
1411   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1412   int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1413   if (!res) {
1414     if (result && *result) unpoison_group(ctx, *result);
1415     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1416   }
1417   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1418   return res;
1420 #define INIT_GETPWNAM_R_AND_FRIENDS      \
1421   COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1422   COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
1423   COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
1424   COMMON_INTERCEPT_FUNCTION(getgrgid_r);
1425 #else
1426 #define INIT_GETPWNAM_R_AND_FRIENDS
1427 #endif
1429 #if SANITIZER_INTERCEPT_GETPWENT
1430 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
1431   void *ctx;
1432   COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
1433   __sanitizer_passwd *res = REAL(getpwent)(dummy);
1434   if (res) unpoison_passwd(ctx, res);
1435   return res;
1437 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
1438   void *ctx;
1439   COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
1440   __sanitizer_group *res = REAL(getgrent)(dummy);
1441   if (res) unpoison_group(ctx, res);;
1442   return res;
1444 #define INIT_GETPWENT                  \
1445   COMMON_INTERCEPT_FUNCTION(getpwent); \
1446   COMMON_INTERCEPT_FUNCTION(getgrent);
1447 #else
1448 #define INIT_GETPWENT
1449 #endif
1451 #if SANITIZER_INTERCEPT_FGETPWENT
1452 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
1453   void *ctx;
1454   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
1455   __sanitizer_passwd *res = REAL(fgetpwent)(fp);
1456   if (res) unpoison_passwd(ctx, res);
1457   return res;
1459 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
1460   void *ctx;
1461   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
1462   __sanitizer_group *res = REAL(fgetgrent)(fp);
1463   if (res) unpoison_group(ctx, res);
1464   return res;
1466 #define INIT_FGETPWENT                  \
1467   COMMON_INTERCEPT_FUNCTION(fgetpwent); \
1468   COMMON_INTERCEPT_FUNCTION(fgetgrent);
1469 #else
1470 #define INIT_FGETPWENT
1471 #endif
1473 #if SANITIZER_INTERCEPT_GETPWENT_R
1474 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
1475             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1476   void *ctx;
1477   COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
1478   // FIXME: under ASan the call below may write to freed memory and corrupt
1479   // its metadata. See
1480   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1481   int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
1482   if (!res) {
1483     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1484     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1485   }
1486   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1487   return res;
1489 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
1490             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
1491   void *ctx;
1492   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
1493   // FIXME: under ASan the call below may write to freed memory and corrupt
1494   // its metadata. See
1495   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1496   int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
1497   if (!res) {
1498     if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp);
1499     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1500   }
1501   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1502   return res;
1504 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
1505             __sanitizer_group **pwbufp) {
1506   void *ctx;
1507   COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
1508   // FIXME: under ASan the call below may write to freed memory and corrupt
1509   // its metadata. See
1510   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1511   int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
1512   if (!res) {
1513     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1514     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1515   }
1516   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1517   return res;
1519 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
1520             SIZE_T buflen, __sanitizer_group **pwbufp) {
1521   void *ctx;
1522   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
1523   // FIXME: under ASan the call below may write to freed memory and corrupt
1524   // its metadata. See
1525   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1526   int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
1527   if (!res) {
1528     if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp);
1529     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
1530   }
1531   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
1532   return res;
1534 #define INIT_GETPWENT_R                   \
1535   COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
1536   COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \
1537   COMMON_INTERCEPT_FUNCTION(getgrent_r);  \
1538   COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
1539 #else
1540 #define INIT_GETPWENT_R
1541 #endif
1543 #if SANITIZER_INTERCEPT_SETPWENT
1544 // The only thing these interceptors do is disable any nested interceptors.
1545 // These functions may open nss modules and call uninstrumented functions from
1546 // them, and we don't want things like strlen() to trigger.
1547 INTERCEPTOR(void, setpwent, int dummy) {
1548   void *ctx;
1549   COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
1550   REAL(setpwent)(dummy);
1552 INTERCEPTOR(void, endpwent, int dummy) {
1553   void *ctx;
1554   COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
1555   REAL(endpwent)(dummy);
1557 INTERCEPTOR(void, setgrent, int dummy) {
1558   void *ctx;
1559   COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
1560   REAL(setgrent)(dummy);
1562 INTERCEPTOR(void, endgrent, int dummy) {
1563   void *ctx;
1564   COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
1565   REAL(endgrent)(dummy);
1567 #define INIT_SETPWENT                  \
1568   COMMON_INTERCEPT_FUNCTION(setpwent); \
1569   COMMON_INTERCEPT_FUNCTION(endpwent); \
1570   COMMON_INTERCEPT_FUNCTION(setgrent); \
1571   COMMON_INTERCEPT_FUNCTION(endgrent);
1572 #else
1573 #define INIT_SETPWENT
1574 #endif
1576 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
1577 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
1578   void *ctx;
1579   COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
1580   // FIXME: under ASan the call below may write to freed memory and corrupt
1581   // its metadata. See
1582   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1583   int res = REAL(clock_getres)(clk_id, tp);
1584   if (!res && tp) {
1585     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1586   }
1587   return res;
1589 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
1590   void *ctx;
1591   COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
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(clock_gettime)(clk_id, tp);
1596   if (!res) {
1597     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
1598   }
1599   return res;
1601 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
1602   void *ctx;
1603   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
1604   COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
1605   return REAL(clock_settime)(clk_id, tp);
1607 #define INIT_CLOCK_GETTIME                  \
1608   COMMON_INTERCEPT_FUNCTION(clock_getres);  \
1609   COMMON_INTERCEPT_FUNCTION(clock_gettime); \
1610   COMMON_INTERCEPT_FUNCTION(clock_settime);
1611 #else
1612 #define INIT_CLOCK_GETTIME
1613 #endif
1615 #if SANITIZER_INTERCEPT_GETITIMER
1616 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
1617   void *ctx;
1618   COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
1619   // FIXME: under ASan the call below may write to freed memory and corrupt
1620   // its metadata. See
1621   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1622   int res = REAL(getitimer)(which, curr_value);
1623   if (!res && curr_value) {
1624     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
1625   }
1626   return res;
1628 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
1629   void *ctx;
1630   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
1631   if (new_value)
1632     COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz);
1633   // FIXME: under ASan the call below may write to freed memory and corrupt
1634   // its metadata. See
1635   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1636   int res = REAL(setitimer)(which, new_value, old_value);
1637   if (!res && old_value) {
1638     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
1639   }
1640   return res;
1642 #define INIT_GETITIMER                  \
1643   COMMON_INTERCEPT_FUNCTION(getitimer); \
1644   COMMON_INTERCEPT_FUNCTION(setitimer);
1645 #else
1646 #define INIT_GETITIMER
1647 #endif
1649 #if SANITIZER_INTERCEPT_GLOB
1650 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
1651   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
1652   // +1 for NULL pointer at the end.
1653   if (pglob->gl_pathv)
1654     COMMON_INTERCEPTOR_WRITE_RANGE(
1655         ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
1656   for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
1657     char *p = pglob->gl_pathv[i];
1658     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
1659   }
1662 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
1664 static void wrapped_gl_closedir(void *dir) {
1665   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1666   pglob_copy->gl_closedir(dir);
1669 static void *wrapped_gl_readdir(void *dir) {
1670   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1671   return pglob_copy->gl_readdir(dir);
1674 static void *wrapped_gl_opendir(const char *s) {
1675   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
1676   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1677   return pglob_copy->gl_opendir(s);
1680 static int wrapped_gl_lstat(const char *s, void *st) {
1681   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1682   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1683   return pglob_copy->gl_lstat(s, st);
1686 static int wrapped_gl_stat(const char *s, void *st) {
1687   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
1688   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
1689   return pglob_copy->gl_stat(s, st);
1692 INTERCEPTOR(int, glob, const char *pattern, int flags,
1693             int (*errfunc)(const char *epath, int eerrno),
1694             __sanitizer_glob_t *pglob) {
1695   void *ctx;
1696   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
1697   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1698   __sanitizer_glob_t glob_copy = {
1699       0,                  0,                   0,
1700       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1701       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1702   if (flags & glob_altdirfunc) {
1703     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1704     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1705     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1706     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1707     Swap(pglob->gl_stat, glob_copy.gl_stat);
1708     pglob_copy = &glob_copy;
1709   }
1710   int res = REAL(glob)(pattern, flags, errfunc, pglob);
1711   if (flags & glob_altdirfunc) {
1712     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1713     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1714     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1715     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1716     Swap(pglob->gl_stat, glob_copy.gl_stat);
1717   }
1718   pglob_copy = 0;
1719   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1720   return res;
1723 INTERCEPTOR(int, glob64, const char *pattern, int flags,
1724             int (*errfunc)(const char *epath, int eerrno),
1725             __sanitizer_glob_t *pglob) {
1726   void *ctx;
1727   COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
1728   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
1729   __sanitizer_glob_t glob_copy = {
1730       0,                  0,                   0,
1731       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
1732       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
1733   if (flags & glob_altdirfunc) {
1734     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1735     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1736     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1737     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1738     Swap(pglob->gl_stat, glob_copy.gl_stat);
1739     pglob_copy = &glob_copy;
1740   }
1741   int res = REAL(glob64)(pattern, flags, errfunc, pglob);
1742   if (flags & glob_altdirfunc) {
1743     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
1744     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
1745     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
1746     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
1747     Swap(pglob->gl_stat, glob_copy.gl_stat);
1748   }
1749   pglob_copy = 0;
1750   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
1751   return res;
1753 #define INIT_GLOB                  \
1754   COMMON_INTERCEPT_FUNCTION(glob); \
1755   COMMON_INTERCEPT_FUNCTION(glob64);
1756 #else  // SANITIZER_INTERCEPT_GLOB
1757 #define INIT_GLOB
1758 #endif  // SANITIZER_INTERCEPT_GLOB
1760 #if SANITIZER_INTERCEPT_WAIT
1761 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
1762 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
1763 // details.
1764 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
1765   void *ctx;
1766   COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
1767   // FIXME: under ASan the call below may write to freed memory and corrupt
1768   // its metadata. See
1769   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1770   int res = REAL(wait)(status);
1771   if (res != -1 && status)
1772     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1773   return res;
1775 // On FreeBSD id_t is always 64-bit wide.
1776 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
1777 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
1778                         int options) {
1779 #else
1780 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
1781                         int options) {
1782 #endif
1783   void *ctx;
1784   COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
1785   // FIXME: under ASan the call below may write to freed memory and corrupt
1786   // its metadata. See
1787   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1788   int res = REAL(waitid)(idtype, id, infop, options);
1789   if (res != -1 && infop)
1790     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
1791   return res;
1793 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
1794   void *ctx;
1795   COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
1796   // FIXME: under ASan the call below may write to freed memory and corrupt
1797   // its metadata. See
1798   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1799   int res = REAL(waitpid)(pid, status, options);
1800   if (res != -1 && status)
1801     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1802   return res;
1804 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
1805   void *ctx;
1806   COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
1807   // FIXME: under ASan the call below may write to freed memory and corrupt
1808   // its metadata. See
1809   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1810   int res = REAL(wait3)(status, options, rusage);
1811   if (res != -1) {
1812     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1813     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1814   }
1815   return res;
1817 #if SANITIZER_ANDROID
1818 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
1819   void *ctx;
1820   COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
1821   // FIXME: under ASan the call below may write to freed memory and corrupt
1822   // its metadata. See
1823   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1824   int res = REAL(__wait4)(pid, status, options, rusage);
1825   if (res != -1) {
1826     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1827     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1828   }
1829   return res;
1831 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
1832 #else
1833 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
1834   void *ctx;
1835   COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
1836   // FIXME: under ASan the call below may write to freed memory and corrupt
1837   // its metadata. See
1838   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1839   int res = REAL(wait4)(pid, status, options, rusage);
1840   if (res != -1) {
1841     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
1842     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
1843   }
1844   return res;
1846 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
1847 #endif  // SANITIZER_ANDROID
1848 #define INIT_WAIT                     \
1849   COMMON_INTERCEPT_FUNCTION(wait);    \
1850   COMMON_INTERCEPT_FUNCTION(waitid);  \
1851   COMMON_INTERCEPT_FUNCTION(waitpid); \
1852   COMMON_INTERCEPT_FUNCTION(wait3);
1853 #else
1854 #define INIT_WAIT
1855 #define INIT_WAIT4
1856 #endif
1858 #if SANITIZER_INTERCEPT_INET
1859 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
1860   void *ctx;
1861   COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
1862   uptr sz = __sanitizer_in_addr_sz(af);
1863   if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
1864   // FIXME: figure out read size based on the address family.
1865   // FIXME: under ASan the call below may write to freed memory and corrupt
1866   // its metadata. See
1867   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1868   char *res = REAL(inet_ntop)(af, src, dst, size);
1869   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1870   return res;
1872 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
1873   void *ctx;
1874   COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
1875   COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
1876   // FIXME: figure out read size based on the address family.
1877   // FIXME: under ASan the call below may write to freed memory and corrupt
1878   // its metadata. See
1879   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1880   int res = REAL(inet_pton)(af, src, dst);
1881   if (res == 1) {
1882     uptr sz = __sanitizer_in_addr_sz(af);
1883     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1884   }
1885   return res;
1887 #define INIT_INET                       \
1888   COMMON_INTERCEPT_FUNCTION(inet_ntop); \
1889   COMMON_INTERCEPT_FUNCTION(inet_pton);
1890 #else
1891 #define INIT_INET
1892 #endif
1894 #if SANITIZER_INTERCEPT_INET
1895 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
1896   void *ctx;
1897   COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
1898   if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
1899   // FIXME: under ASan the call below may write to freed memory and corrupt
1900   // its metadata. See
1901   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1902   int res = REAL(inet_aton)(cp, dst);
1903   if (res != 0) {
1904     uptr sz = __sanitizer_in_addr_sz(af_inet);
1905     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
1906   }
1907   return res;
1909 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
1910 #else
1911 #define INIT_INET_ATON
1912 #endif
1914 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
1915 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
1916   void *ctx;
1917   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
1918   // FIXME: under ASan the call below may write to freed memory and corrupt
1919   // its metadata. See
1920   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1921   int res = REAL(pthread_getschedparam)(thread, policy, param);
1922   if (res == 0) {
1923     if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
1924     if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
1925   }
1926   return res;
1928 #define INIT_PTHREAD_GETSCHEDPARAM \
1929   COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
1930 #else
1931 #define INIT_PTHREAD_GETSCHEDPARAM
1932 #endif
1934 #if SANITIZER_INTERCEPT_GETADDRINFO
1935 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
1936             struct __sanitizer_addrinfo *hints,
1937             struct __sanitizer_addrinfo **out) {
1938   void *ctx;
1939   COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
1940   if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
1941   if (service)
1942     COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
1943   if (hints)
1944     COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
1945   // FIXME: under ASan the call below may write to freed memory and corrupt
1946   // its metadata. See
1947   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1948   int res = REAL(getaddrinfo)(node, service, hints, out);
1949   if (res == 0 && out) {
1950     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
1951     struct __sanitizer_addrinfo *p = *out;
1952     while (p) {
1953       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
1954       if (p->ai_addr)
1955         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
1956       if (p->ai_canonname)
1957         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
1958                                        REAL(strlen)(p->ai_canonname) + 1);
1959       p = p->ai_next;
1960     }
1961   }
1962   return res;
1964 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
1965 #else
1966 #define INIT_GETADDRINFO
1967 #endif
1969 #if SANITIZER_INTERCEPT_GETNAMEINFO
1970 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
1971             unsigned hostlen, char *serv, unsigned servlen, int flags) {
1972   void *ctx;
1973   COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
1974                            serv, servlen, flags);
1975   // FIXME: consider adding READ_RANGE(sockaddr, salen)
1976   // There is padding in in_addr that may make this too noisy
1977   // FIXME: under ASan the call below may write to freed memory and corrupt
1978   // its metadata. See
1979   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
1980   int res =
1981       REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
1982   if (res == 0) {
1983     if (host && hostlen)
1984       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
1985     if (serv && servlen)
1986       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
1987   }
1988   return res;
1990 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
1991 #else
1992 #define INIT_GETNAMEINFO
1993 #endif
1995 #if SANITIZER_INTERCEPT_GETSOCKNAME
1996 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
1997   void *ctx;
1998   COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
1999   COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2000   int addrlen_in = *addrlen;
2001   // FIXME: under ASan the call below may write to freed memory and corrupt
2002   // its metadata. See
2003   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2004   int res = REAL(getsockname)(sock_fd, addr, addrlen);
2005   if (res == 0) {
2006     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
2007   }
2008   return res;
2010 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2011 #else
2012 #define INIT_GETSOCKNAME
2013 #endif
2015 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2016 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2017   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2018   if (h->h_name)
2019     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
2020   char **p = h->h_aliases;
2021   while (*p) {
2022     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
2023     ++p;
2024   }
2025   COMMON_INTERCEPTOR_WRITE_RANGE(
2026       ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2027   p = h->h_addr_list;
2028   while (*p) {
2029     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2030     ++p;
2031   }
2032   COMMON_INTERCEPTOR_WRITE_RANGE(
2033       ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2035 #endif
2037 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
2038 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2039   void *ctx;
2040   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2041   struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2042   if (res) write_hostent(ctx, res);
2043   return res;
2046 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2047             int type) {
2048   void *ctx;
2049   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2050   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2051   struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2052   if (res) write_hostent(ctx, res);
2053   return res;
2056 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2057   void *ctx;
2058   COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2059   struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2060   if (res) write_hostent(ctx, res);
2061   return res;
2064 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2065   void *ctx;
2066   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2067   struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2068   if (res) write_hostent(ctx, res);
2069   return res;
2071 #define INIT_GETHOSTBYNAME                  \
2072   COMMON_INTERCEPT_FUNCTION(gethostent);    \
2073   COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2074   COMMON_INTERCEPT_FUNCTION(gethostbyname); \
2075   COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2076 #else
2077 #define INIT_GETHOSTBYNAME
2078 #endif
2080 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2081 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2082             char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2083             int *h_errnop) {
2084   void *ctx;
2085   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2086                            h_errnop);
2087   // FIXME: under ASan the call below may write to freed memory and corrupt
2088   // its metadata. See
2089   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2090   int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2091   if (result) {
2092     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2093     if (res == 0 && *result) write_hostent(ctx, *result);
2094   }
2095   if (h_errnop)
2096     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2097   return res;
2099 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2100 #else
2101 #define INIT_GETHOSTBYNAME_R
2102 #endif
2104 #if SANITIZER_INTERCEPT_GETHOSTENT_R
2105 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2106             SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2107   void *ctx;
2108   COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2109                            h_errnop);
2110   // FIXME: under ASan the call below may write to freed memory and corrupt
2111   // its metadata. See
2112   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2113   int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2114   if (result) {
2115     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2116     if (res == 0 && *result) write_hostent(ctx, *result);
2117   }
2118   if (h_errnop)
2119     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2120   return res;
2122 #define INIT_GETHOSTENT_R                  \
2123   COMMON_INTERCEPT_FUNCTION(gethostent_r);
2124 #else
2125 #define INIT_GETHOSTENT_R
2126 #endif
2128 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
2129 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
2130             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2131             __sanitizer_hostent **result, int *h_errnop) {
2132   void *ctx;
2133   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
2134                            buflen, result, h_errnop);
2135   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2136   // FIXME: under ASan the call below may write to freed memory and corrupt
2137   // its metadata. See
2138   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2139   int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
2140                                   h_errnop);
2141   if (result) {
2142     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2143     if (res == 0 && *result) write_hostent(ctx, *result);
2144   }
2145   if (h_errnop)
2146     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2147   return res;
2149 #define INIT_GETHOSTBYADDR_R                  \
2150   COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
2151 #else
2152 #define INIT_GETHOSTBYADDR_R
2153 #endif
2155 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
2156 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
2157             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2158             __sanitizer_hostent **result, int *h_errnop) {
2159   void *ctx;
2160   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
2161                            result, h_errnop);
2162   // FIXME: under ASan the call below may write to freed memory and corrupt
2163   // its metadata. See
2164   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2165   int res =
2166       REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
2167   if (result) {
2168     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2169     if (res == 0 && *result) write_hostent(ctx, *result);
2170   }
2171   if (h_errnop)
2172     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2173   return res;
2175 #define INIT_GETHOSTBYNAME2_R                  \
2176   COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
2177 #else
2178 #define INIT_GETHOSTBYNAME2_R
2179 #endif
2181 #if SANITIZER_INTERCEPT_GETSOCKOPT
2182 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2183             int *optlen) {
2184   void *ctx;
2185   COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2186                            optlen);
2187   if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
2188   // FIXME: under ASan the call below may write to freed memory and corrupt
2189   // its metadata. See
2190   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2191   int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2192   if (res == 0)
2193     if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2194   return res;
2196 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2197 #else
2198 #define INIT_GETSOCKOPT
2199 #endif
2201 #if SANITIZER_INTERCEPT_ACCEPT
2202 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
2203   void *ctx;
2204   COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
2205   unsigned addrlen0 = 0;
2206   if (addrlen) {
2207     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2208     addrlen0 = *addrlen;
2209   }
2210   int fd2 = REAL(accept)(fd, addr, addrlen);
2211   if (fd2 >= 0) {
2212     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2213     if (addr && addrlen)
2214       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2215   }
2216   return fd2;
2218 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
2219 #else
2220 #define INIT_ACCEPT
2221 #endif
2223 #if SANITIZER_INTERCEPT_ACCEPT4
2224 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
2225   void *ctx;
2226   COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
2227   unsigned addrlen0 = 0;
2228   if (addrlen) {
2229     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2230     addrlen0 = *addrlen;
2231   }
2232   // FIXME: under ASan the call below may write to freed memory and corrupt
2233   // its metadata. See
2234   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2235   int fd2 = REAL(accept4)(fd, addr, addrlen, f);
2236   if (fd2 >= 0) {
2237     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2238     if (addr && addrlen)
2239       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2240   }
2241   return fd2;
2243 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2244 #else
2245 #define INIT_ACCEPT4
2246 #endif
2248 #if SANITIZER_INTERCEPT_MODF
2249 INTERCEPTOR(double, modf, double x, double *iptr) {
2250   void *ctx;
2251   COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
2252   // FIXME: under ASan the call below may write to freed memory and corrupt
2253   // its metadata. See
2254   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2255   double res = REAL(modf)(x, iptr);
2256   if (iptr) {
2257     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2258   }
2259   return res;
2261 INTERCEPTOR(float, modff, float x, float *iptr) {
2262   void *ctx;
2263   COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
2264   // FIXME: under ASan the call below may write to freed memory and corrupt
2265   // its metadata. See
2266   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2267   float res = REAL(modff)(x, iptr);
2268   if (iptr) {
2269     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2270   }
2271   return res;
2273 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2274   void *ctx;
2275   COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
2276   // FIXME: under ASan the call below may write to freed memory and corrupt
2277   // its metadata. See
2278   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2279   long double res = REAL(modfl)(x, iptr);
2280   if (iptr) {
2281     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2282   }
2283   return res;
2285 #define INIT_MODF                   \
2286   COMMON_INTERCEPT_FUNCTION(modf);  \
2287   COMMON_INTERCEPT_FUNCTION(modff); \
2288   COMMON_INTERCEPT_FUNCTION(modfl);
2289 #else
2290 #define INIT_MODF
2291 #endif
2293 #if SANITIZER_INTERCEPT_RECVMSG
2294 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2295                          SSIZE_T maxlen) {
2296   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2297   if (msg->msg_name && msg->msg_namelen)
2298     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2299   if (msg->msg_iov && msg->msg_iovlen)
2300     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2301                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
2302   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2303   if (msg->msg_control && msg->msg_controllen)
2304     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
2307 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
2308             int flags) {
2309   void *ctx;
2310   COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
2311   // FIXME: under ASan the call below may write to freed memory and corrupt
2312   // its metadata. See
2313   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2314   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
2315   if (res >= 0) {
2316     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2317     if (msg) {
2318       write_msghdr(ctx, msg, res);
2319       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
2320     }
2321   }
2322   return res;
2324 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
2325 #else
2326 #define INIT_RECVMSG
2327 #endif
2329 #if SANITIZER_INTERCEPT_GETPEERNAME
2330 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
2331   void *ctx;
2332   COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
2333   unsigned addr_sz;
2334   if (addrlen) addr_sz = *addrlen;
2335   // FIXME: under ASan the call below may write to freed memory and corrupt
2336   // its metadata. See
2337   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2338   int res = REAL(getpeername)(sockfd, addr, addrlen);
2339   if (!res && addr && addrlen)
2340     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2341   return res;
2343 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
2344 #else
2345 #define INIT_GETPEERNAME
2346 #endif
2348 #if SANITIZER_INTERCEPT_SYSINFO
2349 INTERCEPTOR(int, sysinfo, void *info) {
2350   void *ctx;
2351   // FIXME: under ASan the call below may write to freed memory and corrupt
2352   // its metadata. See
2353   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2354   COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
2355   int res = REAL(sysinfo)(info);
2356   if (!res && info)
2357     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
2358   return res;
2360 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
2361 #else
2362 #define INIT_SYSINFO
2363 #endif
2365 #if SANITIZER_INTERCEPT_READDIR
2366 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
2367   void *ctx;
2368   COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
2369   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2370   __sanitizer_dirent *res = REAL(opendir)(path);
2371   if (res)
2372     COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
2373   return res;
2376 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
2377   void *ctx;
2378   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
2379   // FIXME: under ASan the call below may write to freed memory and corrupt
2380   // its metadata. See
2381   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2382   __sanitizer_dirent *res = REAL(readdir)(dirp);
2383   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2384   return res;
2387 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
2388             __sanitizer_dirent **result) {
2389   void *ctx;
2390   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
2391   // FIXME: under ASan the call below may write to freed memory and corrupt
2392   // its metadata. See
2393   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2394   int res = REAL(readdir_r)(dirp, entry, result);
2395   if (!res) {
2396     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2397     if (*result)
2398       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2399   }
2400   return res;
2403 #define INIT_READDIR                  \
2404   COMMON_INTERCEPT_FUNCTION(opendir); \
2405   COMMON_INTERCEPT_FUNCTION(readdir); \
2406   COMMON_INTERCEPT_FUNCTION(readdir_r);
2407 #else
2408 #define INIT_READDIR
2409 #endif
2411 #if SANITIZER_INTERCEPT_READDIR64
2412 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
2413   void *ctx;
2414   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
2415   // FIXME: under ASan the call below may write to freed memory and corrupt
2416   // its metadata. See
2417   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2418   __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
2419   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
2420   return res;
2423 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
2424             __sanitizer_dirent64 **result) {
2425   void *ctx;
2426   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
2427   // FIXME: under ASan the call below may write to freed memory and corrupt
2428   // its metadata. See
2429   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2430   int res = REAL(readdir64_r)(dirp, entry, result);
2431   if (!res) {
2432     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2433     if (*result)
2434       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
2435   }
2436   return res;
2438 #define INIT_READDIR64                  \
2439   COMMON_INTERCEPT_FUNCTION(readdir64); \
2440   COMMON_INTERCEPT_FUNCTION(readdir64_r);
2441 #else
2442 #define INIT_READDIR64
2443 #endif
2445 #if SANITIZER_INTERCEPT_PTRACE
2446 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
2447   void *ctx;
2448   COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
2449   __sanitizer_iovec local_iovec;
2451   if (data) {
2452     if (request == ptrace_setregs)
2453       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
2454     else if (request == ptrace_setfpregs)
2455       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2456     else if (request == ptrace_setfpxregs)
2457       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2458     else if (request == ptrace_setvfpregs)
2459       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2460     else if (request == ptrace_setsiginfo)
2461       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
2462     // Some kernel might zero the iovec::iov_base in case of invalid
2463     // write access.  In this case copy the invalid address for further
2464     // inspection.
2465     else if (request == ptrace_setregset || request == ptrace_getregset) {
2466       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2467       COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
2468       local_iovec = *iovec;
2469       if (request == ptrace_setregset)
2470         COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
2471     }
2472   }
2474   // FIXME: under ASan the call below may write to freed memory and corrupt
2475   // its metadata. See
2476   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2477   uptr res = REAL(ptrace)(request, pid, addr, data);
2479   if (!res && data) {
2480     // Note that PEEK* requests assign different meaning to the return value.
2481     // This function does not handle them (nor does it need to).
2482     if (request == ptrace_getregs)
2483       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
2484     else if (request == ptrace_getfpregs)
2485       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
2486     else if (request == ptrace_getfpxregs)
2487       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
2488     else if (request == ptrace_getvfpregs)
2489       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
2490     else if (request == ptrace_getsiginfo)
2491       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
2492     else if (request == ptrace_geteventmsg)
2493       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
2494     else if (request == ptrace_getregset) {
2495       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
2496       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
2497       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
2498                                      local_iovec.iov_len);
2499     }
2500   }
2501   return res;
2504 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
2505 #else
2506 #define INIT_PTRACE
2507 #endif
2509 #if SANITIZER_INTERCEPT_SETLOCALE
2510 INTERCEPTOR(char *, setlocale, int category, char *locale) {
2511   void *ctx;
2512   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
2513   if (locale)
2514     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
2515   char *res = REAL(setlocale)(category, locale);
2516   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2517   return res;
2520 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
2521 #else
2522 #define INIT_SETLOCALE
2523 #endif
2525 #if SANITIZER_INTERCEPT_GETCWD
2526 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
2527   void *ctx;
2528   COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
2529   // FIXME: under ASan the call below may write to freed memory and corrupt
2530   // its metadata. See
2531   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2532   char *res = REAL(getcwd)(buf, size);
2533   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2534   return res;
2536 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
2537 #else
2538 #define INIT_GETCWD
2539 #endif
2541 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
2542 INTERCEPTOR(char *, get_current_dir_name, int fake) {
2543   void *ctx;
2544   COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
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   char *res = REAL(get_current_dir_name)(fake);
2549   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2550   return res;
2553 #define INIT_GET_CURRENT_DIR_NAME \
2554   COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
2555 #else
2556 #define INIT_GET_CURRENT_DIR_NAME
2557 #endif
2559 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
2560   CHECK(endptr);
2561   if (nptr == *endptr) {
2562     // No digits were found at strtol call, we need to find out the last
2563     // symbol accessed by strtoll on our own.
2564     // We get this symbol by skipping leading blanks and optional +/- sign.
2565     while (IsSpace(*nptr)) nptr++;
2566     if (*nptr == '+' || *nptr == '-') nptr++;
2567     *endptr = const_cast<char *>(nptr);
2568   }
2569   CHECK(*endptr >= nptr);
2572 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
2573                              char **endptr, char *real_endptr, int base) {
2574   if (endptr) {
2575     *endptr = real_endptr;
2576     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
2577   }
2578   // If base has unsupported value, strtol can exit with EINVAL
2579   // without reading any characters. So do additional checks only
2580   // if base is valid.
2581   bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
2582   if (is_valid_base) {
2583     FixRealStrtolEndptr(nptr, &real_endptr);
2584   }
2585   COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
2586                                  (real_endptr - nptr) + 1 : 0);
2590 #if SANITIZER_INTERCEPT_STRTOIMAX
2591 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
2592   void *ctx;
2593   COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
2594   // FIXME: under ASan the call below may write to freed memory and corrupt
2595   // its metadata. See
2596   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2597   char *real_endptr;
2598   INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
2599   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2600   return res;
2603 INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
2604   void *ctx;
2605   COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
2606   // FIXME: under ASan the call below may write to freed memory and corrupt
2607   // its metadata. See
2608   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2609   char *real_endptr;
2610   INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
2611   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
2612   return res;
2615 #define INIT_STRTOIMAX                  \
2616   COMMON_INTERCEPT_FUNCTION(strtoimax); \
2617   COMMON_INTERCEPT_FUNCTION(strtoumax);
2618 #else
2619 #define INIT_STRTOIMAX
2620 #endif
2622 #if SANITIZER_INTERCEPT_MBSTOWCS
2623 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
2624   void *ctx;
2625   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
2626   // FIXME: under ASan the call below may write to freed memory and corrupt
2627   // its metadata. See
2628   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2629   SIZE_T res = REAL(mbstowcs)(dest, src, len);
2630   if (res != (SIZE_T) - 1 && dest) {
2631     SIZE_T write_cnt = res + (res < len);
2632     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2633   }
2634   return res;
2637 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
2638             void *ps) {
2639   void *ctx;
2640   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
2641   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2642   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2643   // FIXME: under ASan the call below may write to freed memory and corrupt
2644   // its metadata. See
2645   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2646   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
2647   if (res != (SIZE_T)(-1) && dest && src) {
2648     // This function, and several others, may or may not write the terminating
2649     // \0 character. They write it iff they clear *src.
2650     SIZE_T write_cnt = res + !*src;
2651     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2652   }
2653   return res;
2656 #define INIT_MBSTOWCS                  \
2657   COMMON_INTERCEPT_FUNCTION(mbstowcs); \
2658   COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
2659 #else
2660 #define INIT_MBSTOWCS
2661 #endif
2663 #if SANITIZER_INTERCEPT_MBSNRTOWCS
2664 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
2665             SIZE_T len, void *ps) {
2666   void *ctx;
2667   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
2668   if (src) {
2669     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2670     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2671   }
2672   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2673   // FIXME: under ASan the call below may write to freed memory and corrupt
2674   // its metadata. See
2675   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2676   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
2677   if (res != (SIZE_T)(-1) && dest && src) {
2678     SIZE_T write_cnt = res + !*src;
2679     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
2680   }
2681   return res;
2684 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
2685 #else
2686 #define INIT_MBSNRTOWCS
2687 #endif
2689 #if SANITIZER_INTERCEPT_WCSTOMBS
2690 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
2691   void *ctx;
2692   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
2693   // FIXME: under ASan the call below may write to freed memory and corrupt
2694   // its metadata. See
2695   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2696   SIZE_T res = REAL(wcstombs)(dest, src, len);
2697   if (res != (SIZE_T) - 1 && dest) {
2698     SIZE_T write_cnt = res + (res < len);
2699     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2700   }
2701   return res;
2704 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
2705             void *ps) {
2706   void *ctx;
2707   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
2708   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2709   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2710   // FIXME: under ASan the call below may write to freed memory and corrupt
2711   // its metadata. See
2712   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2713   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
2714   if (res != (SIZE_T) - 1 && dest && src) {
2715     SIZE_T write_cnt = res + !*src;
2716     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2717   }
2718   return res;
2721 #define INIT_WCSTOMBS                  \
2722   COMMON_INTERCEPT_FUNCTION(wcstombs); \
2723   COMMON_INTERCEPT_FUNCTION(wcsrtombs);
2724 #else
2725 #define INIT_WCSTOMBS
2726 #endif
2728 #if SANITIZER_INTERCEPT_WCSNRTOMBS
2729 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
2730             SIZE_T len, void *ps) {
2731   void *ctx;
2732   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
2733   if (src) {
2734     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
2735     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
2736   }
2737   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2738   // FIXME: under ASan the call below may write to freed memory and corrupt
2739   // its metadata. See
2740   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2741   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
2742   if (res != ((SIZE_T)-1) && dest && src) {
2743     SIZE_T write_cnt = res + !*src;
2744     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2745   }
2746   return res;
2749 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
2750 #else
2751 #define INIT_WCSNRTOMBS
2752 #endif
2755 #if SANITIZER_INTERCEPT_WCRTOMB
2756 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
2757   void *ctx;
2758   COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
2759   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
2760   // FIXME: under ASan the call below may write to freed memory and corrupt
2761   // its metadata. See
2762   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2763   SIZE_T res = REAL(wcrtomb)(dest, src, ps);
2764   if (res != ((SIZE_T)-1) && dest) {
2765     SIZE_T write_cnt = res;
2766     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
2767   }
2768   return res;
2771 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
2772 #else
2773 #define INIT_WCRTOMB
2774 #endif
2776 #if SANITIZER_INTERCEPT_TCGETATTR
2777 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
2778   void *ctx;
2779   COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
2780   // FIXME: under ASan the call below may write to freed memory and corrupt
2781   // its metadata. See
2782   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2783   int res = REAL(tcgetattr)(fd, termios_p);
2784   if (!res && termios_p)
2785     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
2786   return res;
2789 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
2790 #else
2791 #define INIT_TCGETATTR
2792 #endif
2794 #if SANITIZER_INTERCEPT_REALPATH
2795 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
2796   void *ctx;
2797   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
2798   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2800   // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
2801   // version of a versioned symbol. For realpath(), this gives us something
2802   // (called __old_realpath) that does not handle NULL in the second argument.
2803   // Handle it as part of the interceptor.
2804   char *allocated_path = nullptr;
2805   if (!resolved_path)
2806     allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
2808   char *res = REAL(realpath)(path, resolved_path);
2809   if (allocated_path && !res) WRAP(free)(allocated_path);
2810   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2811   return res;
2813 #define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
2814 #else
2815 #define INIT_REALPATH
2816 #endif
2818 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
2819 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
2820   void *ctx;
2821   COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
2822   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
2823   char *res = REAL(canonicalize_file_name)(path);
2824   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2825   return res;
2827 #define INIT_CANONICALIZE_FILE_NAME \
2828   COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
2829 #else
2830 #define INIT_CANONICALIZE_FILE_NAME
2831 #endif
2833 #if SANITIZER_INTERCEPT_CONFSTR
2834 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
2835   void *ctx;
2836   COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
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   SIZE_T res = REAL(confstr)(name, buf, len);
2841   if (buf && res)
2842     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
2843   return res;
2845 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
2846 #else
2847 #define INIT_CONFSTR
2848 #endif
2850 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
2851 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
2852   void *ctx;
2853   COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
2854   // FIXME: under ASan the call below may write to freed memory and corrupt
2855   // its metadata. See
2856   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2857   int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
2858   if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
2859   return res;
2861 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
2862 #else
2863 #define INIT_SCHED_GETAFFINITY
2864 #endif
2866 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
2867 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
2868   void *ctx;
2869   COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
2870   int res = REAL(sched_getparam)(pid, param);
2871   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
2872   return res;
2874 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
2875 #else
2876 #define INIT_SCHED_GETPARAM
2877 #endif
2879 #if SANITIZER_INTERCEPT_STRERROR
2880 INTERCEPTOR(char *, strerror, int errnum) {
2881   void *ctx;
2882   COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
2883   char *res = REAL(strerror)(errnum);
2884   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
2885   return res;
2887 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
2888 #else
2889 #define INIT_STRERROR
2890 #endif
2892 #if SANITIZER_INTERCEPT_STRERROR_R
2893 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
2894   void *ctx;
2895   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
2896   // FIXME: under ASan the call below may write to freed memory and corrupt
2897   // its metadata. See
2898   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2899   char *res = REAL(strerror_r)(errnum, buf, buflen);
2900   // There are 2 versions of strerror_r:
2901   //  * POSIX version returns 0 on success, negative error code on failure,
2902   //    writes message to buf.
2903   //  * GNU version returns message pointer, which points to either buf or some
2904   //    static storage.
2905   SIZE_T posix_res = (SIZE_T)res;
2906   if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) {
2907     // POSIX version. Spec is not clear on whether buf is NULL-terminated.
2908     // At least on OSX, buf contents are valid even when the call fails.
2909     SIZE_T sz = internal_strnlen(buf, buflen);
2910     if (sz < buflen) ++sz;
2911     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
2912   } else {
2913     // GNU version.
2914     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2915   }
2916   return res;
2918 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
2919 #else
2920 #define INIT_STRERROR_R
2921 #endif
2923 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
2924 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
2925   void *ctx;
2926   COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
2927   // FIXME: under ASan the call below may write to freed memory and corrupt
2928   // its metadata. See
2929   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2930   int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
2931   // This version always returns a null-terminated string.
2932   if (buf && buflen)
2933     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
2934   return res;
2936 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
2937 #else
2938 #define INIT_XPG_STRERROR_R
2939 #endif
2941 #if SANITIZER_INTERCEPT_SCANDIR
2942 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
2943 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
2944                                 const struct __sanitizer_dirent **);
2946 static THREADLOCAL scandir_filter_f scandir_filter;
2947 static THREADLOCAL scandir_compar_f scandir_compar;
2949 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
2950   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2951   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
2952   return scandir_filter(dir);
2955 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
2956                                   const struct __sanitizer_dirent **b) {
2957   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2958   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
2959   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
2960   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
2961   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
2962   return scandir_compar(a, b);
2965 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
2966             scandir_filter_f filter, scandir_compar_f compar) {
2967   void *ctx;
2968   COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
2969   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
2970   scandir_filter = filter;
2971   scandir_compar = compar;
2972   // FIXME: under ASan the call below may write to freed memory and corrupt
2973   // its metadata. See
2974   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
2975   int res = REAL(scandir)(dirp, namelist,
2976                           filter ? wrapped_scandir_filter : nullptr,
2977                           compar ? wrapped_scandir_compar : nullptr);
2978   scandir_filter = nullptr;
2979   scandir_compar = nullptr;
2980   if (namelist && res > 0) {
2981     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
2982     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
2983     for (int i = 0; i < res; ++i)
2984       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
2985                                      (*namelist)[i]->d_reclen);
2986   }
2987   return res;
2989 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
2990 #else
2991 #define INIT_SCANDIR
2992 #endif
2994 #if SANITIZER_INTERCEPT_SCANDIR64
2995 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
2996 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
2997                                   const struct __sanitizer_dirent64 **);
2999 static THREADLOCAL scandir64_filter_f scandir64_filter;
3000 static THREADLOCAL scandir64_compar_f scandir64_compar;
3002 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
3003   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3004   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3005   return scandir64_filter(dir);
3008 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3009                                     const struct __sanitizer_dirent64 **b) {
3010   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3011   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3012   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3013   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3014   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3015   return scandir64_compar(a, b);
3018 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3019             scandir64_filter_f filter, scandir64_compar_f compar) {
3020   void *ctx;
3021   COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3022   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3023   scandir64_filter = filter;
3024   scandir64_compar = compar;
3025   // FIXME: under ASan the call below may write to freed memory and corrupt
3026   // its metadata. See
3027   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3028   int res =
3029       REAL(scandir64)(dirp, namelist,
3030                       filter ? wrapped_scandir64_filter : nullptr,
3031                       compar ? wrapped_scandir64_compar : nullptr);
3032   scandir64_filter = nullptr;
3033   scandir64_compar = nullptr;
3034   if (namelist && res > 0) {
3035     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3036     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3037     for (int i = 0; i < res; ++i)
3038       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3039                                      (*namelist)[i]->d_reclen);
3040   }
3041   return res;
3043 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
3044 #else
3045 #define INIT_SCANDIR64
3046 #endif
3048 #if SANITIZER_INTERCEPT_GETGROUPS
3049 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
3050   void *ctx;
3051   COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
3052   // FIXME: under ASan the call below may write to freed memory and corrupt
3053   // its metadata. See
3054   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3055   int res = REAL(getgroups)(size, lst);
3056   if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
3057   return res;
3059 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
3060 #else
3061 #define INIT_GETGROUPS
3062 #endif
3064 #if SANITIZER_INTERCEPT_POLL
3065 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
3066                         __sanitizer_nfds_t nfds) {
3067   for (unsigned i = 0; i < nfds; ++i) {
3068     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
3069     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
3070   }
3073 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
3074                          __sanitizer_nfds_t nfds) {
3075   for (unsigned i = 0; i < nfds; ++i)
3076     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
3077                                    sizeof(fds[i].revents));
3080 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3081             int timeout) {
3082   void *ctx;
3083   COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
3084   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3085   int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
3086   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3087   return res;
3089 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
3090 #else
3091 #define INIT_POLL
3092 #endif
3094 #if SANITIZER_INTERCEPT_PPOLL
3095 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3096             void *timeout_ts, __sanitizer_sigset_t *sigmask) {
3097   void *ctx;
3098   COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
3099   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3100   if (timeout_ts)
3101     COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
3102   // FIXME: read sigmask when all of sigemptyset, etc are intercepted.
3103   int res =
3104       COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
3105   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3106   return res;
3108 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
3109 #else
3110 #define INIT_PPOLL
3111 #endif
3113 #if SANITIZER_INTERCEPT_WORDEXP
3114 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
3115   void *ctx;
3116   COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
3117   if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
3118   // FIXME: under ASan the call below may write to freed memory and corrupt
3119   // its metadata. See
3120   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3121   int res = REAL(wordexp)(s, p, flags);
3122   if (!res && p) {
3123     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3124     if (p->we_wordc)
3125       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
3126                                      sizeof(*p->we_wordv) * p->we_wordc);
3127     for (uptr i = 0; i < p->we_wordc; ++i) {
3128       char *w = p->we_wordv[i];
3129       if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
3130     }
3131   }
3132   return res;
3134 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
3135 #else
3136 #define INIT_WORDEXP
3137 #endif
3139 #if SANITIZER_INTERCEPT_SIGWAIT
3140 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
3141   void *ctx;
3142   COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
3143   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3144   // FIXME: under ASan the call below may write to freed memory and corrupt
3145   // its metadata. See
3146   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3147   int res = REAL(sigwait)(set, sig);
3148   if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
3149   return res;
3151 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
3152 #else
3153 #define INIT_SIGWAIT
3154 #endif
3156 #if SANITIZER_INTERCEPT_SIGWAITINFO
3157 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
3158   void *ctx;
3159   COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
3160   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3161   // FIXME: under ASan the call below may write to freed memory and corrupt
3162   // its metadata. See
3163   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3164   int res = REAL(sigwaitinfo)(set, info);
3165   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3166   return res;
3168 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
3169 #else
3170 #define INIT_SIGWAITINFO
3171 #endif
3173 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
3174 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
3175             void *timeout) {
3176   void *ctx;
3177   COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
3178   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
3179   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3180   // FIXME: under ASan the call below may write to freed memory and corrupt
3181   // its metadata. See
3182   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3183   int res = REAL(sigtimedwait)(set, info, timeout);
3184   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3185   return res;
3187 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
3188 #else
3189 #define INIT_SIGTIMEDWAIT
3190 #endif
3192 #if SANITIZER_INTERCEPT_SIGSETOPS
3193 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
3194   void *ctx;
3195   COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
3196   // FIXME: under ASan the call below may write to freed memory and corrupt
3197   // its metadata. See
3198   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3199   int res = REAL(sigemptyset)(set);
3200   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3201   return res;
3204 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
3205   void *ctx;
3206   COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
3207   // FIXME: under ASan the call below may write to freed memory and corrupt
3208   // its metadata. See
3209   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3210   int res = REAL(sigfillset)(set);
3211   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3212   return res;
3214 #define INIT_SIGSETOPS                    \
3215   COMMON_INTERCEPT_FUNCTION(sigemptyset); \
3216   COMMON_INTERCEPT_FUNCTION(sigfillset);
3217 #else
3218 #define INIT_SIGSETOPS
3219 #endif
3221 #if SANITIZER_INTERCEPT_SIGPENDING
3222 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
3223   void *ctx;
3224   COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
3225   // FIXME: under ASan the call below may write to freed memory and corrupt
3226   // its metadata. See
3227   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3228   int res = REAL(sigpending)(set);
3229   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
3230   return res;
3232 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
3233 #else
3234 #define INIT_SIGPENDING
3235 #endif
3237 #if SANITIZER_INTERCEPT_SIGPROCMASK
3238 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
3239             __sanitizer_sigset_t *oldset) {
3240   void *ctx;
3241   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
3242   // FIXME: read sigset_t when all of sigemptyset, etc are intercepted
3243   // FIXME: under ASan the call below may write to freed memory and corrupt
3244   // its metadata. See
3245   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3246   int res = REAL(sigprocmask)(how, set, oldset);
3247   if (!res && oldset)
3248     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
3249   return res;
3251 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
3252 #else
3253 #define INIT_SIGPROCMASK
3254 #endif
3256 #if SANITIZER_INTERCEPT_BACKTRACE
3257 INTERCEPTOR(int, backtrace, void **buffer, int size) {
3258   void *ctx;
3259   COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
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   int res = REAL(backtrace)(buffer, size);
3264   if (res && buffer)
3265     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
3266   return res;
3269 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
3270   void *ctx;
3271   COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
3272   if (buffer && size)
3273     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
3274   // FIXME: under ASan the call below may write to freed memory and corrupt
3275   // its metadata. See
3276   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3277   char **res = REAL(backtrace_symbols)(buffer, size);
3278   if (res && size) {
3279     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
3280     for (int i = 0; i < size; ++i)
3281       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
3282   }
3283   return res;
3285 #define INIT_BACKTRACE                  \
3286   COMMON_INTERCEPT_FUNCTION(backtrace); \
3287   COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
3288 #else
3289 #define INIT_BACKTRACE
3290 #endif
3292 #if SANITIZER_INTERCEPT__EXIT
3293 INTERCEPTOR(void, _exit, int status) {
3294   void *ctx;
3295   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
3296   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
3297   if (status == 0) status = status1;
3298   REAL(_exit)(status);
3300 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
3301 #else
3302 #define INIT__EXIT
3303 #endif
3305 #if SANITIZER_INTERCEPT_PHTREAD_MUTEX
3306 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
3307   void *ctx;
3308   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
3309   int res = REAL(pthread_mutex_lock)(m);
3310   if (res == errno_EOWNERDEAD)
3311     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
3312   if (res == 0 || res == errno_EOWNERDEAD)
3313     COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m);
3314   return res;
3317 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
3318   void *ctx;
3319   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
3320   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
3321   return REAL(pthread_mutex_unlock)(m);
3324 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
3325 #define INIT_PTHREAD_MUTEX_UNLOCK \
3326   COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
3327 #else
3328 #define INIT_PTHREAD_MUTEX_LOCK
3329 #define INIT_PTHREAD_MUTEX_UNLOCK
3330 #endif
3332 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
3333 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
3334   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
3335   if (mnt->mnt_fsname)
3336     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
3337                                    REAL(strlen)(mnt->mnt_fsname) + 1);
3338   if (mnt->mnt_dir)
3339     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
3340                                    REAL(strlen)(mnt->mnt_dir) + 1);
3341   if (mnt->mnt_type)
3342     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
3343                                    REAL(strlen)(mnt->mnt_type) + 1);
3344   if (mnt->mnt_opts)
3345     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
3346                                    REAL(strlen)(mnt->mnt_opts) + 1);
3348 #endif
3350 #if SANITIZER_INTERCEPT_GETMNTENT
3351 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
3352   void *ctx;
3353   COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
3354   __sanitizer_mntent *res = REAL(getmntent)(fp);
3355   if (res) write_mntent(ctx, res);
3356   return res;
3358 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
3359 #else
3360 #define INIT_GETMNTENT
3361 #endif
3363 #if SANITIZER_INTERCEPT_GETMNTENT_R
3364 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
3365             __sanitizer_mntent *mntbuf, char *buf, int buflen) {
3366   void *ctx;
3367   COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
3368   __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
3369   if (res) write_mntent(ctx, res);
3370   return res;
3372 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
3373 #else
3374 #define INIT_GETMNTENT_R
3375 #endif
3377 #if SANITIZER_INTERCEPT_STATFS
3378 INTERCEPTOR(int, statfs, char *path, void *buf) {
3379   void *ctx;
3380   COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
3381   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3382   // FIXME: under ASan the call below may write to freed memory and corrupt
3383   // its metadata. See
3384   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3385   int res = REAL(statfs)(path, buf);
3386   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3387   return res;
3389 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
3390   void *ctx;
3391   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
3392   // FIXME: under ASan the call below may write to freed memory and corrupt
3393   // its metadata. See
3394   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3395   int res = REAL(fstatfs)(fd, buf);
3396   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
3397   return res;
3399 #define INIT_STATFS                  \
3400   COMMON_INTERCEPT_FUNCTION(statfs); \
3401   COMMON_INTERCEPT_FUNCTION(fstatfs);
3402 #else
3403 #define INIT_STATFS
3404 #endif
3406 #if SANITIZER_INTERCEPT_STATFS64
3407 INTERCEPTOR(int, statfs64, char *path, void *buf) {
3408   void *ctx;
3409   COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
3410   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3411   // FIXME: under ASan the call below may write to freed memory and corrupt
3412   // its metadata. See
3413   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3414   int res = REAL(statfs64)(path, buf);
3415   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3416   return res;
3418 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
3419   void *ctx;
3420   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
3421   // FIXME: under ASan the call below may write to freed memory and corrupt
3422   // its metadata. See
3423   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3424   int res = REAL(fstatfs64)(fd, buf);
3425   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
3426   return res;
3428 #define INIT_STATFS64                  \
3429   COMMON_INTERCEPT_FUNCTION(statfs64); \
3430   COMMON_INTERCEPT_FUNCTION(fstatfs64);
3431 #else
3432 #define INIT_STATFS64
3433 #endif
3435 #if SANITIZER_INTERCEPT_STATVFS
3436 INTERCEPTOR(int, statvfs, char *path, void *buf) {
3437   void *ctx;
3438   COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
3439   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3440   // FIXME: under ASan the call below may write to freed memory and corrupt
3441   // its metadata. See
3442   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3443   int res = REAL(statvfs)(path, buf);
3444   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3445   return res;
3447 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
3448   void *ctx;
3449   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
3450   // FIXME: under ASan the call below may write to freed memory and corrupt
3451   // its metadata. See
3452   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3453   int res = REAL(fstatvfs)(fd, buf);
3454   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
3455   return res;
3457 #define INIT_STATVFS                  \
3458   COMMON_INTERCEPT_FUNCTION(statvfs); \
3459   COMMON_INTERCEPT_FUNCTION(fstatvfs);
3460 #else
3461 #define INIT_STATVFS
3462 #endif
3464 #if SANITIZER_INTERCEPT_STATVFS64
3465 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
3466   void *ctx;
3467   COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
3468   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3469   // FIXME: under ASan the call below may write to freed memory and corrupt
3470   // its metadata. See
3471   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3472   int res = REAL(statvfs64)(path, buf);
3473   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3474   return res;
3476 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
3477   void *ctx;
3478   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
3479   // FIXME: under ASan the call below may write to freed memory and corrupt
3480   // its metadata. See
3481   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3482   int res = REAL(fstatvfs64)(fd, buf);
3483   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
3484   return res;
3486 #define INIT_STATVFS64                  \
3487   COMMON_INTERCEPT_FUNCTION(statvfs64); \
3488   COMMON_INTERCEPT_FUNCTION(fstatvfs64);
3489 #else
3490 #define INIT_STATVFS64
3491 #endif
3493 #if SANITIZER_INTERCEPT_INITGROUPS
3494 INTERCEPTOR(int, initgroups, char *user, u32 group) {
3495   void *ctx;
3496   COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
3497   if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
3498   int res = REAL(initgroups)(user, group);
3499   return res;
3501 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
3502 #else
3503 #define INIT_INITGROUPS
3504 #endif
3506 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
3507 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
3508   void *ctx;
3509   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
3510   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3511   char *res = REAL(ether_ntoa)(addr);
3512   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3513   return res;
3515 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
3516   void *ctx;
3517   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
3518   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3519   __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
3520   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
3521   return res;
3523 #define INIT_ETHER_NTOA_ATON             \
3524   COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
3525   COMMON_INTERCEPT_FUNCTION(ether_aton);
3526 #else
3527 #define INIT_ETHER_NTOA_ATON
3528 #endif
3530 #if SANITIZER_INTERCEPT_ETHER_HOST
3531 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
3532   void *ctx;
3533   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
3534   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3535   // FIXME: under ASan the call below may write to freed memory and corrupt
3536   // its metadata. See
3537   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3538   int res = REAL(ether_ntohost)(hostname, addr);
3539   if (!res && hostname)
3540     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3541   return res;
3543 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
3544   void *ctx;
3545   COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
3546   if (hostname)
3547     COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3548   // FIXME: under ASan the call below may write to freed memory and corrupt
3549   // its metadata. See
3550   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3551   int res = REAL(ether_hostton)(hostname, addr);
3552   if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3553   return res;
3555 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
3556             char *hostname) {
3557   void *ctx;
3558   COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
3559   if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
3560   // FIXME: under ASan the call below may write to freed memory and corrupt
3561   // its metadata. See
3562   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3563   int res = REAL(ether_line)(line, addr, hostname);
3564   if (!res) {
3565     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3566     if (hostname)
3567       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
3568   }
3569   return res;
3571 #define INIT_ETHER_HOST                     \
3572   COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
3573   COMMON_INTERCEPT_FUNCTION(ether_hostton); \
3574   COMMON_INTERCEPT_FUNCTION(ether_line);
3575 #else
3576 #define INIT_ETHER_HOST
3577 #endif
3579 #if SANITIZER_INTERCEPT_ETHER_R
3580 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
3581   void *ctx;
3582   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
3583   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
3584   // FIXME: under ASan the call below may write to freed memory and corrupt
3585   // its metadata. See
3586   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3587   char *res = REAL(ether_ntoa_r)(addr, buf);
3588   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3589   return res;
3591 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
3592             __sanitizer_ether_addr *addr) {
3593   void *ctx;
3594   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
3595   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3596   // FIXME: under ASan the call below may write to freed memory and corrupt
3597   // its metadata. See
3598   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3599   __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
3600   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
3601   return res;
3603 #define INIT_ETHER_R                       \
3604   COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
3605   COMMON_INTERCEPT_FUNCTION(ether_aton_r);
3606 #else
3607 #define INIT_ETHER_R
3608 #endif
3610 #if SANITIZER_INTERCEPT_SHMCTL
3611 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
3612   void *ctx;
3613   COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
3614   // FIXME: under ASan the call below may write to freed memory and corrupt
3615   // its metadata. See
3616   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3617   int res = REAL(shmctl)(shmid, cmd, buf);
3618   if (res >= 0) {
3619     unsigned sz = 0;
3620     if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
3621       sz = sizeof(__sanitizer_shmid_ds);
3622     else if (cmd == shmctl_ipc_info)
3623       sz = struct_shminfo_sz;
3624     else if (cmd == shmctl_shm_info)
3625       sz = struct_shm_info_sz;
3626     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3627   }
3628   return res;
3630 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
3631 #else
3632 #define INIT_SHMCTL
3633 #endif
3635 #if SANITIZER_INTERCEPT_RANDOM_R
3636 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
3637   void *ctx;
3638   COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
3639   // FIXME: under ASan the call below may write to freed memory and corrupt
3640   // its metadata. See
3641   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3642   int res = REAL(random_r)(buf, result);
3643   if (!res && result)
3644     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3645   return res;
3647 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
3648 #else
3649 #define INIT_RANDOM_R
3650 #endif
3652 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
3653 // its metadata. See
3654 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3655 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
3656     SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
3657     SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
3658     SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
3659     SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
3660     SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
3661 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
3662   INTERCEPTOR(int, fn, void *attr, void *r) {                  \
3663     void *ctx;                                                 \
3664     COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
3665     int res = REAL(fn)(attr, r);                               \
3666     if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
3667     return res;                                                \
3668   }
3669 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
3670   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
3671 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
3672   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
3673 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
3674   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
3675 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
3676   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
3677 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
3678   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
3679 #endif
3681 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
3682 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
3683 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
3684 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
3685 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
3686 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
3687 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
3688 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
3689   void *ctx;
3690   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
3691   // FIXME: under ASan the call below may write to freed memory and corrupt
3692   // its metadata. See
3693   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3694   int res = REAL(pthread_attr_getstack)(attr, addr, size);
3695   if (!res) {
3696     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
3697     if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
3698   }
3699   return res;
3702 // We may need to call the real pthread_attr_getstack from the run-time
3703 // in sanitizer_common, but we don't want to include the interception headers
3704 // there. So, just define this function here.
3705 namespace __sanitizer {
3706 extern "C" {
3707 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
3708   return REAL(pthread_attr_getstack)(attr, addr, size);
3710 }  // extern "C"
3711 }  // namespace __sanitizer
3713 #define INIT_PTHREAD_ATTR_GET                             \
3714   COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
3715   COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
3716   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam);  \
3717   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \
3718   COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
3719   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
3720   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
3721 #else
3722 #define INIT_PTHREAD_ATTR_GET
3723 #endif
3725 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
3726 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
3728 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
3729   COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
3730 #else
3731 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
3732 #endif
3734 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
3735 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
3736             void *cpuset) {
3737   void *ctx;
3738   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
3739                            cpuset);
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(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
3744   if (!res && cpusetsize && cpuset)
3745     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
3746   return res;
3749 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
3750   COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
3751 #else
3752 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
3753 #endif
3755 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
3756 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
3757 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
3758   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
3759 #else
3760 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
3761 #endif
3763 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
3764 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
3765 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
3766   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
3767 #else
3768 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
3769 #endif
3771 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
3772 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
3773 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
3774   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
3775 #else
3776 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
3777 #endif
3779 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3780 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
3781 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
3782   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
3783 #else
3784 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
3785 #endif
3787 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
3788 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
3789 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
3790   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
3791 #else
3792 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
3793 #endif
3795 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
3796 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
3797 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
3798   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
3799 #else
3800 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
3801 #endif
3803 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
3804 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
3805 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
3806   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
3807 #else
3808 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
3809 #endif
3811 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
3812 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
3813 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
3814   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
3815 #else
3816 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
3817 #endif
3819 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
3820 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
3821 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
3822   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
3823 #else
3824 #define INIT_PTHREAD_CONDATTR_GETPSHARED
3825 #endif
3827 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
3828 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
3829 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
3830   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
3831 #else
3832 #define INIT_PTHREAD_CONDATTR_GETCLOCK
3833 #endif
3835 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
3836 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
3837 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
3838   COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
3839 #else
3840 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
3841 #endif
3843 #if SANITIZER_INTERCEPT_TMPNAM
3844 INTERCEPTOR(char *, tmpnam, char *s) {
3845   void *ctx;
3846   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
3847   char *res = REAL(tmpnam)(s);
3848   if (res) {
3849     if (s)
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       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3854     else
3855       COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3856   }
3857   return res;
3859 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
3860 #else
3861 #define INIT_TMPNAM
3862 #endif
3864 #if SANITIZER_INTERCEPT_TMPNAM_R
3865 INTERCEPTOR(char *, tmpnam_r, char *s) {
3866   void *ctx;
3867   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
3868   // FIXME: under ASan the call below may write to freed memory and corrupt
3869   // its metadata. See
3870   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3871   char *res = REAL(tmpnam_r)(s);
3872   if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
3873   return res;
3875 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
3876 #else
3877 #define INIT_TMPNAM_R
3878 #endif
3880 #if SANITIZER_INTERCEPT_TEMPNAM
3881 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
3882   void *ctx;
3883   COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
3884   if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
3885   if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
3886   char *res = REAL(tempnam)(dir, pfx);
3887   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3888   return res;
3890 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
3891 #else
3892 #define INIT_TEMPNAM
3893 #endif
3895 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
3896 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
3897   void *ctx;
3898   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
3899   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
3900   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
3901   return REAL(pthread_setname_np)(thread, name);
3903 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
3904 #else
3905 #define INIT_PTHREAD_SETNAME_NP
3906 #endif
3908 #if SANITIZER_INTERCEPT_SINCOS
3909 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
3910   void *ctx;
3911   COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
3912   // FIXME: under ASan the call below may write to freed memory and corrupt
3913   // its metadata. See
3914   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3915   REAL(sincos)(x, sin, cos);
3916   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3917   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3919 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
3920   void *ctx;
3921   COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
3922   // FIXME: under ASan the call below may write to freed memory and corrupt
3923   // its metadata. See
3924   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3925   REAL(sincosf)(x, sin, cos);
3926   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3927   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3929 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
3930   void *ctx;
3931   COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
3932   // FIXME: under ASan the call below may write to freed memory and corrupt
3933   // its metadata. See
3934   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3935   REAL(sincosl)(x, sin, cos);
3936   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
3937   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
3939 #define INIT_SINCOS                   \
3940   COMMON_INTERCEPT_FUNCTION(sincos);  \
3941   COMMON_INTERCEPT_FUNCTION(sincosf); \
3942   COMMON_INTERCEPT_FUNCTION(sincosl);
3943 #else
3944 #define INIT_SINCOS
3945 #endif
3947 #if SANITIZER_INTERCEPT_REMQUO
3948 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
3949   void *ctx;
3950   COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
3951   // FIXME: under ASan the call below may write to freed memory and corrupt
3952   // its metadata. See
3953   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3954   double res = REAL(remquo)(x, y, quo);
3955   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3956   return res;
3958 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
3959   void *ctx;
3960   COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
3961   // FIXME: under ASan the call below may write to freed memory and corrupt
3962   // its metadata. See
3963   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3964   float res = REAL(remquof)(x, y, quo);
3965   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3966   return res;
3968 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
3969   void *ctx;
3970   COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
3971   // FIXME: under ASan the call below may write to freed memory and corrupt
3972   // its metadata. See
3973   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
3974   long double res = REAL(remquol)(x, y, quo);
3975   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
3976   return res;
3978 #define INIT_REMQUO                   \
3979   COMMON_INTERCEPT_FUNCTION(remquo);  \
3980   COMMON_INTERCEPT_FUNCTION(remquof); \
3981   COMMON_INTERCEPT_FUNCTION(remquol);
3982 #else
3983 #define INIT_REMQUO
3984 #endif
3986 #if SANITIZER_INTERCEPT_LGAMMA
3987 extern int signgam;
3988 INTERCEPTOR(double, lgamma, double x) {
3989   void *ctx;
3990   COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
3991   double res = REAL(lgamma)(x);
3992   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
3993   return res;
3995 INTERCEPTOR(float, lgammaf, float x) {
3996   void *ctx;
3997   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
3998   float res = REAL(lgammaf)(x);
3999   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4000   return res;
4002 INTERCEPTOR(long double, lgammal, long double x) {
4003   void *ctx;
4004   COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
4005   long double res = REAL(lgammal)(x);
4006   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4007   return res;
4009 #define INIT_LGAMMA                   \
4010   COMMON_INTERCEPT_FUNCTION(lgamma);  \
4011   COMMON_INTERCEPT_FUNCTION(lgammaf); \
4012   COMMON_INTERCEPT_FUNCTION(lgammal);
4013 #else
4014 #define INIT_LGAMMA
4015 #endif
4017 #if SANITIZER_INTERCEPT_LGAMMA_R
4018 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
4019   void *ctx;
4020   COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
4021   // FIXME: under ASan the call below may write to freed memory and corrupt
4022   // its metadata. See
4023   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4024   double res = REAL(lgamma_r)(x, signp);
4025   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4026   return res;
4028 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
4029   void *ctx;
4030   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
4031   // FIXME: under ASan the call below may write to freed memory and corrupt
4032   // its metadata. See
4033   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4034   float res = REAL(lgammaf_r)(x, signp);
4035   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4036   return res;
4038 #define INIT_LGAMMA_R                   \
4039   COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
4040   COMMON_INTERCEPT_FUNCTION(lgammaf_r);
4041 #else
4042 #define INIT_LGAMMA_R
4043 #endif
4045 #if SANITIZER_INTERCEPT_LGAMMAL_R
4046 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
4047   void *ctx;
4048   COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
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   long double res = REAL(lgammal_r)(x, signp);
4053   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
4054   return res;
4056 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION(lgammal_r);
4057 #else
4058 #define INIT_LGAMMAL_R
4059 #endif
4061 #if SANITIZER_INTERCEPT_DRAND48_R
4062 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
4063   void *ctx;
4064   COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
4065   // FIXME: under ASan the call below may write to freed memory and corrupt
4066   // its metadata. See
4067   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4068   int res = REAL(drand48_r)(buffer, result);
4069   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4070   return res;
4072 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
4073   void *ctx;
4074   COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
4075   // FIXME: under ASan the call below may write to freed memory and corrupt
4076   // its metadata. See
4077   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4078   int res = REAL(lrand48_r)(buffer, result);
4079   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4080   return res;
4082 #define INIT_DRAND48_R                  \
4083   COMMON_INTERCEPT_FUNCTION(drand48_r); \
4084   COMMON_INTERCEPT_FUNCTION(lrand48_r);
4085 #else
4086 #define INIT_DRAND48_R
4087 #endif
4089 #if SANITIZER_INTERCEPT_RAND_R
4090 INTERCEPTOR(int, rand_r, unsigned *seedp) {
4091   void *ctx;
4092   COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
4093   COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
4094   return REAL(rand_r)(seedp);
4096 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
4097 #else
4098 #define INIT_RAND_R
4099 #endif
4101 #if SANITIZER_INTERCEPT_GETLINE
4102 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
4103   void *ctx;
4104   COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
4105   // FIXME: under ASan the call below may write to freed memory and corrupt
4106   // its metadata. See
4107   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4108   SSIZE_T res = REAL(getline)(lineptr, n, stream);
4109   if (res > 0) {
4110     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
4111     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
4112     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
4113   }
4114   return res;
4117 // FIXME: under ASan the call below may write to freed memory and corrupt its
4118 // metadata. See
4119 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4120 #define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
4121   {                                                                            \
4122     void *ctx;                                                                 \
4123     COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
4124     SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
4125     if (res > 0) {                                                             \
4126       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
4127       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
4128       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
4129     }                                                                          \
4130     return res;                                                                \
4131   }
4133 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
4134             void *stream)
4135 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
4137 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
4138 // with its own body.
4139 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
4140             void *stream)
4141 GETDELIM_INTERCEPTOR_IMPL(getdelim)
4143 #define INIT_GETLINE                     \
4144   COMMON_INTERCEPT_FUNCTION(getline);    \
4145   COMMON_INTERCEPT_FUNCTION(__getdelim); \
4146   COMMON_INTERCEPT_FUNCTION(getdelim);
4147 #else
4148 #define INIT_GETLINE
4149 #endif
4151 #if SANITIZER_INTERCEPT_ICONV
4152 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
4153             char **outbuf, SIZE_T *outbytesleft) {
4154   void *ctx;
4155   COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
4156                            outbytesleft);
4157   if (inbytesleft)
4158     COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
4159   if (inbuf && inbytesleft)
4160     COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
4161   if (outbytesleft)
4162     COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
4163   void *outbuf_orig = outbuf ? *outbuf : nullptr;
4164   // FIXME: under ASan the call below may write to freed memory and corrupt
4165   // its metadata. See
4166   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4167   SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
4168   if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) {
4169     SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
4170     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
4171   }
4172   return res;
4174 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
4175 #else
4176 #define INIT_ICONV
4177 #endif
4179 #if SANITIZER_INTERCEPT_TIMES
4180 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
4181   void *ctx;
4182   COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
4183   // FIXME: under ASan the call below may write to freed memory and corrupt
4184   // its metadata. See
4185   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4186   __sanitizer_clock_t res = REAL(times)(tms);
4187   if (res != (__sanitizer_clock_t)-1 && tms)
4188     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
4189   return res;
4191 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
4192 #else
4193 #define INIT_TIMES
4194 #endif
4196 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
4197 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
4198 // If you see any crashes around this functions, there are 2 known issues with
4199 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
4200 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
4201 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
4202 // to access thread local variables (it should not happen normally,
4203 // because sanitizers use initial-exec tls model).
4204 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
4205   void *ctx;
4206   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
4207   void *res = REAL(__tls_get_addr)(arg);
4208   uptr tls_begin, tls_end;
4209   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
4210   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
4211   if (dtv) {
4212     // New DTLS block has been allocated.
4213     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
4214   }
4215   return res;
4217 #else
4218 #define INIT_TLS_GET_ADDR
4219 #endif
4221 #if SANITIZER_INTERCEPT_LISTXATTR
4222 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
4223   void *ctx;
4224   COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
4225   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4226   // FIXME: under ASan the call below may write to freed memory and corrupt
4227   // its metadata. See
4228   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4229   SSIZE_T res = REAL(listxattr)(path, list, size);
4230   // Here and below, size == 0 is a special case where nothing is written to the
4231   // buffer, and res contains the desired buffer size.
4232   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4233   return res;
4235 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
4236   void *ctx;
4237   COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
4238   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4239   // FIXME: under ASan the call below may write to freed memory and corrupt
4240   // its metadata. See
4241   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4242   SSIZE_T res = REAL(llistxattr)(path, list, size);
4243   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4244   return res;
4246 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
4247   void *ctx;
4248   COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
4249   // FIXME: under ASan the call below may write to freed memory and corrupt
4250   // its metadata. See
4251   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4252   SSIZE_T res = REAL(flistxattr)(fd, list, size);
4253   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
4254   return res;
4256 #define INIT_LISTXATTR                   \
4257   COMMON_INTERCEPT_FUNCTION(listxattr);  \
4258   COMMON_INTERCEPT_FUNCTION(llistxattr); \
4259   COMMON_INTERCEPT_FUNCTION(flistxattr);
4260 #else
4261 #define INIT_LISTXATTR
4262 #endif
4264 #if SANITIZER_INTERCEPT_GETXATTR
4265 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
4266             SIZE_T size) {
4267   void *ctx;
4268   COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
4269   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4270   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4271   // FIXME: under ASan the call below may write to freed memory and corrupt
4272   // its metadata. See
4273   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4274   SSIZE_T res = REAL(getxattr)(path, name, value, size);
4275   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4276   return res;
4278 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
4279             SIZE_T size) {
4280   void *ctx;
4281   COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
4282   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4283   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4284   // FIXME: under ASan the call below may write to freed memory and corrupt
4285   // its metadata. See
4286   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4287   SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
4288   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4289   return res;
4291 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
4292             SIZE_T size) {
4293   void *ctx;
4294   COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
4295   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
4296   // FIXME: under ASan the call below may write to freed memory and corrupt
4297   // its metadata. See
4298   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4299   SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
4300   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
4301   return res;
4303 #define INIT_GETXATTR                   \
4304   COMMON_INTERCEPT_FUNCTION(getxattr);  \
4305   COMMON_INTERCEPT_FUNCTION(lgetxattr); \
4306   COMMON_INTERCEPT_FUNCTION(fgetxattr);
4307 #else
4308 #define INIT_GETXATTR
4309 #endif
4311 #if SANITIZER_INTERCEPT_GETRESID
4312 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
4313   void *ctx;
4314   COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
4315   // FIXME: under ASan the call below may write to freed memory and corrupt
4316   // its metadata. See
4317   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4318   int res = REAL(getresuid)(ruid, euid, suid);
4319   if (res >= 0) {
4320     if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
4321     if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
4322     if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
4323   }
4324   return res;
4326 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
4327   void *ctx;
4328   COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
4329   // FIXME: under ASan the call below may write to freed memory and corrupt
4330   // its metadata. See
4331   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4332   int res = REAL(getresgid)(rgid, egid, sgid);
4333   if (res >= 0) {
4334     if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
4335     if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
4336     if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
4337   }
4338   return res;
4340 #define INIT_GETRESID                   \
4341   COMMON_INTERCEPT_FUNCTION(getresuid); \
4342   COMMON_INTERCEPT_FUNCTION(getresgid);
4343 #else
4344 #define INIT_GETRESID
4345 #endif
4347 #if SANITIZER_INTERCEPT_GETIFADDRS
4348 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
4349 // intercept freeifaddrs(). If that ceases to be the case, we might need to
4350 // intercept it to poison the memory again.
4351 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
4352   void *ctx;
4353   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
4354   // FIXME: under ASan the call below may write to freed memory and corrupt
4355   // its metadata. See
4356   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4357   int res = REAL(getifaddrs)(ifap);
4358   if (res == 0 && ifap) {
4359     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
4360     __sanitizer_ifaddrs *p = *ifap;
4361     while (p) {
4362       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
4363       if (p->ifa_name)
4364         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
4365                                        REAL(strlen)(p->ifa_name) + 1);
4366       if (p->ifa_addr)
4367         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
4368       if (p->ifa_netmask)
4369         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
4370       // On Linux this is a union, but the other member also points to a
4371       // struct sockaddr, so the following is sufficient.
4372       if (p->ifa_dstaddr)
4373         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
4374       // FIXME(smatveev): Unpoison p->ifa_data as well.
4375       p = p->ifa_next;
4376     }
4377   }
4378   return res;
4380 #define INIT_GETIFADDRS                  \
4381   COMMON_INTERCEPT_FUNCTION(getifaddrs);
4382 #else
4383 #define INIT_GETIFADDRS
4384 #endif
4386 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
4387 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
4388   void *ctx;
4389   COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
4390   // FIXME: under ASan the call below may write to freed memory and corrupt
4391   // its metadata. See
4392   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4393   char *res = REAL(if_indextoname)(ifindex, ifname);
4394   if (res && ifname)
4395     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4396   return res;
4398 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
4399   void *ctx;
4400   COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
4401   if (ifname)
4402     COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
4403   return REAL(if_nametoindex)(ifname);
4405 #define INIT_IF_INDEXTONAME                  \
4406   COMMON_INTERCEPT_FUNCTION(if_indextoname); \
4407   COMMON_INTERCEPT_FUNCTION(if_nametoindex);
4408 #else
4409 #define INIT_IF_INDEXTONAME
4410 #endif
4412 #if SANITIZER_INTERCEPT_CAPGET
4413 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
4414   void *ctx;
4415   COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
4416   if (hdrp)
4417     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4418   // FIXME: under ASan the call below may write to freed memory and corrupt
4419   // its metadata. See
4420   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4421   int res = REAL(capget)(hdrp, datap);
4422   if (res == 0 && datap)
4423     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
4424   // We can also return -1 and write to hdrp->version if the version passed in
4425   // hdrp->version is unsupported. But that's not a trivial condition to check,
4426   // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
4427   return res;
4429 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
4430   void *ctx;
4431   COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
4432   if (hdrp)
4433     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
4434   if (datap)
4435     COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
4436   return REAL(capset)(hdrp, datap);
4438 #define INIT_CAPGET                  \
4439   COMMON_INTERCEPT_FUNCTION(capget); \
4440   COMMON_INTERCEPT_FUNCTION(capset);
4441 #else
4442 #define INIT_CAPGET
4443 #endif
4445 #if SANITIZER_INTERCEPT_AEABI_MEM
4446 DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr)
4447 DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr)
4448 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr)
4450 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
4451   return WRAP(memmove)(to, from, size);
4453 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
4454   return WRAP(memmove)(to, from, size);
4456 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
4457   return WRAP(memmove)(to, from, size);
4459 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
4460   return WRAP(memcpy)(to, from, size);
4462 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
4463   return WRAP(memcpy)(to, from, size);
4465 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
4466   return WRAP(memcpy)(to, from, size);
4468 // Note the argument order.
4469 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
4470   return WRAP(memset)(block, c, size);
4472 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
4473   return WRAP(memset)(block, c, size);
4475 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
4476   return WRAP(memset)(block, c, size);
4478 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
4479   return WRAP(memset)(block, 0, size);
4481 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
4482   return WRAP(memset)(block, 0, size);
4484 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
4485   return WRAP(memset)(block, 0, size);
4487 #define INIT_AEABI_MEM                         \
4488   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
4489   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
4490   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
4491   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
4492   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
4493   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
4494   COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
4495   COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
4496   COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
4497   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
4498   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
4499   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
4500 #else
4501 #define INIT_AEABI_MEM
4502 #endif  // SANITIZER_INTERCEPT_AEABI_MEM
4504 #if SANITIZER_INTERCEPT___BZERO
4505 DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr);
4507 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
4508   return WRAP(memset)(block, 0, size);
4510 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
4511 #else
4512 #define INIT___BZERO
4513 #endif  // SANITIZER_INTERCEPT___BZERO
4515 #if SANITIZER_INTERCEPT_FTIME
4516 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
4517   void *ctx;
4518   COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
4519   // FIXME: under ASan the call below may write to freed memory and corrupt
4520   // its metadata. See
4521   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4522   int res = REAL(ftime)(tp);
4523   if (tp)
4524     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
4525   return res;
4527 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
4528 #else
4529 #define INIT_FTIME
4530 #endif  // SANITIZER_INTERCEPT_FTIME
4532 #if SANITIZER_INTERCEPT_XDR
4533 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
4534             unsigned size, int op) {
4535   void *ctx;
4536   COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
4537   // FIXME: under ASan the call below may write to freed memory and corrupt
4538   // its metadata. See
4539   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4540   REAL(xdrmem_create)(xdrs, addr, size, op);
4541   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4542   if (op == __sanitizer_XDR_ENCODE) {
4543     // It's not obvious how much data individual xdr_ routines write.
4544     // Simply unpoison the entire target buffer in advance.
4545     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
4546   }
4549 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
4550   void *ctx;
4551   COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
4552   // FIXME: under ASan the call below may write to freed memory and corrupt
4553   // its metadata. See
4554   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4555   REAL(xdrstdio_create)(xdrs, file, op);
4556   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
4559 // FIXME: under ASan the call below may write to freed memory and corrupt
4560 // its metadata. See
4561 // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4562 #define XDR_INTERCEPTOR(F, T)                             \
4563   INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
4564     void *ctx;                                            \
4565     COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
4566     if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
4567       COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
4568     int res = REAL(F)(xdrs, p);                           \
4569     if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
4570       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
4571     return res;                                           \
4572   }
4574 XDR_INTERCEPTOR(xdr_short, short)
4575 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
4576 XDR_INTERCEPTOR(xdr_int, int)
4577 XDR_INTERCEPTOR(xdr_u_int, unsigned)
4578 XDR_INTERCEPTOR(xdr_long, long)
4579 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
4580 XDR_INTERCEPTOR(xdr_hyper, long long)
4581 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
4582 XDR_INTERCEPTOR(xdr_longlong_t, long long)
4583 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
4584 XDR_INTERCEPTOR(xdr_int8_t, u8)
4585 XDR_INTERCEPTOR(xdr_uint8_t, u8)
4586 XDR_INTERCEPTOR(xdr_int16_t, u16)
4587 XDR_INTERCEPTOR(xdr_uint16_t, u16)
4588 XDR_INTERCEPTOR(xdr_int32_t, u32)
4589 XDR_INTERCEPTOR(xdr_uint32_t, u32)
4590 XDR_INTERCEPTOR(xdr_int64_t, u64)
4591 XDR_INTERCEPTOR(xdr_uint64_t, u64)
4592 XDR_INTERCEPTOR(xdr_quad_t, long long)
4593 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
4594 XDR_INTERCEPTOR(xdr_bool, bool)
4595 XDR_INTERCEPTOR(xdr_enum, int)
4596 XDR_INTERCEPTOR(xdr_char, char)
4597 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
4598 XDR_INTERCEPTOR(xdr_float, float)
4599 XDR_INTERCEPTOR(xdr_double, double)
4601 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
4602 // wrapstring, sizeof
4604 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
4605             unsigned maxsize) {
4606   void *ctx;
4607   COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
4608   if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4609     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4610     COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
4611     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
4612   }
4613   // FIXME: under ASan the call below may write to freed memory and corrupt
4614   // its metadata. See
4615   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4616   int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
4617   if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
4618     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4619     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
4620     if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
4621   }
4622   return res;
4625 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
4626             unsigned maxsize) {
4627   void *ctx;
4628   COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
4629   if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
4630     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
4631     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4632   }
4633   // FIXME: under ASan the call below may write to freed memory and corrupt
4634   // its metadata. See
4635   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4636   int res = REAL(xdr_string)(xdrs, p, maxsize);
4637   if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
4638     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4639     if (res && *p)
4640       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
4641   }
4642   return res;
4645 #define INIT_XDR                               \
4646   COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
4647   COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
4648   COMMON_INTERCEPT_FUNCTION(xdr_short);        \
4649   COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
4650   COMMON_INTERCEPT_FUNCTION(xdr_int);          \
4651   COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
4652   COMMON_INTERCEPT_FUNCTION(xdr_long);         \
4653   COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
4654   COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
4655   COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
4656   COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
4657   COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
4658   COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
4659   COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
4660   COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
4661   COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
4662   COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
4663   COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
4664   COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
4665   COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
4666   COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
4667   COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
4668   COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
4669   COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
4670   COMMON_INTERCEPT_FUNCTION(xdr_char);         \
4671   COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
4672   COMMON_INTERCEPT_FUNCTION(xdr_float);        \
4673   COMMON_INTERCEPT_FUNCTION(xdr_double);       \
4674   COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
4675   COMMON_INTERCEPT_FUNCTION(xdr_string);
4676 #else
4677 #define INIT_XDR
4678 #endif  // SANITIZER_INTERCEPT_XDR
4680 #if SANITIZER_INTERCEPT_TSEARCH
4681 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
4682             int (*compar)(const void *, const void *)) {
4683   void *ctx;
4684   COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
4685   // FIXME: under ASan the call below may write to freed memory and corrupt
4686   // its metadata. See
4687   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4688   void *res = REAL(tsearch)(key, rootp, compar);
4689   if (res && *(void **)res == key)
4690     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
4691   return res;
4693 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
4694 #else
4695 #define INIT_TSEARCH
4696 #endif
4698 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
4699     SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4700 void unpoison_file(__sanitizer_FILE *fp) {
4701 #if SANITIZER_HAS_STRUCT_FILE
4702   COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
4703   if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
4704     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
4705                                         fp->_IO_read_end - fp->_IO_read_base);
4706 #endif  // SANITIZER_HAS_STRUCT_FILE
4708 #endif
4710 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
4711 // These guys are called when a .c source is built with -O2.
4712 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
4713   void *ctx;
4714   COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
4715   int res = REAL(__uflow)(fp);
4716   unpoison_file(fp);
4717   return res;
4719 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
4720   void *ctx;
4721   COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
4722   int res = REAL(__underflow)(fp);
4723   unpoison_file(fp);
4724   return res;
4726 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
4727   void *ctx;
4728   COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
4729   int res = REAL(__overflow)(fp, ch);
4730   unpoison_file(fp);
4731   return res;
4733 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
4734   void *ctx;
4735   COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
4736   int res = REAL(__wuflow)(fp);
4737   unpoison_file(fp);
4738   return res;
4740 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
4741   void *ctx;
4742   COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
4743   int res = REAL(__wunderflow)(fp);
4744   unpoison_file(fp);
4745   return res;
4747 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
4748   void *ctx;
4749   COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
4750   int res = REAL(__woverflow)(fp, ch);
4751   unpoison_file(fp);
4752   return res;
4754 #define INIT_LIBIO_INTERNALS               \
4755   COMMON_INTERCEPT_FUNCTION(__uflow);      \
4756   COMMON_INTERCEPT_FUNCTION(__underflow);  \
4757   COMMON_INTERCEPT_FUNCTION(__overflow);   \
4758   COMMON_INTERCEPT_FUNCTION(__wuflow);     \
4759   COMMON_INTERCEPT_FUNCTION(__wunderflow); \
4760   COMMON_INTERCEPT_FUNCTION(__woverflow);
4761 #else
4762 #define INIT_LIBIO_INTERNALS
4763 #endif
4765 #if SANITIZER_INTERCEPT_FOPEN
4766 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
4767   void *ctx;
4768   COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
4769   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4770   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4771   __sanitizer_FILE *res = REAL(fopen)(path, mode);
4772   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4773   if (res) unpoison_file(res);
4774   return res;
4776 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
4777   void *ctx;
4778   COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
4779   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4780   __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
4781   if (res) unpoison_file(res);
4782   return res;
4784 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
4785             __sanitizer_FILE *fp) {
4786   void *ctx;
4787   COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
4788   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4789   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4790   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4791   __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
4792   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4793   if (res) unpoison_file(res);
4794   return res;
4796 #define INIT_FOPEN                   \
4797   COMMON_INTERCEPT_FUNCTION(fopen);  \
4798   COMMON_INTERCEPT_FUNCTION(fdopen); \
4799   COMMON_INTERCEPT_FUNCTION(freopen);
4800 #else
4801 #define INIT_FOPEN
4802 #endif
4804 #if SANITIZER_INTERCEPT_FOPEN64
4805 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
4806   void *ctx;
4807   COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
4808   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4809   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4810   __sanitizer_FILE *res = REAL(fopen64)(path, mode);
4811   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4812   if (res) unpoison_file(res);
4813   return res;
4815 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
4816             __sanitizer_FILE *fp) {
4817   void *ctx;
4818   COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
4819   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4820   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
4821   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4822   __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
4823   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
4824   if (res) unpoison_file(res);
4825   return res;
4827 #define INIT_FOPEN64                  \
4828   COMMON_INTERCEPT_FUNCTION(fopen64); \
4829   COMMON_INTERCEPT_FUNCTION(freopen64);
4830 #else
4831 #define INIT_FOPEN64
4832 #endif
4834 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
4835 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
4836   void *ctx;
4837   COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
4838   // FIXME: under ASan the call below may write to freed memory and corrupt
4839   // its metadata. See
4840   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4841   __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
4842   if (res) {
4843     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4844     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4845     unpoison_file(res);
4846     FileMetadata file = {ptr, sizeloc};
4847     SetInterceptorMetadata(res, file);
4848   }
4849   return res;
4851 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
4852             SIZE_T *sizeloc) {
4853   void *ctx;
4854   COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
4855   __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
4856   if (res) {
4857     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
4858     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
4859     unpoison_file(res);
4860     FileMetadata file = {(char **)ptr, sizeloc};
4861     SetInterceptorMetadata(res, file);
4862   }
4863   return res;
4865 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
4866             const char *mode) {
4867   void *ctx;
4868   COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
4869   // FIXME: under ASan the call below may write to freed memory and corrupt
4870   // its metadata. See
4871   // https://code.google.com/p/address-sanitizer/issues/detail?id=321.
4872   __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
4873   if (res) unpoison_file(res);
4874   return res;
4876 #define INIT_OPEN_MEMSTREAM                   \
4877   COMMON_INTERCEPT_FUNCTION(open_memstream);  \
4878   COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
4879   COMMON_INTERCEPT_FUNCTION(fmemopen);
4880 #else
4881 #define INIT_OPEN_MEMSTREAM
4882 #endif
4884 #if SANITIZER_INTERCEPT_OBSTACK
4885 static void initialize_obstack(__sanitizer_obstack *obstack) {
4886   COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
4887   if (obstack->chunk)
4888     COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
4889                                         sizeof(*obstack->chunk));
4892 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
4893             int align, void *(*alloc_fn)(uptr arg, uptr sz),
4894             void (*free_fn)(uptr arg, void *p)) {
4895   void *ctx;
4896   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
4897                            free_fn);
4898   int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
4899   if (res) initialize_obstack(obstack);
4900   return res;
4902 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
4903             int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
4904   void *ctx;
4905   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
4906                            free_fn);
4907   int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
4908   if (res) initialize_obstack(obstack);
4909   return res;
4911 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
4912   void *ctx;
4913   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
4914   REAL(_obstack_newchunk)(obstack, length);
4915   if (obstack->chunk)
4916     COMMON_INTERCEPTOR_INITIALIZE_RANGE(
4917         obstack->chunk, obstack->next_free - (char *)obstack->chunk);
4919 #define INIT_OBSTACK                           \
4920   COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
4921   COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
4922   COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
4923 #else
4924 #define INIT_OBSTACK
4925 #endif
4927 #if SANITIZER_INTERCEPT_FFLUSH
4928 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
4929   void *ctx;
4930   COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
4931   int res = REAL(fflush)(fp);
4932   // FIXME: handle fp == NULL
4933   if (fp) {
4934     const FileMetadata *m = GetInterceptorMetadata(fp);
4935     if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4936   }
4937   return res;
4939 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
4940 #else
4941 #define INIT_FFLUSH
4942 #endif
4944 #if SANITIZER_INTERCEPT_FCLOSE
4945 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
4946   void *ctx;
4947   COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
4948   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
4949   const FileMetadata *m = GetInterceptorMetadata(fp);
4950   int res = REAL(fclose)(fp);
4951   if (m) {
4952     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
4953     DeleteInterceptorMetadata(fp);
4954   }
4955   return res;
4957 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
4958 #else
4959 #define INIT_FCLOSE
4960 #endif
4962 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
4963 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
4964   void *ctx;
4965   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
4966   if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
4967   COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
4968   void *res = REAL(dlopen)(filename, flag);
4969   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
4970   return res;
4973 INTERCEPTOR(int, dlclose, void *handle) {
4974   void *ctx;
4975   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
4976   int res = REAL(dlclose)(handle);
4977   COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
4978   return res;
4980 #define INIT_DLOPEN_DLCLOSE          \
4981   COMMON_INTERCEPT_FUNCTION(dlopen); \
4982   COMMON_INTERCEPT_FUNCTION(dlclose);
4983 #else
4984 #define INIT_DLOPEN_DLCLOSE
4985 #endif
4987 #if SANITIZER_INTERCEPT_GETPASS
4988 INTERCEPTOR(char *, getpass, const char *prompt) {
4989   void *ctx;
4990   COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
4991   if (prompt)
4992     COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
4993   char *res = REAL(getpass)(prompt);
4994   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
4995   return res;
4998 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
4999 #else
5000 #define INIT_GETPASS
5001 #endif
5003 #if SANITIZER_INTERCEPT_TIMERFD
5004 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
5005             void *old_value) {
5006   void *ctx;
5007   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
5008                            old_value);
5009   COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
5010   int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
5011   if (res != -1 && old_value)
5012     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
5013   return res;
5016 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
5017   void *ctx;
5018   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
5019   int res = REAL(timerfd_gettime)(fd, curr_value);
5020   if (res != -1 && curr_value)
5021     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
5022   return res;
5024 #define INIT_TIMERFD                          \
5025   COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
5026   COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
5027 #else
5028 #define INIT_TIMERFD
5029 #endif
5031 #if SANITIZER_INTERCEPT_MLOCKX
5032 // Linux kernel has a bug that leads to kernel deadlock if a process
5033 // maps TBs of memory and then calls mlock().
5034 static void MlockIsUnsupported() {
5035   static atomic_uint8_t printed;
5036   if (atomic_exchange(&printed, 1, memory_order_relaxed))
5037     return;
5038   VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
5039           SanitizerToolName);
5042 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
5043   MlockIsUnsupported();
5044   return 0;
5047 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
5048   MlockIsUnsupported();
5049   return 0;
5052 INTERCEPTOR(int, mlockall, int flags) {
5053   MlockIsUnsupported();
5054   return 0;
5057 INTERCEPTOR(int, munlockall, void) {
5058   MlockIsUnsupported();
5059   return 0;
5062 #define INIT_MLOCKX                                                            \
5063   COMMON_INTERCEPT_FUNCTION(mlock);                                            \
5064   COMMON_INTERCEPT_FUNCTION(munlock);                                          \
5065   COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
5066   COMMON_INTERCEPT_FUNCTION(munlockall);
5068 #else
5069 #define INIT_MLOCKX
5070 #endif  // SANITIZER_INTERCEPT_MLOCKX
5072 #if SANITIZER_INTERCEPT_FOPENCOOKIE
5073 struct WrappedCookie {
5074   void *real_cookie;
5075   __sanitizer_cookie_io_functions_t real_io_funcs;
5078 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
5079   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5080   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5081   __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
5082   return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
5085 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
5086   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5087   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5088   __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
5089   return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
5092 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
5093   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5094   COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
5095   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5096   __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
5097   return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
5098                    : -1;
5101 static int wrapped_close(void *cookie) {
5102   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
5103   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
5104   __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
5105   int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
5106   InternalFree(wrapped_cookie);
5107   return res;
5110 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
5111             __sanitizer_cookie_io_functions_t io_funcs) {
5112   void *ctx;
5113   COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
5114   WrappedCookie *wrapped_cookie =
5115       (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
5116   wrapped_cookie->real_cookie = cookie;
5117   wrapped_cookie->real_io_funcs = io_funcs;
5118   __sanitizer_FILE *res =
5119       REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
5120                                                wrapped_seek, wrapped_close});
5121   return res;
5124 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
5125 #else
5126 #define INIT_FOPENCOOKIE
5127 #endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
5129 #if SANITIZER_INTERCEPT_SEM
5130 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
5131   void *ctx;
5132   COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
5133   // Workaround a bug in glibc's "old" semaphore implementation by
5134   // zero-initializing the sem_t contents. This has to be done here because
5135   // interceptors bind to the lowest symbols version by default, hitting the
5136   // buggy code path while the non-sanitized build of the same code works fine.
5137   REAL(memset)(s, 0, sizeof(*s));
5138   int res = REAL(sem_init)(s, pshared, value);
5139   return res;
5142 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
5143   void *ctx;
5144   COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
5145   int res = REAL(sem_destroy)(s);
5146   return res;
5149 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
5150   void *ctx;
5151   COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
5152   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
5153   if (res == 0) {
5154     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5155   }
5156   return res;
5159 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
5160   void *ctx;
5161   COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
5162   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
5163   if (res == 0) {
5164     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5165   }
5166   return res;
5169 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
5170   void *ctx;
5171   COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
5172   COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
5173   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
5174   if (res == 0) {
5175     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5176   }
5177   return res;
5180 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
5181   void *ctx;
5182   COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
5183   COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
5184   int res = REAL(sem_post)(s);
5185   return res;
5188 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
5189   void *ctx;
5190   COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
5191   int res = REAL(sem_getvalue)(s, sval);
5192   if (res == 0) {
5193     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
5194     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
5195   }
5196   return res;
5198 #define INIT_SEM                                                               \
5199   COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
5200   COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
5201   COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
5202   COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
5203   COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
5204   COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
5205   COMMON_INTERCEPT_FUNCTION(sem_getvalue);
5206 #else
5207 #define INIT_SEM
5208 #endif // SANITIZER_INTERCEPT_SEM
5210 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
5211 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
5212   void *ctx;
5213   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
5214   int res = REAL(pthread_setcancelstate)(state, oldstate);
5215   if (res == 0)
5216     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
5217   return res;
5220 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
5221   void *ctx;
5222   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
5223   int res = REAL(pthread_setcanceltype)(type, oldtype);
5224   if (res == 0)
5225     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
5226   return res;
5228 #define INIT_PTHREAD_SETCANCEL                                                 \
5229   COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
5230   COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
5231 #else
5232 #define INIT_PTHREAD_SETCANCEL
5233 #endif
5235 #if SANITIZER_INTERCEPT_MINCORE
5236 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
5237   void *ctx;
5238   COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
5239   int res = REAL(mincore)(addr, length, vec);
5240   if (res == 0) {
5241     uptr page_size = GetPageSizeCached();
5242     uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
5243     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
5244   }
5245   return res;
5247 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
5248 #else
5249 #define INIT_MINCORE
5250 #endif
5252 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
5253 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
5254             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5255             uptr flags) {
5256   void *ctx;
5257   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
5258                            remote_iov, riovcnt, flags);
5259   SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
5260                                        riovcnt, flags);
5261   if (res > 0)
5262     write_iovec(ctx, local_iov, liovcnt, res);
5263   return res;
5266 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
5267             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
5268             uptr flags) {
5269   void *ctx;
5270   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
5271                            remote_iov, riovcnt, flags);
5272   SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
5273                                         riovcnt, flags);
5274   if (res > 0)
5275     read_iovec(ctx, local_iov, liovcnt, res);
5276   return res;
5278 #define INIT_PROCESS_VM_READV                                                  \
5279   COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
5280   COMMON_INTERCEPT_FUNCTION(process_vm_writev);
5281 #else
5282 #define INIT_PROCESS_VM_READV
5283 #endif
5285 static void InitializeCommonInterceptors() {
5286   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
5287   interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap();
5289   INIT_TEXTDOMAIN;
5290   INIT_STRCMP;
5291   INIT_STRNCMP;
5292   INIT_STRCASECMP;
5293   INIT_STRNCASECMP;
5294   INIT_STRSTR;
5295   INIT_STRCASESTR;
5296   INIT_STRSPN;
5297   INIT_STRPBRK;
5298   INIT_MEMCHR;
5299   INIT_MEMCMP;
5300   INIT_MEMRCHR;
5301   INIT_READ;
5302   INIT_PREAD;
5303   INIT_PREAD64;
5304   INIT_READV;
5305   INIT_PREADV;
5306   INIT_PREADV64;
5307   INIT_WRITE;
5308   INIT_PWRITE;
5309   INIT_PWRITE64;
5310   INIT_WRITEV;
5311   INIT_PWRITEV;
5312   INIT_PWRITEV64;
5313   INIT_PRCTL;
5314   INIT_LOCALTIME_AND_FRIENDS;
5315   INIT_STRPTIME;
5316   INIT_SCANF;
5317   INIT_ISOC99_SCANF;
5318   INIT_PRINTF;
5319   INIT_PRINTF_L;
5320   INIT_ISOC99_PRINTF;
5321   INIT_FREXP;
5322   INIT_FREXPF_FREXPL;
5323   INIT_GETPWNAM_AND_FRIENDS;
5324   INIT_GETPWNAM_R_AND_FRIENDS;
5325   INIT_GETPWENT;
5326   INIT_FGETPWENT;
5327   INIT_GETPWENT_R;
5328   INIT_SETPWENT;
5329   INIT_CLOCK_GETTIME;
5330   INIT_GETITIMER;
5331   INIT_TIME;
5332   INIT_GLOB;
5333   INIT_WAIT;
5334   INIT_WAIT4;
5335   INIT_INET;
5336   INIT_PTHREAD_GETSCHEDPARAM;
5337   INIT_GETADDRINFO;
5338   INIT_GETNAMEINFO;
5339   INIT_GETSOCKNAME;
5340   INIT_GETHOSTBYNAME;
5341   INIT_GETHOSTBYNAME_R;
5342   INIT_GETHOSTBYNAME2_R;
5343   INIT_GETHOSTBYADDR_R;
5344   INIT_GETHOSTENT_R;
5345   INIT_GETSOCKOPT;
5346   INIT_ACCEPT;
5347   INIT_ACCEPT4;
5348   INIT_MODF;
5349   INIT_RECVMSG;
5350   INIT_GETPEERNAME;
5351   INIT_IOCTL;
5352   INIT_INET_ATON;
5353   INIT_SYSINFO;
5354   INIT_READDIR;
5355   INIT_READDIR64;
5356   INIT_PTRACE;
5357   INIT_SETLOCALE;
5358   INIT_GETCWD;
5359   INIT_GET_CURRENT_DIR_NAME;
5360   INIT_STRTOIMAX;
5361   INIT_MBSTOWCS;
5362   INIT_MBSNRTOWCS;
5363   INIT_WCSTOMBS;
5364   INIT_WCSNRTOMBS;
5365   INIT_WCRTOMB;
5366   INIT_TCGETATTR;
5367   INIT_REALPATH;
5368   INIT_CANONICALIZE_FILE_NAME;
5369   INIT_CONFSTR;
5370   INIT_SCHED_GETAFFINITY;
5371   INIT_SCHED_GETPARAM;
5372   INIT_STRERROR;
5373   INIT_STRERROR_R;
5374   INIT_XPG_STRERROR_R;
5375   INIT_SCANDIR;
5376   INIT_SCANDIR64;
5377   INIT_GETGROUPS;
5378   INIT_POLL;
5379   INIT_PPOLL;
5380   INIT_WORDEXP;
5381   INIT_SIGWAIT;
5382   INIT_SIGWAITINFO;
5383   INIT_SIGTIMEDWAIT;
5384   INIT_SIGSETOPS;
5385   INIT_SIGPENDING;
5386   INIT_SIGPROCMASK;
5387   INIT_BACKTRACE;
5388   INIT__EXIT;
5389   INIT_PTHREAD_MUTEX_LOCK;
5390   INIT_PTHREAD_MUTEX_UNLOCK;
5391   INIT_GETMNTENT;
5392   INIT_GETMNTENT_R;
5393   INIT_STATFS;
5394   INIT_STATFS64;
5395   INIT_STATVFS;
5396   INIT_STATVFS64;
5397   INIT_INITGROUPS;
5398   INIT_ETHER_NTOA_ATON;
5399   INIT_ETHER_HOST;
5400   INIT_ETHER_R;
5401   INIT_SHMCTL;
5402   INIT_RANDOM_R;
5403   INIT_PTHREAD_ATTR_GET;
5404   INIT_PTHREAD_ATTR_GETINHERITSCHED;
5405   INIT_PTHREAD_ATTR_GETAFFINITY_NP;
5406   INIT_PTHREAD_MUTEXATTR_GETPSHARED;
5407   INIT_PTHREAD_MUTEXATTR_GETTYPE;
5408   INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
5409   INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
5410   INIT_PTHREAD_MUTEXATTR_GETROBUST;
5411   INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
5412   INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
5413   INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
5414   INIT_PTHREAD_CONDATTR_GETPSHARED;
5415   INIT_PTHREAD_CONDATTR_GETCLOCK;
5416   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
5417   INIT_TMPNAM;
5418   INIT_TMPNAM_R;
5419   INIT_TEMPNAM;
5420   INIT_PTHREAD_SETNAME_NP;
5421   INIT_SINCOS;
5422   INIT_REMQUO;
5423   INIT_LGAMMA;
5424   INIT_LGAMMA_R;
5425   INIT_LGAMMAL_R;
5426   INIT_DRAND48_R;
5427   INIT_RAND_R;
5428   INIT_GETLINE;
5429   INIT_ICONV;
5430   INIT_TIMES;
5431   INIT_TLS_GET_ADDR;
5432   INIT_LISTXATTR;
5433   INIT_GETXATTR;
5434   INIT_GETRESID;
5435   INIT_GETIFADDRS;
5436   INIT_IF_INDEXTONAME;
5437   INIT_CAPGET;
5438   INIT_AEABI_MEM;
5439   INIT___BZERO;
5440   INIT_FTIME;
5441   INIT_XDR;
5442   INIT_TSEARCH;
5443   INIT_LIBIO_INTERNALS;
5444   INIT_FOPEN;
5445   INIT_FOPEN64;
5446   INIT_OPEN_MEMSTREAM;
5447   INIT_OBSTACK;
5448   INIT_FFLUSH;
5449   INIT_FCLOSE;
5450   INIT_DLOPEN_DLCLOSE;
5451   INIT_GETPASS;
5452   INIT_TIMERFD;
5453   INIT_MLOCKX;
5454   INIT_FOPENCOOKIE;
5455   INIT_SEM;
5456   INIT_PTHREAD_SETCANCEL;
5457   INIT_MINCORE;
5458   INIT_PROCESS_VM_READV;