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