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