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