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