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