]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm-project / compiler-rt / lib / sanitizer_common / sanitizer_common_interceptors.inc
1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // Common function interceptors for tools like AddressSanitizer,
10 // ThreadSanitizer, MemorySanitizer, etc.
11 //
12 // This file should be included into the tool's interceptor file,
13 // which has to define its own macros:
14 //   COMMON_INTERCEPTOR_ENTER
15 //   COMMON_INTERCEPTOR_ENTER_NOIGNORE
16 //   COMMON_INTERCEPTOR_READ_RANGE
17 //   COMMON_INTERCEPTOR_WRITE_RANGE
18 //   COMMON_INTERCEPTOR_INITIALIZE_RANGE
19 //   COMMON_INTERCEPTOR_DIR_ACQUIRE
20 //   COMMON_INTERCEPTOR_FD_ACQUIRE
21 //   COMMON_INTERCEPTOR_FD_RELEASE
22 //   COMMON_INTERCEPTOR_FD_ACCESS
23 //   COMMON_INTERCEPTOR_SET_THREAD_NAME
24 //   COMMON_INTERCEPTOR_ON_DLOPEN
25 //   COMMON_INTERCEPTOR_ON_EXIT
26 //   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
27 //   COMMON_INTERCEPTOR_MUTEX_POST_LOCK
28 //   COMMON_INTERCEPTOR_MUTEX_UNLOCK
29 //   COMMON_INTERCEPTOR_MUTEX_REPAIR
30 //   COMMON_INTERCEPTOR_SET_PTHREAD_NAME
31 //   COMMON_INTERCEPTOR_HANDLE_RECVMSG
32 //   COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
33 //   COMMON_INTERCEPTOR_MEMSET_IMPL
34 //   COMMON_INTERCEPTOR_MEMMOVE_IMPL
35 //   COMMON_INTERCEPTOR_MEMCPY_IMPL
36 //   COMMON_INTERCEPTOR_MMAP_IMPL
37 //   COMMON_INTERCEPTOR_COPY_STRING
38 //   COMMON_INTERCEPTOR_STRNDUP_IMPL
39 //   COMMON_INTERCEPTOR_STRERROR
40 //===----------------------------------------------------------------------===//
41
42 #include "interception/interception.h"
43 #include "sanitizer_addrhashmap.h"
44 #include "sanitizer_errno.h"
45 #include "sanitizer_placement_new.h"
46 #include "sanitizer_platform_interceptors.h"
47 #include "sanitizer_symbolizer.h"
48 #include "sanitizer_tls_get_addr.h"
49
50 #include <stdarg.h>
51
52 #if SANITIZER_INTERCEPTOR_HOOKS
53 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);
54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
55   SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}
56 #else
57 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
58 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
59
60 #endif  // SANITIZER_INTERCEPTOR_HOOKS
61
62 #if SANITIZER_WINDOWS && !defined(va_copy)
63 #define va_copy(dst, src) ((dst) = (src))
64 #endif // _WIN32
65
66 #if SANITIZER_FREEBSD
67 #define pthread_setname_np pthread_set_name_np
68 #define inet_aton __inet_aton
69 #define inet_pton __inet_pton
70 #define iconv __bsd_iconv
71 #endif
72
73 #if SANITIZER_NETBSD
74 #define clock_getres __clock_getres50
75 #define clock_gettime __clock_gettime50
76 #define clock_settime __clock_settime50
77 #define ctime __ctime50
78 #define ctime_r __ctime_r50
79 #define devname __devname50
80 #define fgetpos __fgetpos50
81 #define fsetpos __fsetpos50
82 #define fstatvfs __fstatvfs90
83 #define fstatvfs1 __fstatvfs190
84 #define fts_children __fts_children60
85 #define fts_close __fts_close60
86 #define fts_open __fts_open60
87 #define fts_read __fts_read60
88 #define fts_set __fts_set60
89 #define getitimer __getitimer50
90 #define getmntinfo __getmntinfo90
91 #define getpwent __getpwent50
92 #define getpwnam __getpwnam50
93 #define getpwnam_r __getpwnam_r50
94 #define getpwuid __getpwuid50
95 #define getpwuid_r __getpwuid_r50
96 #define getutent __getutent50
97 #define getutxent __getutxent50
98 #define getutxid __getutxid50
99 #define getutxline __getutxline50
100 #define getvfsstat __getvfsstat90
101 #define pututxline __pututxline50
102 #define glob __glob30
103 #define gmtime __gmtime50
104 #define gmtime_r __gmtime_r50
105 #define localtime __locatime50
106 #define localtime_r __localtime_r50
107 #define mktime __mktime50
108 #define lstat __lstat50
109 #define opendir __opendir30
110 #define readdir __readdir30
111 #define readdir_r __readdir_r30
112 #define scandir __scandir30
113 #define setitimer __setitimer50
114 #define setlocale __setlocale50
115 #define shmctl __shmctl50
116 #define sigemptyset __sigemptyset14
117 #define sigfillset __sigfillset14
118 #define sigpending __sigpending14
119 #define sigprocmask __sigprocmask14
120 #define sigtimedwait __sigtimedwait50
121 #define stat __stat50
122 #define statvfs __statvfs90
123 #define statvfs1 __statvfs190
124 #define time __time50
125 #define times __times13
126 #define unvis __unvis50
127 #define wait3 __wait350
128 #define wait4 __wait450
129 extern const unsigned short *_ctype_tab_;
130 extern const short *_toupper_tab_;
131 extern const short *_tolower_tab_;
132 #endif
133
134 // Platform-specific options.
135 #if SANITIZER_MAC
136 namespace __sanitizer {
137 bool PlatformHasDifferentMemcpyAndMemmove();
138 }
139 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \
140   (__sanitizer::PlatformHasDifferentMemcpyAndMemmove())
141 #elif SANITIZER_WINDOWS64
142 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false
143 #else
144 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true
145 #endif  // SANITIZER_MAC
146
147 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
148 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
149 #endif
150
151 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
152 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
153 #endif
154
155 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
156 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
157 #endif
158
159 #ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
160 #define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {}
161 #endif
162
163 #ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK
164 #define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {}
165 #endif
166
167 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
168 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
169 #endif
170
171 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
172 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
173 #endif
174
175 #ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
176 #define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
177 #endif
178
179 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
180 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
181 #endif
182
183 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
184 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
185 #endif
186
187 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
188 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
189 #endif
190
191 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
192 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
193 #endif
194
195 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
196 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
197 #endif
198
199 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
200 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
201   COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
202 #endif
203
204 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
205 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
206 #endif
207
208 #define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
209     COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
210       common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) )
211
212 #ifndef COMMON_INTERCEPTOR_ON_DLOPEN
213 #define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
214   CheckNoDeepBind(filename, flag);
215 #endif
216
217 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
218 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
219 #endif
220
221 #ifndef COMMON_INTERCEPTOR_ACQUIRE
222 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
223 #endif
224
225 #ifndef COMMON_INTERCEPTOR_RELEASE
226 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
227 #endif
228
229 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
230 #define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
231 #endif
232
233 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
234 #define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
235 #endif
236
237 #ifdef SANITIZER_NLDBL_VERSION
238 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
239     COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
240 #else
241 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
242     COMMON_INTERCEPT_FUNCTION(fn)
243 #endif
244
245 #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
246 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
247   {                                                       \
248     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)        \
249       return internal_memset(dst, v, size);               \
250     COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);  \
251     if (common_flags()->intercept_intrin)                 \
252       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);     \
253     return REAL(memset)(dst, v, size);                    \
254   }
255 #endif
256
257 #ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
258 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \
259   {                                                          \
260     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)           \
261       return internal_memmove(dst, src, size);               \
262     COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);  \
263     if (common_flags()->intercept_intrin) {                  \
264       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);        \
265       COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);         \
266     }                                                        \
267     return REAL(memmove)(dst, src, size);                    \
268   }
269 #endif
270
271 #ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
272 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \
273   {                                                         \
274     if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {        \
275       return internal_memmove(dst, src, size);              \
276     }                                                       \
277     COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);  \
278     if (common_flags()->intercept_intrin) {                 \
279       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);       \
280       COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);        \
281     }                                                       \
282     return REAL(memcpy)(dst, src, size);                    \
283   }
284 #endif
285
286 #ifndef COMMON_INTERCEPTOR_MMAP_IMPL
287 #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
288                                      off)                                  \
289   { return REAL(mmap)(addr, sz, prot, flags, fd, off); }
290 #endif
291
292 #ifndef COMMON_INTERCEPTOR_COPY_STRING
293 #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
294 #endif
295
296 #ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
297 #define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size)                         \
298   COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size);                            \
299   uptr copy_length = internal_strnlen(s, size);                               \
300   char *new_mem = (char *)WRAP(malloc)(copy_length + 1);                      \
301   if (common_flags()->intercept_strndup) {                                    \
302     COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1));       \
303   }                                                                           \
304   COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length);               \
305   internal_memcpy(new_mem, s, copy_length);                                   \
306   new_mem[copy_length] = '\0';                                                \
307   return new_mem;
308 #endif
309
310 #ifndef COMMON_INTERCEPTOR_STRERROR
311 #define COMMON_INTERCEPTOR_STRERROR() {}
312 #endif
313
314 struct FileMetadata {
315   // For open_memstream().
316   char **addr;
317   SIZE_T *size;
318 };
319
320 struct CommonInterceptorMetadata {
321   enum {
322     CIMT_INVALID = 0,
323     CIMT_FILE
324   } type;
325   union {
326     FileMetadata file;
327   };
328 };
329
330 #if SI_POSIX
331 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
332
333 static MetadataHashMap *interceptor_metadata_map;
334
335 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
336                                           const FileMetadata &file) {
337   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
338   CHECK(h.created());
339   h->type = CommonInterceptorMetadata::CIMT_FILE;
340   h->file = file;
341 }
342
343 UNUSED static const FileMetadata *GetInterceptorMetadata(
344     __sanitizer_FILE *addr) {
345   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
346                             /* remove */ false,
347                             /* create */ false);
348   if (addr && h.exists()) {
349     CHECK(!h.created());
350     CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
351     return &h->file;
352   } else {
353     return 0;
354   }
355 }
356
357 UNUSED static void DeleteInterceptorMetadata(void *addr) {
358   MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
359   CHECK(h.exists());
360 }
361 #endif  // SI_POSIX
362
363 #if SANITIZER_INTERCEPT_STRLEN
364 INTERCEPTOR(SIZE_T, strlen, const char *s) {
365   // Sometimes strlen is called prior to InitializeCommonInterceptors,
366   // in which case the REAL(strlen) typically used in
367   // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
368   // to handle that.
369   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
370     return internal_strlen(s);
371   void *ctx;
372   COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
373   SIZE_T result = REAL(strlen)(s);
374   if (common_flags()->intercept_strlen)
375     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
376   return result;
377 }
378 #define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
379 #else
380 #define INIT_STRLEN
381 #endif
382
383 #if SANITIZER_INTERCEPT_STRNLEN
384 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
385   void *ctx;
386   COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
387   SIZE_T length = REAL(strnlen)(s, maxlen);
388   if (common_flags()->intercept_strlen)
389     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
390   return length;
391 }
392 #define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
393 #else
394 #define INIT_STRNLEN
395 #endif
396
397 #if SANITIZER_INTERCEPT_STRNDUP
398 INTERCEPTOR(char*, strndup, const char *s, uptr size) {
399   void *ctx;
400   COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
401 }
402 #define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
403 #else
404 #define INIT_STRNDUP
405 #endif // SANITIZER_INTERCEPT_STRNDUP
406
407 #if SANITIZER_INTERCEPT___STRNDUP
408 INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
409   void *ctx;
410   COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
411 }
412 #define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
413 #else
414 #define INIT___STRNDUP
415 #endif // SANITIZER_INTERCEPT___STRNDUP
416
417 #if SANITIZER_INTERCEPT_TEXTDOMAIN
418 INTERCEPTOR(char*, textdomain, const char *domainname) {
419   void *ctx;
420   COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
421   if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
422   char *domain = REAL(textdomain)(domainname);
423   if (domain) {
424     COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1);
425   }
426   return domain;
427 }
428 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
429 #else
430 #define INIT_TEXTDOMAIN
431 #endif
432
433 #if SANITIZER_INTERCEPT_STRCMP
434 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
435   return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
436 }
437
438 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
439                               const char *s1, const char *s2, int result)
440
441 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
442   void *ctx;
443   COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
444   unsigned char c1, c2;
445   uptr i;
446   for (i = 0;; i++) {
447     c1 = (unsigned char)s1[i];
448     c2 = (unsigned char)s2[i];
449     if (c1 != c2 || c1 == '\0') break;
450   }
451   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
452   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
453   int result = CharCmpX(c1, c2);
454   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
455                              s2, result);
456   return result;
457 }
458
459 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
460                               const char *s1, const char *s2, uptr n,
461                               int result)
462
463 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
464   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
465     return internal_strncmp(s1, s2, size);
466   void *ctx;
467   COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
468   unsigned char c1 = 0, c2 = 0;
469   uptr i;
470   for (i = 0; i < size; i++) {
471     c1 = (unsigned char)s1[i];
472     c2 = (unsigned char)s2[i];
473     if (c1 != c2 || c1 == '\0') break;
474   }
475   uptr i1 = i;
476   uptr i2 = i;
477   if (common_flags()->strict_string_checks) {
478     for (; i1 < size && s1[i1]; i1++) {}
479     for (; i2 < size && s2[i2]; i2++) {}
480   }
481   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
482   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
483   int result = CharCmpX(c1, c2);
484   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
485                              s2, size, result);
486   return result;
487 }
488
489 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
490 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
491 #else
492 #define INIT_STRCMP
493 #define INIT_STRNCMP
494 #endif
495
496 #if SANITIZER_INTERCEPT_STRCASECMP
497 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
498   int c1_low = ToLower(c1);
499   int c2_low = ToLower(c2);
500   return c1_low - c2_low;
501 }
502
503 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
504                               const char *s1, const char *s2, int result)
505
506 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
507   void *ctx;
508   COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
509   unsigned char c1 = 0, c2 = 0;
510   uptr i;
511   for (i = 0;; i++) {
512     c1 = (unsigned char)s1[i];
513     c2 = (unsigned char)s2[i];
514     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
515   }
516   COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
517   COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
518   int result = CharCaseCmp(c1, c2);
519   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
520                              s1, s2, result);
521   return result;
522 }
523
524 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
525                               const char *s1, const char *s2, uptr size,
526                               int result)
527
528 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {
529   void *ctx;
530   COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
531   unsigned char c1 = 0, c2 = 0;
532   uptr i;
533   for (i = 0; i < size; i++) {
534     c1 = (unsigned char)s1[i];
535     c2 = (unsigned char)s2[i];
536     if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
537   }
538   uptr i1 = i;
539   uptr i2 = i;
540   if (common_flags()->strict_string_checks) {
541     for (; i1 < size && s1[i1]; i1++) {}
542     for (; i2 < size && s2[i2]; i2++) {}
543   }
544   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
545   COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
546   int result = CharCaseCmp(c1, c2);
547   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
548                              s1, s2, size, result);
549   return result;
550 }
551
552 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
553 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
554 #else
555 #define INIT_STRCASECMP
556 #define INIT_STRNCASECMP
557 #endif
558
559 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
560 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
561                                const char *s2) {
562     uptr len1 = REAL(strlen)(s1);
563     uptr len2 = REAL(strlen)(s2);
564     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
565     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
566 }
567 #endif
568
569 #if SANITIZER_INTERCEPT_STRSTR
570
571 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
572                               const char *s1, const char *s2, char *result)
573
574 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
575   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
576     return internal_strstr(s1, s2);
577   void *ctx;
578   COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
579   char *r = REAL(strstr)(s1, s2);
580   if (common_flags()->intercept_strstr)
581     StrstrCheck(ctx, r, s1, s2);
582   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
583                              s2, r);
584   return r;
585 }
586
587 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
588 #else
589 #define INIT_STRSTR
590 #endif
591
592 #if SANITIZER_INTERCEPT_STRCASESTR
593
594 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
595                               const char *s1, const char *s2, char *result)
596
597 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
598   void *ctx;
599   COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
600   char *r = REAL(strcasestr)(s1, s2);
601   if (common_flags()->intercept_strstr)
602     StrstrCheck(ctx, r, s1, s2);
603   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
604                              s1, s2, r);
605   return r;
606 }
607
608 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
609 #else
610 #define INIT_STRCASESTR
611 #endif
612
613 #if SANITIZER_INTERCEPT_STRTOK
614
615 INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
616   void *ctx;
617   COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);
618   if (!common_flags()->intercept_strtok) {
619     return REAL(strtok)(str, delimiters);
620   }
621   if (common_flags()->strict_string_checks) {
622     // If strict_string_checks is enabled, we check the whole first argument
623     // string on the first call (strtok saves this string in a static buffer
624     // for subsequent calls). We do not need to check strtok's result.
625     // As the delimiters can change, we check them every call.
626     if (str != nullptr) {
627       COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
628     }
629     COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,
630                                   REAL(strlen)(delimiters) + 1);
631     return REAL(strtok)(str, delimiters);
632   } else {
633     // However, when strict_string_checks is disabled we cannot check the
634     // whole string on the first call. Instead, we check the result string
635     // which is guaranteed to be a NULL-terminated substring of the first
636     // argument. We also conservatively check one character of str and the
637     // delimiters.
638     if (str != nullptr) {
639       COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);
640     }
641     COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);
642     char *result = REAL(strtok)(str, delimiters);
643     if (result != nullptr) {
644       COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1);
645     } else if (str != nullptr) {
646       // No delimiter were found, it's safe to assume that the entire str was
647       // scanned.
648       COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
649     }
650     return result;
651   }
652 }
653
654 #define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)
655 #else
656 #define INIT_STRTOK
657 #endif
658
659 #if SANITIZER_INTERCEPT_MEMMEM
660 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
661                               const void *s1, SIZE_T len1, const void *s2,
662                               SIZE_T len2, void *result)
663
664 INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
665             SIZE_T len2) {
666   void *ctx;
667   COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
668   void *r = REAL(memmem)(s1, len1, s2, len2);
669   if (common_flags()->intercept_memmem) {
670     COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
671     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
672   }
673   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
674                              s1, len1, s2, len2, r);
675   return r;
676 }
677
678 #define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
679 #else
680 #define INIT_MEMMEM
681 #endif  // SANITIZER_INTERCEPT_MEMMEM
682
683 #if SANITIZER_INTERCEPT_STRCHR
684 INTERCEPTOR(char*, strchr, const char *s, int c) {
685   void *ctx;
686   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
687     return internal_strchr(s, c);
688   COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
689   char *result = REAL(strchr)(s, c);
690   if (common_flags()->intercept_strchr) {
691     // Keep strlen as macro argument, as macro may ignore it.
692     COMMON_INTERCEPTOR_READ_STRING(ctx, s,
693       (result ? result - s : REAL(strlen)(s)) + 1);
694   }
695   return result;
696 }
697 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
698 #else
699 #define INIT_STRCHR
700 #endif
701
702 #if SANITIZER_INTERCEPT_STRCHRNUL
703 INTERCEPTOR(char*, strchrnul, const char *s, int c) {
704   void *ctx;
705   COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
706   char *result = REAL(strchrnul)(s, c);
707   uptr len = result - s + 1;
708   if (common_flags()->intercept_strchr)
709     COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
710   return result;
711 }
712 #define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
713 #else
714 #define INIT_STRCHRNUL
715 #endif
716
717 #if SANITIZER_INTERCEPT_STRRCHR
718 INTERCEPTOR(char*, strrchr, const char *s, int c) {
719   void *ctx;
720   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
721     return internal_strrchr(s, c);
722   COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
723   if (common_flags()->intercept_strchr)
724     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
725   return REAL(strrchr)(s, c);
726 }
727 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
728 #else
729 #define INIT_STRRCHR
730 #endif
731
732 #if SANITIZER_INTERCEPT_STRSPN
733 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
734   void *ctx;
735   COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
736   SIZE_T r = REAL(strspn)(s1, s2);
737   if (common_flags()->intercept_strspn) {
738     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
739     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
740   }
741   return r;
742 }
743
744 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
745   void *ctx;
746   COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
747   SIZE_T r = REAL(strcspn)(s1, s2);
748   if (common_flags()->intercept_strspn) {
749     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
750     COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
751   }
752   return r;
753 }
754
755 #define INIT_STRSPN \
756   COMMON_INTERCEPT_FUNCTION(strspn); \
757   COMMON_INTERCEPT_FUNCTION(strcspn);
758 #else
759 #define INIT_STRSPN
760 #endif
761
762 #if SANITIZER_INTERCEPT_STRPBRK
763 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
764   void *ctx;
765   COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
766   char *r = REAL(strpbrk)(s1, s2);
767   if (common_flags()->intercept_strpbrk) {
768     COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1);
769     COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
770         r ? r - s1 + 1 : REAL(strlen)(s1) + 1);
771   }
772   return r;
773 }
774
775 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
776 #else
777 #define INIT_STRPBRK
778 #endif
779
780 #if SANITIZER_INTERCEPT_MEMSET
781 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
782   void *ctx;
783   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);
784 }
785
786 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
787 #else
788 #define INIT_MEMSET
789 #endif
790
791 #if SANITIZER_INTERCEPT_MEMMOVE
792 INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
793   void *ctx;
794   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
795 }
796
797 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
798 #else
799 #define INIT_MEMMOVE
800 #endif
801
802 #if SANITIZER_INTERCEPT_MEMCPY
803 INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
804   // On OS X, calling internal_memcpy here will cause memory corruptions,
805   // because memcpy and memmove are actually aliases of the same
806   // implementation.  We need to use internal_memmove here.
807   // N.B.: If we switch this to internal_ we'll have to use internal_memmove
808   // due to memcpy being an alias of memmove on OS X.
809   void *ctx;
810   if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) {
811     COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
812   } else {
813     COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
814   }
815 }
816
817 #define INIT_MEMCPY                                  \
818   do {                                               \
819     if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \
820       COMMON_INTERCEPT_FUNCTION(memcpy);             \
821     } else {                                         \
822       ASSIGN_REAL(memcpy, memmove);                  \
823     }                                                \
824     CHECK(REAL(memcpy));                             \
825   } while (false)
826
827 #else
828 #define INIT_MEMCPY
829 #endif
830
831 #if SANITIZER_INTERCEPT_MEMCMP
832 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
833                               const void *s1, const void *s2, uptr n,
834                               int result)
835
836 // Common code for `memcmp` and `bcmp`.
837 int MemcmpInterceptorCommon(void *ctx,
838                             int (*real_fn)(const void *, const void *, uptr),
839                             const void *a1, const void *a2, uptr size) {
840   if (common_flags()->intercept_memcmp) {
841     if (common_flags()->strict_memcmp) {
842       // Check the entire regions even if the first bytes of the buffers are
843       // different.
844       COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
845       COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
846       // Fallthrough to REAL(memcmp) below.
847     } else {
848       unsigned char c1 = 0, c2 = 0;
849       const unsigned char *s1 = (const unsigned char*)a1;
850       const unsigned char *s2 = (const unsigned char*)a2;
851       uptr i;
852       for (i = 0; i < size; i++) {
853         c1 = s1[i];
854         c2 = s2[i];
855         if (c1 != c2) break;
856       }
857       COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
858       COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
859       int r = CharCmpX(c1, c2);
860       CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
861                                  a1, a2, size, r);
862       return r;
863     }
864   }
865   int result = real_fn(a1, a2, size);
866   CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
867                              a2, size, result);
868   return result;
869 }
870
871 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
872   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
873     return internal_memcmp(a1, a2, size);
874   void *ctx;
875   COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
876   return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
877 }
878
879 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
880 #else
881 #define INIT_MEMCMP
882 #endif
883
884 #if SANITIZER_INTERCEPT_BCMP
885 INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) {
886   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
887     return internal_memcmp(a1, a2, size);
888   void *ctx;
889   COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
890   return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
891 }
892
893 #define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
894 #else
895 #define INIT_BCMP
896 #endif
897
898 #if SANITIZER_INTERCEPT_MEMCHR
899 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
900   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
901     return internal_memchr(s, c, n);
902   void *ctx;
903   COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
904 #if SANITIZER_WINDOWS
905   void *res;
906   if (REAL(memchr)) {
907     res = REAL(memchr)(s, c, n);
908   } else {
909     res = internal_memchr(s, c, n);
910   }
911 #else
912   void *res = REAL(memchr)(s, c, n);
913 #endif
914   uptr len = res ? (char *)res - (const char *)s + 1 : n;
915   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
916   return res;
917 }
918
919 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
920 #else
921 #define INIT_MEMCHR
922 #endif
923
924 #if SANITIZER_INTERCEPT_MEMRCHR
925 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
926   void *ctx;
927   COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
928   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
929   return REAL(memrchr)(s, c, n);
930 }
931
932 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
933 #else
934 #define INIT_MEMRCHR
935 #endif
936
937 #if SANITIZER_INTERCEPT_FREXP
938 INTERCEPTOR(double, frexp, double x, int *exp) {
939   void *ctx;
940   COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
941   // Assuming frexp() always writes to |exp|.
942   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
943   double res = REAL(frexp)(x, exp);
944   return res;
945 }
946
947 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
948 #else
949 #define INIT_FREXP
950 #endif  // SANITIZER_INTERCEPT_FREXP
951
952 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
953 INTERCEPTOR(float, frexpf, float x, int *exp) {
954   void *ctx;
955   COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
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   float res = REAL(frexpf)(x, exp);
960   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
961   return res;
962 }
963
964 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
965   void *ctx;
966   COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
967   // FIXME: under ASan the call below may write to freed memory and corrupt
968   // its metadata. See
969   // https://github.com/google/sanitizers/issues/321.
970   long double res = REAL(frexpl)(x, exp);
971   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
972   return res;
973 }
974
975 #define INIT_FREXPF_FREXPL           \
976   COMMON_INTERCEPT_FUNCTION(frexpf); \
977   COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
978 #else
979 #define INIT_FREXPF_FREXPL
980 #endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
981
982 #if SI_POSIX
983 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
984                         SIZE_T iovlen, SIZE_T maxlen) {
985   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
986     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
987     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
988     maxlen -= sz;
989   }
990 }
991
992 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
993                        SIZE_T iovlen, SIZE_T maxlen) {
994   COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
995   for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
996     SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
997     COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
998     maxlen -= sz;
999   }
1000 }
1001 #endif
1002
1003 #if SANITIZER_INTERCEPT_READ
1004 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
1005   void *ctx;
1006   COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
1007   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1008   // FIXME: under ASan the call below may write to freed memory and corrupt
1009   // its metadata. See
1010   // https://github.com/google/sanitizers/issues/321.
1011   SSIZE_T res = REAL(read)(fd, ptr, count);
1012   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1013   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1014   return res;
1015 }
1016 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
1017 #else
1018 #define INIT_READ
1019 #endif
1020
1021 #if SANITIZER_INTERCEPT_FREAD
1022 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
1023   // libc file streams can call user-supplied functions, see fopencookie.
1024   void *ctx;
1025   COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
1026   // FIXME: under ASan the call below may write to freed memory and corrupt
1027   // its metadata. See
1028   // https://github.com/google/sanitizers/issues/321.
1029   SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
1030   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
1031   return res;
1032 }
1033 #define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
1034 #else
1035 #define INIT_FREAD
1036 #endif
1037
1038 #if SANITIZER_INTERCEPT_PREAD
1039 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1040   void *ctx;
1041   COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
1042   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1043   // FIXME: under ASan the call below may write to freed memory and corrupt
1044   // its metadata. See
1045   // https://github.com/google/sanitizers/issues/321.
1046   SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
1047   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1048   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1049   return res;
1050 }
1051 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
1052 #else
1053 #define INIT_PREAD
1054 #endif
1055
1056 #if SANITIZER_INTERCEPT_PREAD64
1057 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
1058   void *ctx;
1059   COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
1060   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1061   // FIXME: under ASan the call below may write to freed memory and corrupt
1062   // its metadata. See
1063   // https://github.com/google/sanitizers/issues/321.
1064   SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
1065   if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1066   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1067   return res;
1068 }
1069 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
1070 #else
1071 #define INIT_PREAD64
1072 #endif
1073
1074 #if SANITIZER_INTERCEPT_READV
1075 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
1076                         int iovcnt) {
1077   void *ctx;
1078   COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
1079   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1080   SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
1081   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1082   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1083   return res;
1084 }
1085 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
1086 #else
1087 #define INIT_READV
1088 #endif
1089
1090 #if SANITIZER_INTERCEPT_PREADV
1091 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
1092             OFF_T offset) {
1093   void *ctx;
1094   COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
1095   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1096   SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
1097   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1098   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1099   return res;
1100 }
1101 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
1102 #else
1103 #define INIT_PREADV
1104 #endif
1105
1106 #if SANITIZER_INTERCEPT_PREADV64
1107 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
1108             OFF64_T offset) {
1109   void *ctx;
1110   COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
1111   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1112   SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
1113   if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1114   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1115   return res;
1116 }
1117 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
1118 #else
1119 #define INIT_PREADV64
1120 #endif
1121
1122 #if SANITIZER_INTERCEPT_WRITE
1123 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
1124   void *ctx;
1125   COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
1126   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1127   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1128   SSIZE_T res = REAL(write)(fd, ptr, count);
1129   // FIXME: this check should be _before_ the call to REAL(write), not after
1130   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1131   return res;
1132 }
1133 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
1134 #else
1135 #define INIT_WRITE
1136 #endif
1137
1138 #if SANITIZER_INTERCEPT_FWRITE
1139 INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) {
1140   // libc file streams can call user-supplied functions, see fopencookie.
1141   void *ctx;
1142   COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
1143   SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
1144   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
1145   return res;
1146 }
1147 #define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
1148 #else
1149 #define INIT_FWRITE
1150 #endif
1151
1152 #if SANITIZER_INTERCEPT_PWRITE
1153 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1154   void *ctx;
1155   COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
1156   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1157   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1158   SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
1159   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1160   return res;
1161 }
1162 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
1163 #else
1164 #define INIT_PWRITE
1165 #endif
1166
1167 #if SANITIZER_INTERCEPT_PWRITE64
1168 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
1169             OFF64_T offset) {
1170   void *ctx;
1171   COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
1172   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1173   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1174   SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
1175   if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1176   return res;
1177 }
1178 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
1179 #else
1180 #define INIT_PWRITE64
1181 #endif
1182
1183 #if SANITIZER_INTERCEPT_WRITEV
1184 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
1185                         int iovcnt) {
1186   void *ctx;
1187   COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
1188   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1189   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1190   SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
1191   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1192   return res;
1193 }
1194 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
1195 #else
1196 #define INIT_WRITEV
1197 #endif
1198
1199 #if SANITIZER_INTERCEPT_PWRITEV
1200 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
1201             OFF_T offset) {
1202   void *ctx;
1203   COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
1204   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1205   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1206   SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
1207   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1208   return res;
1209 }
1210 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
1211 #else
1212 #define INIT_PWRITEV
1213 #endif
1214
1215 #if SANITIZER_INTERCEPT_PWRITEV64
1216 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
1217             OFF64_T offset) {
1218   void *ctx;
1219   COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
1220   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1221   if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1222   SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
1223   if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1224   return res;
1225 }
1226 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
1227 #else
1228 #define INIT_PWRITEV64
1229 #endif
1230
1231 #if SANITIZER_INTERCEPT_FGETS
1232 INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {
1233   // libc file streams can call user-supplied functions, see fopencookie.
1234   void *ctx;
1235   COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);
1236   // FIXME: under ASan the call below may write to freed memory and corrupt
1237   // its metadata. See
1238   // https://github.com/google/sanitizers/issues/321.
1239   char *res = REAL(fgets)(s, size, file);
1240   if (res)
1241     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
1242   return res;
1243 }
1244 #define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)
1245 #else
1246 #define INIT_FGETS
1247 #endif
1248
1249 #if SANITIZER_INTERCEPT_FPUTS
1250 INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
1251   // libc file streams can call user-supplied functions, see fopencookie.
1252   void *ctx;
1253   COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
1254   if (!SANITIZER_MAC || s) {  // `fputs(NULL, file)` is supported on Darwin.
1255     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
1256   }
1257   return REAL(fputs)(s, file);
1258 }
1259 #define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
1260 #else
1261 #define INIT_FPUTS
1262 #endif
1263
1264 #if SANITIZER_INTERCEPT_PUTS
1265 INTERCEPTOR(int, puts, char *s) {
1266   // libc file streams can call user-supplied functions, see fopencookie.
1267   void *ctx;
1268   COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
1269   if (!SANITIZER_MAC || s) {  // `puts(NULL)` is supported on Darwin.
1270     COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
1271   }
1272   return REAL(puts)(s);
1273 }
1274 #define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
1275 #else
1276 #define INIT_PUTS
1277 #endif
1278
1279 #if SANITIZER_INTERCEPT_PRCTL
1280 INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
1281             unsigned long arg4, unsigned long arg5) {
1282   void *ctx;
1283   COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
1284   static const int PR_SET_NAME = 15;
1285   int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
1286   if (option == PR_SET_NAME) {
1287     char buff[16];
1288     internal_strncpy(buff, (char *)arg2, 15);
1289     buff[15] = 0;
1290     COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
1291   }
1292   return res;
1293 }
1294 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
1295 #else
1296 #define INIT_PRCTL
1297 #endif  // SANITIZER_INTERCEPT_PRCTL
1298
1299 #if SANITIZER_INTERCEPT_TIME
1300 INTERCEPTOR(unsigned long, time, unsigned long *t) {
1301   void *ctx;
1302   COMMON_INTERCEPTOR_ENTER(ctx, time, t);
1303   unsigned long local_t;
1304   unsigned long res = REAL(time)(&local_t);
1305   if (t && res != (unsigned long)-1) {
1306     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
1307     *t = local_t;
1308   }
1309   return res;
1310 }
1311 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
1312 #else
1313 #define INIT_TIME
1314 #endif  // SANITIZER_INTERCEPT_TIME
1315
1316 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1317 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
1318   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1319 #if !SANITIZER_SOLARIS
1320   if (tm->tm_zone) {
1321     // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
1322     // can point to shared memory and tsan would report a data race.
1323     COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
1324                                         REAL(strlen(tm->tm_zone)) + 1);
1325   }
1326 #endif
1327 }
1328 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
1329   void *ctx;
1330   COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
1331   __sanitizer_tm *res = REAL(localtime)(timep);
1332   if (res) {
1333     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1334     unpoison_tm(ctx, res);
1335   }
1336   return res;
1337 }
1338 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
1339   void *ctx;
1340   COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1341   __sanitizer_tm *res = REAL(localtime_r)(timep, result);
1342   if (res) {
1343     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1344     unpoison_tm(ctx, res);
1345   }
1346   return res;
1347 }
1348 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
1349   void *ctx;
1350   COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
1351   __sanitizer_tm *res = REAL(gmtime)(timep);
1352   if (res) {
1353     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1354     unpoison_tm(ctx, res);
1355   }
1356   return res;
1357 }
1358 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
1359   void *ctx;
1360   COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
1361   __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
1362   if (res) {
1363     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1364     unpoison_tm(ctx, res);
1365   }
1366   return res;
1367 }
1368 INTERCEPTOR(char *, ctime, unsigned long *timep) {
1369   void *ctx;
1370   COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
1371   // FIXME: under ASan the call below may write to freed memory and corrupt
1372   // its metadata. See
1373   // https://github.com/google/sanitizers/issues/321.
1374   char *res = REAL(ctime)(timep);
1375   if (res) {
1376     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1377     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1378   }
1379   return res;
1380 }
1381 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
1382   void *ctx;
1383   COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
1384   // FIXME: under ASan the call below may write to freed memory and corrupt
1385   // its metadata. See
1386   // https://github.com/google/sanitizers/issues/321.
1387   char *res = REAL(ctime_r)(timep, result);
1388   if (res) {
1389     COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1390     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1391   }
1392   return res;
1393 }
1394 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
1395   void *ctx;
1396   COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
1397   // FIXME: under ASan the call below may write to freed memory and corrupt
1398   // its metadata. See
1399   // https://github.com/google/sanitizers/issues/321.
1400   char *res = REAL(asctime)(tm);
1401   if (res) {
1402     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1403     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1404   }
1405   return res;
1406 }
1407 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
1408   void *ctx;
1409   COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
1410   // FIXME: under ASan the call below may write to freed memory and corrupt
1411   // its metadata. See
1412   // https://github.com/google/sanitizers/issues/321.
1413   char *res = REAL(asctime_r)(tm, result);
1414   if (res) {
1415     COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1416     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
1417   }
1418   return res;
1419 }
1420 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
1421   void *ctx;
1422   COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
1423   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
1424   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
1425   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
1426   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
1427   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
1428   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
1429   COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
1430   long res = REAL(mktime)(tm);
1431   if (res != -1) unpoison_tm(ctx, tm);
1432   return res;
1433 }
1434 #define INIT_LOCALTIME_AND_FRIENDS        \
1435   COMMON_INTERCEPT_FUNCTION(localtime);   \
1436   COMMON_INTERCEPT_FUNCTION(localtime_r); \
1437   COMMON_INTERCEPT_FUNCTION(gmtime);      \
1438   COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
1439   COMMON_INTERCEPT_FUNCTION(ctime);       \
1440   COMMON_INTERCEPT_FUNCTION(ctime_r);     \
1441   COMMON_INTERCEPT_FUNCTION(asctime);     \
1442   COMMON_INTERCEPT_FUNCTION(asctime_r);   \
1443   COMMON_INTERCEPT_FUNCTION(mktime);
1444 #else
1445 #define INIT_LOCALTIME_AND_FRIENDS
1446 #endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1447
1448 #if SANITIZER_INTERCEPT_STRPTIME
1449 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
1450   void *ctx;
1451   COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
1452   if (format)
1453     COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1);
1454   // FIXME: under ASan the call below may write to freed memory and corrupt
1455   // its metadata. See
1456   // https://github.com/google/sanitizers/issues/321.
1457   char *res = REAL(strptime)(s, format, tm);
1458   COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
1459   if (res && tm) {
1460     // Do not call unpoison_tm here, because strptime does not, in fact,
1461     // initialize the entire struct tm. For example, tm_zone pointer is left
1462     // uninitialized.
1463     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1464   }
1465   return res;
1466 }
1467 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
1468 #else
1469 #define INIT_STRPTIME
1470 #endif
1471
1472 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
1473 #include "sanitizer_common_interceptors_format.inc"
1474
1475 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
1476   {                                                                            \
1477     void *ctx;                                                                 \
1478     va_list ap;                                                                \
1479     va_start(ap, format);                                                      \
1480     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
1481     int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
1482     va_end(ap);                                                                \
1483     return res;                                                                \
1484   }
1485
1486 #endif
1487
1488 #if SANITIZER_INTERCEPT_SCANF
1489
1490 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
1491   {                                                                            \
1492     void *ctx;                                                                 \
1493     COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
1494     va_list aq;                                                                \
1495     va_copy(aq, ap);                                                           \
1496     int res = REAL(vname)(__VA_ARGS__);                                        \
1497     if (res > 0)                                                               \
1498       scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
1499     va_end(aq);                                                                \
1500     return res;                                                                \
1501   }
1502
1503 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
1504 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
1505
1506 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
1507 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
1508
1509 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
1510 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
1511
1512 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1513 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
1514 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
1515
1516 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
1517             va_list ap)
1518 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
1519
1520 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
1521 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
1522 #endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
1523
1524 INTERCEPTOR(int, scanf, const char *format, ...)
1525 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
1526
1527 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
1528 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
1529
1530 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
1531 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
1532
1533 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1534 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
1535 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
1536
1537 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
1538 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
1539
1540 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
1541 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
1542 #endif
1543
1544 #endif
1545
1546 #if SANITIZER_INTERCEPT_SCANF
1547 #define INIT_SCANF                    \
1548   COMMON_INTERCEPT_FUNCTION_LDBL(scanf);   \
1549   COMMON_INTERCEPT_FUNCTION_LDBL(sscanf);  \
1550   COMMON_INTERCEPT_FUNCTION_LDBL(fscanf);  \
1551   COMMON_INTERCEPT_FUNCTION_LDBL(vscanf);  \
1552   COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \
1553   COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);
1554 #else
1555 #define INIT_SCANF
1556 #endif
1557
1558 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1559 #define INIT_ISOC99_SCANF                      \
1560   COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
1561   COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
1562   COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
1563   COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
1564   COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1565   COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1566 #else
1567 #define INIT_ISOC99_SCANF
1568 #endif
1569
1570 #if SANITIZER_INTERCEPT_PRINTF
1571
1572 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
1573   void *ctx;                                                                   \
1574   COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
1575   va_list aq;                                                                  \
1576   va_copy(aq, ap);
1577
1578 #define VPRINTF_INTERCEPTOR_RETURN()                                           \
1579   va_end(aq);
1580
1581 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
1582   {                                                                            \
1583     VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
1584     if (common_flags()->check_printf)                                          \
1585       printf_common(ctx, format, aq);                                          \
1586     int res = REAL(vname)(__VA_ARGS__);                                        \
1587     VPRINTF_INTERCEPTOR_RETURN();                                              \
1588     return res;                                                                \
1589   }
1590
1591 // FIXME: under ASan the REAL() call below may write to freed memory and
1592 // corrupt its metadata. See
1593 // https://github.com/google/sanitizers/issues/321.
1594 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
1595   {                                                                            \
1596     VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
1597     if (common_flags()->check_printf) {                                        \
1598       printf_common(ctx, format, aq);                                          \
1599     }                                                                          \
1600     int res = REAL(vname)(str, __VA_ARGS__);                                   \
1601     if (res >= 0) {                                                            \
1602       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
1603     }                                                                          \
1604     VPRINTF_INTERCEPTOR_RETURN();                                              \
1605     return res;                                                                \
1606   }
1607
1608 // FIXME: under ASan the REAL() call below may write to freed memory and
1609 // corrupt its metadata. See
1610 // https://github.com/google/sanitizers/issues/321.
1611 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
1612   {                                                                            \
1613     VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
1614     if (common_flags()->check_printf) {                                        \
1615       printf_common(ctx, format, aq);                                          \
1616     }                                                                          \
1617     int res = REAL(vname)(str, size, __VA_ARGS__);                             \
1618     if (res >= 0) {                                                            \
1619       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
1620     }                                                                          \
1621     VPRINTF_INTERCEPTOR_RETURN();                                              \
1622     return res;                                                                \
1623   }
1624
1625 // FIXME: under ASan the REAL() call below may write to freed memory and
1626 // corrupt its metadata. See
1627 // https://github.com/google/sanitizers/issues/321.
1628 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
1629   {                                                                            \
1630     VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
1631     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
1632     if (common_flags()->check_printf) {                                        \
1633       printf_common(ctx, format, aq);                                          \
1634     }                                                                          \
1635     int res = REAL(vname)(strp, __VA_ARGS__);                                  \
1636     if (res >= 0) {                                                            \
1637       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
1638     }                                                                          \
1639     VPRINTF_INTERCEPTOR_RETURN();                                              \
1640     return res;                                                                \
1641   }
1642
1643 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1644 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1645
1646 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1647             va_list ap)
1648 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1649
1650 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1651             va_list ap)
1652 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1653
1654 #if SANITIZER_INTERCEPT___PRINTF_CHK
1655 INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
1656             SIZE_T size_to, const char *format, va_list ap)
1657 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1658 #endif
1659
1660 #if SANITIZER_INTERCEPT_PRINTF_L
1661 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1662             const char *format, va_list ap)
1663 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1664
1665 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1666             const char *format, ...)
1667 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1668 #endif  // SANITIZER_INTERCEPT_PRINTF_L
1669
1670 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1671 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1672
1673 #if SANITIZER_INTERCEPT___PRINTF_CHK
1674 INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
1675             const char *format, va_list ap)
1676 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1677 #endif
1678
1679 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1680 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1681
1682 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1683 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1684 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1685
1686 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1687             const char *format, va_list ap)
1688 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1689
1690 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1691             va_list ap)
1692 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1693
1694 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1695             va_list ap)
1696 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1697                           ap)
1698
1699 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1700
1701 INTERCEPTOR(int, printf, const char *format, ...)
1702 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1703
1704 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1705 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1706
1707 #if SANITIZER_INTERCEPT___PRINTF_CHK
1708 INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
1709             const char *format, ...)
1710 FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
1711 #endif
1712
1713 INTERCEPTOR(int, sprintf, char *str, const char *format, ...)
1714 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)
1715
1716 #if SANITIZER_INTERCEPT___PRINTF_CHK
1717 INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
1718             const char *format, ...)
1719 FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)
1720 #endif
1721
1722 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1723 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1724
1725 #if SANITIZER_INTERCEPT___PRINTF_CHK
1726 INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
1727             SIZE_T size_to, const char *format, ...)
1728 FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
1729 #endif
1730
1731 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1732 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1733
1734 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1735 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1736 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1737
1738 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1739             ...)
1740 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1741
1742 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1743 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1744
1745 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1746             const char *format, ...)
1747 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1748                         format)
1749
1750 #endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1751
1752 #endif  // SANITIZER_INTERCEPT_PRINTF
1753
1754 #if SANITIZER_INTERCEPT_PRINTF
1755 #define INIT_PRINTF                     \
1756   COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
1757   COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
1758   COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
1759   COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
1760   COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
1761   COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
1762   COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
1763   COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1764   COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
1765   COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1766 #else
1767 #define INIT_PRINTF
1768 #endif
1769
1770 #if SANITIZER_INTERCEPT___PRINTF_CHK
1771 #define INIT___PRINTF_CHK                     \
1772   COMMON_INTERCEPT_FUNCTION(__sprintf_chk);   \
1773   COMMON_INTERCEPT_FUNCTION(__snprintf_chk);  \
1774   COMMON_INTERCEPT_FUNCTION(__vsprintf_chk);  \
1775   COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
1776   COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
1777 #else
1778 #define INIT___PRINTF_CHK
1779 #endif
1780
1781 #if SANITIZER_INTERCEPT_PRINTF_L
1782 #define INIT_PRINTF_L                     \
1783   COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
1784   COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1785 #else
1786 #define INIT_PRINTF_L
1787 #endif
1788
1789 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1790 #define INIT_ISOC99_PRINTF                       \
1791   COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
1792   COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
1793   COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
1794   COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
1795   COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
1796   COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
1797   COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1798   COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1799 #else
1800 #define INIT_ISOC99_PRINTF
1801 #endif
1802
1803 #if SANITIZER_INTERCEPT_IOCTL
1804 #include "sanitizer_common_interceptors_ioctl.inc"
1805 #include "sanitizer_interceptors_ioctl_netbsd.inc"
1806 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1807   // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1808   // can trigger a report and we need to be able to unwind through this
1809   // function.  On Mac in debug mode we might not have a frame pointer, because
1810   // ioctl_common_[pre|post] doesn't get inlined here.
1811   ENABLE_FRAME_POINTER;
1812
1813   void *ctx;
1814   va_list ap;
1815   va_start(ap, request);
1816   void *arg = va_arg(ap, void *);
1817   va_end(ap);
1818   COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1819
1820   CHECK(ioctl_initialized);
1821
1822   // Note: TSan does not use common flags, and they are zero-initialized.
1823   // This effectively disables ioctl handling in TSan.
1824   if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1825
1826   // Although request is unsigned long, the rest of the interceptor uses it
1827   // as just "unsigned" to save space, because we know that all values fit in
1828   // "unsigned" - they are compile-time constants.
1829
1830   const ioctl_desc *desc = ioctl_lookup(request);
1831   ioctl_desc decoded_desc;
1832   if (!desc) {
1833     VPrintf(2, "Decoding unknown ioctl 0x%x\n", request);
1834     if (!ioctl_decode(request, &decoded_desc))
1835       Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request);
1836     else
1837       desc = &decoded_desc;
1838   }
1839
1840   if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1841   int res = REAL(ioctl)(d, request, arg);
1842   // FIXME: some ioctls have different return values for success and failure.
1843   if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1844   return res;
1845 }
1846 #define INIT_IOCTL \
1847   ioctl_init();    \
1848   COMMON_INTERCEPT_FUNCTION(ioctl);
1849 #else
1850 #define INIT_IOCTL
1851 #endif
1852
1853 #if SANITIZER_POSIX
1854 UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1855   if (pwd) {
1856     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1857     if (pwd->pw_name)
1858       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,
1859                                      REAL(strlen)(pwd->pw_name) + 1);
1860     if (pwd->pw_passwd)
1861       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,
1862                                      REAL(strlen)(pwd->pw_passwd) + 1);
1863 #if !SANITIZER_ANDROID
1864     if (pwd->pw_gecos)
1865       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
1866                                      REAL(strlen)(pwd->pw_gecos) + 1);
1867 #endif
1868 #if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
1869     if (pwd->pw_class)
1870       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
1871                                      REAL(strlen)(pwd->pw_class) + 1);
1872 #endif
1873     if (pwd->pw_dir)
1874       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,
1875                                      REAL(strlen)(pwd->pw_dir) + 1);
1876     if (pwd->pw_shell)
1877       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,
1878                                      REAL(strlen)(pwd->pw_shell) + 1);
1879   }
1880 }
1881
1882 UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1883   if (grp) {
1884     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1885     if (grp->gr_name)
1886       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,
1887                                      REAL(strlen)(grp->gr_name) + 1);
1888     if (grp->gr_passwd)
1889       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,
1890                                      REAL(strlen)(grp->gr_passwd) + 1);
1891     char **p = grp->gr_mem;
1892     for (; *p; ++p) {
1893       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
1894     }
1895     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,
1896                                    (p - grp->gr_mem + 1) * sizeof(*p));
1897   }
1898 }
1899 #endif  // SANITIZER_POSIX
1900
1901 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1902 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1903   void *ctx;
1904   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1905   if (name)
1906     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1907   __sanitizer_passwd *res = REAL(getpwnam)(name);
1908   unpoison_passwd(ctx, res);
1909   return res;
1910 }
1911 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1912   void *ctx;
1913   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1914   __sanitizer_passwd *res = REAL(getpwuid)(uid);
1915   unpoison_passwd(ctx, res);
1916   return res;
1917 }
1918 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1919   void *ctx;
1920   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1921   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1922   __sanitizer_group *res = REAL(getgrnam)(name);
1923   unpoison_group(ctx, res);
1924   return res;
1925 }
1926 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1927   void *ctx;
1928   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1929   __sanitizer_group *res = REAL(getgrgid)(gid);
1930   unpoison_group(ctx, res);
1931   return res;
1932 }
1933 #define INIT_GETPWNAM_AND_FRIENDS      \
1934   COMMON_INTERCEPT_FUNCTION(getpwnam); \
1935   COMMON_INTERCEPT_FUNCTION(getpwuid); \
1936   COMMON_INTERCEPT_FUNCTION(getgrnam); \
1937   COMMON_INTERCEPT_FUNCTION(getgrgid);
1938 #else
1939 #define INIT_GETPWNAM_AND_FRIENDS
1940 #endif
1941
1942 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1943 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1944             char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1945   void *ctx;
1946   COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1947   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1948   // FIXME: under ASan the call below may write to freed memory and corrupt
1949   // its metadata. See
1950   // https://github.com/google/sanitizers/issues/321.
1951   int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1952   if (!res && result)
1953     unpoison_passwd(ctx, *result);
1954   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1955   return res;
1956 }
1957 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1958             SIZE_T buflen, __sanitizer_passwd **result) {
1959   void *ctx;
1960   COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
1961   // FIXME: under ASan the call below may write to freed memory and corrupt
1962   // its metadata. See
1963   // https://github.com/google/sanitizers/issues/321.
1964   int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1965   if (!res && result)
1966     unpoison_passwd(ctx, *result);
1967   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1968   return res;
1969 }
1970 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1971             char *buf, SIZE_T buflen, __sanitizer_group **result) {
1972   void *ctx;
1973   COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1974   COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
1975   // FIXME: under ASan the call below may write to freed memory and corrupt
1976   // its metadata. See
1977   // https://github.com/google/sanitizers/issues/321.
1978   int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1979   if (!res && result)
1980     unpoison_group(ctx, *result);
1981   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1982   return res;
1983 }
1984 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1985             SIZE_T buflen, __sanitizer_group **result) {
1986   void *ctx;
1987   COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
1988   // FIXME: under ASan the call below may write to freed memory and corrupt
1989   // its metadata. See
1990   // https://github.com/google/sanitizers/issues/321.
1991   int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
1992   if (!res && result)
1993     unpoison_group(ctx, *result);
1994   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1995   return res;
1996 }
1997 #define INIT_GETPWNAM_R_AND_FRIENDS      \
1998   COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
1999   COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
2000   COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
2001   COMMON_INTERCEPT_FUNCTION(getgrgid_r);
2002 #else
2003 #define INIT_GETPWNAM_R_AND_FRIENDS
2004 #endif
2005
2006 #if SANITIZER_INTERCEPT_GETPWENT
2007 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
2008   void *ctx;
2009   COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
2010   __sanitizer_passwd *res = REAL(getpwent)(dummy);
2011   unpoison_passwd(ctx, res);
2012   return res;
2013 }
2014 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
2015   void *ctx;
2016   COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
2017   __sanitizer_group *res = REAL(getgrent)(dummy);
2018   unpoison_group(ctx, res);
2019   return res;
2020 }
2021 #define INIT_GETPWENT                  \
2022   COMMON_INTERCEPT_FUNCTION(getpwent); \
2023   COMMON_INTERCEPT_FUNCTION(getgrent);
2024 #else
2025 #define INIT_GETPWENT
2026 #endif
2027
2028 #if SANITIZER_INTERCEPT_FGETPWENT
2029 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
2030   void *ctx;
2031   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
2032   __sanitizer_passwd *res = REAL(fgetpwent)(fp);
2033   unpoison_passwd(ctx, res);
2034   return res;
2035 }
2036 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
2037   void *ctx;
2038   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
2039   __sanitizer_group *res = REAL(fgetgrent)(fp);
2040   unpoison_group(ctx, res);
2041   return res;
2042 }
2043 #define INIT_FGETPWENT                  \
2044   COMMON_INTERCEPT_FUNCTION(fgetpwent); \
2045   COMMON_INTERCEPT_FUNCTION(fgetgrent);
2046 #else
2047 #define INIT_FGETPWENT
2048 #endif
2049
2050 #if SANITIZER_INTERCEPT_GETPWENT_R
2051 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
2052             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2053   void *ctx;
2054   COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
2055   // FIXME: under ASan the call below may write to freed memory and corrupt
2056   // its metadata. See
2057   // https://github.com/google/sanitizers/issues/321.
2058   int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
2059   if (!res && pwbufp)
2060     unpoison_passwd(ctx, *pwbufp);
2061   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2062   return res;
2063 }
2064 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
2065             __sanitizer_group **pwbufp) {
2066   void *ctx;
2067   COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
2068   // FIXME: under ASan the call below may write to freed memory and corrupt
2069   // its metadata. See
2070   // https://github.com/google/sanitizers/issues/321.
2071   int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
2072   if (!res && pwbufp)
2073     unpoison_group(ctx, *pwbufp);
2074   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2075   return res;
2076 }
2077 #define INIT_GETPWENT_R                   \
2078   COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
2079   COMMON_INTERCEPT_FUNCTION(getgrent_r);
2080 #else
2081 #define INIT_GETPWENT_R
2082 #endif
2083
2084 #if SANITIZER_INTERCEPT_FGETPWENT_R
2085 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
2086             SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2087   void *ctx;
2088   COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
2089   // FIXME: under ASan the call below may write to freed memory and corrupt
2090   // its metadata. See
2091   // https://github.com/google/sanitizers/issues/321.
2092   int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
2093   if (!res && pwbufp)
2094     unpoison_passwd(ctx, *pwbufp);
2095   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2096   return res;
2097 }
2098 #define INIT_FGETPWENT_R                  \
2099   COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
2100 #else
2101 #define INIT_FGETPWENT_R
2102 #endif
2103
2104 #if SANITIZER_INTERCEPT_FGETGRENT_R
2105 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
2106             SIZE_T buflen, __sanitizer_group **pwbufp) {
2107   void *ctx;
2108   COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
2109   // FIXME: under ASan the call below may write to freed memory and corrupt
2110   // its metadata. See
2111   // https://github.com/google/sanitizers/issues/321.
2112   int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
2113   if (!res && pwbufp)
2114     unpoison_group(ctx, *pwbufp);
2115   if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2116   return res;
2117 }
2118 #define INIT_FGETGRENT_R                  \
2119   COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
2120 #else
2121 #define INIT_FGETGRENT_R
2122 #endif
2123
2124 #if SANITIZER_INTERCEPT_SETPWENT
2125 // The only thing these interceptors do is disable any nested interceptors.
2126 // These functions may open nss modules and call uninstrumented functions from
2127 // them, and we don't want things like strlen() to trigger.
2128 INTERCEPTOR(void, setpwent, int dummy) {
2129   void *ctx;
2130   COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
2131   REAL(setpwent)(dummy);
2132 }
2133 INTERCEPTOR(void, endpwent, int dummy) {
2134   void *ctx;
2135   COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
2136   REAL(endpwent)(dummy);
2137 }
2138 INTERCEPTOR(void, setgrent, int dummy) {
2139   void *ctx;
2140   COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
2141   REAL(setgrent)(dummy);
2142 }
2143 INTERCEPTOR(void, endgrent, int dummy) {
2144   void *ctx;
2145   COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
2146   REAL(endgrent)(dummy);
2147 }
2148 #define INIT_SETPWENT                  \
2149   COMMON_INTERCEPT_FUNCTION(setpwent); \
2150   COMMON_INTERCEPT_FUNCTION(endpwent); \
2151   COMMON_INTERCEPT_FUNCTION(setgrent); \
2152   COMMON_INTERCEPT_FUNCTION(endgrent);
2153 #else
2154 #define INIT_SETPWENT
2155 #endif
2156
2157 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
2158 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
2159   void *ctx;
2160   COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
2161   // FIXME: under ASan the call below may write to freed memory and corrupt
2162   // its metadata. See
2163   // https://github.com/google/sanitizers/issues/321.
2164   int res = REAL(clock_getres)(clk_id, tp);
2165   if (!res && tp) {
2166     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2167   }
2168   return res;
2169 }
2170 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
2171   void *ctx;
2172   COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
2173   // FIXME: under ASan the call below may write to freed memory and corrupt
2174   // its metadata. See
2175   // https://github.com/google/sanitizers/issues/321.
2176   int res = REAL(clock_gettime)(clk_id, tp);
2177   if (!res) {
2178     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2179   }
2180   return res;
2181 }
2182 namespace __sanitizer {
2183 extern "C" {
2184 int real_clock_gettime(u32 clk_id, void *tp) {
2185   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
2186     return internal_clock_gettime(clk_id, tp);
2187   return REAL(clock_gettime)(clk_id, tp);
2188 }
2189 }  // extern "C"
2190 }  // namespace __sanitizer
2191 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
2192   void *ctx;
2193   COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
2194   COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
2195   return REAL(clock_settime)(clk_id, tp);
2196 }
2197 #define INIT_CLOCK_GETTIME                  \
2198   COMMON_INTERCEPT_FUNCTION(clock_getres);  \
2199   COMMON_INTERCEPT_FUNCTION(clock_gettime); \
2200   COMMON_INTERCEPT_FUNCTION(clock_settime);
2201 #else
2202 #define INIT_CLOCK_GETTIME
2203 #endif
2204
2205 #if SANITIZER_INTERCEPT_GETITIMER
2206 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
2207   void *ctx;
2208   COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
2209   // FIXME: under ASan the call below may write to freed memory and corrupt
2210   // its metadata. See
2211   // https://github.com/google/sanitizers/issues/321.
2212   int res = REAL(getitimer)(which, curr_value);
2213   if (!res && curr_value) {
2214     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
2215   }
2216   return res;
2217 }
2218 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
2219   void *ctx;
2220   COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
2221   if (new_value) {
2222     // itimerval can contain padding that may be legitimately uninitialized
2223     const struct __sanitizer_itimerval *nv =
2224         (const struct __sanitizer_itimerval *)new_value;
2225     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
2226                                   sizeof(__sanitizer_time_t));
2227     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
2228                                   sizeof(__sanitizer_suseconds_t));
2229     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
2230                                   sizeof(__sanitizer_time_t));
2231     COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
2232                                   sizeof(__sanitizer_suseconds_t));
2233   }
2234   // FIXME: under ASan the call below may write to freed memory and corrupt
2235   // its metadata. See
2236   // https://github.com/google/sanitizers/issues/321.
2237   int res = REAL(setitimer)(which, new_value, old_value);
2238   if (!res && old_value) {
2239     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
2240   }
2241   return res;
2242 }
2243 #define INIT_GETITIMER                  \
2244   COMMON_INTERCEPT_FUNCTION(getitimer); \
2245   COMMON_INTERCEPT_FUNCTION(setitimer);
2246 #else
2247 #define INIT_GETITIMER
2248 #endif
2249
2250 #if SANITIZER_INTERCEPT_GLOB
2251 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
2252   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
2253   // +1 for NULL pointer at the end.
2254   if (pglob->gl_pathv)
2255     COMMON_INTERCEPTOR_WRITE_RANGE(
2256         ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
2257   for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
2258     char *p = pglob->gl_pathv[i];
2259     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1);
2260   }
2261 }
2262
2263 #if SANITIZER_SOLARIS
2264 INTERCEPTOR(int, glob, const char *pattern, int flags,
2265             int (*errfunc)(const char *epath, int eerrno),
2266             __sanitizer_glob_t *pglob) {
2267   void *ctx;
2268   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2269   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2270   int res = REAL(glob)(pattern, flags, errfunc, pglob);
2271   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2272   return res;
2273 }
2274 #else
2275 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
2276
2277 static void wrapped_gl_closedir(void *dir) {
2278   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2279   pglob_copy->gl_closedir(dir);
2280 }
2281
2282 static void *wrapped_gl_readdir(void *dir) {
2283   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2284   return pglob_copy->gl_readdir(dir);
2285 }
2286
2287 static void *wrapped_gl_opendir(const char *s) {
2288   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2289   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
2290   return pglob_copy->gl_opendir(s);
2291 }
2292
2293 static int wrapped_gl_lstat(const char *s, void *st) {
2294   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2295   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
2296   return pglob_copy->gl_lstat(s, st);
2297 }
2298
2299 static int wrapped_gl_stat(const char *s, void *st) {
2300   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2301   COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1);
2302   return pglob_copy->gl_stat(s, st);
2303 }
2304
2305 static const __sanitizer_glob_t kGlobCopy = {
2306       0,                  0,                   0,
2307       0,                  wrapped_gl_closedir, wrapped_gl_readdir,
2308       wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
2309
2310 INTERCEPTOR(int, glob, const char *pattern, int flags,
2311             int (*errfunc)(const char *epath, int eerrno),
2312             __sanitizer_glob_t *pglob) {
2313   void *ctx;
2314   COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2315   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2316   __sanitizer_glob_t glob_copy;
2317   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2318   if (flags & glob_altdirfunc) {
2319     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2320     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2321     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2322     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2323     Swap(pglob->gl_stat, glob_copy.gl_stat);
2324     pglob_copy = &glob_copy;
2325   }
2326   int res = REAL(glob)(pattern, flags, errfunc, pglob);
2327   if (flags & glob_altdirfunc) {
2328     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2329     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2330     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2331     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2332     Swap(pglob->gl_stat, glob_copy.gl_stat);
2333   }
2334   pglob_copy = 0;
2335   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2336   return res;
2337 }
2338 #endif  // SANITIZER_SOLARIS
2339 #define INIT_GLOB                  \
2340   COMMON_INTERCEPT_FUNCTION(glob);
2341 #else  // SANITIZER_INTERCEPT_GLOB
2342 #define INIT_GLOB
2343 #endif  // SANITIZER_INTERCEPT_GLOB
2344
2345 #if SANITIZER_INTERCEPT_GLOB64
2346 INTERCEPTOR(int, glob64, const char *pattern, int flags,
2347             int (*errfunc)(const char *epath, int eerrno),
2348             __sanitizer_glob_t *pglob) {
2349   void *ctx;
2350   COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
2351   COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2352   __sanitizer_glob_t glob_copy;
2353   internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2354   if (flags & glob_altdirfunc) {
2355     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2356     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2357     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2358     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2359     Swap(pglob->gl_stat, glob_copy.gl_stat);
2360     pglob_copy = &glob_copy;
2361   }
2362   int res = REAL(glob64)(pattern, flags, errfunc, pglob);
2363   if (flags & glob_altdirfunc) {
2364     Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2365     Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2366     Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2367     Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2368     Swap(pglob->gl_stat, glob_copy.gl_stat);
2369   }
2370   pglob_copy = 0;
2371   if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2372   return res;
2373 }
2374 #define INIT_GLOB64                \
2375   COMMON_INTERCEPT_FUNCTION(glob64);
2376 #else  // SANITIZER_INTERCEPT_GLOB64
2377 #define INIT_GLOB64
2378 #endif  // SANITIZER_INTERCEPT_GLOB64
2379
2380 #if SANITIZER_INTERCEPT_WAIT
2381 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
2382 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
2383 // details.
2384 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
2385   void *ctx;
2386   COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
2387   // FIXME: under ASan the call below may write to freed memory and corrupt
2388   // its metadata. See
2389   // https://github.com/google/sanitizers/issues/321.
2390   int res = REAL(wait)(status);
2391   if (res != -1 && status)
2392     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2393   return res;
2394 }
2395 // On FreeBSD id_t is always 64-bit wide.
2396 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
2397 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
2398                         int options) {
2399 #else
2400 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
2401                         int options) {
2402 #endif
2403   void *ctx;
2404   COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
2405   // FIXME: under ASan the call below may write to freed memory and corrupt
2406   // its metadata. See
2407   // https://github.com/google/sanitizers/issues/321.
2408   int res = REAL(waitid)(idtype, id, infop, options);
2409   if (res != -1 && infop)
2410     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
2411   return res;
2412 }
2413 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
2414   void *ctx;
2415   COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
2416   // FIXME: under ASan the call below may write to freed memory and corrupt
2417   // its metadata. See
2418   // https://github.com/google/sanitizers/issues/321.
2419   int res = REAL(waitpid)(pid, status, options);
2420   if (res != -1 && status)
2421     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2422   return res;
2423 }
2424 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
2425   void *ctx;
2426   COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
2427   // FIXME: under ASan the call below may write to freed memory and corrupt
2428   // its metadata. See
2429   // https://github.com/google/sanitizers/issues/321.
2430   int res = REAL(wait3)(status, options, rusage);
2431   if (res != -1) {
2432     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2433     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2434   }
2435   return res;
2436 }
2437 #if SANITIZER_ANDROID
2438 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
2439   void *ctx;
2440   COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
2441   // FIXME: under ASan the call below may write to freed memory and corrupt
2442   // its metadata. See
2443   // https://github.com/google/sanitizers/issues/321.
2444   int res = REAL(__wait4)(pid, status, options, rusage);
2445   if (res != -1) {
2446     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2447     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2448   }
2449   return res;
2450 }
2451 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
2452 #else
2453 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
2454   void *ctx;
2455   COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
2456   // FIXME: under ASan the call below may write to freed memory and corrupt
2457   // its metadata. See
2458   // https://github.com/google/sanitizers/issues/321.
2459   int res = REAL(wait4)(pid, status, options, rusage);
2460   if (res != -1) {
2461     if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2462     if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2463   }
2464   return res;
2465 }
2466 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
2467 #endif  // SANITIZER_ANDROID
2468 #define INIT_WAIT                     \
2469   COMMON_INTERCEPT_FUNCTION(wait);    \
2470   COMMON_INTERCEPT_FUNCTION(waitid);  \
2471   COMMON_INTERCEPT_FUNCTION(waitpid); \
2472   COMMON_INTERCEPT_FUNCTION(wait3);
2473 #else
2474 #define INIT_WAIT
2475 #define INIT_WAIT4
2476 #endif
2477
2478 #if SANITIZER_INTERCEPT_INET
2479 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
2480   void *ctx;
2481   COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
2482   uptr sz = __sanitizer_in_addr_sz(af);
2483   if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
2484   // FIXME: figure out read size based on the address family.
2485   // FIXME: under ASan the call below may write to freed memory and corrupt
2486   // its metadata. See
2487   // https://github.com/google/sanitizers/issues/321.
2488   char *res = REAL(inet_ntop)(af, src, dst, size);
2489   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
2490   return res;
2491 }
2492 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
2493   void *ctx;
2494   COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
2495   COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
2496   // FIXME: figure out read size based on the address family.
2497   // FIXME: under ASan the call below may write to freed memory and corrupt
2498   // its metadata. See
2499   // https://github.com/google/sanitizers/issues/321.
2500   int res = REAL(inet_pton)(af, src, dst);
2501   if (res == 1) {
2502     uptr sz = __sanitizer_in_addr_sz(af);
2503     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2504   }
2505   return res;
2506 }
2507 #define INIT_INET                       \
2508   COMMON_INTERCEPT_FUNCTION(inet_ntop); \
2509   COMMON_INTERCEPT_FUNCTION(inet_pton);
2510 #else
2511 #define INIT_INET
2512 #endif
2513
2514 #if SANITIZER_INTERCEPT_INET
2515 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
2516   void *ctx;
2517   COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
2518   if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1);
2519   // FIXME: under ASan the call below may write to freed memory and corrupt
2520   // its metadata. See
2521   // https://github.com/google/sanitizers/issues/321.
2522   int res = REAL(inet_aton)(cp, dst);
2523   if (res != 0) {
2524     uptr sz = __sanitizer_in_addr_sz(af_inet);
2525     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2526   }
2527   return res;
2528 }
2529 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
2530 #else
2531 #define INIT_INET_ATON
2532 #endif
2533
2534 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
2535 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
2536   void *ctx;
2537   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
2538   // FIXME: under ASan the call below may write to freed memory and corrupt
2539   // its metadata. See
2540   // https://github.com/google/sanitizers/issues/321.
2541   int res = REAL(pthread_getschedparam)(thread, policy, param);
2542   if (res == 0) {
2543     if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
2544     if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
2545   }
2546   return res;
2547 }
2548 #define INIT_PTHREAD_GETSCHEDPARAM \
2549   COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
2550 #else
2551 #define INIT_PTHREAD_GETSCHEDPARAM
2552 #endif
2553
2554 #if SANITIZER_INTERCEPT_GETADDRINFO
2555 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
2556             struct __sanitizer_addrinfo *hints,
2557             struct __sanitizer_addrinfo **out) {
2558   void *ctx;
2559   COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
2560   if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1);
2561   if (service)
2562     COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1);
2563   if (hints)
2564     COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
2565   // FIXME: under ASan the call below may write to freed memory and corrupt
2566   // its metadata. See
2567   // https://github.com/google/sanitizers/issues/321.
2568   int res = REAL(getaddrinfo)(node, service, hints, out);
2569   if (res == 0 && out) {
2570     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
2571     struct __sanitizer_addrinfo *p = *out;
2572     while (p) {
2573       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2574       if (p->ai_addr)
2575         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
2576       if (p->ai_canonname)
2577         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
2578                                        REAL(strlen)(p->ai_canonname) + 1);
2579       p = p->ai_next;
2580     }
2581   }
2582   return res;
2583 }
2584 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
2585 #else
2586 #define INIT_GETADDRINFO
2587 #endif
2588
2589 #if SANITIZER_INTERCEPT_GETNAMEINFO
2590 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
2591             unsigned hostlen, char *serv, unsigned servlen, int flags) {
2592   void *ctx;
2593   COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
2594                            serv, servlen, flags);
2595   // FIXME: consider adding READ_RANGE(sockaddr, salen)
2596   // There is padding in in_addr that may make this too noisy
2597   // FIXME: under ASan the call below may write to freed memory and corrupt
2598   // its metadata. See
2599   // https://github.com/google/sanitizers/issues/321.
2600   int res =
2601       REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
2602   if (res == 0) {
2603     if (host && hostlen)
2604       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1);
2605     if (serv && servlen)
2606       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1);
2607   }
2608   return res;
2609 }
2610 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
2611 #else
2612 #define INIT_GETNAMEINFO
2613 #endif
2614
2615 #if SANITIZER_INTERCEPT_GETSOCKNAME
2616 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) {
2617   void *ctx;
2618   COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
2619   COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2620   int addrlen_in = *addrlen;
2621   // FIXME: under ASan the call below may write to freed memory and corrupt
2622   // its metadata. See
2623   // https://github.com/google/sanitizers/issues/321.
2624   int res = REAL(getsockname)(sock_fd, addr, addrlen);
2625   if (res == 0) {
2626     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen));
2627   }
2628   return res;
2629 }
2630 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2631 #else
2632 #define INIT_GETSOCKNAME
2633 #endif
2634
2635 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2636 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2637   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2638   if (h->h_name)
2639     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1);
2640   char **p = h->h_aliases;
2641   while (*p) {
2642     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
2643     ++p;
2644   }
2645   COMMON_INTERCEPTOR_WRITE_RANGE(
2646       ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2647   p = h->h_addr_list;
2648   while (*p) {
2649     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2650     ++p;
2651   }
2652   COMMON_INTERCEPTOR_WRITE_RANGE(
2653       ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2654 }
2655 #endif
2656
2657 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
2658 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2659   void *ctx;
2660   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2661   struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2662   if (res) write_hostent(ctx, res);
2663   return res;
2664 }
2665
2666 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2667             int type) {
2668   void *ctx;
2669   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2670   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2671   struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2672   if (res) write_hostent(ctx, res);
2673   return res;
2674 }
2675
2676 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2677   void *ctx;
2678   COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2679   struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2680   if (res) write_hostent(ctx, res);
2681   return res;
2682 }
2683 #define INIT_GETHOSTBYNAME                  \
2684   COMMON_INTERCEPT_FUNCTION(gethostent);    \
2685   COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2686   COMMON_INTERCEPT_FUNCTION(gethostbyname);
2687 #else
2688 #define INIT_GETHOSTBYNAME
2689 #endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME
2690
2691 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2
2692 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2693   void *ctx;
2694   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2695   struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2696   if (res) write_hostent(ctx, res);
2697   return res;
2698 }
2699 #define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2700 #else
2701 #define INIT_GETHOSTBYNAME2
2702 #endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME2
2703
2704 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2705 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2706             char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2707             int *h_errnop) {
2708   void *ctx;
2709   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2710                            h_errnop);
2711   // FIXME: under ASan the call below may write to freed memory and corrupt
2712   // its metadata. See
2713   // https://github.com/google/sanitizers/issues/321.
2714   int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2715   if (result) {
2716     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2717     if (res == 0 && *result) write_hostent(ctx, *result);
2718   }
2719   if (h_errnop)
2720     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2721   return res;
2722 }
2723 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2724 #else
2725 #define INIT_GETHOSTBYNAME_R
2726 #endif
2727
2728 #if SANITIZER_INTERCEPT_GETHOSTENT_R
2729 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2730             SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2731   void *ctx;
2732   COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2733                            h_errnop);
2734   // FIXME: under ASan the call below may write to freed memory and corrupt
2735   // its metadata. See
2736   // https://github.com/google/sanitizers/issues/321.
2737   int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2738   if (result) {
2739     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2740     if (res == 0 && *result) write_hostent(ctx, *result);
2741   }
2742   if (h_errnop)
2743     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2744   return res;
2745 }
2746 #define INIT_GETHOSTENT_R                  \
2747   COMMON_INTERCEPT_FUNCTION(gethostent_r);
2748 #else
2749 #define INIT_GETHOSTENT_R
2750 #endif
2751
2752 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
2753 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
2754             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2755             __sanitizer_hostent **result, int *h_errnop) {
2756   void *ctx;
2757   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
2758                            buflen, result, h_errnop);
2759   COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2760   // FIXME: under ASan the call below may write to freed memory and corrupt
2761   // its metadata. See
2762   // https://github.com/google/sanitizers/issues/321.
2763   int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
2764                                   h_errnop);
2765   if (result) {
2766     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2767     if (res == 0 && *result) write_hostent(ctx, *result);
2768   }
2769   if (h_errnop)
2770     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2771   return res;
2772 }
2773 #define INIT_GETHOSTBYADDR_R                  \
2774   COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
2775 #else
2776 #define INIT_GETHOSTBYADDR_R
2777 #endif
2778
2779 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
2780 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
2781             struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2782             __sanitizer_hostent **result, int *h_errnop) {
2783   void *ctx;
2784   COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
2785                            result, h_errnop);
2786   // FIXME: under ASan the call below may write to freed memory and corrupt
2787   // its metadata. See
2788   // https://github.com/google/sanitizers/issues/321.
2789   int res =
2790       REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
2791   if (result) {
2792     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2793     if (res == 0 && *result) write_hostent(ctx, *result);
2794   }
2795   if (h_errnop)
2796     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2797   return res;
2798 }
2799 #define INIT_GETHOSTBYNAME2_R                  \
2800   COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
2801 #else
2802 #define INIT_GETHOSTBYNAME2_R
2803 #endif
2804
2805 #if SANITIZER_INTERCEPT_GETSOCKOPT
2806 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2807             int *optlen) {
2808   void *ctx;
2809   COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2810                            optlen);
2811   if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
2812   // FIXME: under ASan the call below may write to freed memory and corrupt
2813   // its metadata. See
2814   // https://github.com/google/sanitizers/issues/321.
2815   int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2816   if (res == 0)
2817     if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2818   return res;
2819 }
2820 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2821 #else
2822 #define INIT_GETSOCKOPT
2823 #endif
2824
2825 #if SANITIZER_INTERCEPT_ACCEPT
2826 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
2827   void *ctx;
2828   COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
2829   unsigned addrlen0 = 0;
2830   if (addrlen) {
2831     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2832     addrlen0 = *addrlen;
2833   }
2834   int fd2 = REAL(accept)(fd, addr, addrlen);
2835   if (fd2 >= 0) {
2836     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2837     if (addr && addrlen)
2838       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2839   }
2840   return fd2;
2841 }
2842 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
2843 #else
2844 #define INIT_ACCEPT
2845 #endif
2846
2847 #if SANITIZER_INTERCEPT_ACCEPT4
2848 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
2849   void *ctx;
2850   COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
2851   unsigned addrlen0 = 0;
2852   if (addrlen) {
2853     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2854     addrlen0 = *addrlen;
2855   }
2856   // FIXME: under ASan the call below may write to freed memory and corrupt
2857   // its metadata. See
2858   // https://github.com/google/sanitizers/issues/321.
2859   int fd2 = REAL(accept4)(fd, addr, addrlen, f);
2860   if (fd2 >= 0) {
2861     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2862     if (addr && addrlen)
2863       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2864   }
2865   return fd2;
2866 }
2867 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2868 #else
2869 #define INIT_ACCEPT4
2870 #endif
2871
2872 #if SANITIZER_INTERCEPT_PACCEPT
2873 INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,
2874             __sanitizer_sigset_t *set, int f) {
2875   void *ctx;
2876   COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);
2877   unsigned addrlen0 = 0;
2878   if (addrlen) {
2879     COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2880     addrlen0 = *addrlen;
2881   }
2882   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
2883   int fd2 = REAL(paccept)(fd, addr, addrlen, set, f);
2884   if (fd2 >= 0) {
2885     if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2886     if (addr && addrlen)
2887       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2888   }
2889   return fd2;
2890 }
2891 #define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);
2892 #else
2893 #define INIT_PACCEPT
2894 #endif
2895
2896 #if SANITIZER_INTERCEPT_MODF
2897 INTERCEPTOR(double, modf, double x, double *iptr) {
2898   void *ctx;
2899   COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
2900   // FIXME: under ASan the call below may write to freed memory and corrupt
2901   // its metadata. See
2902   // https://github.com/google/sanitizers/issues/321.
2903   double res = REAL(modf)(x, iptr);
2904   if (iptr) {
2905     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2906   }
2907   return res;
2908 }
2909 INTERCEPTOR(float, modff, float x, float *iptr) {
2910   void *ctx;
2911   COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
2912   // FIXME: under ASan the call below may write to freed memory and corrupt
2913   // its metadata. See
2914   // https://github.com/google/sanitizers/issues/321.
2915   float res = REAL(modff)(x, iptr);
2916   if (iptr) {
2917     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2918   }
2919   return res;
2920 }
2921 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
2922   void *ctx;
2923   COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
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   long double res = REAL(modfl)(x, iptr);
2928   if (iptr) {
2929     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
2930   }
2931   return res;
2932 }
2933 #define INIT_MODF                   \
2934   COMMON_INTERCEPT_FUNCTION(modf);  \
2935   COMMON_INTERCEPT_FUNCTION(modff); \
2936   COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
2937 #else
2938 #define INIT_MODF
2939 #endif
2940
2941 #if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG
2942 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
2943                          SSIZE_T maxlen) {
2944   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
2945   if (msg->msg_name && msg->msg_namelen)
2946     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
2947   if (msg->msg_iov && msg->msg_iovlen)
2948     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
2949                                    sizeof(*msg->msg_iov) * msg->msg_iovlen);
2950   write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
2951   if (msg->msg_control && msg->msg_controllen)
2952     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
2953 }
2954 #endif
2955
2956 #if SANITIZER_INTERCEPT_RECVMSG
2957 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
2958             int flags) {
2959   void *ctx;
2960   COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
2961   // FIXME: under ASan the call below may write to freed memory and corrupt
2962   // its metadata. See
2963   // https://github.com/google/sanitizers/issues/321.
2964   SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
2965   if (res >= 0) {
2966     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2967     if (msg) {
2968       write_msghdr(ctx, msg, res);
2969       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
2970     }
2971   }
2972   return res;
2973 }
2974 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
2975 #else
2976 #define INIT_RECVMSG
2977 #endif
2978
2979 #if SANITIZER_INTERCEPT_RECVMMSG
2980 INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
2981             unsigned int vlen, int flags, void *timeout) {
2982   void *ctx;
2983   COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);
2984   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
2985   int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);
2986   if (res >= 0) {
2987     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
2988     for (int i = 0; i < res; ++i) {
2989       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
2990                                      sizeof(msgvec[i].msg_len));
2991       write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
2992       COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);
2993     }
2994   }
2995   return res;
2996 }
2997 #define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);
2998 #else
2999 #define INIT_RECVMMSG
3000 #endif
3001
3002 #if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG
3003 static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
3004   const unsigned kCmsgDataOffset =
3005       RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
3006
3007   char *p = (char *)control;
3008   char *const control_end = p + controllen;
3009   while (true) {
3010     if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
3011     __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
3012     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
3013
3014     if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
3015
3016     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
3017                                   sizeof(cmsg->cmsg_level));
3018     COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
3019                                   sizeof(cmsg->cmsg_type));
3020
3021     if (cmsg->cmsg_len > kCmsgDataOffset) {
3022       char *data = p + kCmsgDataOffset;
3023       unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
3024       if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
3025     }
3026
3027     p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
3028   }
3029 }
3030
3031 static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
3032                         SSIZE_T maxlen) {
3033 #define R(f) \
3034   COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
3035   R(name);
3036   R(namelen);
3037   R(iov);
3038   R(iovlen);
3039   R(control);
3040   R(controllen);
3041   R(flags);
3042 #undef R
3043   if (msg->msg_name && msg->msg_namelen)
3044     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
3045   if (msg->msg_iov && msg->msg_iovlen)
3046     COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
3047                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
3048   read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
3049   if (msg->msg_control && msg->msg_controllen)
3050     read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
3051 }
3052 #endif
3053
3054 #if SANITIZER_INTERCEPT_SENDMSG
3055 INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
3056             int flags) {
3057   void *ctx;
3058   COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
3059   if (fd >= 0) {
3060     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3061     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3062   }
3063   SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
3064   if (common_flags()->intercept_send && res >= 0 && msg)
3065     read_msghdr(ctx, msg, res);
3066   return res;
3067 }
3068 #define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
3069 #else
3070 #define INIT_SENDMSG
3071 #endif
3072
3073 #if SANITIZER_INTERCEPT_SENDMMSG
3074 INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
3075             unsigned vlen, int flags) {
3076   void *ctx;
3077   COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);
3078   if (fd >= 0) {
3079     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3080     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3081   }
3082   int res = REAL(sendmmsg)(fd, msgvec, vlen, flags);
3083   if (res >= 0 && msgvec) {
3084     for (int i = 0; i < res; ++i) {
3085       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
3086                                      sizeof(msgvec[i].msg_len));
3087       if (common_flags()->intercept_send)
3088         read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
3089     }
3090   }
3091   return res;
3092 }
3093 #define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);
3094 #else
3095 #define INIT_SENDMMSG
3096 #endif
3097
3098 #if SANITIZER_INTERCEPT_GETPEERNAME
3099 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
3100   void *ctx;
3101   COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
3102   unsigned addr_sz;
3103   if (addrlen) addr_sz = *addrlen;
3104   // FIXME: under ASan the call below may write to freed memory and corrupt
3105   // its metadata. See
3106   // https://github.com/google/sanitizers/issues/321.
3107   int res = REAL(getpeername)(sockfd, addr, addrlen);
3108   if (!res && addr && addrlen)
3109     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
3110   return res;
3111 }
3112 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
3113 #else
3114 #define INIT_GETPEERNAME
3115 #endif
3116
3117 #if SANITIZER_INTERCEPT_SYSINFO
3118 INTERCEPTOR(int, sysinfo, void *info) {
3119   void *ctx;
3120   // FIXME: under ASan the call below may write to freed memory and corrupt
3121   // its metadata. See
3122   // https://github.com/google/sanitizers/issues/321.
3123   COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
3124   int res = REAL(sysinfo)(info);
3125   if (!res && info)
3126     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
3127   return res;
3128 }
3129 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
3130 #else
3131 #define INIT_SYSINFO
3132 #endif
3133
3134 #if SANITIZER_INTERCEPT_READDIR
3135 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
3136   void *ctx;
3137   COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
3138   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3139   __sanitizer_dirent *res = REAL(opendir)(path);
3140   if (res)
3141     COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
3142   return res;
3143 }
3144
3145 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
3146   void *ctx;
3147   COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
3148   // FIXME: under ASan the call below may write to freed memory and corrupt
3149   // its metadata. See
3150   // https://github.com/google/sanitizers/issues/321.
3151   __sanitizer_dirent *res = REAL(readdir)(dirp);
3152   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3153   return res;
3154 }
3155
3156 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
3157             __sanitizer_dirent **result) {
3158   void *ctx;
3159   COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
3160   // FIXME: under ASan the call below may write to freed memory and corrupt
3161   // its metadata. See
3162   // https://github.com/google/sanitizers/issues/321.
3163   int res = REAL(readdir_r)(dirp, entry, result);
3164   if (!res) {
3165     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3166     if (*result)
3167       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3168   }
3169   return res;
3170 }
3171
3172 #define INIT_READDIR                  \
3173   COMMON_INTERCEPT_FUNCTION(opendir); \
3174   COMMON_INTERCEPT_FUNCTION(readdir); \
3175   COMMON_INTERCEPT_FUNCTION(readdir_r);
3176 #else
3177 #define INIT_READDIR
3178 #endif
3179
3180 #if SANITIZER_INTERCEPT_READDIR64
3181 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
3182   void *ctx;
3183   COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
3184   // FIXME: under ASan the call below may write to freed memory and corrupt
3185   // its metadata. See
3186   // https://github.com/google/sanitizers/issues/321.
3187   __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
3188   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3189   return res;
3190 }
3191
3192 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
3193             __sanitizer_dirent64 **result) {
3194   void *ctx;
3195   COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
3196   // FIXME: under ASan the call below may write to freed memory and corrupt
3197   // its metadata. See
3198   // https://github.com/google/sanitizers/issues/321.
3199   int res = REAL(readdir64_r)(dirp, entry, result);
3200   if (!res) {
3201     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3202     if (*result)
3203       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3204   }
3205   return res;
3206 }
3207 #define INIT_READDIR64                  \
3208   COMMON_INTERCEPT_FUNCTION(readdir64); \
3209   COMMON_INTERCEPT_FUNCTION(readdir64_r);
3210 #else
3211 #define INIT_READDIR64
3212 #endif
3213
3214 #if SANITIZER_INTERCEPT_PTRACE
3215 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
3216   void *ctx;
3217   COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
3218   __sanitizer_iovec local_iovec;
3219
3220   if (data) {
3221     if (request == ptrace_setregs) {
3222       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
3223     } else if (request == ptrace_setfpregs) {
3224       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3225     } else if (request == ptrace_setfpxregs) {
3226       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3227     } else if (request == ptrace_setvfpregs) {
3228       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3229     } else if (request == ptrace_setsiginfo) {
3230       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
3231
3232     // Some kernel might zero the iovec::iov_base in case of invalid
3233     // write access.  In this case copy the invalid address for further
3234     // inspection.
3235     } else if (request == ptrace_setregset || request == ptrace_getregset) {
3236       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3237       COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
3238       local_iovec = *iovec;
3239       if (request == ptrace_setregset)
3240         COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
3241     }
3242   }
3243
3244   // FIXME: under ASan the call below may write to freed memory and corrupt
3245   // its metadata. See
3246   // https://github.com/google/sanitizers/issues/321.
3247   uptr res = REAL(ptrace)(request, pid, addr, data);
3248
3249   if (!res && data) {
3250     // Note that PEEK* requests assign different meaning to the return value.
3251     // This function does not handle them (nor does it need to).
3252     if (request == ptrace_getregs) {
3253       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
3254     } else if (request == ptrace_getfpregs) {
3255       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3256     } else if (request == ptrace_getfpxregs) {
3257       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3258     } else if (request == ptrace_getvfpregs) {
3259       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3260     } else if (request == ptrace_getsiginfo) {
3261       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
3262     } else if (request == ptrace_geteventmsg) {
3263       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
3264     } else if (request == ptrace_getregset) {
3265       __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3266       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
3267       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
3268                                      local_iovec.iov_len);
3269     }
3270   }
3271   return res;
3272 }
3273
3274 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
3275 #else
3276 #define INIT_PTRACE
3277 #endif
3278
3279 #if SANITIZER_INTERCEPT_SETLOCALE
3280 static void unpoison_ctype_arrays(void *ctx) {
3281 #if SANITIZER_NETBSD
3282   // These arrays contain 256 regular elements in unsigned char range + 1 EOF
3283   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
3284   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
3285   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
3286 #endif
3287 }
3288
3289 INTERCEPTOR(char *, setlocale, int category, char *locale) {
3290   void *ctx;
3291   COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
3292   if (locale)
3293     COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1);
3294   char *res = REAL(setlocale)(category, locale);
3295   if (res) {
3296     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3297     unpoison_ctype_arrays(ctx);
3298   }
3299   return res;
3300 }
3301
3302 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
3303 #else
3304 #define INIT_SETLOCALE
3305 #endif
3306
3307 #if SANITIZER_INTERCEPT_GETCWD
3308 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
3309   void *ctx;
3310   COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
3311   // FIXME: under ASan the call below may write to freed memory and corrupt
3312   // its metadata. See
3313   // https://github.com/google/sanitizers/issues/321.
3314   char *res = REAL(getcwd)(buf, size);
3315   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3316   return res;
3317 }
3318 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
3319 #else
3320 #define INIT_GETCWD
3321 #endif
3322
3323 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
3324 INTERCEPTOR(char *, get_current_dir_name, int fake) {
3325   void *ctx;
3326   COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
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   char *res = REAL(get_current_dir_name)(fake);
3331   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3332   return res;
3333 }
3334
3335 #define INIT_GET_CURRENT_DIR_NAME \
3336   COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
3337 #else
3338 #define INIT_GET_CURRENT_DIR_NAME
3339 #endif
3340
3341 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
3342   CHECK(endptr);
3343   if (nptr == *endptr) {
3344     // No digits were found at strtol call, we need to find out the last
3345     // symbol accessed by strtoll on our own.
3346     // We get this symbol by skipping leading blanks and optional +/- sign.
3347     while (IsSpace(*nptr)) nptr++;
3348     if (*nptr == '+' || *nptr == '-') nptr++;
3349     *endptr = const_cast<char *>(nptr);
3350   }
3351   CHECK(*endptr >= nptr);
3352 }
3353
3354 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
3355                              char **endptr, char *real_endptr, int base) {
3356   if (endptr) {
3357     *endptr = real_endptr;
3358     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
3359   }
3360   // If base has unsupported value, strtol can exit with EINVAL
3361   // without reading any characters. So do additional checks only
3362   // if base is valid.
3363   bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
3364   if (is_valid_base) {
3365     FixRealStrtolEndptr(nptr, &real_endptr);
3366   }
3367   COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
3368                                  (real_endptr - nptr) + 1 : 0);
3369 }
3370
3371
3372 #if SANITIZER_INTERCEPT_STRTOIMAX
3373 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
3374   void *ctx;
3375   COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
3376   // FIXME: under ASan the call below may write to freed memory and corrupt
3377   // its metadata. See
3378   // https://github.com/google/sanitizers/issues/321.
3379   char *real_endptr;
3380   INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
3381   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3382   return res;
3383 }
3384
3385 INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
3386   void *ctx;
3387   COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
3388   // FIXME: under ASan the call below may write to freed memory and corrupt
3389   // its metadata. See
3390   // https://github.com/google/sanitizers/issues/321.
3391   char *real_endptr;
3392   UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
3393   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3394   return res;
3395 }
3396
3397 #define INIT_STRTOIMAX                  \
3398   COMMON_INTERCEPT_FUNCTION(strtoimax); \
3399   COMMON_INTERCEPT_FUNCTION(strtoumax);
3400 #else
3401 #define INIT_STRTOIMAX
3402 #endif
3403
3404 #if SANITIZER_INTERCEPT_MBSTOWCS
3405 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
3406   void *ctx;
3407   COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
3408   // FIXME: under ASan the call below may write to freed memory and corrupt
3409   // its metadata. See
3410   // https://github.com/google/sanitizers/issues/321.
3411   SIZE_T res = REAL(mbstowcs)(dest, src, len);
3412   if (res != (SIZE_T) - 1 && dest) {
3413     SIZE_T write_cnt = res + (res < len);
3414     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3415   }
3416   return res;
3417 }
3418
3419 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
3420             void *ps) {
3421   void *ctx;
3422   COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
3423   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3424   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3425   // FIXME: under ASan the call below may write to freed memory and corrupt
3426   // its metadata. See
3427   // https://github.com/google/sanitizers/issues/321.
3428   SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
3429   if (res != (SIZE_T)(-1) && dest && src) {
3430     // This function, and several others, may or may not write the terminating
3431     // \0 character. They write it iff they clear *src.
3432     SIZE_T write_cnt = res + !*src;
3433     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3434   }
3435   return res;
3436 }
3437
3438 #define INIT_MBSTOWCS                  \
3439   COMMON_INTERCEPT_FUNCTION(mbstowcs); \
3440   COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
3441 #else
3442 #define INIT_MBSTOWCS
3443 #endif
3444
3445 #if SANITIZER_INTERCEPT_MBSNRTOWCS
3446 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
3447             SIZE_T len, void *ps) {
3448   void *ctx;
3449   COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
3450   if (src) {
3451     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3452     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3453   }
3454   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3455   // FIXME: under ASan the call below may write to freed memory and corrupt
3456   // its metadata. See
3457   // https://github.com/google/sanitizers/issues/321.
3458   SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
3459   if (res != (SIZE_T)(-1) && dest && src) {
3460     SIZE_T write_cnt = res + !*src;
3461     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3462   }
3463   return res;
3464 }
3465
3466 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
3467 #else
3468 #define INIT_MBSNRTOWCS
3469 #endif
3470
3471 #if SANITIZER_INTERCEPT_WCSTOMBS
3472 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
3473   void *ctx;
3474   COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
3475   // FIXME: under ASan the call below may write to freed memory and corrupt
3476   // its metadata. See
3477   // https://github.com/google/sanitizers/issues/321.
3478   SIZE_T res = REAL(wcstombs)(dest, src, len);
3479   if (res != (SIZE_T) - 1 && dest) {
3480     SIZE_T write_cnt = res + (res < len);
3481     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3482   }
3483   return res;
3484 }
3485
3486 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
3487             void *ps) {
3488   void *ctx;
3489   COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
3490   if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3491   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3492   // FIXME: under ASan the call below may write to freed memory and corrupt
3493   // its metadata. See
3494   // https://github.com/google/sanitizers/issues/321.
3495   SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
3496   if (res != (SIZE_T) - 1 && dest && src) {
3497     SIZE_T write_cnt = res + !*src;
3498     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3499   }
3500   return res;
3501 }
3502
3503 #define INIT_WCSTOMBS                  \
3504   COMMON_INTERCEPT_FUNCTION(wcstombs); \
3505   COMMON_INTERCEPT_FUNCTION(wcsrtombs);
3506 #else
3507 #define INIT_WCSTOMBS
3508 #endif
3509
3510 #if SANITIZER_INTERCEPT_WCSNRTOMBS
3511 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
3512             SIZE_T len, void *ps) {
3513   void *ctx;
3514   COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
3515   if (src) {
3516     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3517     if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3518   }
3519   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3520   // FIXME: under ASan the call below may write to freed memory and corrupt
3521   // its metadata. See
3522   // https://github.com/google/sanitizers/issues/321.
3523   SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
3524   if (res != ((SIZE_T)-1) && dest && src) {
3525     SIZE_T write_cnt = res + !*src;
3526     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3527   }
3528   return res;
3529 }
3530
3531 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
3532 #else
3533 #define INIT_WCSNRTOMBS
3534 #endif
3535
3536
3537 #if SANITIZER_INTERCEPT_WCRTOMB
3538 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
3539   void *ctx;
3540   COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
3541   if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3542
3543   if (!dest)
3544     return REAL(wcrtomb)(dest, src, ps);
3545
3546   char local_dest[32];
3547   SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
3548   if (res != ((SIZE_T)-1)) {
3549     CHECK_LE(res, sizeof(local_dest));
3550     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3551     REAL(memcpy)(dest, local_dest, res);
3552   }
3553   return res;
3554 }
3555
3556 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
3557 #else
3558 #define INIT_WCRTOMB
3559 #endif
3560
3561 #if SANITIZER_INTERCEPT_WCTOMB
3562 INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
3563   void *ctx;
3564   COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
3565   if (!dest)
3566     return REAL(wctomb)(dest, src);
3567
3568   char local_dest[32];
3569   int res = REAL(wctomb)(local_dest, src);
3570   if (res != -1) {
3571     CHECK_LE(res, sizeof(local_dest));
3572     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3573     REAL(memcpy)(dest, local_dest, res);
3574   }
3575   return res;
3576 }
3577
3578 #define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
3579 #else
3580 #define INIT_WCTOMB
3581 #endif
3582
3583 #if SANITIZER_INTERCEPT_TCGETATTR
3584 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
3585   void *ctx;
3586   COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
3587   // FIXME: under ASan the call below may write to freed memory and corrupt
3588   // its metadata. See
3589   // https://github.com/google/sanitizers/issues/321.
3590   int res = REAL(tcgetattr)(fd, termios_p);
3591   if (!res && termios_p)
3592     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
3593   return res;
3594 }
3595
3596 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
3597 #else
3598 #define INIT_TCGETATTR
3599 #endif
3600
3601 #if SANITIZER_INTERCEPT_REALPATH
3602 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
3603   void *ctx;
3604   COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
3605   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3606
3607   // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
3608   // version of a versioned symbol. For realpath(), this gives us something
3609   // (called __old_realpath) that does not handle NULL in the second argument.
3610   // Handle it as part of the interceptor.
3611   char *allocated_path = nullptr;
3612   if (!resolved_path)
3613     allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
3614
3615   char *res = REAL(realpath)(path, resolved_path);
3616   if (allocated_path && !res) WRAP(free)(allocated_path);
3617   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3618   return res;
3619 }
3620 #define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
3621 #else
3622 #define INIT_REALPATH
3623 #endif
3624
3625 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
3626 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
3627   void *ctx;
3628   COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
3629   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
3630   char *res = REAL(canonicalize_file_name)(path);
3631   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3632   return res;
3633 }
3634 #define INIT_CANONICALIZE_FILE_NAME \
3635   COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
3636 #else
3637 #define INIT_CANONICALIZE_FILE_NAME
3638 #endif
3639
3640 #if SANITIZER_INTERCEPT_CONFSTR
3641 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
3642   void *ctx;
3643   COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
3644   // FIXME: under ASan the call below may write to freed memory and corrupt
3645   // its metadata. See
3646   // https://github.com/google/sanitizers/issues/321.
3647   SIZE_T res = REAL(confstr)(name, buf, len);
3648   if (buf && res)
3649     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
3650   return res;
3651 }
3652 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
3653 #else
3654 #define INIT_CONFSTR
3655 #endif
3656
3657 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
3658 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
3659   void *ctx;
3660   COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
3661   // FIXME: under ASan the call below may write to freed memory and corrupt
3662   // its metadata. See
3663   // https://github.com/google/sanitizers/issues/321.
3664   int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
3665   if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
3666   return res;
3667 }
3668 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
3669 #else
3670 #define INIT_SCHED_GETAFFINITY
3671 #endif
3672
3673 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
3674 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
3675   void *ctx;
3676   COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
3677   int res = REAL(sched_getparam)(pid, param);
3678   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
3679   return res;
3680 }
3681 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
3682 #else
3683 #define INIT_SCHED_GETPARAM
3684 #endif
3685
3686 #if SANITIZER_INTERCEPT_STRERROR
3687 INTERCEPTOR(char *, strerror, int errnum) {
3688   void *ctx;
3689   COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
3690   COMMON_INTERCEPTOR_STRERROR();
3691   char *res = REAL(strerror)(errnum);
3692   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3693   return res;
3694 }
3695 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
3696 #else
3697 #define INIT_STRERROR
3698 #endif
3699
3700 #if SANITIZER_INTERCEPT_STRERROR_R
3701 // There are 2 versions of strerror_r:
3702 //  * POSIX version returns 0 on success, negative error code on failure,
3703 //    writes message to buf.
3704 //  * GNU version returns message pointer, which points to either buf or some
3705 //    static storage.
3706 #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
3707     SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD ||                 \
3708     SANITIZER_FREEBSD || SANITIZER_OPENBSD
3709 // POSIX version. Spec is not clear on whether buf is NULL-terminated.
3710 // At least on OSX, buf contents are valid even when the call fails.
3711 INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
3712   void *ctx;
3713   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
3714   // FIXME: under ASan the call below may write to freed memory and corrupt
3715   // its metadata. See
3716   // https://github.com/google/sanitizers/issues/321.
3717   int res = REAL(strerror_r)(errnum, buf, buflen);
3718
3719   SIZE_T sz = internal_strnlen(buf, buflen);
3720   if (sz < buflen) ++sz;
3721   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3722   return res;
3723 }
3724 #else
3725 // GNU version.
3726 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
3727   void *ctx;
3728   COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
3729   // FIXME: under ASan the call below may write to freed memory and corrupt
3730   // its metadata. See
3731   // https://github.com/google/sanitizers/issues/321.
3732   char *res = REAL(strerror_r)(errnum, buf, buflen);
3733   if (res == buf)
3734     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
3735   else
3736     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
3737   return res;
3738 }
3739 #endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
3740        //SANITIZER_MAC
3741 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
3742 #else
3743 #define INIT_STRERROR_R
3744 #endif
3745
3746 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
3747 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
3748   void *ctx;
3749   COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
3750   // FIXME: under ASan the call below may write to freed memory and corrupt
3751   // its metadata. See
3752   // https://github.com/google/sanitizers/issues/321.
3753   int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
3754   // This version always returns a null-terminated string.
3755   if (buf && buflen)
3756     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
3757   return res;
3758 }
3759 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
3760 #else
3761 #define INIT_XPG_STRERROR_R
3762 #endif
3763
3764 #if SANITIZER_INTERCEPT_SCANDIR
3765 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
3766 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
3767                                 const struct __sanitizer_dirent **);
3768
3769 static THREADLOCAL scandir_filter_f scandir_filter;
3770 static THREADLOCAL scandir_compar_f scandir_compar;
3771
3772 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
3773   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3774   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3775   return scandir_filter(dir);
3776 }
3777
3778 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
3779                                   const struct __sanitizer_dirent **b) {
3780   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3781   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3782   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3783   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3784   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3785   return scandir_compar(a, b);
3786 }
3787
3788 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
3789             scandir_filter_f filter, scandir_compar_f compar) {
3790   void *ctx;
3791   COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
3792   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3793   scandir_filter = filter;
3794   scandir_compar = compar;
3795   // FIXME: under ASan the call below may write to freed memory and corrupt
3796   // its metadata. See
3797   // https://github.com/google/sanitizers/issues/321.
3798   int res = REAL(scandir)(dirp, namelist,
3799                           filter ? wrapped_scandir_filter : nullptr,
3800                           compar ? wrapped_scandir_compar : nullptr);
3801   scandir_filter = nullptr;
3802   scandir_compar = nullptr;
3803   if (namelist && res > 0) {
3804     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3805     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3806     for (int i = 0; i < res; ++i)
3807       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3808                                      (*namelist)[i]->d_reclen);
3809   }
3810   return res;
3811 }
3812 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
3813 #else
3814 #define INIT_SCANDIR
3815 #endif
3816
3817 #if SANITIZER_INTERCEPT_SCANDIR64
3818 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
3819 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
3820                                   const struct __sanitizer_dirent64 **);
3821
3822 static THREADLOCAL scandir64_filter_f scandir64_filter;
3823 static THREADLOCAL scandir64_compar_f scandir64_compar;
3824
3825 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
3826   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3827   COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3828   return scandir64_filter(dir);
3829 }
3830
3831 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3832                                     const struct __sanitizer_dirent64 **b) {
3833   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3834   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3835   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3836   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3837   COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3838   return scandir64_compar(a, b);
3839 }
3840
3841 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3842             scandir64_filter_f filter, scandir64_compar_f compar) {
3843   void *ctx;
3844   COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3845   if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1);
3846   scandir64_filter = filter;
3847   scandir64_compar = compar;
3848   // FIXME: under ASan the call below may write to freed memory and corrupt
3849   // its metadata. See
3850   // https://github.com/google/sanitizers/issues/321.
3851   int res =
3852       REAL(scandir64)(dirp, namelist,
3853                       filter ? wrapped_scandir64_filter : nullptr,
3854                       compar ? wrapped_scandir64_compar : nullptr);
3855   scandir64_filter = nullptr;
3856   scandir64_compar = nullptr;
3857   if (namelist && res > 0) {
3858     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3859     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3860     for (int i = 0; i < res; ++i)
3861       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3862                                      (*namelist)[i]->d_reclen);
3863   }
3864   return res;
3865 }
3866 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
3867 #else
3868 #define INIT_SCANDIR64
3869 #endif
3870
3871 #if SANITIZER_INTERCEPT_GETGROUPS
3872 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
3873   void *ctx;
3874   COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
3875   // FIXME: under ASan the call below may write to freed memory and corrupt
3876   // its metadata. See
3877   // https://github.com/google/sanitizers/issues/321.
3878   int res = REAL(getgroups)(size, lst);
3879   if (res >= 0 && lst && size > 0)
3880     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
3881   return res;
3882 }
3883 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
3884 #else
3885 #define INIT_GETGROUPS
3886 #endif
3887
3888 #if SANITIZER_INTERCEPT_POLL
3889 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
3890                         __sanitizer_nfds_t nfds) {
3891   for (unsigned i = 0; i < nfds; ++i) {
3892     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
3893     COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
3894   }
3895 }
3896
3897 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
3898                          __sanitizer_nfds_t nfds) {
3899   for (unsigned i = 0; i < nfds; ++i)
3900     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
3901                                    sizeof(fds[i].revents));
3902 }
3903
3904 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3905             int timeout) {
3906   void *ctx;
3907   COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
3908   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3909   int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
3910   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3911   return res;
3912 }
3913 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
3914 #else
3915 #define INIT_POLL
3916 #endif
3917
3918 #if SANITIZER_INTERCEPT_PPOLL
3919 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
3920             void *timeout_ts, __sanitizer_sigset_t *sigmask) {
3921   void *ctx;
3922   COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
3923   if (fds && nfds) read_pollfd(ctx, fds, nfds);
3924   if (timeout_ts)
3925     COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
3926   if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));
3927   int res =
3928       COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
3929   if (fds && nfds) write_pollfd(ctx, fds, nfds);
3930   return res;
3931 }
3932 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
3933 #else
3934 #define INIT_PPOLL
3935 #endif
3936
3937 #if SANITIZER_INTERCEPT_WORDEXP
3938 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
3939   void *ctx;
3940   COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
3941   if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1);
3942   // FIXME: under ASan the call below may write to freed memory and corrupt
3943   // its metadata. See
3944   // https://github.com/google/sanitizers/issues/321.
3945   int res = REAL(wordexp)(s, p, flags);
3946   if (!res && p) {
3947     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
3948     if (p->we_wordc)
3949       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
3950                                      sizeof(*p->we_wordv) * p->we_wordc);
3951     for (uptr i = 0; i < p->we_wordc; ++i) {
3952       char *w = p->we_wordv[i];
3953       if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1);
3954     }
3955   }
3956   return res;
3957 }
3958 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
3959 #else
3960 #define INIT_WORDEXP
3961 #endif
3962
3963 #if SANITIZER_INTERCEPT_SIGWAIT
3964 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
3965   void *ctx;
3966   COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
3967   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
3968   // FIXME: under ASan the call below may write to freed memory and corrupt
3969   // its metadata. See
3970   // https://github.com/google/sanitizers/issues/321.
3971   int res = REAL(sigwait)(set, sig);
3972   if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
3973   return res;
3974 }
3975 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
3976 #else
3977 #define INIT_SIGWAIT
3978 #endif
3979
3980 #if SANITIZER_INTERCEPT_SIGWAITINFO
3981 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
3982   void *ctx;
3983   COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
3984   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
3985   // FIXME: under ASan the call below may write to freed memory and corrupt
3986   // its metadata. See
3987   // https://github.com/google/sanitizers/issues/321.
3988   int res = REAL(sigwaitinfo)(set, info);
3989   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
3990   return res;
3991 }
3992 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
3993 #else
3994 #define INIT_SIGWAITINFO
3995 #endif
3996
3997 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
3998 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
3999             void *timeout) {
4000   void *ctx;
4001   COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
4002   if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
4003   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4004   // FIXME: under ASan the call below may write to freed memory and corrupt
4005   // its metadata. See
4006   // https://github.com/google/sanitizers/issues/321.
4007   int res = REAL(sigtimedwait)(set, info, timeout);
4008   if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
4009   return res;
4010 }
4011 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
4012 #else
4013 #define INIT_SIGTIMEDWAIT
4014 #endif
4015
4016 #if SANITIZER_INTERCEPT_SIGSETOPS
4017 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
4018   void *ctx;
4019   COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
4020   // FIXME: under ASan the call below may write to freed memory and corrupt
4021   // its metadata. See
4022   // https://github.com/google/sanitizers/issues/321.
4023   int res = REAL(sigemptyset)(set);
4024   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4025   return res;
4026 }
4027
4028 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
4029   void *ctx;
4030   COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
4031   // FIXME: under ASan the call below may write to freed memory and corrupt
4032   // its metadata. See
4033   // https://github.com/google/sanitizers/issues/321.
4034   int res = REAL(sigfillset)(set);
4035   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4036   return res;
4037 }
4038 #define INIT_SIGSETOPS                    \
4039   COMMON_INTERCEPT_FUNCTION(sigemptyset); \
4040   COMMON_INTERCEPT_FUNCTION(sigfillset);
4041 #else
4042 #define INIT_SIGSETOPS
4043 #endif
4044
4045 #if SANITIZER_INTERCEPT_SIGPENDING
4046 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
4047   void *ctx;
4048   COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
4049   // FIXME: under ASan the call below may write to freed memory and corrupt
4050   // its metadata. See
4051   // https://github.com/google/sanitizers/issues/321.
4052   int res = REAL(sigpending)(set);
4053   if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4054   return res;
4055 }
4056 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
4057 #else
4058 #define INIT_SIGPENDING
4059 #endif
4060
4061 #if SANITIZER_INTERCEPT_SIGPROCMASK
4062 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
4063             __sanitizer_sigset_t *oldset) {
4064   void *ctx;
4065   COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
4066   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4067   // FIXME: under ASan the call below may write to freed memory and corrupt
4068   // its metadata. See
4069   // https://github.com/google/sanitizers/issues/321.
4070   int res = REAL(sigprocmask)(how, set, oldset);
4071   if (!res && oldset)
4072     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4073   return res;
4074 }
4075 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
4076 #else
4077 #define INIT_SIGPROCMASK
4078 #endif
4079
4080 #if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
4081 INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
4082             __sanitizer_sigset_t *oldset) {
4083   void *ctx;
4084   COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
4085   if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4086   // FIXME: under ASan the call below may write to freed memory and corrupt
4087   // its metadata. See
4088   // https://github.com/google/sanitizers/issues/321.
4089   int res = REAL(pthread_sigmask)(how, set, oldset);
4090   if (!res && oldset)
4091     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4092   return res;
4093 }
4094 #define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
4095 #else
4096 #define INIT_PTHREAD_SIGMASK
4097 #endif
4098
4099 #if SANITIZER_INTERCEPT_BACKTRACE
4100 INTERCEPTOR(int, backtrace, void **buffer, int size) {
4101   void *ctx;
4102   COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
4103   // FIXME: under ASan the call below may write to freed memory and corrupt
4104   // its metadata. See
4105   // https://github.com/google/sanitizers/issues/321.
4106   int res = REAL(backtrace)(buffer, size);
4107   if (res && buffer)
4108     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
4109   return res;
4110 }
4111
4112 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
4113   void *ctx;
4114   COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
4115   if (buffer && size)
4116     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
4117   // FIXME: under ASan the call below may write to freed memory and corrupt
4118   // its metadata. See
4119   // https://github.com/google/sanitizers/issues/321.
4120   char **res = REAL(backtrace_symbols)(buffer, size);
4121   if (res && size) {
4122     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
4123     for (int i = 0; i < size; ++i)
4124       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1);
4125   }
4126   return res;
4127 }
4128 #define INIT_BACKTRACE                  \
4129   COMMON_INTERCEPT_FUNCTION(backtrace); \
4130   COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
4131 #else
4132 #define INIT_BACKTRACE
4133 #endif
4134
4135 #if SANITIZER_INTERCEPT__EXIT
4136 INTERCEPTOR(void, _exit, int status) {
4137   void *ctx;
4138   COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
4139   COMMON_INTERCEPTOR_USER_CALLBACK_START();
4140   int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
4141   COMMON_INTERCEPTOR_USER_CALLBACK_END();
4142   if (status == 0) status = status1;
4143   REAL(_exit)(status);
4144 }
4145 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
4146 #else
4147 #define INIT__EXIT
4148 #endif
4149
4150 #if SANITIZER_INTERCEPT_PTHREAD_MUTEX
4151 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
4152   void *ctx;
4153   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
4154   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4155   int res = REAL(pthread_mutex_lock)(m);
4156   if (res == errno_EOWNERDEAD)
4157     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4158   if (res == 0 || res == errno_EOWNERDEAD)
4159     COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4160   if (res == errno_EINVAL)
4161     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4162   return res;
4163 }
4164
4165 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
4166   void *ctx;
4167   COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
4168   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4169   int res = REAL(pthread_mutex_unlock)(m);
4170   if (res == errno_EINVAL)
4171     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4172   return res;
4173 }
4174
4175 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
4176 #define INIT_PTHREAD_MUTEX_UNLOCK \
4177   COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
4178 #else
4179 #define INIT_PTHREAD_MUTEX_LOCK
4180 #define INIT_PTHREAD_MUTEX_UNLOCK
4181 #endif
4182
4183 #if SANITIZER_INTERCEPT___PTHREAD_MUTEX
4184 INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
4185   void *ctx;
4186   COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m);
4187   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4188   int res = REAL(__pthread_mutex_lock)(m);
4189   if (res == errno_EOWNERDEAD)
4190     COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4191   if (res == 0 || res == errno_EOWNERDEAD)
4192     COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4193   if (res == errno_EINVAL)
4194     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4195   return res;
4196 }
4197
4198 INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
4199   void *ctx;
4200   COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m);
4201   COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4202   int res = REAL(__pthread_mutex_unlock)(m);
4203   if (res == errno_EINVAL)
4204     COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4205   return res;
4206 }
4207
4208 #define INIT___PTHREAD_MUTEX_LOCK \
4209   COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock)
4210 #define INIT___PTHREAD_MUTEX_UNLOCK \
4211   COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock)
4212 #else
4213 #define INIT___PTHREAD_MUTEX_LOCK
4214 #define INIT___PTHREAD_MUTEX_UNLOCK
4215 #endif
4216
4217 #if SANITIZER_INTERCEPT___LIBC_MUTEX
4218 INTERCEPTOR(int, __libc_mutex_lock, void *m)
4219 ALIAS(WRAPPER_NAME(pthread_mutex_lock));
4220
4221 INTERCEPTOR(int, __libc_mutex_unlock, void *m)
4222 ALIAS(WRAPPER_NAME(pthread_mutex_unlock));
4223
4224 INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
4225 ALIAS(WRAPPER_NAME(pthread_setcancelstate));
4226
4227 #define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock)
4228 #define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock)
4229 #define INIT___LIBC_THR_SETCANCELSTATE \
4230   COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
4231 #else
4232 #define INIT___LIBC_MUTEX_LOCK
4233 #define INIT___LIBC_MUTEX_UNLOCK
4234 #define INIT___LIBC_THR_SETCANCELSTATE
4235 #endif
4236
4237 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
4238 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
4239   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
4240   if (mnt->mnt_fsname)
4241     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
4242                                    REAL(strlen)(mnt->mnt_fsname) + 1);
4243   if (mnt->mnt_dir)
4244     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
4245                                    REAL(strlen)(mnt->mnt_dir) + 1);
4246   if (mnt->mnt_type)
4247     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
4248                                    REAL(strlen)(mnt->mnt_type) + 1);
4249   if (mnt->mnt_opts)
4250     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
4251                                    REAL(strlen)(mnt->mnt_opts) + 1);
4252 }
4253 #endif
4254
4255 #if SANITIZER_INTERCEPT_GETMNTENT
4256 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
4257   void *ctx;
4258   COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
4259   __sanitizer_mntent *res = REAL(getmntent)(fp);
4260   if (res) write_mntent(ctx, res);
4261   return res;
4262 }
4263 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
4264 #else
4265 #define INIT_GETMNTENT
4266 #endif
4267
4268 #if SANITIZER_INTERCEPT_GETMNTENT_R
4269 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
4270             __sanitizer_mntent *mntbuf, char *buf, int buflen) {
4271   void *ctx;
4272   COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
4273   __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
4274   if (res) write_mntent(ctx, res);
4275   return res;
4276 }
4277 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
4278 #else
4279 #define INIT_GETMNTENT_R
4280 #endif
4281
4282 #if SANITIZER_INTERCEPT_STATFS
4283 INTERCEPTOR(int, statfs, char *path, void *buf) {
4284   void *ctx;
4285   COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
4286   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4287   // FIXME: under ASan the call below may write to freed memory and corrupt
4288   // its metadata. See
4289   // https://github.com/google/sanitizers/issues/321.
4290   int res = REAL(statfs)(path, buf);
4291   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4292   return res;
4293 }
4294 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
4295   void *ctx;
4296   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
4297   // FIXME: under ASan the call below may write to freed memory and corrupt
4298   // its metadata. See
4299   // https://github.com/google/sanitizers/issues/321.
4300   int res = REAL(fstatfs)(fd, buf);
4301   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4302   return res;
4303 }
4304 #define INIT_STATFS                  \
4305   COMMON_INTERCEPT_FUNCTION(statfs); \
4306   COMMON_INTERCEPT_FUNCTION(fstatfs);
4307 #else
4308 #define INIT_STATFS
4309 #endif
4310
4311 #if SANITIZER_INTERCEPT_STATFS64
4312 INTERCEPTOR(int, statfs64, char *path, void *buf) {
4313   void *ctx;
4314   COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
4315   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4316   // FIXME: under ASan the call below may write to freed memory and corrupt
4317   // its metadata. See
4318   // https://github.com/google/sanitizers/issues/321.
4319   int res = REAL(statfs64)(path, buf);
4320   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4321   return res;
4322 }
4323 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
4324   void *ctx;
4325   COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
4326   // FIXME: under ASan the call below may write to freed memory and corrupt
4327   // its metadata. See
4328   // https://github.com/google/sanitizers/issues/321.
4329   int res = REAL(fstatfs64)(fd, buf);
4330   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4331   return res;
4332 }
4333 #define INIT_STATFS64                  \
4334   COMMON_INTERCEPT_FUNCTION(statfs64); \
4335   COMMON_INTERCEPT_FUNCTION(fstatfs64);
4336 #else
4337 #define INIT_STATFS64
4338 #endif
4339
4340 #if SANITIZER_INTERCEPT_STATVFS
4341 INTERCEPTOR(int, statvfs, char *path, void *buf) {
4342   void *ctx;
4343   COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
4344   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4345   // FIXME: under ASan the call below may write to freed memory and corrupt
4346   // its metadata. See
4347   // https://github.com/google/sanitizers/issues/321.
4348   int res = REAL(statvfs)(path, buf);
4349   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4350   return res;
4351 }
4352 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
4353   void *ctx;
4354   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
4355   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
4356   // FIXME: under ASan the call below may write to freed memory and corrupt
4357   // its metadata. See
4358   // https://github.com/google/sanitizers/issues/321.
4359   int res = REAL(fstatvfs)(fd, buf);
4360   if (!res) {
4361     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4362     if (fd >= 0)
4363       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
4364   }
4365   return res;
4366 }
4367 #define INIT_STATVFS                  \
4368   COMMON_INTERCEPT_FUNCTION(statvfs); \
4369   COMMON_INTERCEPT_FUNCTION(fstatvfs);
4370 #else
4371 #define INIT_STATVFS
4372 #endif
4373
4374 #if SANITIZER_INTERCEPT_STATVFS64
4375 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
4376   void *ctx;
4377   COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
4378   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
4379   // FIXME: under ASan the call below may write to freed memory and corrupt
4380   // its metadata. See
4381   // https://github.com/google/sanitizers/issues/321.
4382   int res = REAL(statvfs64)(path, buf);
4383   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4384   return res;
4385 }
4386 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
4387   void *ctx;
4388   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
4389   // FIXME: under ASan the call below may write to freed memory and corrupt
4390   // its metadata. See
4391   // https://github.com/google/sanitizers/issues/321.
4392   int res = REAL(fstatvfs64)(fd, buf);
4393   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4394   return res;
4395 }
4396 #define INIT_STATVFS64                  \
4397   COMMON_INTERCEPT_FUNCTION(statvfs64); \
4398   COMMON_INTERCEPT_FUNCTION(fstatvfs64);
4399 #else
4400 #define INIT_STATVFS64
4401 #endif
4402
4403 #if SANITIZER_INTERCEPT_INITGROUPS
4404 INTERCEPTOR(int, initgroups, char *user, u32 group) {
4405   void *ctx;
4406   COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
4407   if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1);
4408   int res = REAL(initgroups)(user, group);
4409   return res;
4410 }
4411 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
4412 #else
4413 #define INIT_INITGROUPS
4414 #endif
4415
4416 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
4417 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
4418   void *ctx;
4419   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
4420   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4421   char *res = REAL(ether_ntoa)(addr);
4422   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4423   return res;
4424 }
4425 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
4426   void *ctx;
4427   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
4428   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
4429   __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
4430   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
4431   return res;
4432 }
4433 #define INIT_ETHER_NTOA_ATON             \
4434   COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
4435   COMMON_INTERCEPT_FUNCTION(ether_aton);
4436 #else
4437 #define INIT_ETHER_NTOA_ATON
4438 #endif
4439
4440 #if SANITIZER_INTERCEPT_ETHER_HOST
4441 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
4442   void *ctx;
4443   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
4444   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4445   // FIXME: under ASan the call below may write to freed memory and corrupt
4446   // its metadata. See
4447   // https://github.com/google/sanitizers/issues/321.
4448   int res = REAL(ether_ntohost)(hostname, addr);
4449   if (!res && hostname)
4450     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
4451   return res;
4452 }
4453 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
4454   void *ctx;
4455   COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
4456   if (hostname)
4457     COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
4458   // FIXME: under ASan the call below may write to freed memory and corrupt
4459   // its metadata. See
4460   // https://github.com/google/sanitizers/issues/321.
4461   int res = REAL(ether_hostton)(hostname, addr);
4462   if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4463   return res;
4464 }
4465 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
4466             char *hostname) {
4467   void *ctx;
4468   COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
4469   if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1);
4470   // FIXME: under ASan the call below may write to freed memory and corrupt
4471   // its metadata. See
4472   // https://github.com/google/sanitizers/issues/321.
4473   int res = REAL(ether_line)(line, addr, hostname);
4474   if (!res) {
4475     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4476     if (hostname)
4477       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1);
4478   }
4479   return res;
4480 }
4481 #define INIT_ETHER_HOST                     \
4482   COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
4483   COMMON_INTERCEPT_FUNCTION(ether_hostton); \
4484   COMMON_INTERCEPT_FUNCTION(ether_line);
4485 #else
4486 #define INIT_ETHER_HOST
4487 #endif
4488
4489 #if SANITIZER_INTERCEPT_ETHER_R
4490 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
4491   void *ctx;
4492   COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
4493   if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4494   // FIXME: under ASan the call below may write to freed memory and corrupt
4495   // its metadata. See
4496   // https://github.com/google/sanitizers/issues/321.
4497   char *res = REAL(ether_ntoa_r)(addr, buf);
4498   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
4499   return res;
4500 }
4501 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
4502             __sanitizer_ether_addr *addr) {
4503   void *ctx;
4504   COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
4505   if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
4506   // FIXME: under ASan the call below may write to freed memory and corrupt
4507   // its metadata. See
4508   // https://github.com/google/sanitizers/issues/321.
4509   __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
4510   if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
4511   return res;
4512 }
4513 #define INIT_ETHER_R                       \
4514   COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
4515   COMMON_INTERCEPT_FUNCTION(ether_aton_r);
4516 #else
4517 #define INIT_ETHER_R
4518 #endif
4519
4520 #if SANITIZER_INTERCEPT_SHMCTL
4521 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
4522   void *ctx;
4523   COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
4524   // FIXME: under ASan the call below may write to freed memory and corrupt
4525   // its metadata. See
4526   // https://github.com/google/sanitizers/issues/321.
4527   int res = REAL(shmctl)(shmid, cmd, buf);
4528   if (res >= 0) {
4529     unsigned sz = 0;
4530     if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
4531       sz = sizeof(__sanitizer_shmid_ds);
4532     else if (cmd == shmctl_ipc_info)
4533       sz = struct_shminfo_sz;
4534     else if (cmd == shmctl_shm_info)
4535       sz = struct_shm_info_sz;
4536     if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
4537   }
4538   return res;
4539 }
4540 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
4541 #else
4542 #define INIT_SHMCTL
4543 #endif
4544
4545 #if SANITIZER_INTERCEPT_RANDOM_R
4546 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
4547   void *ctx;
4548   COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
4549   // FIXME: under ASan the call below may write to freed memory and corrupt
4550   // its metadata. See
4551   // https://github.com/google/sanitizers/issues/321.
4552   int res = REAL(random_r)(buf, result);
4553   if (!res && result)
4554     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4555   return res;
4556 }
4557 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
4558 #else
4559 #define INIT_RANDOM_R
4560 #endif
4561
4562 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
4563 // its metadata. See
4564 // https://github.com/google/sanitizers/issues/321.
4565 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
4566     SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED ||        \
4567     SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
4568     SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
4569     SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
4570     SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
4571     SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
4572 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
4573   INTERCEPTOR(int, fn, void *attr, void *r) {                  \
4574     void *ctx;                                                 \
4575     COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
4576     int res = REAL(fn)(attr, r);                               \
4577     if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
4578     return res;                                                \
4579   }
4580 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
4581   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
4582 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
4583   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
4584 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
4585   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
4586 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
4587   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
4588 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
4589   INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
4590 #endif
4591
4592 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
4593 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
4594 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
4595 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
4596 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
4597 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
4598   void *ctx;
4599   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
4600   // FIXME: under ASan the call below may write to freed memory and corrupt
4601   // its metadata. See
4602   // https://github.com/google/sanitizers/issues/321.
4603   int res = REAL(pthread_attr_getstack)(attr, addr, size);
4604   if (!res) {
4605     if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4606     if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
4607   }
4608   return res;
4609 }
4610
4611 // We may need to call the real pthread_attr_getstack from the run-time
4612 // in sanitizer_common, but we don't want to include the interception headers
4613 // there. So, just define this function here.
4614 namespace __sanitizer {
4615 extern "C" {
4616 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
4617   return REAL(pthread_attr_getstack)(attr, addr, size);
4618 }
4619 }  // extern "C"
4620 }  // namespace __sanitizer
4621
4622 #define INIT_PTHREAD_ATTR_GET                             \
4623   COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
4624   COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
4625   COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
4626   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
4627   COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
4628 #else
4629 #define INIT_PTHREAD_ATTR_GET
4630 #endif
4631
4632 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED
4633 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
4634 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
4635
4636 #define INIT_PTHREAD_ATTR_GET_SCHED                      \
4637   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
4638   COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);
4639 #else
4640 #define INIT_PTHREAD_ATTR_GET_SCHED
4641 #endif
4642
4643 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
4644 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
4645
4646 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
4647   COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
4648 #else
4649 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
4650 #endif
4651
4652 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
4653 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
4654             void *cpuset) {
4655   void *ctx;
4656   COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
4657                            cpuset);
4658   // FIXME: under ASan the call below may write to freed memory and corrupt
4659   // its metadata. See
4660   // https://github.com/google/sanitizers/issues/321.
4661   int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
4662   if (!res && cpusetsize && cpuset)
4663     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
4664   return res;
4665 }
4666
4667 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
4668   COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
4669 #else
4670 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
4671 #endif
4672
4673 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
4674 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
4675 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
4676   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
4677 #else
4678 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
4679 #endif
4680
4681 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
4682 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
4683 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
4684   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
4685 #else
4686 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
4687 #endif
4688
4689 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
4690 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
4691 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
4692   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
4693 #else
4694 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
4695 #endif
4696
4697 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4698 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
4699 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
4700   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
4701 #else
4702 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4703 #endif
4704
4705 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
4706 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
4707 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
4708   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
4709 #else
4710 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
4711 #endif
4712
4713 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
4714 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
4715 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
4716   COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
4717 #else
4718 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
4719 #endif
4720
4721 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
4722 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
4723 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
4724   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
4725 #else
4726 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
4727 #endif
4728
4729 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
4730 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
4731 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
4732   COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
4733 #else
4734 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
4735 #endif
4736
4737 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
4738 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
4739 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
4740   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
4741 #else
4742 #define INIT_PTHREAD_CONDATTR_GETPSHARED
4743 #endif
4744
4745 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
4746 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
4747 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
4748   COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
4749 #else
4750 #define INIT_PTHREAD_CONDATTR_GETCLOCK
4751 #endif
4752
4753 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
4754 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
4755 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
4756   COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
4757 #else
4758 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
4759 #endif
4760
4761 #if SANITIZER_INTERCEPT_TMPNAM
4762 INTERCEPTOR(char *, tmpnam, char *s) {
4763   void *ctx;
4764   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
4765   char *res = REAL(tmpnam)(s);
4766   if (res) {
4767     if (s)
4768       // FIXME: under ASan the call below may write to freed memory and corrupt
4769       // its metadata. See
4770       // https://github.com/google/sanitizers/issues/321.
4771       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4772     else
4773       COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4774   }
4775   return res;
4776 }
4777 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
4778 #else
4779 #define INIT_TMPNAM
4780 #endif
4781
4782 #if SANITIZER_INTERCEPT_TMPNAM_R
4783 INTERCEPTOR(char *, tmpnam_r, char *s) {
4784   void *ctx;
4785   COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
4786   // FIXME: under ASan the call below may write to freed memory and corrupt
4787   // its metadata. See
4788   // https://github.com/google/sanitizers/issues/321.
4789   char *res = REAL(tmpnam_r)(s);
4790   if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1);
4791   return res;
4792 }
4793 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
4794 #else
4795 #define INIT_TMPNAM_R
4796 #endif
4797
4798 #if SANITIZER_INTERCEPT_TTYNAME
4799 INTERCEPTOR(char *, ttyname, int fd) {
4800   void *ctx;
4801   COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);
4802   char *res = REAL(ttyname)(fd);
4803   if (res != nullptr)
4804     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4805   return res;
4806 }
4807 #define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);
4808 #else
4809 #define INIT_TTYNAME
4810 #endif
4811
4812 #if SANITIZER_INTERCEPT_TTYNAME_R
4813 INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
4814   void *ctx;
4815   COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);
4816   int res = REAL(ttyname_r)(fd, name, namesize);
4817   if (res == 0)
4818     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
4819   return res;
4820 }
4821 #define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);
4822 #else
4823 #define INIT_TTYNAME_R
4824 #endif
4825
4826 #if SANITIZER_INTERCEPT_TEMPNAM
4827 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
4828   void *ctx;
4829   COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
4830   if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1);
4831   if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1);
4832   char *res = REAL(tempnam)(dir, pfx);
4833   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
4834   return res;
4835 }
4836 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
4837 #else
4838 #define INIT_TEMPNAM
4839 #endif
4840
4841 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
4842 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
4843   void *ctx;
4844   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
4845   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
4846   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
4847   return REAL(pthread_setname_np)(thread, name);
4848 }
4849 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
4850 #elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
4851 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
4852   void *ctx;
4853   char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
4854   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
4855   COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
4856   internal_snprintf(newname, sizeof(newname), name, arg);
4857   COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
4858   return REAL(pthread_setname_np)(thread, name, arg);
4859 }
4860 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
4861 #else
4862 #define INIT_PTHREAD_SETNAME_NP
4863 #endif
4864
4865 #if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP
4866 INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {
4867   void *ctx;
4868   COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);
4869   int res = REAL(pthread_getname_np)(thread, name, len);
4870   if (!res)
4871     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);
4872   return res;
4873 }
4874 #define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);
4875 #else
4876 #define INIT_PTHREAD_GETNAME_NP
4877 #endif
4878
4879 #if SANITIZER_INTERCEPT_SINCOS
4880 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
4881   void *ctx;
4882   COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
4883   // FIXME: under ASan the call below may write to freed memory and corrupt
4884   // its metadata. See
4885   // https://github.com/google/sanitizers/issues/321.
4886   REAL(sincos)(x, sin, cos);
4887   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4888   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4889 }
4890 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
4891   void *ctx;
4892   COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
4893   // FIXME: under ASan the call below may write to freed memory and corrupt
4894   // its metadata. See
4895   // https://github.com/google/sanitizers/issues/321.
4896   REAL(sincosf)(x, sin, cos);
4897   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4898   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4899 }
4900 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
4901   void *ctx;
4902   COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
4903   // FIXME: under ASan the call below may write to freed memory and corrupt
4904   // its metadata. See
4905   // https://github.com/google/sanitizers/issues/321.
4906   REAL(sincosl)(x, sin, cos);
4907   if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
4908   if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
4909 }
4910 #define INIT_SINCOS                   \
4911   COMMON_INTERCEPT_FUNCTION(sincos);  \
4912   COMMON_INTERCEPT_FUNCTION(sincosf); \
4913   COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
4914 #else
4915 #define INIT_SINCOS
4916 #endif
4917
4918 #if SANITIZER_INTERCEPT_REMQUO
4919 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
4920   void *ctx;
4921   COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
4922   // FIXME: under ASan the call below may write to freed memory and corrupt
4923   // its metadata. See
4924   // https://github.com/google/sanitizers/issues/321.
4925   double res = REAL(remquo)(x, y, quo);
4926   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4927   return res;
4928 }
4929 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
4930   void *ctx;
4931   COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
4932   // FIXME: under ASan the call below may write to freed memory and corrupt
4933   // its metadata. See
4934   // https://github.com/google/sanitizers/issues/321.
4935   float res = REAL(remquof)(x, y, quo);
4936   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4937   return res;
4938 }
4939 #define INIT_REMQUO                   \
4940   COMMON_INTERCEPT_FUNCTION(remquo);  \
4941   COMMON_INTERCEPT_FUNCTION(remquof);
4942 #else
4943 #define INIT_REMQUO
4944 #endif
4945
4946 #if SANITIZER_INTERCEPT_REMQUOL
4947 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
4948   void *ctx;
4949   COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
4950   // FIXME: under ASan the call below may write to freed memory and corrupt
4951   // its metadata. See
4952   // https://github.com/google/sanitizers/issues/321.
4953   long double res = REAL(remquol)(x, y, quo);
4954   if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
4955   return res;
4956 }
4957 #define INIT_REMQUOL                  \
4958   COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
4959 #else
4960 #define INIT_REMQUOL
4961 #endif
4962
4963 #if SANITIZER_INTERCEPT_LGAMMA
4964 extern int signgam;
4965 INTERCEPTOR(double, lgamma, double x) {
4966   void *ctx;
4967   COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
4968   double res = REAL(lgamma)(x);
4969   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4970   return res;
4971 }
4972 INTERCEPTOR(float, lgammaf, float x) {
4973   void *ctx;
4974   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
4975   float res = REAL(lgammaf)(x);
4976   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4977   return res;
4978 }
4979 #define INIT_LGAMMA                   \
4980   COMMON_INTERCEPT_FUNCTION(lgamma);  \
4981   COMMON_INTERCEPT_FUNCTION(lgammaf);
4982 #else
4983 #define INIT_LGAMMA
4984 #endif
4985
4986 #if SANITIZER_INTERCEPT_LGAMMAL
4987 INTERCEPTOR(long double, lgammal, long double x) {
4988   void *ctx;
4989   COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
4990   long double res = REAL(lgammal)(x);
4991   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
4992   return res;
4993 }
4994 #define INIT_LGAMMAL                  \
4995   COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
4996 #else
4997 #define INIT_LGAMMAL
4998 #endif
4999
5000 #if SANITIZER_INTERCEPT_LGAMMA_R
5001 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
5002   void *ctx;
5003   COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
5004   // FIXME: under ASan the call below may write to freed memory and corrupt
5005   // its metadata. See
5006   // https://github.com/google/sanitizers/issues/321.
5007   double res = REAL(lgamma_r)(x, signp);
5008   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5009   return res;
5010 }
5011 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
5012   void *ctx;
5013   COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
5014   // FIXME: under ASan the call below may write to freed memory and corrupt
5015   // its metadata. See
5016   // https://github.com/google/sanitizers/issues/321.
5017   float res = REAL(lgammaf_r)(x, signp);
5018   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5019   return res;
5020 }
5021 #define INIT_LGAMMA_R                   \
5022   COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
5023   COMMON_INTERCEPT_FUNCTION(lgammaf_r);
5024 #else
5025 #define INIT_LGAMMA_R
5026 #endif
5027
5028 #if SANITIZER_INTERCEPT_LGAMMAL_R
5029 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
5030   void *ctx;
5031   COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
5032   // FIXME: under ASan the call below may write to freed memory and corrupt
5033   // its metadata. See
5034   // https://github.com/google/sanitizers/issues/321.
5035   long double res = REAL(lgammal_r)(x, signp);
5036   if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5037   return res;
5038 }
5039 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
5040 #else
5041 #define INIT_LGAMMAL_R
5042 #endif
5043
5044 #if SANITIZER_INTERCEPT_DRAND48_R
5045 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
5046   void *ctx;
5047   COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
5048   // FIXME: under ASan the call below may write to freed memory and corrupt
5049   // its metadata. See
5050   // https://github.com/google/sanitizers/issues/321.
5051   int res = REAL(drand48_r)(buffer, result);
5052   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5053   return res;
5054 }
5055 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
5056   void *ctx;
5057   COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
5058   // FIXME: under ASan the call below may write to freed memory and corrupt
5059   // its metadata. See
5060   // https://github.com/google/sanitizers/issues/321.
5061   int res = REAL(lrand48_r)(buffer, result);
5062   if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5063   return res;
5064 }
5065 #define INIT_DRAND48_R                  \
5066   COMMON_INTERCEPT_FUNCTION(drand48_r); \
5067   COMMON_INTERCEPT_FUNCTION(lrand48_r);
5068 #else
5069 #define INIT_DRAND48_R
5070 #endif
5071
5072 #if SANITIZER_INTERCEPT_RAND_R
5073 INTERCEPTOR(int, rand_r, unsigned *seedp) {
5074   void *ctx;
5075   COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
5076   COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
5077   return REAL(rand_r)(seedp);
5078 }
5079 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
5080 #else
5081 #define INIT_RAND_R
5082 #endif
5083
5084 #if SANITIZER_INTERCEPT_GETLINE
5085 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
5086   void *ctx;
5087   COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
5088   // FIXME: under ASan the call below may write to freed memory and corrupt
5089   // its metadata. See
5090   // https://github.com/google/sanitizers/issues/321.
5091   SSIZE_T res = REAL(getline)(lineptr, n, stream);
5092   if (res > 0) {
5093     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
5094     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
5095     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
5096   }
5097   return res;
5098 }
5099
5100 // FIXME: under ASan the call below may write to freed memory and corrupt its
5101 // metadata. See
5102 // https://github.com/google/sanitizers/issues/321.
5103 #define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
5104   {                                                                            \
5105     void *ctx;                                                                 \
5106     COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
5107     SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
5108     if (res > 0) {                                                             \
5109       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
5110       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
5111       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
5112     }                                                                          \
5113     return res;                                                                \
5114   }
5115
5116 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
5117             void *stream)
5118 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
5119
5120 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
5121 // with its own body.
5122 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
5123             void *stream)
5124 GETDELIM_INTERCEPTOR_IMPL(getdelim)
5125
5126 #define INIT_GETLINE                     \
5127   COMMON_INTERCEPT_FUNCTION(getline);    \
5128   COMMON_INTERCEPT_FUNCTION(__getdelim); \
5129   COMMON_INTERCEPT_FUNCTION(getdelim);
5130 #else
5131 #define INIT_GETLINE
5132 #endif
5133
5134 #if SANITIZER_INTERCEPT_ICONV
5135 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
5136             char **outbuf, SIZE_T *outbytesleft) {
5137   void *ctx;
5138   COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
5139                            outbytesleft);
5140   if (inbytesleft)
5141     COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
5142   if (inbuf && inbytesleft)
5143     COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
5144   if (outbytesleft)
5145     COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
5146   void *outbuf_orig = outbuf ? *outbuf : nullptr;
5147   // FIXME: under ASan the call below may write to freed memory and corrupt
5148   // its metadata. See
5149   // https://github.com/google/sanitizers/issues/321.
5150   SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
5151   if (outbuf && *outbuf > outbuf_orig) {
5152     SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
5153     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
5154   }
5155   return res;
5156 }
5157 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
5158 #else
5159 #define INIT_ICONV
5160 #endif
5161
5162 #if SANITIZER_INTERCEPT_TIMES
5163 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
5164   void *ctx;
5165   COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
5166   // FIXME: under ASan the call below may write to freed memory and corrupt
5167   // its metadata. See
5168   // https://github.com/google/sanitizers/issues/321.
5169   __sanitizer_clock_t res = REAL(times)(tms);
5170   if (res != (__sanitizer_clock_t)-1 && tms)
5171     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
5172   return res;
5173 }
5174 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
5175 #else
5176 #define INIT_TIMES
5177 #endif
5178
5179 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
5180 #if !SANITIZER_S390
5181 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
5182 // If you see any crashes around this functions, there are 2 known issues with
5183 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
5184 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
5185 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
5186 // to access thread local variables (it should not happen normally,
5187 // because sanitizers use initial-exec tls model).
5188 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
5189   void *ctx;
5190   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
5191   void *res = REAL(__tls_get_addr)(arg);
5192   uptr tls_begin, tls_end;
5193   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5194   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
5195   if (dtv) {
5196     // New DTLS block has been allocated.
5197     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5198   }
5199   return res;
5200 }
5201 #if SANITIZER_PPC
5202 // On PowerPC, we also need to intercept __tls_get_addr_opt, which has
5203 // mostly the same semantics as __tls_get_addr, but its presence enables
5204 // some optimizations in linker (which are safe to ignore here).
5205 extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
5206                           visibility("default")))
5207 void *__tls_get_addr_opt(void *arg);
5208 #endif
5209 #else // SANITIZER_S390
5210 // On s390, we have to intercept two functions here:
5211 // - __tls_get_addr_internal, which is a glibc-internal function that is like
5212 //   the usual __tls_get_addr, but returns a TP-relative offset instead of
5213 //   a proper pointer.  It is used by dlsym for TLS symbols.
5214 // - __tls_get_offset, which is like the above, but also takes a GOT-relative
5215 //   descriptor offset as an argument instead of a pointer.  GOT address
5216 //   is passed in r12, so it's necessary to write it in assembly.  This is
5217 //   the function used by the compiler.
5218 extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
5219 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
5220 DEFINE_REAL(uptr, __tls_get_offset, void *arg)
5221 extern "C" uptr __tls_get_offset(void *arg);
5222 extern "C" uptr __interceptor___tls_get_offset(void *arg);
5223 INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
5224   void *ctx;
5225   COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
5226   uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
5227   uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
5228   void *ptr = reinterpret_cast<void *>(res + tp);
5229   uptr tls_begin, tls_end;
5230   COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5231   DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
5232   if (dtv) {
5233     // New DTLS block has been allocated.
5234     COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5235   }
5236   return res;
5237 }
5238 // We need a hidden symbol aliasing the above, so that we can jump
5239 // directly to it from the assembly below.
5240 extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
5241                           visibility("hidden")))
5242 uptr __tls_get_addr_hidden(void *arg);
5243 // Now carefully intercept __tls_get_offset.
5244 asm(
5245   ".text\n"
5246 // The __intercept_ version has to exist, so that gen_dynamic_list.py
5247 // exports our symbol.
5248   ".weak __tls_get_offset\n"
5249   ".type __tls_get_offset, @function\n"
5250   "__tls_get_offset:\n"
5251   ".global __interceptor___tls_get_offset\n"
5252   ".type __interceptor___tls_get_offset, @function\n"
5253   "__interceptor___tls_get_offset:\n"
5254 #ifdef __s390x__
5255   "la %r2, 0(%r2,%r12)\n"
5256   "jg __tls_get_addr_hidden\n"
5257 #else
5258   "basr %r3,0\n"
5259   "0: la %r2,0(%r2,%r12)\n"
5260   "l %r4,1f-0b(%r3)\n"
5261   "b 0(%r4,%r3)\n"
5262   "1: .long __tls_get_addr_hidden - 0b\n"
5263 #endif
5264   ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
5265 // Assembly wrapper to call REAL(__tls_get_offset)(arg)
5266   ".type __tls_get_offset_wrapper, @function\n"
5267   "__tls_get_offset_wrapper:\n"
5268 #ifdef __s390x__
5269   "sgr %r2,%r12\n"
5270 #else
5271   "sr %r2,%r12\n"
5272 #endif
5273   "br %r3\n"
5274   ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
5275 );
5276 #endif // SANITIZER_S390
5277 #else
5278 #define INIT_TLS_GET_ADDR
5279 #endif
5280
5281 #if SANITIZER_INTERCEPT_LISTXATTR
5282 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
5283   void *ctx;
5284   COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
5285   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5286   // FIXME: under ASan the call below may write to freed memory and corrupt
5287   // its metadata. See
5288   // https://github.com/google/sanitizers/issues/321.
5289   SSIZE_T res = REAL(listxattr)(path, list, size);
5290   // Here and below, size == 0 is a special case where nothing is written to the
5291   // buffer, and res contains the desired buffer size.
5292   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5293   return res;
5294 }
5295 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
5296   void *ctx;
5297   COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
5298   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5299   // FIXME: under ASan the call below may write to freed memory and corrupt
5300   // its metadata. See
5301   // https://github.com/google/sanitizers/issues/321.
5302   SSIZE_T res = REAL(llistxattr)(path, list, size);
5303   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5304   return res;
5305 }
5306 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
5307   void *ctx;
5308   COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
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   SSIZE_T res = REAL(flistxattr)(fd, list, size);
5313   if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5314   return res;
5315 }
5316 #define INIT_LISTXATTR                   \
5317   COMMON_INTERCEPT_FUNCTION(listxattr);  \
5318   COMMON_INTERCEPT_FUNCTION(llistxattr); \
5319   COMMON_INTERCEPT_FUNCTION(flistxattr);
5320 #else
5321 #define INIT_LISTXATTR
5322 #endif
5323
5324 #if SANITIZER_INTERCEPT_GETXATTR
5325 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
5326             SIZE_T size) {
5327   void *ctx;
5328   COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
5329   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5330   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
5331   // FIXME: under ASan the call below may write to freed memory and corrupt
5332   // its metadata. See
5333   // https://github.com/google/sanitizers/issues/321.
5334   SSIZE_T res = REAL(getxattr)(path, name, value, size);
5335   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5336   return res;
5337 }
5338 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
5339             SIZE_T size) {
5340   void *ctx;
5341   COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
5342   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5343   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
5344   // FIXME: under ASan the call below may write to freed memory and corrupt
5345   // its metadata. See
5346   // https://github.com/google/sanitizers/issues/321.
5347   SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
5348   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5349   return res;
5350 }
5351 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
5352             SIZE_T size) {
5353   void *ctx;
5354   COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
5355   if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
5356   // FIXME: under ASan the call below may write to freed memory and corrupt
5357   // its metadata. See
5358   // https://github.com/google/sanitizers/issues/321.
5359   SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
5360   if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5361   return res;
5362 }
5363 #define INIT_GETXATTR                   \
5364   COMMON_INTERCEPT_FUNCTION(getxattr);  \
5365   COMMON_INTERCEPT_FUNCTION(lgetxattr); \
5366   COMMON_INTERCEPT_FUNCTION(fgetxattr);
5367 #else
5368 #define INIT_GETXATTR
5369 #endif
5370
5371 #if SANITIZER_INTERCEPT_GETRESID
5372 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
5373   void *ctx;
5374   COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
5375   // FIXME: under ASan the call below may write to freed memory and corrupt
5376   // its metadata. See
5377   // https://github.com/google/sanitizers/issues/321.
5378   int res = REAL(getresuid)(ruid, euid, suid);
5379   if (res >= 0) {
5380     if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
5381     if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
5382     if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
5383   }
5384   return res;
5385 }
5386 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
5387   void *ctx;
5388   COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
5389   // FIXME: under ASan the call below may write to freed memory and corrupt
5390   // its metadata. See
5391   // https://github.com/google/sanitizers/issues/321.
5392   int res = REAL(getresgid)(rgid, egid, sgid);
5393   if (res >= 0) {
5394     if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
5395     if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
5396     if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
5397   }
5398   return res;
5399 }
5400 #define INIT_GETRESID                   \
5401   COMMON_INTERCEPT_FUNCTION(getresuid); \
5402   COMMON_INTERCEPT_FUNCTION(getresgid);
5403 #else
5404 #define INIT_GETRESID
5405 #endif
5406
5407 #if SANITIZER_INTERCEPT_GETIFADDRS
5408 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
5409 // intercept freeifaddrs(). If that ceases to be the case, we might need to
5410 // intercept it to poison the memory again.
5411 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
5412   void *ctx;
5413   COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
5414   // FIXME: under ASan the call below may write to freed memory and corrupt
5415   // its metadata. See
5416   // https://github.com/google/sanitizers/issues/321.
5417   int res = REAL(getifaddrs)(ifap);
5418   if (res == 0 && ifap) {
5419     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
5420     __sanitizer_ifaddrs *p = *ifap;
5421     while (p) {
5422       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
5423       if (p->ifa_name)
5424         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
5425                                        REAL(strlen)(p->ifa_name) + 1);
5426       if (p->ifa_addr)
5427         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
5428       if (p->ifa_netmask)
5429         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
5430       // On Linux this is a union, but the other member also points to a
5431       // struct sockaddr, so the following is sufficient.
5432       if (p->ifa_dstaddr)
5433         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
5434       // FIXME(smatveev): Unpoison p->ifa_data as well.
5435       p = p->ifa_next;
5436     }
5437   }
5438   return res;
5439 }
5440 #define INIT_GETIFADDRS                  \
5441   COMMON_INTERCEPT_FUNCTION(getifaddrs);
5442 #else
5443 #define INIT_GETIFADDRS
5444 #endif
5445
5446 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
5447 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
5448   void *ctx;
5449   COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
5450   // FIXME: under ASan the call below may write to freed memory and corrupt
5451   // its metadata. See
5452   // https://github.com/google/sanitizers/issues/321.
5453   char *res = REAL(if_indextoname)(ifindex, ifname);
5454   if (res && ifname)
5455     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
5456   return res;
5457 }
5458 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
5459   void *ctx;
5460   COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
5461   if (ifname)
5462     COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1);
5463   return REAL(if_nametoindex)(ifname);
5464 }
5465 #define INIT_IF_INDEXTONAME                  \
5466   COMMON_INTERCEPT_FUNCTION(if_indextoname); \
5467   COMMON_INTERCEPT_FUNCTION(if_nametoindex);
5468 #else
5469 #define INIT_IF_INDEXTONAME
5470 #endif
5471
5472 #if SANITIZER_INTERCEPT_CAPGET
5473 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
5474   void *ctx;
5475   COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
5476   if (hdrp)
5477     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5478   // FIXME: under ASan the call below may write to freed memory and corrupt
5479   // its metadata. See
5480   // https://github.com/google/sanitizers/issues/321.
5481   int res = REAL(capget)(hdrp, datap);
5482   if (res == 0 && datap)
5483     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
5484   // We can also return -1 and write to hdrp->version if the version passed in
5485   // hdrp->version is unsupported. But that's not a trivial condition to check,
5486   // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
5487   return res;
5488 }
5489 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
5490   void *ctx;
5491   COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
5492   if (hdrp)
5493     COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5494   if (datap)
5495     COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
5496   return REAL(capset)(hdrp, datap);
5497 }
5498 #define INIT_CAPGET                  \
5499   COMMON_INTERCEPT_FUNCTION(capget); \
5500   COMMON_INTERCEPT_FUNCTION(capset);
5501 #else
5502 #define INIT_CAPGET
5503 #endif
5504
5505 #if SANITIZER_INTERCEPT_AEABI_MEM
5506 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
5507   void *ctx;
5508   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5509 }
5510
5511 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
5512   void *ctx;
5513   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5514 }
5515
5516 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
5517   void *ctx;
5518   COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5519 }
5520
5521 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
5522   void *ctx;
5523   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5524 }
5525
5526 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
5527   void *ctx;
5528   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5529 }
5530
5531 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
5532   void *ctx;
5533   COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5534 }
5535
5536 // Note the argument order.
5537 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
5538   void *ctx;
5539   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5540 }
5541
5542 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
5543   void *ctx;
5544   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5545 }
5546
5547 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
5548   void *ctx;
5549   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5550 }
5551
5552 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
5553   void *ctx;
5554   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5555 }
5556
5557 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
5558   void *ctx;
5559   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5560 }
5561
5562 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
5563   void *ctx;
5564   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5565 }
5566
5567 #define INIT_AEABI_MEM                         \
5568   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
5569   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
5570   COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
5571   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
5572   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
5573   COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
5574   COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
5575   COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
5576   COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
5577   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
5578   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
5579   COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
5580 #else
5581 #define INIT_AEABI_MEM
5582 #endif  // SANITIZER_INTERCEPT_AEABI_MEM
5583
5584 #if SANITIZER_INTERCEPT___BZERO
5585 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
5586   void *ctx;
5587   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5588 }
5589 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
5590 #else
5591 #define INIT___BZERO
5592 #endif  // SANITIZER_INTERCEPT___BZERO
5593
5594 #if SANITIZER_INTERCEPT_BZERO
5595 INTERCEPTOR(void *, bzero, void *block, uptr size) {
5596   void *ctx;
5597   COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5598 }
5599 #define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);
5600 #else
5601 #define INIT_BZERO
5602 #endif  // SANITIZER_INTERCEPT_BZERO
5603
5604 #if SANITIZER_INTERCEPT_FTIME
5605 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
5606   void *ctx;
5607   COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
5608   // FIXME: under ASan the call below may write to freed memory and corrupt
5609   // its metadata. See
5610   // https://github.com/google/sanitizers/issues/321.
5611   int res = REAL(ftime)(tp);
5612   if (tp)
5613     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
5614   return res;
5615 }
5616 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
5617 #else
5618 #define INIT_FTIME
5619 #endif  // SANITIZER_INTERCEPT_FTIME
5620
5621 #if SANITIZER_INTERCEPT_XDR
5622 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
5623             unsigned size, int op) {
5624   void *ctx;
5625   COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
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   REAL(xdrmem_create)(xdrs, addr, size, op);
5630   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
5631   if (op == __sanitizer_XDR_ENCODE) {
5632     // It's not obvious how much data individual xdr_ routines write.
5633     // Simply unpoison the entire target buffer in advance.
5634     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
5635   }
5636 }
5637
5638 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
5639   void *ctx;
5640   COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
5641   // FIXME: under ASan the call below may write to freed memory and corrupt
5642   // its metadata. See
5643   // https://github.com/google/sanitizers/issues/321.
5644   REAL(xdrstdio_create)(xdrs, file, op);
5645   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
5646 }
5647
5648 // FIXME: under ASan the call below may write to freed memory and corrupt
5649 // its metadata. See
5650 // https://github.com/google/sanitizers/issues/321.
5651 #define XDR_INTERCEPTOR(F, T)                             \
5652   INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
5653     void *ctx;                                            \
5654     COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
5655     if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
5656       COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
5657     int res = REAL(F)(xdrs, p);                           \
5658     if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
5659       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
5660     return res;                                           \
5661   }
5662
5663 XDR_INTERCEPTOR(xdr_short, short)
5664 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
5665 XDR_INTERCEPTOR(xdr_int, int)
5666 XDR_INTERCEPTOR(xdr_u_int, unsigned)
5667 XDR_INTERCEPTOR(xdr_long, long)
5668 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
5669 XDR_INTERCEPTOR(xdr_hyper, long long)
5670 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
5671 XDR_INTERCEPTOR(xdr_longlong_t, long long)
5672 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
5673 XDR_INTERCEPTOR(xdr_int8_t, u8)
5674 XDR_INTERCEPTOR(xdr_uint8_t, u8)
5675 XDR_INTERCEPTOR(xdr_int16_t, u16)
5676 XDR_INTERCEPTOR(xdr_uint16_t, u16)
5677 XDR_INTERCEPTOR(xdr_int32_t, u32)
5678 XDR_INTERCEPTOR(xdr_uint32_t, u32)
5679 XDR_INTERCEPTOR(xdr_int64_t, u64)
5680 XDR_INTERCEPTOR(xdr_uint64_t, u64)
5681 XDR_INTERCEPTOR(xdr_quad_t, long long)
5682 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
5683 XDR_INTERCEPTOR(xdr_bool, bool)
5684 XDR_INTERCEPTOR(xdr_enum, int)
5685 XDR_INTERCEPTOR(xdr_char, char)
5686 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
5687 XDR_INTERCEPTOR(xdr_float, float)
5688 XDR_INTERCEPTOR(xdr_double, double)
5689
5690 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
5691 // wrapstring, sizeof
5692
5693 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
5694             unsigned maxsize) {
5695   void *ctx;
5696   COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
5697   if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
5698     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
5699     COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
5700     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
5701   }
5702   // FIXME: under ASan the call below may write to freed memory and corrupt
5703   // its metadata. See
5704   // https://github.com/google/sanitizers/issues/321.
5705   int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
5706   if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
5707     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
5708     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
5709     if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
5710   }
5711   return res;
5712 }
5713
5714 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
5715             unsigned maxsize) {
5716   void *ctx;
5717   COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
5718   if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
5719     COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
5720     COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
5721   }
5722   // FIXME: under ASan the call below may write to freed memory and corrupt
5723   // its metadata. See
5724   // https://github.com/google/sanitizers/issues/321.
5725   int res = REAL(xdr_string)(xdrs, p, maxsize);
5726   if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
5727     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
5728     if (res && *p)
5729       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1);
5730   }
5731   return res;
5732 }
5733
5734 #define INIT_XDR                               \
5735   COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
5736   COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
5737   COMMON_INTERCEPT_FUNCTION(xdr_short);        \
5738   COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
5739   COMMON_INTERCEPT_FUNCTION(xdr_int);          \
5740   COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
5741   COMMON_INTERCEPT_FUNCTION(xdr_long);         \
5742   COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
5743   COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
5744   COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
5745   COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
5746   COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
5747   COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
5748   COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
5749   COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
5750   COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
5751   COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
5752   COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
5753   COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
5754   COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
5755   COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
5756   COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
5757   COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
5758   COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
5759   COMMON_INTERCEPT_FUNCTION(xdr_char);         \
5760   COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
5761   COMMON_INTERCEPT_FUNCTION(xdr_float);        \
5762   COMMON_INTERCEPT_FUNCTION(xdr_double);       \
5763   COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
5764   COMMON_INTERCEPT_FUNCTION(xdr_string);
5765 #else
5766 #define INIT_XDR
5767 #endif  // SANITIZER_INTERCEPT_XDR
5768
5769 #if SANITIZER_INTERCEPT_TSEARCH
5770 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
5771             int (*compar)(const void *, const void *)) {
5772   void *ctx;
5773   COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
5774   // FIXME: under ASan the call below may write to freed memory and corrupt
5775   // its metadata. See
5776   // https://github.com/google/sanitizers/issues/321.
5777   void *res = REAL(tsearch)(key, rootp, compar);
5778   if (res && *(void **)res == key)
5779     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
5780   return res;
5781 }
5782 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
5783 #else
5784 #define INIT_TSEARCH
5785 #endif
5786
5787 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
5788     SANITIZER_INTERCEPT_OPEN_MEMSTREAM
5789 void unpoison_file(__sanitizer_FILE *fp) {
5790 #if SANITIZER_HAS_STRUCT_FILE
5791   COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
5792 #if SANITIZER_NETBSD
5793   if (fp->_bf._base && fp->_bf._size > 0)
5794     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
5795                                         fp->_bf._size);
5796 #else
5797   if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
5798     COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
5799                                         fp->_IO_read_end - fp->_IO_read_base);
5800 #endif
5801 #endif  // SANITIZER_HAS_STRUCT_FILE
5802 }
5803 #endif
5804
5805 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
5806 // These guys are called when a .c source is built with -O2.
5807 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
5808   void *ctx;
5809   COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
5810   int res = REAL(__uflow)(fp);
5811   unpoison_file(fp);
5812   return res;
5813 }
5814 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
5815   void *ctx;
5816   COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
5817   int res = REAL(__underflow)(fp);
5818   unpoison_file(fp);
5819   return res;
5820 }
5821 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
5822   void *ctx;
5823   COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
5824   int res = REAL(__overflow)(fp, ch);
5825   unpoison_file(fp);
5826   return res;
5827 }
5828 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
5829   void *ctx;
5830   COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
5831   int res = REAL(__wuflow)(fp);
5832   unpoison_file(fp);
5833   return res;
5834 }
5835 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
5836   void *ctx;
5837   COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
5838   int res = REAL(__wunderflow)(fp);
5839   unpoison_file(fp);
5840   return res;
5841 }
5842 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
5843   void *ctx;
5844   COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
5845   int res = REAL(__woverflow)(fp, ch);
5846   unpoison_file(fp);
5847   return res;
5848 }
5849 #define INIT_LIBIO_INTERNALS               \
5850   COMMON_INTERCEPT_FUNCTION(__uflow);      \
5851   COMMON_INTERCEPT_FUNCTION(__underflow);  \
5852   COMMON_INTERCEPT_FUNCTION(__overflow);   \
5853   COMMON_INTERCEPT_FUNCTION(__wuflow);     \
5854   COMMON_INTERCEPT_FUNCTION(__wunderflow); \
5855   COMMON_INTERCEPT_FUNCTION(__woverflow);
5856 #else
5857 #define INIT_LIBIO_INTERNALS
5858 #endif
5859
5860 #if SANITIZER_INTERCEPT_FOPEN
5861 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
5862   void *ctx;
5863   COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
5864   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5865   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5866   __sanitizer_FILE *res = REAL(fopen)(path, mode);
5867   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5868   if (res) unpoison_file(res);
5869   return res;
5870 }
5871 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
5872   void *ctx;
5873   COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
5874   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5875   __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
5876   if (res) unpoison_file(res);
5877   return res;
5878 }
5879 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
5880             __sanitizer_FILE *fp) {
5881   void *ctx;
5882   COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
5883   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5884   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5885   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5886   __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
5887   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5888   if (res) unpoison_file(res);
5889   return res;
5890 }
5891 #define INIT_FOPEN                   \
5892   COMMON_INTERCEPT_FUNCTION(fopen);  \
5893   COMMON_INTERCEPT_FUNCTION(fdopen); \
5894   COMMON_INTERCEPT_FUNCTION(freopen);
5895 #else
5896 #define INIT_FOPEN
5897 #endif
5898
5899 #if SANITIZER_INTERCEPT_FOPEN64
5900 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
5901   void *ctx;
5902   COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
5903   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5904   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5905   __sanitizer_FILE *res = REAL(fopen64)(path, mode);
5906   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5907   if (res) unpoison_file(res);
5908   return res;
5909 }
5910 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
5911             __sanitizer_FILE *fp) {
5912   void *ctx;
5913   COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
5914   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
5915   COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1);
5916   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
5917   __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
5918   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
5919   if (res) unpoison_file(res);
5920   return res;
5921 }
5922 #define INIT_FOPEN64                  \
5923   COMMON_INTERCEPT_FUNCTION(fopen64); \
5924   COMMON_INTERCEPT_FUNCTION(freopen64);
5925 #else
5926 #define INIT_FOPEN64
5927 #endif
5928
5929 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
5930 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
5931   void *ctx;
5932   COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
5933   // FIXME: under ASan the call below may write to freed memory and corrupt
5934   // its metadata. See
5935   // https://github.com/google/sanitizers/issues/321.
5936   __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
5937   if (res) {
5938     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
5939     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
5940     unpoison_file(res);
5941     FileMetadata file = {ptr, sizeloc};
5942     SetInterceptorMetadata(res, file);
5943   }
5944   return res;
5945 }
5946 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
5947             SIZE_T *sizeloc) {
5948   void *ctx;
5949   COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
5950   __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
5951   if (res) {
5952     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
5953     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
5954     unpoison_file(res);
5955     FileMetadata file = {(char **)ptr, sizeloc};
5956     SetInterceptorMetadata(res, file);
5957   }
5958   return res;
5959 }
5960 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
5961             const char *mode) {
5962   void *ctx;
5963   COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
5964   // FIXME: under ASan the call below may write to freed memory and corrupt
5965   // its metadata. See
5966   // https://github.com/google/sanitizers/issues/321.
5967   __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
5968   if (res) unpoison_file(res);
5969   return res;
5970 }
5971 #define INIT_OPEN_MEMSTREAM                   \
5972   COMMON_INTERCEPT_FUNCTION(open_memstream);  \
5973   COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
5974   COMMON_INTERCEPT_FUNCTION(fmemopen);
5975 #else
5976 #define INIT_OPEN_MEMSTREAM
5977 #endif
5978
5979 #if SANITIZER_INTERCEPT_OBSTACK
5980 static void initialize_obstack(__sanitizer_obstack *obstack) {
5981   COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
5982   if (obstack->chunk)
5983     COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
5984                                         sizeof(*obstack->chunk));
5985 }
5986
5987 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
5988             int align, void *(*alloc_fn)(uptr arg, uptr sz),
5989             void (*free_fn)(uptr arg, void *p)) {
5990   void *ctx;
5991   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
5992                            free_fn);
5993   int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
5994   if (res) initialize_obstack(obstack);
5995   return res;
5996 }
5997 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
5998             int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
5999   void *ctx;
6000   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
6001                            free_fn);
6002   int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
6003   if (res) initialize_obstack(obstack);
6004   return res;
6005 }
6006 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
6007   void *ctx;
6008   COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
6009   REAL(_obstack_newchunk)(obstack, length);
6010   if (obstack->chunk)
6011     COMMON_INTERCEPTOR_INITIALIZE_RANGE(
6012         obstack->chunk, obstack->next_free - (char *)obstack->chunk);
6013 }
6014 #define INIT_OBSTACK                           \
6015   COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
6016   COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
6017   COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
6018 #else
6019 #define INIT_OBSTACK
6020 #endif
6021
6022 #if SANITIZER_INTERCEPT_FFLUSH
6023 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
6024   void *ctx;
6025   COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
6026   int res = REAL(fflush)(fp);
6027   // FIXME: handle fp == NULL
6028   if (fp) {
6029     const FileMetadata *m = GetInterceptorMetadata(fp);
6030     if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6031   }
6032   return res;
6033 }
6034 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
6035 #else
6036 #define INIT_FFLUSH
6037 #endif
6038
6039 #if SANITIZER_INTERCEPT_FCLOSE
6040 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
6041   void *ctx;
6042   COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
6043   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6044   const FileMetadata *m = GetInterceptorMetadata(fp);
6045   int res = REAL(fclose)(fp);
6046   if (m) {
6047     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6048     DeleteInterceptorMetadata(fp);
6049   }
6050   return res;
6051 }
6052 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
6053 #else
6054 #define INIT_FCLOSE
6055 #endif
6056
6057 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
6058 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
6059   void *ctx;
6060   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
6061   if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
6062   COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
6063   void *res = REAL(dlopen)(filename, flag);
6064   Symbolizer::GetOrInit()->InvalidateModuleList();
6065   COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
6066   return res;
6067 }
6068
6069 INTERCEPTOR(int, dlclose, void *handle) {
6070   void *ctx;
6071   COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
6072   int res = REAL(dlclose)(handle);
6073   Symbolizer::GetOrInit()->InvalidateModuleList();
6074   COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
6075   return res;
6076 }
6077 #define INIT_DLOPEN_DLCLOSE          \
6078   COMMON_INTERCEPT_FUNCTION(dlopen); \
6079   COMMON_INTERCEPT_FUNCTION(dlclose);
6080 #else
6081 #define INIT_DLOPEN_DLCLOSE
6082 #endif
6083
6084 #if SANITIZER_INTERCEPT_GETPASS
6085 INTERCEPTOR(char *, getpass, const char *prompt) {
6086   void *ctx;
6087   COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
6088   if (prompt)
6089     COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1);
6090   char *res = REAL(getpass)(prompt);
6091   if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1);
6092   return res;
6093 }
6094
6095 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
6096 #else
6097 #define INIT_GETPASS
6098 #endif
6099
6100 #if SANITIZER_INTERCEPT_TIMERFD
6101 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
6102             void *old_value) {
6103   void *ctx;
6104   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
6105                            old_value);
6106   COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
6107   int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
6108   if (res != -1 && old_value)
6109     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
6110   return res;
6111 }
6112
6113 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
6114   void *ctx;
6115   COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
6116   int res = REAL(timerfd_gettime)(fd, curr_value);
6117   if (res != -1 && curr_value)
6118     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
6119   return res;
6120 }
6121 #define INIT_TIMERFD                          \
6122   COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
6123   COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
6124 #else
6125 #define INIT_TIMERFD
6126 #endif
6127
6128 #if SANITIZER_INTERCEPT_MLOCKX
6129 // Linux kernel has a bug that leads to kernel deadlock if a process
6130 // maps TBs of memory and then calls mlock().
6131 static void MlockIsUnsupported() {
6132   static atomic_uint8_t printed;
6133   if (atomic_exchange(&printed, 1, memory_order_relaxed))
6134     return;
6135   VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
6136           SanitizerToolName);
6137 }
6138
6139 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
6140   MlockIsUnsupported();
6141   return 0;
6142 }
6143
6144 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
6145   MlockIsUnsupported();
6146   return 0;
6147 }
6148
6149 INTERCEPTOR(int, mlockall, int flags) {
6150   MlockIsUnsupported();
6151   return 0;
6152 }
6153
6154 INTERCEPTOR(int, munlockall, void) {
6155   MlockIsUnsupported();
6156   return 0;
6157 }
6158
6159 #define INIT_MLOCKX                                                            \
6160   COMMON_INTERCEPT_FUNCTION(mlock);                                            \
6161   COMMON_INTERCEPT_FUNCTION(munlock);                                          \
6162   COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
6163   COMMON_INTERCEPT_FUNCTION(munlockall);
6164
6165 #else
6166 #define INIT_MLOCKX
6167 #endif  // SANITIZER_INTERCEPT_MLOCKX
6168
6169 #if SANITIZER_INTERCEPT_FOPENCOOKIE
6170 struct WrappedCookie {
6171   void *real_cookie;
6172   __sanitizer_cookie_io_functions_t real_io_funcs;
6173 };
6174
6175 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
6176   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6177   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6178   __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
6179   return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
6180 }
6181
6182 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
6183   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6184   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6185   __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
6186   return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
6187 }
6188
6189 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
6190   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6191   COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
6192   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6193   __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
6194   return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
6195                    : -1;
6196 }
6197
6198 static int wrapped_close(void *cookie) {
6199   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
6200   WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6201   __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
6202   int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
6203   InternalFree(wrapped_cookie);
6204   return res;
6205 }
6206
6207 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
6208             __sanitizer_cookie_io_functions_t io_funcs) {
6209   void *ctx;
6210   COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
6211   WrappedCookie *wrapped_cookie =
6212       (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
6213   wrapped_cookie->real_cookie = cookie;
6214   wrapped_cookie->real_io_funcs = io_funcs;
6215   __sanitizer_FILE *res =
6216       REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
6217                                                wrapped_seek, wrapped_close});
6218   return res;
6219 }
6220
6221 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
6222 #else
6223 #define INIT_FOPENCOOKIE
6224 #endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
6225
6226 #if SANITIZER_INTERCEPT_SEM
6227 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
6228   void *ctx;
6229   COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
6230   // Workaround a bug in glibc's "old" semaphore implementation by
6231   // zero-initializing the sem_t contents. This has to be done here because
6232   // interceptors bind to the lowest symbols version by default, hitting the
6233   // buggy code path while the non-sanitized build of the same code works fine.
6234   REAL(memset)(s, 0, sizeof(*s));
6235   int res = REAL(sem_init)(s, pshared, value);
6236   return res;
6237 }
6238
6239 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
6240   void *ctx;
6241   COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
6242   int res = REAL(sem_destroy)(s);
6243   return res;
6244 }
6245
6246 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
6247   void *ctx;
6248   COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
6249   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
6250   if (res == 0) {
6251     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6252   }
6253   return res;
6254 }
6255
6256 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
6257   void *ctx;
6258   COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
6259   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s);
6260   if (res == 0) {
6261     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6262   }
6263   return res;
6264 }
6265
6266 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
6267   void *ctx;
6268   COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
6269   COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
6270   int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
6271   if (res == 0) {
6272     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6273   }
6274   return res;
6275 }
6276
6277 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
6278   void *ctx;
6279   COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
6280   COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
6281   int res = REAL(sem_post)(s);
6282   return res;
6283 }
6284
6285 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
6286   void *ctx;
6287   COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
6288   int res = REAL(sem_getvalue)(s, sval);
6289   if (res == 0) {
6290     COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6291     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
6292   }
6293   return res;
6294 }
6295 #define INIT_SEM                                                               \
6296   COMMON_INTERCEPT_FUNCTION(sem_init);                                         \
6297   COMMON_INTERCEPT_FUNCTION(sem_destroy);                                      \
6298   COMMON_INTERCEPT_FUNCTION(sem_wait);                                         \
6299   COMMON_INTERCEPT_FUNCTION(sem_trywait);                                      \
6300   COMMON_INTERCEPT_FUNCTION(sem_timedwait);                                    \
6301   COMMON_INTERCEPT_FUNCTION(sem_post);                                         \
6302   COMMON_INTERCEPT_FUNCTION(sem_getvalue);
6303 #else
6304 #define INIT_SEM
6305 #endif // SANITIZER_INTERCEPT_SEM
6306
6307 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
6308 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
6309   void *ctx;
6310   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
6311   int res = REAL(pthread_setcancelstate)(state, oldstate);
6312   if (res == 0 && oldstate != nullptr)
6313     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
6314   return res;
6315 }
6316
6317 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
6318   void *ctx;
6319   COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
6320   int res = REAL(pthread_setcanceltype)(type, oldtype);
6321   if (res == 0 && oldtype != nullptr)
6322     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
6323   return res;
6324 }
6325 #define INIT_PTHREAD_SETCANCEL                                                 \
6326   COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
6327   COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
6328 #else
6329 #define INIT_PTHREAD_SETCANCEL
6330 #endif
6331
6332 #if SANITIZER_INTERCEPT_MINCORE
6333 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
6334   void *ctx;
6335   COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
6336   int res = REAL(mincore)(addr, length, vec);
6337   if (res == 0) {
6338     uptr page_size = GetPageSizeCached();
6339     uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
6340     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
6341   }
6342   return res;
6343 }
6344 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
6345 #else
6346 #define INIT_MINCORE
6347 #endif
6348
6349 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
6350 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
6351             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6352             uptr flags) {
6353   void *ctx;
6354   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
6355                            remote_iov, riovcnt, flags);
6356   SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
6357                                        riovcnt, flags);
6358   if (res > 0)
6359     write_iovec(ctx, local_iov, liovcnt, res);
6360   return res;
6361 }
6362
6363 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
6364             uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6365             uptr flags) {
6366   void *ctx;
6367   COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
6368                            remote_iov, riovcnt, flags);
6369   SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
6370                                         riovcnt, flags);
6371   if (res > 0)
6372     read_iovec(ctx, local_iov, liovcnt, res);
6373   return res;
6374 }
6375 #define INIT_PROCESS_VM_READV                                                  \
6376   COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
6377   COMMON_INTERCEPT_FUNCTION(process_vm_writev);
6378 #else
6379 #define INIT_PROCESS_VM_READV
6380 #endif
6381
6382 #if SANITIZER_INTERCEPT_CTERMID
6383 INTERCEPTOR(char *, ctermid, char *s) {
6384   void *ctx;
6385   COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
6386   char *res = REAL(ctermid)(s);
6387   if (res) {
6388     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
6389   }
6390   return res;
6391 }
6392 #define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
6393 #else
6394 #define INIT_CTERMID
6395 #endif
6396
6397 #if SANITIZER_INTERCEPT_CTERMID_R
6398 INTERCEPTOR(char *, ctermid_r, char *s) {
6399   void *ctx;
6400   COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
6401   char *res = REAL(ctermid_r)(s);
6402   if (res) {
6403     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1);
6404   }
6405   return res;
6406 }
6407 #define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
6408 #else
6409 #define INIT_CTERMID_R
6410 #endif
6411
6412 #if SANITIZER_INTERCEPT_RECV_RECVFROM
6413 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
6414   void *ctx;
6415   COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
6416   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6417   SSIZE_T res = REAL(recv)(fd, buf, len, flags);
6418   if (res > 0) {
6419     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6420   }
6421   if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
6422   return res;
6423 }
6424
6425 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
6426             void *srcaddr, int *addrlen) {
6427   void *ctx;
6428   COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
6429                            addrlen);
6430   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6431   SIZE_T srcaddr_sz;
6432   if (srcaddr) srcaddr_sz = *addrlen;
6433   (void)srcaddr_sz;  // prevent "set but not used" warning
6434   SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
6435   if (res > 0) {
6436     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6437     if (srcaddr)
6438       COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
6439                                           Min((SIZE_T)*addrlen, srcaddr_sz));
6440   }
6441   return res;
6442 }
6443 #define INIT_RECV_RECVFROM          \
6444   COMMON_INTERCEPT_FUNCTION(recv);  \
6445   COMMON_INTERCEPT_FUNCTION(recvfrom);
6446 #else
6447 #define INIT_RECV_RECVFROM
6448 #endif
6449
6450 #if SANITIZER_INTERCEPT_SEND_SENDTO
6451 INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
6452   void *ctx;
6453   COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
6454   if (fd >= 0) {
6455     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6456     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6457   }
6458   SSIZE_T res = REAL(send)(fd, buf, len, flags);
6459   if (common_flags()->intercept_send && res > 0)
6460     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
6461   return res;
6462 }
6463
6464 INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
6465             void *dstaddr, int addrlen) {
6466   void *ctx;
6467   COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
6468   if (fd >= 0) {
6469     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6470     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6471   }
6472   // Can't check dstaddr as it may have uninitialized padding at the end.
6473   SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
6474   if (common_flags()->intercept_send && res > 0)
6475     COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
6476   return res;
6477 }
6478 #define INIT_SEND_SENDTO           \
6479   COMMON_INTERCEPT_FUNCTION(send); \
6480   COMMON_INTERCEPT_FUNCTION(sendto);
6481 #else
6482 #define INIT_SEND_SENDTO
6483 #endif
6484
6485 #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
6486 INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
6487   void *ctx;
6488   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
6489   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6490   int res = REAL(eventfd_read)(fd, value);
6491   if (res == 0) {
6492     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
6493     if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
6494   }
6495   return res;
6496 }
6497 INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
6498   void *ctx;
6499   COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
6500   if (fd >= 0) {
6501     COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6502     COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6503   }
6504   int res = REAL(eventfd_write)(fd, value);
6505   return res;
6506 }
6507 #define INIT_EVENTFD_READ_WRITE            \
6508   COMMON_INTERCEPT_FUNCTION(eventfd_read); \
6509   COMMON_INTERCEPT_FUNCTION(eventfd_write)
6510 #else
6511 #define INIT_EVENTFD_READ_WRITE
6512 #endif
6513
6514 #if SANITIZER_INTERCEPT_STAT
6515 INTERCEPTOR(int, stat, const char *path, void *buf) {
6516   void *ctx;
6517   COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
6518   if (common_flags()->intercept_stat)
6519     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6520   int res = REAL(stat)(path, buf);
6521   if (!res)
6522     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6523   return res;
6524 }
6525 #define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
6526 #else
6527 #define INIT_STAT
6528 #endif
6529
6530 #if SANITIZER_INTERCEPT_LSTAT
6531 INTERCEPTOR(int, lstat, const char *path, void *buf) {
6532   void *ctx;
6533   COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);
6534   if (common_flags()->intercept_stat)
6535     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6536   int res = REAL(lstat)(path, buf);
6537   if (!res)
6538     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6539   return res;
6540 }
6541 #define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)
6542 #else
6543 #define INIT_LSTAT
6544 #endif
6545
6546 #if SANITIZER_INTERCEPT___XSTAT
6547 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
6548   void *ctx;
6549   COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
6550   if (common_flags()->intercept_stat)
6551     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6552   int res = REAL(__xstat)(version, path, buf);
6553   if (!res)
6554     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6555   return res;
6556 }
6557 #define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
6558 #else
6559 #define INIT___XSTAT
6560 #endif
6561
6562 #if SANITIZER_INTERCEPT___XSTAT64
6563 INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
6564   void *ctx;
6565   COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
6566   if (common_flags()->intercept_stat)
6567     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6568   int res = REAL(__xstat64)(version, path, buf);
6569   if (!res)
6570     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
6571   return res;
6572 }
6573 #define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
6574 #else
6575 #define INIT___XSTAT64
6576 #endif
6577
6578 #if SANITIZER_INTERCEPT___LXSTAT
6579 INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
6580   void *ctx;
6581   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
6582   if (common_flags()->intercept_stat)
6583     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6584   int res = REAL(__lxstat)(version, path, buf);
6585   if (!res)
6586     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6587   return res;
6588 }
6589 #define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
6590 #else
6591 #define INIT___LXSTAT
6592 #endif
6593
6594 #if SANITIZER_INTERCEPT___LXSTAT64
6595 INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
6596   void *ctx;
6597   COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
6598   if (common_flags()->intercept_stat)
6599     COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6600   int res = REAL(__lxstat64)(version, path, buf);
6601   if (!res)
6602     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
6603   return res;
6604 }
6605 #define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
6606 #else
6607 #define INIT___LXSTAT64
6608 #endif
6609
6610 // FIXME: add other *stat interceptor
6611
6612 #if SANITIZER_INTERCEPT_UTMP
6613 INTERCEPTOR(void *, getutent, int dummy) {
6614   void *ctx;
6615   COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);
6616   void *res = REAL(getutent)(dummy);
6617   if (res)
6618     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6619   return res;
6620 }
6621 INTERCEPTOR(void *, getutid, void *ut) {
6622   void *ctx;
6623   COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);
6624   void *res = REAL(getutid)(ut);
6625   if (res)
6626     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6627   return res;
6628 }
6629 INTERCEPTOR(void *, getutline, void *ut) {
6630   void *ctx;
6631   COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);
6632   void *res = REAL(getutline)(ut);
6633   if (res)
6634     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6635   return res;
6636 }
6637 #define INIT_UTMP                      \
6638   COMMON_INTERCEPT_FUNCTION(getutent); \
6639   COMMON_INTERCEPT_FUNCTION(getutid);  \
6640   COMMON_INTERCEPT_FUNCTION(getutline);
6641 #else
6642 #define INIT_UTMP
6643 #endif
6644
6645 #if SANITIZER_INTERCEPT_UTMPX
6646 INTERCEPTOR(void *, getutxent, int dummy) {
6647   void *ctx;
6648   COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);
6649   void *res = REAL(getutxent)(dummy);
6650   if (res)
6651     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
6652   return res;
6653 }
6654 INTERCEPTOR(void *, getutxid, void *ut) {
6655   void *ctx;
6656   COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);
6657   void *res = REAL(getutxid)(ut);
6658   if (res)
6659     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
6660   return res;
6661 }
6662 INTERCEPTOR(void *, getutxline, void *ut) {
6663   void *ctx;
6664   COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);
6665   void *res = REAL(getutxline)(ut);
6666   if (res)
6667     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
6668   return res;
6669 }
6670 INTERCEPTOR(void *, pututxline, const void *ut) {
6671   void *ctx;
6672   COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
6673   if (ut)
6674     COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
6675   void *res = REAL(pututxline)(ut);
6676   if (res)
6677     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
6678   return res;
6679 }
6680 #define INIT_UTMPX                      \
6681   COMMON_INTERCEPT_FUNCTION(getutxent); \
6682   COMMON_INTERCEPT_FUNCTION(getutxid);  \
6683   COMMON_INTERCEPT_FUNCTION(getutxline); \
6684   COMMON_INTERCEPT_FUNCTION(pututxline);
6685 #else
6686 #define INIT_UTMPX
6687 #endif
6688
6689 #if SANITIZER_INTERCEPT_GETLOADAVG
6690 INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {
6691   void *ctx;
6692   COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);
6693   int res = REAL(getloadavg)(loadavg, nelem);
6694   if (res > 0)
6695     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));
6696   return res;
6697 }
6698 #define INIT_GETLOADAVG                      \
6699   COMMON_INTERCEPT_FUNCTION(getloadavg);
6700 #else
6701 #define INIT_GETLOADAVG
6702 #endif
6703
6704 #if SANITIZER_INTERCEPT_MCHECK_MPROBE
6705 INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
6706   return 0;
6707 }
6708
6709 INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
6710   return 0;
6711 }
6712
6713 INTERCEPTOR(int, mprobe, void *ptr) {
6714   return 0;
6715 }
6716 #endif
6717
6718 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
6719   void *ctx;
6720   COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
6721   SIZE_T res = REAL(wcslen)(s);
6722   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
6723   return res;
6724 }
6725
6726 INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
6727   void *ctx;
6728   COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
6729   SIZE_T res = REAL(wcsnlen)(s, n);
6730   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
6731   return res;
6732 }
6733 #define INIT_WCSLEN                  \
6734   COMMON_INTERCEPT_FUNCTION(wcslen); \
6735   COMMON_INTERCEPT_FUNCTION(wcsnlen);
6736
6737 #if SANITIZER_INTERCEPT_WCSCAT
6738 INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
6739   void *ctx;
6740   COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
6741   SIZE_T src_size = REAL(wcslen)(src);
6742   SIZE_T dst_size = REAL(wcslen)(dst);
6743   COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
6744   COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
6745   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
6746                                  (src_size + 1) * sizeof(wchar_t));
6747   return REAL(wcscat)(dst, src);
6748 }
6749
6750 INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
6751   void *ctx;
6752   COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
6753   SIZE_T src_size = REAL(wcsnlen)(src, n);
6754   SIZE_T dst_size = REAL(wcslen)(dst);
6755   COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
6756                                 Min(src_size + 1, n) * sizeof(wchar_t));
6757   COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
6758   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
6759                                  (src_size + 1) * sizeof(wchar_t));
6760   return REAL(wcsncat)(dst, src, n);
6761 }
6762 #define INIT_WCSCAT                  \
6763   COMMON_INTERCEPT_FUNCTION(wcscat); \
6764   COMMON_INTERCEPT_FUNCTION(wcsncat);
6765 #else
6766 #define INIT_WCSCAT
6767 #endif
6768
6769 #if SANITIZER_INTERCEPT_WCSDUP
6770 INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {
6771   void *ctx;
6772   COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);
6773   SIZE_T len = REAL(wcslen)(s);
6774   COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));
6775   wchar_t *result = REAL(wcsdup)(s);
6776   if (result)
6777     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));
6778   return result;
6779 }
6780
6781 #define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);
6782 #else
6783 #define INIT_WCSDUP
6784 #endif
6785
6786 #if SANITIZER_INTERCEPT_STRXFRM
6787 static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); }
6788
6789 static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); }
6790
6791 #define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...)             \
6792   {                                                                        \
6793     void *ctx;                                                             \
6794     COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \
6795     COMMON_INTERCEPTOR_READ_RANGE(ctx, src,                                \
6796                                   sizeof(*src) * (RealStrLen(src) + 1));   \
6797     SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__);             \
6798     if (res < len)                                                         \
6799       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \
6800     return res;                                                            \
6801   }
6802
6803 INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {
6804   STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);
6805 }
6806
6807 INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,
6808             void *locale) {
6809   STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);
6810 }
6811
6812 #define INIT_STRXFRM                  \
6813   COMMON_INTERCEPT_FUNCTION(strxfrm); \
6814   COMMON_INTERCEPT_FUNCTION(strxfrm_l);
6815 #else
6816 #define INIT_STRXFRM
6817 #endif
6818
6819 #if SANITIZER_INTERCEPT___STRXFRM_L
6820 INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,
6821             void *locale) {
6822   STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);
6823 }
6824
6825 #define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);
6826 #else
6827 #define INIT___STRXFRM_L
6828 #endif
6829
6830 #if SANITIZER_INTERCEPT_WCSXFRM
6831 INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {
6832   STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);
6833 }
6834
6835 INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
6836             void *locale) {
6837   STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);
6838 }
6839
6840 #define INIT_WCSXFRM                  \
6841   COMMON_INTERCEPT_FUNCTION(wcsxfrm); \
6842   COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);
6843 #else
6844 #define INIT_WCSXFRM
6845 #endif
6846
6847 #if SANITIZER_INTERCEPT___WCSXFRM_L
6848 INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
6849             void *locale) {
6850   STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);
6851 }
6852
6853 #define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);
6854 #else
6855 #define INIT___WCSXFRM_L
6856 #endif
6857
6858 #if SANITIZER_INTERCEPT_ACCT
6859 INTERCEPTOR(int, acct, const char *file) {
6860   void *ctx;
6861   COMMON_INTERCEPTOR_ENTER(ctx, acct, file);
6862   if (file)
6863     COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
6864   return REAL(acct)(file);
6865 }
6866 #define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)
6867 #else
6868 #define INIT_ACCT
6869 #endif
6870
6871 #if SANITIZER_INTERCEPT_USER_FROM_UID
6872 INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {
6873   void *ctx;
6874   const char *user;
6875   COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);
6876   user = REAL(user_from_uid)(uid, nouser);
6877   if (user)
6878     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1);
6879   return user;
6880 }
6881 #define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)
6882 #else
6883 #define INIT_USER_FROM_UID
6884 #endif
6885
6886 #if SANITIZER_INTERCEPT_UID_FROM_USER
6887 INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {
6888   void *ctx;
6889   int res;
6890   COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);
6891   if (name)
6892     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
6893   res = REAL(uid_from_user)(name, uid);
6894   if (uid)
6895     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));
6896   return res;
6897 }
6898 #define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)
6899 #else
6900 #define INIT_UID_FROM_USER
6901 #endif
6902
6903 #if SANITIZER_INTERCEPT_GROUP_FROM_GID
6904 INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {
6905   void *ctx;
6906   const char *group;
6907   COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);
6908   group = REAL(group_from_gid)(gid, nogroup);
6909   if (group)
6910     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1);
6911   return group;
6912 }
6913 #define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)
6914 #else
6915 #define INIT_GROUP_FROM_GID
6916 #endif
6917
6918 #if SANITIZER_INTERCEPT_GID_FROM_GROUP
6919 INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {
6920   void *ctx;
6921   int res;
6922   COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);
6923   if (group)
6924     COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1);
6925   res = REAL(gid_from_group)(group, gid);
6926   if (gid)
6927     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));
6928   return res;
6929 }
6930 #define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)
6931 #else
6932 #define INIT_GID_FROM_GROUP
6933 #endif
6934
6935 #if SANITIZER_INTERCEPT_ACCESS
6936 INTERCEPTOR(int, access, const char *path, int mode) {
6937   void *ctx;
6938   COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);
6939   if (path)
6940     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
6941   return REAL(access)(path, mode);
6942 }
6943 #define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)
6944 #else
6945 #define INIT_ACCESS
6946 #endif
6947
6948 #if SANITIZER_INTERCEPT_FACCESSAT
6949 INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
6950   void *ctx;
6951   COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);
6952   if (path)
6953     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
6954   return REAL(faccessat)(fd, path, mode, flags);
6955 }
6956 #define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)
6957 #else
6958 #define INIT_FACCESSAT
6959 #endif
6960
6961 #if SANITIZER_INTERCEPT_GETGROUPLIST
6962 INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
6963             int *ngroups) {
6964   void *ctx;
6965   int res;
6966   COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
6967   if (name)
6968     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
6969   if (ngroups)
6970     COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
6971   res = REAL(getgrouplist)(name, basegid, groups, ngroups);
6972   if (!res && groups && ngroups) {
6973     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
6974     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
6975   }
6976   return res;
6977 }
6978
6979 #define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);
6980 #else
6981 #define INIT_GETGROUPLIST
6982 #endif
6983
6984 #if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP
6985 INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
6986             int maxgrp, int *ngroups) {
6987   void *ctx;
6988   int res;
6989   COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,
6990                            maxgrp, ngroups);
6991   if (name)
6992     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
6993   res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
6994   if (!res && groups && ngroups) {
6995     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
6996     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
6997   }
6998   return res;
6999 }
7000
7001 #define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);
7002 #else
7003 #define INIT_GETGROUPMEMBERSHIP
7004 #endif
7005
7006 #if SANITIZER_INTERCEPT_READLINK
7007 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
7008   void* ctx;
7009   COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
7010   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
7011   SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
7012   if (res > 0)
7013     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7014   return res;
7015 }
7016
7017 #define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
7018 #else
7019 #define INIT_READLINK
7020 #endif
7021
7022 #if SANITIZER_INTERCEPT_READLINKAT
7023 INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
7024             SIZE_T bufsiz) {
7025   void* ctx;
7026   COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
7027   COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
7028   SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
7029   if (res > 0)
7030     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7031   return res;
7032 }
7033
7034 #define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
7035 #else
7036 #define INIT_READLINKAT
7037 #endif
7038
7039 #if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
7040 INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
7041             struct file_handle *handle, int *mount_id, int flags) {
7042   void* ctx;
7043   COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
7044                            mount_id, flags);
7045   COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1);
7046
7047   __sanitizer_file_handle *sanitizer_handle =
7048       reinterpret_cast<__sanitizer_file_handle*>(handle);
7049   COMMON_INTERCEPTOR_READ_RANGE(
7050       ctx, &sanitizer_handle->handle_bytes,
7051       sizeof(sanitizer_handle->handle_bytes));
7052
7053   int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
7054   if (!res) {
7055     COMMON_INTERCEPTOR_WRITE_RANGE(
7056         ctx, &sanitizer_handle->handle_bytes,
7057         sizeof(sanitizer_handle->handle_bytes));
7058     COMMON_INTERCEPTOR_WRITE_RANGE(
7059         ctx, &sanitizer_handle->handle_type,
7060         sizeof(sanitizer_handle->handle_type));
7061     COMMON_INTERCEPTOR_WRITE_RANGE(
7062         ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7063     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
7064   }
7065   return res;
7066 }
7067
7068 #define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
7069 #else
7070 #define INIT_NAME_TO_HANDLE_AT
7071 #endif
7072
7073 #if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
7074 INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
7075             int flags) {
7076   void* ctx;
7077   COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
7078
7079   __sanitizer_file_handle *sanitizer_handle =
7080       reinterpret_cast<__sanitizer_file_handle*>(handle);
7081   COMMON_INTERCEPTOR_READ_RANGE(
7082       ctx, &sanitizer_handle->handle_bytes,
7083       sizeof(sanitizer_handle->handle_bytes));
7084   COMMON_INTERCEPTOR_READ_RANGE(
7085       ctx, &sanitizer_handle->handle_type,
7086       sizeof(sanitizer_handle->handle_type));
7087   COMMON_INTERCEPTOR_READ_RANGE(
7088       ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7089
7090   return REAL(open_by_handle_at)(mount_fd, handle, flags);
7091 }
7092
7093 #define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
7094 #else
7095 #define INIT_OPEN_BY_HANDLE_AT
7096 #endif
7097
7098 #if SANITIZER_INTERCEPT_STRLCPY
7099 INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {
7100   void *ctx;
7101   SIZE_T res;
7102   COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);
7103   if (src) {
7104     // Keep strnlen as macro argument, as macro may ignore it.
7105     COMMON_INTERCEPTOR_READ_STRING(
7106         ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);
7107   }
7108   res = REAL(strlcpy)(dst, src, size);
7109   COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1);
7110   return res;
7111 }
7112
7113 INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {
7114   void *ctx;
7115   SIZE_T len = 0;
7116   COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);
7117   // src is checked in the strlcpy() interceptor
7118   if (dst) {
7119     len = internal_strnlen(dst, size);
7120     COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);
7121   }
7122   // Reuse the rest of the code in the strlcpy() interceptor
7123   return WRAP(strlcpy)(dst + len, src, size - len) + len;
7124 }
7125 #define INIT_STRLCPY \
7126   COMMON_INTERCEPT_FUNCTION(strlcpy); \
7127   COMMON_INTERCEPT_FUNCTION(strlcat);
7128 #else
7129 #define INIT_STRLCPY
7130 #endif
7131
7132 #if SANITIZER_INTERCEPT_MMAP
7133 INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,
7134             OFF_T off) {
7135   void *ctx;
7136   if (common_flags()->detect_write_exec)
7137     ReportMmapWriteExec(prot);
7138   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7139     return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7140   COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
7141   COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);
7142 }
7143
7144 INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {
7145   void *ctx;
7146   if (common_flags()->detect_write_exec)
7147     ReportMmapWriteExec(prot);
7148   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7149     return (int)internal_mprotect(addr, sz, prot);
7150   COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);
7151   MprotectMallocZones(addr, prot);
7152   return REAL(mprotect)(addr, sz, prot);
7153 }
7154 #define INIT_MMAP                                                              \
7155   COMMON_INTERCEPT_FUNCTION(mmap);                                             \
7156   COMMON_INTERCEPT_FUNCTION(mprotect);
7157 #else
7158 #define INIT_MMAP
7159 #endif
7160
7161 #if SANITIZER_INTERCEPT_MMAP64
7162 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,
7163             OFF64_T off) {
7164   void *ctx;
7165   if (common_flags()->detect_write_exec)
7166     ReportMmapWriteExec(prot);
7167   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7168     return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7169   COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
7170   COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);
7171 }
7172 #define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);
7173 #else
7174 #define INIT_MMAP64
7175 #endif
7176
7177 #if SANITIZER_INTERCEPT_DEVNAME
7178 INTERCEPTOR(char *, devname, u64 dev, u32 type) {
7179   void *ctx;
7180   char *name;
7181   COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);
7182   name = REAL(devname)(dev, type);
7183   if (name)
7184     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
7185   return name;
7186 }
7187 #define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);
7188 #else
7189 #define INIT_DEVNAME
7190 #endif
7191
7192 #if SANITIZER_INTERCEPT_DEVNAME_R
7193 #if SANITIZER_NETBSD
7194 #define DEVNAME_R_RETTYPE int
7195 #define DEVNAME_R_SUCCESS(x) (!(x))
7196 #else
7197 #define DEVNAME_R_RETTYPE char*
7198 #define DEVNAME_R_SUCCESS(x) (x)
7199 #endif
7200 INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
7201             uptr len) {
7202   void *ctx;
7203   COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
7204   DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
7205   if (DEVNAME_R_SUCCESS(res))
7206     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1);
7207   return res;
7208 }
7209 #define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);
7210 #else
7211 #define INIT_DEVNAME_R
7212 #endif
7213
7214 #if SANITIZER_INTERCEPT_FGETLN
7215 INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {
7216   void *ctx;
7217   COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);
7218   char *str = REAL(fgetln)(stream, len);
7219   if (str && len) {
7220     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7221     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);
7222   }
7223   return str;
7224 }
7225 #define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)
7226 #else
7227 #define INIT_FGETLN
7228 #endif
7229
7230 #if SANITIZER_INTERCEPT_STRMODE
7231 INTERCEPTOR(void, strmode, u32 mode, char *bp) {
7232   void *ctx;
7233   COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);
7234   REAL(strmode)(mode, bp);
7235   if (bp)
7236     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1);
7237 }
7238 #define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)
7239 #else
7240 #define INIT_STRMODE
7241 #endif
7242
7243 #if SANITIZER_INTERCEPT_TTYENT
7244 INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {
7245   void *ctx;
7246   COMMON_INTERCEPTOR_ENTER(ctx, getttyent);
7247   struct __sanitizer_ttyent *ttyent = REAL(getttyent)();
7248   if (ttyent)
7249     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7250   return ttyent;
7251 }
7252 INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
7253   void *ctx;
7254   COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);
7255   if (name)
7256     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
7257   struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);
7258   if (ttyent)
7259     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7260   return ttyent;
7261 }
7262 INTERCEPTOR(int, setttyentpath, char *path) {
7263   void *ctx;
7264   COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
7265   if (path)
7266     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
7267   return REAL(setttyentpath)(path);
7268 }
7269 #define INIT_TTYENT \
7270   COMMON_INTERCEPT_FUNCTION(getttyent); \
7271   COMMON_INTERCEPT_FUNCTION(getttynam); \
7272   COMMON_INTERCEPT_FUNCTION(setttyentpath)
7273 #else
7274 #define INIT_TTYENT
7275 #endif
7276
7277 #if SANITIZER_INTERCEPT_PROTOENT
7278 INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
7279   void *ctx;
7280   COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
7281   struct __sanitizer_protoent *p = REAL(getprotoent)();
7282   if (p) {
7283     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
7284
7285     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
7286
7287     SIZE_T pp_size = 1; // One handles the trailing \0
7288
7289     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
7290        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
7291
7292     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
7293                                    pp_size * sizeof(char **));
7294   }
7295   return p;
7296 }
7297
7298 INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
7299   void *ctx;
7300   COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);
7301   if (name)
7302     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
7303   struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
7304   if (p) {
7305     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
7306
7307     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
7308
7309     SIZE_T pp_size = 1; // One handles the trailing \0
7310
7311     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
7312        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
7313
7314     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
7315                                    pp_size * sizeof(char **));
7316   }
7317   return p;
7318 }
7319
7320 INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
7321   void *ctx;
7322   COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
7323   struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
7324   if (p) {
7325     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
7326
7327     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1);
7328
7329     SIZE_T pp_size = 1; // One handles the trailing \0
7330
7331     for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
7332        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1);
7333
7334     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
7335                                    pp_size * sizeof(char **));
7336   }
7337   return p;
7338 }
7339 #define INIT_PROTOENT \
7340   COMMON_INTERCEPT_FUNCTION(getprotoent); \
7341   COMMON_INTERCEPT_FUNCTION(getprotobyname); \
7342   COMMON_INTERCEPT_FUNCTION(getprotobynumber)
7343 #else
7344 #define INIT_PROTOENT
7345 #endif
7346
7347 #if SANITIZER_INTERCEPT_NETENT
7348 INTERCEPTOR(struct __sanitizer_netent *, getnetent) {
7349   void *ctx;
7350   COMMON_INTERCEPTOR_ENTER(ctx, getnetent);
7351   struct __sanitizer_netent *n = REAL(getnetent)();
7352   if (n) {
7353     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7354
7355     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
7356
7357     SIZE_T nn_size = 1; // One handles the trailing \0
7358
7359     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7360       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
7361
7362     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7363                                    nn_size * sizeof(char **));
7364   }
7365   return n;
7366 }
7367
7368 INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {
7369   void *ctx;
7370   COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);
7371   if (name)
7372     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
7373   struct __sanitizer_netent *n = REAL(getnetbyname)(name);
7374   if (n) {
7375     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7376
7377     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
7378
7379     SIZE_T nn_size = 1; // One handles the trailing \0
7380
7381     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7382       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
7383
7384     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7385                                    nn_size * sizeof(char **));
7386   }
7387   return n;
7388 }
7389
7390 INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
7391   void *ctx;
7392   COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);
7393   struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);
7394   if (n) {
7395     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7396
7397     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1);
7398
7399     SIZE_T nn_size = 1; // One handles the trailing \0
7400
7401     for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7402       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1);
7403
7404     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7405                                    nn_size * sizeof(char **));
7406   }
7407   return n;
7408 }
7409 #define INIT_NETENT \
7410   COMMON_INTERCEPT_FUNCTION(getnetent); \
7411   COMMON_INTERCEPT_FUNCTION(getnetbyname); \
7412   COMMON_INTERCEPT_FUNCTION(getnetbyaddr)
7413 #else
7414 #define INIT_NETENT
7415 #endif
7416
7417 #if SANITIZER_INTERCEPT_GETMNTINFO
7418 INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
7419   void *ctx;
7420   COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
7421   int cnt = REAL(getmntinfo)(mntbufp, flags);
7422   if (cnt > 0 && mntbufp) {
7423     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
7424     if (*mntbufp)
7425 #if SANITIZER_NETBSD
7426       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
7427 #else
7428       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
7429 #endif
7430   }
7431   return cnt;
7432 }
7433 #define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
7434 #else
7435 #define INIT_GETMNTINFO
7436 #endif
7437
7438 #if SANITIZER_INTERCEPT_MI_VECTOR_HASH
7439 INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
7440             u32 hashes[3]) {
7441   void *ctx;
7442   COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
7443   if (key)
7444     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
7445   REAL(mi_vector_hash)(key, len, seed, hashes);
7446   if (hashes)
7447     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
7448 }
7449 #define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
7450 #else
7451 #define INIT_MI_VECTOR_HASH
7452 #endif
7453
7454 #if SANITIZER_INTERCEPT_SETVBUF
7455 INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
7456   SIZE_T size) {
7457   void *ctx;
7458   COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
7459   int ret = REAL(setvbuf)(stream, buf, mode, size);
7460   if (buf)
7461     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
7462   if (stream)
7463       unpoison_file(stream);
7464   return ret;
7465 }
7466
7467 INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
7468   void *ctx;
7469   COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
7470   REAL(setbuf)(stream, buf);
7471   if (buf) {
7472     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
7473   }
7474   if (stream)
7475       unpoison_file(stream);
7476 }
7477
7478 INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) {
7479   void *ctx;
7480   COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode);
7481   REAL(setbuffer)(stream, buf, mode);
7482   if (buf) {
7483     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
7484   }
7485   if (stream)
7486     unpoison_file(stream);
7487 }
7488
7489 INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
7490   void *ctx;
7491   COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
7492   REAL(setlinebuf)(stream);
7493   if (stream)
7494     unpoison_file(stream);
7495 }
7496 #define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
7497     COMMON_INTERCEPT_FUNCTION(setbuf); \
7498     COMMON_INTERCEPT_FUNCTION(setbuffer); \
7499     COMMON_INTERCEPT_FUNCTION(setlinebuf)
7500 #else
7501 #define INIT_SETVBUF
7502 #endif
7503
7504 #if SANITIZER_INTERCEPT_GETVFSSTAT
7505 INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
7506   void *ctx;
7507   COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
7508   int ret = REAL(getvfsstat)(buf, bufsize, flags);
7509   if (buf && ret > 0)
7510     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
7511   return ret;
7512 }
7513 #define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
7514 #else
7515 #define INIT_GETVFSSTAT
7516 #endif
7517
7518 #if SANITIZER_INTERCEPT_REGEX
7519 INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
7520   void *ctx;
7521   COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
7522   if (pattern)
7523     COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1);
7524   int res = REAL(regcomp)(preg, pattern, cflags);
7525   if (!res)
7526     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
7527   return res;
7528 }
7529 INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
7530             struct __sanitizer_regmatch *pmatch[], int eflags) {
7531   void *ctx;
7532   COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
7533   if (preg)
7534     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7535   if (string)
7536     COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1);
7537   int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
7538   if (!res && pmatch)
7539     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
7540   return res;
7541 }
7542 INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
7543             SIZE_T errbuf_size) {
7544   void *ctx;
7545   COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
7546   if (preg)
7547     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7548   SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
7549   if (errbuf)
7550     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1);
7551   return res;
7552 }
7553 INTERCEPTOR(void, regfree, const void *preg) {
7554   void *ctx;
7555   COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
7556   if (preg)
7557     COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7558   REAL(regfree)(preg);
7559 }
7560 #define INIT_REGEX                                                             \
7561   COMMON_INTERCEPT_FUNCTION(regcomp);                                          \
7562   COMMON_INTERCEPT_FUNCTION(regexec);                                          \
7563   COMMON_INTERCEPT_FUNCTION(regerror);                                         \
7564   COMMON_INTERCEPT_FUNCTION(regfree);
7565 #else
7566 #define INIT_REGEX
7567 #endif
7568
7569 #if SANITIZER_INTERCEPT_REGEXSUB
7570 INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
7571             const struct __sanitizer_regmatch *rm, const char *str) {
7572   void *ctx;
7573   COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
7574   if (sub)
7575     COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
7576   // The implementation demands and hardcodes 10 elements
7577   if (rm)
7578     COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
7579   if (str)
7580     COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1);
7581   SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
7582   if (res > 0 && buf)
7583     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
7584   return res;
7585 }
7586 INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
7587             const struct __sanitizer_regmatch *rm, const char *sstr) {
7588   void *ctx;
7589   COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
7590   if (sub)
7591     COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1);
7592   // Hardcode 10 elements as this is hardcoded size
7593   if (rm)
7594     COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
7595   if (sstr)
7596     COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1);
7597   SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
7598   if (res > 0 && buf) {
7599     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
7600     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1);
7601   }
7602   return res;
7603 }
7604
7605 #define INIT_REGEXSUB                                                          \
7606   COMMON_INTERCEPT_FUNCTION(regnsub);                                          \
7607   COMMON_INTERCEPT_FUNCTION(regasub);
7608 #else
7609 #define INIT_REGEXSUB
7610 #endif
7611
7612 #if SANITIZER_INTERCEPT_FTS
7613 INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
7614             int (*compar)(void **, void **)) {
7615   void *ctx;
7616   COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
7617   if (path_argv) {
7618     for (char *const *pa = path_argv; ; ++pa) {
7619       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
7620       if (!*pa)
7621         break;
7622       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
7623     }
7624   }
7625   // TODO(kamil): handle compar callback
7626   void *fts = REAL(fts_open)(path_argv, options, compar);
7627   if (fts)
7628     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
7629   return fts;
7630 }
7631
7632 INTERCEPTOR(void *, fts_read, void *ftsp) {
7633   void *ctx;
7634   COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
7635   if (ftsp)
7636     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
7637   void *ftsent = REAL(fts_read)(ftsp);
7638   if (ftsent)
7639     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
7640   return ftsent;
7641 }
7642
7643 INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
7644   void *ctx;
7645   COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
7646   if (ftsp)
7647     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
7648   void *ftsent = REAL(fts_children)(ftsp, options);
7649   if (ftsent)
7650     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
7651   return ftsent;
7652 }
7653
7654 INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
7655   void *ctx;
7656   COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
7657   if (ftsp)
7658     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
7659   if (f)
7660     COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
7661   return REAL(fts_set)(ftsp, f, options);
7662 }
7663
7664 INTERCEPTOR(int, fts_close, void *ftsp) {
7665   void *ctx;
7666   COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
7667   if (ftsp)
7668     COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
7669   return REAL(fts_close)(ftsp);
7670 }
7671 #define INIT_FTS                                                               \
7672   COMMON_INTERCEPT_FUNCTION(fts_open);                                         \
7673   COMMON_INTERCEPT_FUNCTION(fts_read);                                         \
7674   COMMON_INTERCEPT_FUNCTION(fts_children);                                     \
7675   COMMON_INTERCEPT_FUNCTION(fts_set);                                          \
7676   COMMON_INTERCEPT_FUNCTION(fts_close);
7677 #else
7678 #define INIT_FTS
7679 #endif
7680
7681 #if SANITIZER_INTERCEPT_SYSCTL
7682 INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
7683             SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
7684   void *ctx;
7685   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7686     return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
7687   COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
7688                            newlen);
7689   if (name)
7690     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
7691   if (oldlenp)
7692     COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
7693   if (newp && newlen)
7694     COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
7695   int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
7696   if (!res) {
7697     if (oldlenp) {
7698       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
7699       if (oldp)
7700         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
7701     }
7702   }
7703   return res;
7704 }
7705
7706 INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
7707             void *newp, SIZE_T newlen) {
7708   void *ctx;
7709   if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7710     return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
7711   COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
7712                            newlen);
7713   if (sname)
7714     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
7715   if (oldlenp)
7716     COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
7717   if (newp && newlen)
7718     COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
7719   int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
7720   if (!res) {
7721     if (oldlenp) {
7722       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
7723       if (oldp)
7724         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
7725     }
7726   }
7727   return res;
7728 }
7729
7730 INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
7731             SIZE_T *namelenp) {
7732   void *ctx;
7733   COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
7734   if (sname)
7735     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
7736   if (namelenp)
7737     COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
7738   int res = REAL(sysctlnametomib)(sname, name, namelenp);
7739   if (!res) {
7740     if (namelenp) {
7741       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
7742       if (name)
7743         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
7744     }
7745   }
7746   return res;
7747 }
7748
7749 #define INIT_SYSCTL                        \
7750   COMMON_INTERCEPT_FUNCTION(sysctl);       \
7751   COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
7752   COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
7753 #else
7754 #define INIT_SYSCTL
7755 #endif
7756
7757 #if SANITIZER_INTERCEPT_ASYSCTL
7758 INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
7759   void *ctx;
7760   COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
7761   if (name)
7762     COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
7763   void *res = REAL(asysctl)(name, namelen, len);
7764   if (res && len) {
7765     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7766     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
7767   }
7768   return res;
7769 }
7770
7771 INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
7772   void *ctx;
7773   COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
7774   if (sname)
7775     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
7776   void *res = REAL(asysctlbyname)(sname, len);
7777   if (res && len) {
7778     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7779     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
7780   }
7781   return res;
7782 }
7783 #define INIT_ASYSCTL                           \
7784   COMMON_INTERCEPT_FUNCTION(asysctl);          \
7785   COMMON_INTERCEPT_FUNCTION(asysctlbyname);
7786 #else
7787 #define INIT_ASYSCTL
7788 #endif
7789
7790 #if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
7791 INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
7792             unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
7793             int v) {
7794   void *ctx;
7795   COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
7796                            csz, rnode, v);
7797   if (sname)
7798     COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1);
7799   if (namelenp)
7800     COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
7801   if (csz)
7802     COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
7803   // Skip rnode, it's rarely used and not trivial to sanitize
7804   // It's also used mostly internally
7805   int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
7806   if (!res) {
7807     if (namelenp) {
7808       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
7809       if (name)
7810         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
7811     }
7812     if (csz) {
7813       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
7814       if (cname)
7815         COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
7816     }
7817   }
7818   return res;
7819 }
7820 #define INIT_SYSCTLGETMIBINFO                  \
7821   COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
7822 #else
7823 #define INIT_SYSCTLGETMIBINFO
7824 #endif
7825
7826 #if SANITIZER_INTERCEPT_NL_LANGINFO
7827 INTERCEPTOR(char *, nl_langinfo, long item) {
7828   void *ctx;
7829   COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
7830   char *ret = REAL(nl_langinfo)(item);
7831   if (ret)
7832     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
7833   return ret;
7834 }
7835 #define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
7836 #else
7837 #define INIT_NL_LANGINFO
7838 #endif
7839
7840 #if SANITIZER_INTERCEPT_MODCTL
7841 INTERCEPTOR(int, modctl, int operation, void *argp) {
7842   void *ctx;
7843   int ret;
7844   COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
7845
7846   if (operation == modctl_load) {
7847     if (argp) {
7848       __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
7849       COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
7850       if (ml->ml_filename)
7851         COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
7852                                       REAL(strlen)(ml->ml_filename) + 1);
7853       if (ml->ml_props)
7854         COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
7855     }
7856     ret = REAL(modctl)(operation, argp);
7857   } else if (operation == modctl_unload) {
7858     if (argp) {
7859       const char *name = (const char *)argp;
7860       COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1);
7861     }
7862     ret = REAL(modctl)(operation, argp);
7863   } else if (operation == modctl_stat) {
7864     uptr iov_len;
7865     struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
7866     if (iov) {
7867       COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
7868       iov_len = iov->iov_len;
7869     }
7870     ret = REAL(modctl)(operation, argp);
7871     if (iov)
7872       COMMON_INTERCEPTOR_WRITE_RANGE(
7873           ctx, iov->iov_base, Min(iov_len,  iov->iov_len));
7874   } else if (operation == modctl_exists) {
7875     ret = REAL(modctl)(operation, argp);
7876   } else {
7877     ret = REAL(modctl)(operation, argp);
7878   }
7879
7880   return ret;
7881 }
7882 #define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
7883 #else
7884 #define INIT_MODCTL
7885 #endif
7886
7887 #if SANITIZER_INTERCEPT_STRTONUM
7888 INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
7889             long long maxval, const char **errstr) {
7890   void *ctx;
7891   COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
7892
7893   // TODO(kamil): Implement strtoll as a common inteceptor
7894   char *real_endptr;
7895   long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
7896   StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
7897
7898   ret = REAL(strtonum)(nptr, minval, maxval, errstr);
7899   if (errstr) {
7900     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
7901      if (*errstr)
7902       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1);
7903   }
7904   return ret;
7905 }
7906 #define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
7907 #else
7908 #define INIT_STRTONUM
7909 #endif
7910
7911 #if SANITIZER_INTERCEPT_FPARSELN
7912 INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
7913             SIZE_T *lineno, const char delim[3], int flags) {
7914   void *ctx;
7915   COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
7916   if (lineno)
7917     COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
7918   if (delim)
7919     COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
7920   char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
7921   if (ret) {
7922     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1);
7923     if (len)
7924       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7925     if (lineno)
7926       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
7927   }
7928   return ret;
7929 }
7930 #define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
7931 #else
7932 #define INIT_FPARSELN
7933 #endif
7934
7935 #if SANITIZER_INTERCEPT_STATVFS1
7936 INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
7937   void *ctx;
7938   COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
7939   if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
7940   int res = REAL(statvfs1)(path, buf, flags);
7941   if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
7942   return res;
7943 }
7944 INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
7945   void *ctx;
7946   COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
7947   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7948   int res = REAL(fstatvfs1)(fd, buf, flags);
7949   if (!res) {
7950     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
7951     if (fd >= 0)
7952       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
7953   }
7954   return res;
7955 }
7956 #define INIT_STATVFS1                  \
7957   COMMON_INTERCEPT_FUNCTION(statvfs1);  \
7958   COMMON_INTERCEPT_FUNCTION(fstatvfs1);
7959 #else
7960 #define INIT_STATVFS1
7961 #endif
7962
7963 #if SANITIZER_INTERCEPT_STRTOI
7964 INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
7965             INTMAX_T low, INTMAX_T high, int *rstatus) {
7966   void *ctx;
7967   COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
7968   char *real_endptr;
7969   INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
7970   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
7971   if (rstatus)
7972     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
7973   return ret;
7974 }
7975
7976 INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
7977             UINTMAX_T low, UINTMAX_T high, int *rstatus) {
7978   void *ctx;
7979   COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
7980   char *real_endptr;
7981   UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
7982   StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
7983   if (rstatus)
7984     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
7985   return ret;
7986 }
7987 #define INIT_STRTOI                                                            \
7988   COMMON_INTERCEPT_FUNCTION(strtoi);                                           \
7989   COMMON_INTERCEPT_FUNCTION(strtou)
7990 #else
7991 #define INIT_STRTOI
7992 #endif
7993
7994 #if SANITIZER_INTERCEPT_CAPSICUM
7995 #define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...)          \
7996   {                                                                        \
7997     void *ctx;                                                             \
7998     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
7999     if (rights)                                                            \
8000       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));         \
8001     __sanitizer_cap_rights_t *ret =                                        \
8002         REAL(cap_rights_init)(rights, ##__VA_ARGS__);                      \
8003     if (ret)                                                               \
8004       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));              \
8005     return ret;                                                            \
8006   }
8007
8008 #define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...)           \
8009   {                                                                       \
8010     void *ctx;                                                            \
8011     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
8012     if (rights)                                                           \
8013       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));        \
8014     __sanitizer_cap_rights_t *ret =                                       \
8015         REAL(cap_rights_set)(rights, ##__VA_ARGS__);                      \
8016     if (ret)                                                              \
8017       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));             \
8018     return ret;                                                           \
8019   }
8020
8021 #define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...)         \
8022   {                                                                         \
8023     void *ctx;                                                              \
8024     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
8025     if (rights)                                                             \
8026       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));          \
8027     __sanitizer_cap_rights_t *ret =                                         \
8028         REAL(cap_rights_clear)(rights, ##__VA_ARGS__);                      \
8029     if (ret)                                                                \
8030       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));               \
8031     return ret;                                                             \
8032   }
8033
8034 #define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...)        \
8035   {                                                                          \
8036     void *ctx;                                                               \
8037     COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
8038     if (rights)                                                              \
8039       COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));           \
8040     return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__);                   \
8041   }
8042
8043 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
8044             __sanitizer_cap_rights_t *rights) {
8045   CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
8046 }
8047
8048 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
8049             __sanitizer_cap_rights_t *rights) {
8050   CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
8051 }
8052
8053 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
8054             __sanitizer_cap_rights_t *rights) {
8055   CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
8056 }
8057
8058 INTERCEPTOR(bool, cap_rights_is_set,
8059             __sanitizer_cap_rights_t *rights) {
8060   CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
8061 }
8062
8063 INTERCEPTOR(int, cap_rights_limit, int fd,
8064             const __sanitizer_cap_rights_t *rights) {
8065   void *ctx;
8066   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
8067   if (rights)
8068     COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8069
8070   return REAL(cap_rights_limit)(fd, rights);
8071 }
8072
8073 INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
8074   void *ctx;
8075   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
8076   int ret = REAL(cap_rights_get)(fd, rights);
8077   if (!ret && rights)
8078     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
8079
8080   return ret;
8081 }
8082
8083 INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
8084   void *ctx;
8085   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
8086   if (rights)
8087     COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8088
8089   return REAL(cap_rights_is_valid(rights));
8090 }
8091
8092 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
8093   __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8094   void *ctx;
8095   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
8096   if (src)
8097     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8098
8099   __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
8100   if (dst)
8101     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8102
8103   return ret;
8104 }
8105
8106 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
8107   __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8108   void *ctx;
8109   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
8110   if (src)
8111     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8112
8113   __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
8114   if (dst)
8115     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8116
8117   return ret;
8118 }
8119
8120 INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
8121   const __sanitizer_cap_rights *little) {
8122   void *ctx;
8123   COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
8124   if (little)
8125     COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
8126   if (big)
8127     COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
8128
8129   return REAL(cap_rights_contains)(big, little);
8130 }
8131
8132 INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
8133   void *ctx;
8134   COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
8135   if (cmds)
8136     COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
8137
8138   return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
8139 }
8140
8141 INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
8142   void *ctx;
8143   COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
8144   int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
8145   if (!ret && cmds)
8146     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
8147
8148   return ret;
8149 }
8150 #define INIT_CAPSICUM                          \
8151   COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
8152   COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
8153   COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
8154   COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
8155   COMMON_INTERCEPT_FUNCTION(cap_rights_get);   \
8156   COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
8157   COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
8158   COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
8159   COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
8160   COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
8161   COMMON_INTERCEPT_FUNCTION(cap_ioctls_get);   \
8162   COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
8163 #else
8164 #define INIT_CAPSICUM
8165 #endif
8166
8167 #if SANITIZER_INTERCEPT_SHA1
8168 INTERCEPTOR(void, SHA1Init, void *context) {
8169   void *ctx;
8170   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
8171   REAL(SHA1Init)(context);
8172   if (context)
8173     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8174 }
8175 INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
8176   void *ctx;
8177   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
8178   if (data && len > 0)
8179     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8180   if (context)
8181     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8182   REAL(SHA1Update)(context, data, len);
8183   if (context)
8184     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8185 }
8186 INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
8187   void *ctx;
8188   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
8189   if (context)
8190     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8191   REAL(SHA1Final)(digest, context);
8192   if (digest)
8193     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8194 }
8195 INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
8196   void *ctx;
8197   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
8198   if (state)
8199     COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8200   if (buffer)
8201     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
8202   REAL(SHA1Transform)(state, buffer);
8203   if (state)
8204     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8205 }
8206 INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
8207   void *ctx;
8208   COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
8209   if (context)
8210     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8211   char *ret = REAL(SHA1End)(context, buf);
8212   if (ret)
8213     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8214   return ret;
8215 }
8216 INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
8217   void *ctx;
8218   COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
8219   if (filename)
8220     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8221   char *ret = REAL(SHA1File)(filename, buf);
8222   if (ret)
8223     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8224   return ret;
8225 }
8226 INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
8227   OFF_T length) {
8228   void *ctx;
8229   COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
8230   if (filename)
8231     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8232   char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
8233   if (ret)
8234     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8235   return ret;
8236 }
8237 INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
8238   void *ctx;
8239   COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
8240   if (data)
8241     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8242   char *ret = REAL(SHA1Data)(data, len, buf);
8243   if (ret)
8244     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8245   return ret;
8246 }
8247 #define INIT_SHA1                                                              \
8248   COMMON_INTERCEPT_FUNCTION(SHA1Init);                                         \
8249   COMMON_INTERCEPT_FUNCTION(SHA1Update);                                       \
8250   COMMON_INTERCEPT_FUNCTION(SHA1Final);                                        \
8251   COMMON_INTERCEPT_FUNCTION(SHA1Transform);                                    \
8252   COMMON_INTERCEPT_FUNCTION(SHA1End);                                          \
8253   COMMON_INTERCEPT_FUNCTION(SHA1File);                                         \
8254   COMMON_INTERCEPT_FUNCTION(SHA1FileChunk);                                    \
8255   COMMON_INTERCEPT_FUNCTION(SHA1Data)
8256 #else
8257 #define INIT_SHA1
8258 #endif
8259
8260 #if SANITIZER_INTERCEPT_MD4
8261 INTERCEPTOR(void, MD4Init, void *context) {
8262   void *ctx;
8263   COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
8264   REAL(MD4Init)(context);
8265   if (context)
8266     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8267 }
8268
8269 INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
8270             unsigned int len) {
8271   void *ctx;
8272   COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
8273   if (data && len > 0)
8274     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8275   if (context)
8276     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8277   REAL(MD4Update)(context, data, len);
8278   if (context)
8279     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8280 }
8281
8282 INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
8283   void *ctx;
8284   COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
8285   if (context)
8286     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8287   REAL(MD4Final)(digest, context);
8288   if (digest)
8289     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8290 }
8291
8292 INTERCEPTOR(char *, MD4End, void *context, char *buf) {
8293   void *ctx;
8294   COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
8295   if (context)
8296     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8297   char *ret = REAL(MD4End)(context, buf);
8298   if (ret)
8299     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8300   return ret;
8301 }
8302
8303 INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
8304   void *ctx;
8305   COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
8306   if (filename)
8307     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8308   char *ret = REAL(MD4File)(filename, buf);
8309   if (ret)
8310     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8311   return ret;
8312 }
8313
8314 INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
8315             char *buf) {
8316   void *ctx;
8317   COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
8318   if (data && len > 0)
8319     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8320   char *ret = REAL(MD4Data)(data, len, buf);
8321   if (ret)
8322     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8323   return ret;
8324 }
8325
8326 #define INIT_MD4                                                               \
8327   COMMON_INTERCEPT_FUNCTION(MD4Init);                                          \
8328   COMMON_INTERCEPT_FUNCTION(MD4Update);                                        \
8329   COMMON_INTERCEPT_FUNCTION(MD4Final);                                         \
8330   COMMON_INTERCEPT_FUNCTION(MD4End);                                           \
8331   COMMON_INTERCEPT_FUNCTION(MD4File);                                          \
8332   COMMON_INTERCEPT_FUNCTION(MD4Data)
8333 #else
8334 #define INIT_MD4
8335 #endif
8336
8337 #if SANITIZER_INTERCEPT_RMD160
8338 INTERCEPTOR(void, RMD160Init, void *context) {
8339   void *ctx;
8340   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
8341   REAL(RMD160Init)(context);
8342   if (context)
8343     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8344 }
8345 INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
8346   void *ctx;
8347   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
8348   if (data && len > 0)
8349     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8350   if (context)
8351     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8352   REAL(RMD160Update)(context, data, len);
8353   if (context)
8354     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8355 }
8356 INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
8357   void *ctx;
8358   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
8359   if (context)
8360     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8361   REAL(RMD160Final)(digest, context);
8362   if (digest)
8363     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8364 }
8365 INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
8366   void *ctx;
8367   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
8368   if (state)
8369     COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8370   if (buffer)
8371     COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
8372   REAL(RMD160Transform)(state, buffer);
8373   if (state)
8374     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8375 }
8376 INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
8377   void *ctx;
8378   COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
8379   if (context)
8380     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8381   char *ret = REAL(RMD160End)(context, buf);
8382   if (ret)
8383     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8384   return ret;
8385 }
8386 INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
8387   void *ctx;
8388   COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
8389   if (filename)
8390     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8391   char *ret = REAL(RMD160File)(filename, buf);
8392   if (ret)
8393     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8394   return ret;
8395 }
8396 INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
8397   OFF_T length) {
8398   void *ctx;
8399   COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
8400   if (filename)
8401     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8402   char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
8403   if (ret)
8404     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8405   return ret;
8406 }
8407 INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
8408   void *ctx;
8409   COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
8410   if (data && len > 0)
8411     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8412   char *ret = REAL(RMD160Data)(data, len, buf);
8413   if (ret)
8414     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8415   return ret;
8416 }
8417 #define INIT_RMD160                                                            \
8418   COMMON_INTERCEPT_FUNCTION(RMD160Init);                                       \
8419   COMMON_INTERCEPT_FUNCTION(RMD160Update);                                     \
8420   COMMON_INTERCEPT_FUNCTION(RMD160Final);                                      \
8421   COMMON_INTERCEPT_FUNCTION(RMD160Transform);                                  \
8422   COMMON_INTERCEPT_FUNCTION(RMD160End);                                        \
8423   COMMON_INTERCEPT_FUNCTION(RMD160File);                                       \
8424   COMMON_INTERCEPT_FUNCTION(RMD160FileChunk);                                  \
8425   COMMON_INTERCEPT_FUNCTION(RMD160Data)
8426 #else
8427 #define INIT_RMD160
8428 #endif
8429
8430 #if SANITIZER_INTERCEPT_MD5
8431 INTERCEPTOR(void, MD5Init, void *context) {
8432   void *ctx;
8433   COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context);
8434   REAL(MD5Init)(context);
8435   if (context)
8436     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
8437 }
8438
8439 INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data,
8440             unsigned int len) {
8441   void *ctx;
8442   COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len);
8443   if (data && len > 0)
8444     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8445   if (context)
8446     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8447   REAL(MD5Update)(context, data, len);
8448   if (context)
8449     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
8450 }
8451
8452 INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) {
8453   void *ctx;
8454   COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context);
8455   if (context)
8456     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8457   REAL(MD5Final)(digest, context);
8458   if (digest)
8459     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8460 }
8461
8462 INTERCEPTOR(char *, MD5End, void *context, char *buf) {
8463   void *ctx;
8464   COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf);
8465   if (context)
8466     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8467   char *ret = REAL(MD5End)(context, buf);
8468   if (ret)
8469     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8470   return ret;
8471 }
8472
8473 INTERCEPTOR(char *, MD5File, const char *filename, char *buf) {
8474   void *ctx;
8475   COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf);
8476   if (filename)
8477     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8478   char *ret = REAL(MD5File)(filename, buf);
8479   if (ret)
8480     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8481   return ret;
8482 }
8483
8484 INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len,
8485             char *buf) {
8486   void *ctx;
8487   COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf);
8488   if (data && len > 0)
8489     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8490   char *ret = REAL(MD5Data)(data, len, buf);
8491   if (ret)
8492     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8493   return ret;
8494 }
8495
8496 #define INIT_MD5                                                               \
8497   COMMON_INTERCEPT_FUNCTION(MD5Init);                                          \
8498   COMMON_INTERCEPT_FUNCTION(MD5Update);                                        \
8499   COMMON_INTERCEPT_FUNCTION(MD5Final);                                         \
8500   COMMON_INTERCEPT_FUNCTION(MD5End);                                           \
8501   COMMON_INTERCEPT_FUNCTION(MD5File);                                          \
8502   COMMON_INTERCEPT_FUNCTION(MD5Data)
8503 #else
8504 #define INIT_MD5
8505 #endif
8506
8507 #if SANITIZER_INTERCEPT_FSEEK
8508 INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
8509   void *ctx;
8510   COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
8511   return REAL(fseek)(stream, offset, whence);
8512 }
8513 INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
8514   void *ctx;
8515   COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
8516   return REAL(fseeko)(stream, offset, whence);
8517 }
8518 INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
8519   void *ctx;
8520   COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
8521   return REAL(ftell)(stream);
8522 }
8523 INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
8524   void *ctx;
8525   COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
8526   return REAL(ftello)(stream);
8527 }
8528 INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
8529   void *ctx;
8530   COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
8531   return REAL(rewind)(stream);
8532 }
8533 INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
8534   void *ctx;
8535   COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
8536   int ret = REAL(fgetpos)(stream, pos);
8537   if (pos && !ret)
8538     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
8539   return ret;
8540 }
8541 INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
8542   void *ctx;
8543   COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
8544   if (pos)
8545     COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
8546   return REAL(fsetpos)(stream, pos);
8547 }
8548 #define INIT_FSEEK \
8549   COMMON_INTERCEPT_FUNCTION(fseek); \
8550   COMMON_INTERCEPT_FUNCTION(fseeko); \
8551   COMMON_INTERCEPT_FUNCTION(ftell); \
8552   COMMON_INTERCEPT_FUNCTION(ftello); \
8553   COMMON_INTERCEPT_FUNCTION(rewind); \
8554   COMMON_INTERCEPT_FUNCTION(fgetpos); \
8555   COMMON_INTERCEPT_FUNCTION(fsetpos)
8556 #else
8557 #define INIT_FSEEK
8558 #endif
8559
8560 #if SANITIZER_INTERCEPT_MD2
8561 INTERCEPTOR(void, MD2Init, void *context) {
8562   void *ctx;
8563   COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
8564   REAL(MD2Init)(context);
8565   if (context)
8566     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
8567 }
8568
8569 INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
8570             unsigned int len) {
8571   void *ctx;
8572   COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
8573   if (data && len > 0)
8574     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8575   if (context)
8576     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8577   REAL(MD2Update)(context, data, len);
8578   if (context)
8579     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
8580 }
8581
8582 INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
8583   void *ctx;
8584   COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
8585   if (context)
8586     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8587   REAL(MD2Final)(digest, context);
8588   if (digest)
8589     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8590 }
8591
8592 INTERCEPTOR(char *, MD2End, void *context, char *buf) {
8593   void *ctx;
8594   COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
8595   if (context)
8596     COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8597   char *ret = REAL(MD2End)(context, buf);
8598   if (ret)
8599     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
8600   return ret;
8601 }
8602
8603 INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
8604   void *ctx;
8605   COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
8606   if (filename)
8607     COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);
8608   char *ret = REAL(MD2File)(filename, buf);
8609   if (ret)
8610     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
8611   return ret;
8612 }
8613
8614 INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
8615             char *buf) {
8616   void *ctx;
8617   COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
8618   if (data && len > 0)
8619     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8620   char *ret = REAL(MD2Data)(data, len, buf);
8621   if (ret)
8622     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
8623   return ret;
8624 }
8625
8626 #define INIT_MD2                                                               \
8627   COMMON_INTERCEPT_FUNCTION(MD2Init);                                          \
8628   COMMON_INTERCEPT_FUNCTION(MD2Update);                                        \
8629   COMMON_INTERCEPT_FUNCTION(MD2Final);                                         \
8630   COMMON_INTERCEPT_FUNCTION(MD2End);                                           \
8631   COMMON_INTERCEPT_FUNCTION(MD2File);                                          \
8632   COMMON_INTERCEPT_FUNCTION(MD2Data)
8633 #else
8634 #define INIT_MD2
8635 #endif
8636
8637 #if SANITIZER_INTERCEPT_SHA2
8638 #define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \
8639   INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \
8640     void *ctx; \
8641     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \
8642     REAL(SHA##LEN##_Init)(context); \
8643     if (context) \
8644       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
8645   } \
8646   INTERCEPTOR(void, SHA##LEN##_Update, void *context, \
8647               const u8 *data, SIZE_T len) { \
8648     void *ctx; \
8649     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \
8650     if (data && len > 0) \
8651       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
8652     if (context) \
8653       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
8654     REAL(SHA##LEN##_Update)(context, data, len); \
8655     if (context) \
8656       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
8657   } \
8658   INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
8659   void *context) { \
8660     void *ctx; \
8661     CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
8662     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
8663     if (context) \
8664       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
8665     REAL(SHA##LEN##_Final)(digest, context); \
8666     if (digest) \
8667       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \
8668                                      sizeof(digest[0]) * \
8669   SHA##LEN##_digest_length); \
8670   } \
8671   INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \
8672     void *ctx; \
8673     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \
8674     if (context) \
8675       COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
8676     char *ret = REAL(SHA##LEN##_End)(context, buf); \
8677     if (ret) \
8678       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
8679     return ret; \
8680   } \
8681   INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \
8682     void *ctx; \
8683     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \
8684     if (filename) \
8685       COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
8686     char *ret = REAL(SHA##LEN##_File)(filename, buf); \
8687     if (ret) \
8688       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
8689     return ret; \
8690   } \
8691   INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \
8692               OFF_T offset, OFF_T length) { \
8693     void *ctx; \
8694     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \
8695   length); \
8696     if (filename) \
8697       COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\
8698     char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \
8699     if (ret) \
8700       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
8701     return ret; \
8702   } \
8703   INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \
8704     void *ctx; \
8705     COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \
8706     if (data && len > 0) \
8707       COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
8708     char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \
8709     if (ret) \
8710       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
8711     return ret; \
8712   }
8713
8714 SHA2_INTERCEPTORS(224, u32);
8715 SHA2_INTERCEPTORS(256, u32);
8716 SHA2_INTERCEPTORS(384, u64);
8717 SHA2_INTERCEPTORS(512, u64);
8718
8719 #define INIT_SHA2_INTECEPTORS(LEN) \
8720   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \
8721   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \
8722   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \
8723   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \
8724   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \
8725   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \
8726   COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data)
8727
8728 #define INIT_SHA2 \
8729   INIT_SHA2_INTECEPTORS(224); \
8730   INIT_SHA2_INTECEPTORS(256); \
8731   INIT_SHA2_INTECEPTORS(384); \
8732   INIT_SHA2_INTECEPTORS(512)
8733 #undef SHA2_INTERCEPTORS
8734 #else
8735 #define INIT_SHA2
8736 #endif
8737
8738 #if SANITIZER_INTERCEPT_VIS
8739 INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
8740   void *ctx;
8741   COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
8742   char *end = REAL(vis)(dst, c, flag, nextc);
8743   // dst is NULL terminated and end points to the NULL char
8744   if (dst && end)
8745     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
8746   return end;
8747 }
8748 INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
8749   void *ctx;
8750   COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
8751   char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
8752   // nvis cannot make sure the dst is NULL terminated
8753   if (dst && end)
8754     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
8755   return end;
8756 }
8757 INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
8758   void *ctx;
8759   COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
8760   if (src)
8761     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8762   int len = REAL(strvis)(dst, src, flag);
8763   if (dst)
8764     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
8765   return len;
8766 }
8767 INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
8768   void *ctx;
8769   COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
8770   if (src)
8771     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8772   int len = REAL(stravis)(dst, src, flag);
8773   if (dst) {
8774     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
8775     if (*dst)
8776       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
8777   }
8778   return len;
8779 }
8780 INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
8781   void *ctx;
8782   COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
8783   if (src)
8784     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8785   int len = REAL(strnvis)(dst, dlen, src, flag);
8786   // The interface will be valid even if there is no space for NULL char
8787   if (dst && len > 0)
8788     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
8789   return len;
8790 }
8791 INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
8792   void *ctx;
8793   COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
8794   if (src)
8795     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8796   int ret = REAL(strvisx)(dst, src, len, flag);
8797   if (dst)
8798     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8799   return ret;
8800 }
8801 INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
8802             int flag) {
8803   void *ctx;
8804   COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
8805   if (src)
8806     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8807   int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
8808   if (dst && ret >= 0)
8809     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8810   return ret;
8811 }
8812 INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
8813             int flag, int *cerr_ptr) {
8814   void *ctx;
8815   COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
8816   if (src)
8817     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8818   // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
8819   // according to the implementation
8820   if (cerr_ptr)
8821     COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
8822   int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
8823   if (dst && ret >= 0)
8824     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8825   if (cerr_ptr)
8826     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
8827   return ret;
8828 }
8829 INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
8830             const char *extra) {
8831   void *ctx;
8832   COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
8833   if (extra)
8834     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8835   char *end = REAL(svis)(dst, c, flag, nextc, extra);
8836   if (dst && end)
8837     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
8838   return end;
8839 }
8840 INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
8841             const char *extra) {
8842   void *ctx;
8843   COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
8844   if (extra)
8845     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8846   char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
8847   if (dst && end)
8848     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
8849                                    Min((SIZE_T)(end - dst + 1), dlen));
8850   return end;
8851 }
8852 INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
8853             const char *extra) {
8854   void *ctx;
8855   COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
8856   if (src)
8857     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8858   if (extra)
8859     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8860   int len = REAL(strsvis)(dst, src, flag, extra);
8861   if (dst)
8862     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
8863   return len;
8864 }
8865 INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
8866             const char *extra) {
8867   void *ctx;
8868   COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
8869   if (src)
8870     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8871   if (extra)
8872     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8873   int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
8874   // The interface will be valid even if there is no space for NULL char
8875   if (dst && len >= 0)
8876     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
8877   return len;
8878 }
8879 INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
8880             const char *extra) {
8881   void *ctx;
8882   COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
8883   if (src)
8884     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8885   if (extra)
8886     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8887   int ret = REAL(strsvisx)(dst, src, len, flag, extra);
8888   if (dst)
8889     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8890   return ret;
8891 }
8892 INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
8893             int flag, const char *extra) {
8894   void *ctx;
8895   COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
8896   if (src)
8897     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8898   if (extra)
8899     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8900   int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
8901   if (dst && ret >= 0)
8902     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8903   return ret;
8904 }
8905 INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
8906             SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
8907   void *ctx;
8908   COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
8909                            cerr_ptr);
8910   if (src)
8911     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
8912   if (extra)
8913     COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1);
8914   // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
8915   // according to the implementation
8916   if (cerr_ptr)
8917     COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
8918   int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
8919   if (dst && ret >= 0)
8920     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8921   if (cerr_ptr)
8922     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
8923   return ret;
8924 }
8925 INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
8926   void *ctx;
8927   COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
8928   if (astate)
8929     COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
8930   int ret = REAL(unvis)(cp, c, astate, flag);
8931   if (ret == unvis_valid || ret == unvis_validpush) {
8932     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
8933   }
8934   return ret;
8935 }
8936 INTERCEPTOR(int, strunvis, char *dst, const char *src) {
8937   void *ctx;
8938   COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
8939   if (src)
8940     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8941   int ret = REAL(strunvis)(dst, src);
8942   if (ret != -1)
8943     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8944   return ret;
8945 }
8946 INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
8947   void *ctx;
8948   COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
8949   if (src)
8950     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8951   int ret = REAL(strnunvis)(dst, dlen, src);
8952   if (ret != -1)
8953     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8954   return ret;
8955 }
8956 INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
8957   void *ctx;
8958   COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
8959   if (src)
8960     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8961   int ret = REAL(strunvisx)(dst, src, flag);
8962   if (ret != -1)
8963     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8964   return ret;
8965 }
8966 INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
8967             int flag) {
8968   void *ctx;
8969   COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
8970   if (src)
8971     COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1);
8972   int ret = REAL(strnunvisx)(dst, dlen, src, flag);
8973   if (ret != -1)
8974     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
8975   return ret;
8976 }
8977 #define INIT_VIS                                                               \
8978   COMMON_INTERCEPT_FUNCTION(vis);                                              \
8979   COMMON_INTERCEPT_FUNCTION(nvis);                                             \
8980   COMMON_INTERCEPT_FUNCTION(strvis);                                           \
8981   COMMON_INTERCEPT_FUNCTION(stravis);                                          \
8982   COMMON_INTERCEPT_FUNCTION(strnvis);                                          \
8983   COMMON_INTERCEPT_FUNCTION(strvisx);                                          \
8984   COMMON_INTERCEPT_FUNCTION(strnvisx);                                         \
8985   COMMON_INTERCEPT_FUNCTION(strenvisx);                                        \
8986   COMMON_INTERCEPT_FUNCTION(svis);                                             \
8987   COMMON_INTERCEPT_FUNCTION(snvis);                                            \
8988   COMMON_INTERCEPT_FUNCTION(strsvis);                                          \
8989   COMMON_INTERCEPT_FUNCTION(strsnvis);                                         \
8990   COMMON_INTERCEPT_FUNCTION(strsvisx);                                         \
8991   COMMON_INTERCEPT_FUNCTION(strsnvisx);                                        \
8992   COMMON_INTERCEPT_FUNCTION(strsenvisx);                                       \
8993   COMMON_INTERCEPT_FUNCTION(unvis);                                            \
8994   COMMON_INTERCEPT_FUNCTION(strunvis);                                         \
8995   COMMON_INTERCEPT_FUNCTION(strnunvis);                                        \
8996   COMMON_INTERCEPT_FUNCTION(strunvisx);                                        \
8997   COMMON_INTERCEPT_FUNCTION(strnunvisx)
8998 #else
8999 #define INIT_VIS
9000 #endif
9001
9002 #if SANITIZER_INTERCEPT_CDB
9003 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
9004   void *ctx;
9005   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
9006   if (path)
9007     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
9008   struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
9009   if (cdbr)
9010     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9011   return cdbr;
9012 }
9013
9014 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
9015   int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
9016   void *ctx;
9017   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
9018     cookie);
9019   if (base && size)
9020     COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
9021   struct __sanitizer_cdbr *cdbr =
9022     REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
9023   if (cdbr)
9024     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9025   return cdbr;
9026 }
9027
9028 INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
9029   void *ctx;
9030   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
9031   if (cdbr)
9032     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9033   return REAL(cdbr_entries)(cdbr);
9034 }
9035
9036 INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
9037             const void **data, SIZE_T *datalen) {
9038   void *ctx;
9039   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
9040   if (cdbr)
9041     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9042   int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
9043   if (!ret) {
9044     if (data)
9045       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9046     if (datalen)
9047       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9048     if (data && datalen)
9049       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9050   }
9051   return ret;
9052 }
9053
9054 INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
9055             SIZE_T keylen, const void **data, SIZE_T *datalen) {
9056   void *ctx;
9057   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
9058   if (cdbr)
9059     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9060   if (key)
9061     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9062   int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
9063   if (!ret) {
9064     if (data)
9065       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9066     if (datalen)
9067       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9068     if (data && datalen)
9069       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9070   }
9071   return ret;
9072 }
9073
9074 INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
9075   void *ctx;
9076   COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
9077   if (cdbr)
9078     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9079   REAL(cdbr_close)(cdbr);
9080 }
9081
9082 INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
9083   void *ctx;
9084   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
9085   struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
9086   if (ret)
9087     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
9088   return ret;
9089 }
9090
9091 INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
9092   SIZE_T keylen, const void *data, SIZE_T datalen) {
9093   void *ctx;
9094   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
9095   if (cdbw)
9096     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9097   if (data && datalen)
9098     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9099   if (key && keylen)
9100     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9101   int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
9102   if (!ret && cdbw)
9103     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9104   return ret;
9105 }
9106
9107 INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
9108   SIZE_T datalen, u32 *index) {
9109   void *ctx;
9110   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
9111   if (cdbw)
9112     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9113   if (data && datalen)
9114     COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9115   int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
9116   if (!ret) {
9117     if (index)
9118       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
9119     if (cdbw)
9120       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9121   }
9122   return ret;
9123 }
9124
9125 INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
9126   SIZE_T keylen, u32 index) {
9127   void *ctx;
9128   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
9129   if (cdbw)
9130     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9131   if (key && keylen)
9132     COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9133   int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
9134   if (!ret && cdbw)
9135     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9136   return ret;
9137 }
9138
9139 INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
9140   const char descr[16], u32 (*seedgen)(void)) {
9141   void *ctx;
9142   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
9143   COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
9144   if (cdbw)
9145     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9146   if (descr)
9147     COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
9148   if (seedgen)
9149     COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
9150   int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
9151   if (!ret) {
9152     if (cdbw)
9153       COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9154     if (output >= 0)
9155       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
9156   }
9157   return ret;
9158 }
9159
9160 INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
9161   void *ctx;
9162   COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
9163   if (cdbw)
9164     COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9165   REAL(cdbw_close)(cdbw);
9166 }
9167
9168 #define INIT_CDB \
9169   COMMON_INTERCEPT_FUNCTION(cdbr_open); \
9170   COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
9171   COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
9172   COMMON_INTERCEPT_FUNCTION(cdbr_get); \
9173   COMMON_INTERCEPT_FUNCTION(cdbr_find); \
9174   COMMON_INTERCEPT_FUNCTION(cdbr_close); \
9175   COMMON_INTERCEPT_FUNCTION(cdbw_open); \
9176   COMMON_INTERCEPT_FUNCTION(cdbw_put); \
9177   COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
9178   COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
9179   COMMON_INTERCEPT_FUNCTION(cdbw_output); \
9180   COMMON_INTERCEPT_FUNCTION(cdbw_close)
9181 #else
9182 #define INIT_CDB
9183 #endif
9184
9185 #if SANITIZER_INTERCEPT_GETFSENT
9186 INTERCEPTOR(void *, getfsent) {
9187   void *ctx;
9188   COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
9189   void *ret = REAL(getfsent)();
9190   if (ret)
9191     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9192   return ret;
9193 }
9194
9195 INTERCEPTOR(void *, getfsspec, const char *spec) {
9196   void *ctx;
9197   COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
9198   if (spec)
9199     COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1);
9200   void *ret = REAL(getfsspec)(spec);
9201   if (ret)
9202     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9203   return ret;
9204 }
9205
9206 INTERCEPTOR(void *, getfsfile, const char *file) {
9207   void *ctx;
9208   COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
9209   if (file)
9210     COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
9211   void *ret = REAL(getfsfile)(file);
9212   if (ret)
9213     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9214   return ret;
9215 }
9216
9217 #define INIT_GETFSENT \
9218   COMMON_INTERCEPT_FUNCTION(getfsent); \
9219   COMMON_INTERCEPT_FUNCTION(getfsspec); \
9220   COMMON_INTERCEPT_FUNCTION(getfsfile);
9221 #else
9222 #define INIT_GETFSENT
9223 #endif
9224
9225 #if SANITIZER_INTERCEPT_ARC4RANDOM
9226 INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
9227   void *ctx;
9228   COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
9229   REAL(arc4random_buf)(buf, len);
9230   if (buf && len)
9231     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
9232 }
9233
9234 INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
9235   void *ctx;
9236   COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
9237   if (dat && datlen)
9238     COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
9239   REAL(arc4random_addrandom)(dat, datlen);
9240 }
9241
9242 #define INIT_ARC4RANDOM \
9243   COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
9244   COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
9245 #else
9246 #define INIT_ARC4RANDOM
9247 #endif
9248
9249 #if SANITIZER_INTERCEPT_POPEN
9250 INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
9251   void *ctx;
9252   COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
9253   if (command)
9254     COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1);
9255   if (type)
9256     COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
9257   __sanitizer_FILE *res = REAL(popen)(command, type);
9258   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9259   if (res) unpoison_file(res);
9260   return res;
9261 }
9262 #define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
9263 #else
9264 #define INIT_POPEN
9265 #endif
9266
9267 #if SANITIZER_INTERCEPT_POPENVE
9268 INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
9269             char *const *argv, char *const *envp, const char *type) {
9270   void *ctx;
9271   COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
9272   if (path)
9273     COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
9274   if (argv) {
9275     for (char *const *pa = argv; ; ++pa) {
9276       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9277       if (!*pa)
9278         break;
9279       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
9280     }
9281   }
9282   if (envp) {
9283     for (char *const *pa = envp; ; ++pa) {
9284       COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9285       if (!*pa)
9286         break;
9287       COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
9288     }
9289   }
9290   if (type)
9291     COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
9292   __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
9293   COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9294   if (res) unpoison_file(res);
9295   return res;
9296 }
9297 #define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
9298 #else
9299 #define INIT_POPENVE
9300 #endif
9301
9302 #if SANITIZER_INTERCEPT_PCLOSE
9303 INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
9304   void *ctx;
9305   COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
9306   COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
9307   const FileMetadata *m = GetInterceptorMetadata(fp);
9308   int res = REAL(pclose)(fp);
9309   if (m) {
9310     COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
9311     DeleteInterceptorMetadata(fp);
9312   }
9313   return res;
9314 }
9315 #define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
9316 #else
9317 #define INIT_PCLOSE
9318 #endif
9319
9320 #if SANITIZER_INTERCEPT_FUNOPEN
9321 typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
9322 typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
9323 typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
9324 typedef int (*funopen_closefn)(void *cookie);
9325
9326 struct WrappedFunopenCookie {
9327   void *real_cookie;
9328   funopen_readfn real_read;
9329   funopen_writefn real_write;
9330   funopen_seekfn real_seek;
9331   funopen_closefn real_close;
9332 };
9333
9334 static int wrapped_funopen_read(void *cookie, char *buf, int len) {
9335   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9336   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9337   funopen_readfn real_read = wrapped_cookie->real_read;
9338   return real_read(wrapped_cookie->real_cookie, buf, len);
9339 }
9340
9341 static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
9342   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9343   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9344   funopen_writefn real_write = wrapped_cookie->real_write;
9345   return real_write(wrapped_cookie->real_cookie, buf, len);
9346 }
9347
9348 static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
9349   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9350   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9351   funopen_seekfn real_seek = wrapped_cookie->real_seek;
9352   return real_seek(wrapped_cookie->real_cookie, offset, whence);
9353 }
9354
9355 static int wrapped_funopen_close(void *cookie) {
9356   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9357   WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9358   funopen_closefn real_close = wrapped_cookie->real_close;
9359   int res = real_close(wrapped_cookie->real_cookie);
9360   InternalFree(wrapped_cookie);
9361   return res;
9362 }
9363
9364 INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
9365             funopen_writefn writefn, funopen_seekfn seekfn,
9366             funopen_closefn closefn) {
9367   void *ctx;
9368   COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
9369                            closefn);
9370
9371   WrappedFunopenCookie *wrapped_cookie =
9372       (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
9373   wrapped_cookie->real_cookie = cookie;
9374   wrapped_cookie->real_read = readfn;
9375   wrapped_cookie->real_write = writefn;
9376   wrapped_cookie->real_seek = seekfn;
9377   wrapped_cookie->real_close = closefn;
9378
9379   __sanitizer_FILE *res =
9380       REAL(funopen)(wrapped_cookie,
9381                     readfn  ? wrapped_funopen_read  : nullptr,
9382                     writefn ? wrapped_funopen_write : nullptr,
9383                     seekfn  ? wrapped_funopen_seek  : nullptr,
9384                     closefn ? wrapped_funopen_close : nullptr);
9385   if (res)
9386     unpoison_file(res);
9387   return res;
9388 }
9389 #define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
9390 #else
9391 #define INIT_FUNOPEN
9392 #endif
9393
9394 #if SANITIZER_INTERCEPT_FUNOPEN2
9395 typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
9396 typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
9397 typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
9398 typedef int (*funopen2_flushfn)(void *cookie);
9399 typedef int (*funopen2_closefn)(void *cookie);
9400
9401 struct WrappedFunopen2Cookie {
9402   void *real_cookie;
9403   funopen2_readfn real_read;
9404   funopen2_writefn real_write;
9405   funopen2_seekfn real_seek;
9406   funopen2_flushfn real_flush;
9407   funopen2_closefn real_close;
9408 };
9409
9410 static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
9411   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9412   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9413   funopen2_readfn real_read = wrapped_cookie->real_read;
9414   return real_read(wrapped_cookie->real_cookie, buf, len);
9415 }
9416
9417 static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
9418                                       SIZE_T len) {
9419   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9420   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9421   funopen2_writefn real_write = wrapped_cookie->real_write;
9422   return real_write(wrapped_cookie->real_cookie, buf, len);
9423 }
9424
9425 static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
9426   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9427   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9428   funopen2_seekfn real_seek = wrapped_cookie->real_seek;
9429   return real_seek(wrapped_cookie->real_cookie, offset, whence);
9430 }
9431
9432 static int wrapped_funopen2_flush(void *cookie) {
9433   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9434   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9435   funopen2_flushfn real_flush = wrapped_cookie->real_flush;
9436   return real_flush(wrapped_cookie->real_cookie);
9437 }
9438
9439 static int wrapped_funopen2_close(void *cookie) {
9440   COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9441   WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9442   funopen2_closefn real_close = wrapped_cookie->real_close;
9443   int res = real_close(wrapped_cookie->real_cookie);
9444   InternalFree(wrapped_cookie);
9445   return res;
9446 }
9447
9448 INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
9449             funopen2_writefn writefn, funopen2_seekfn seekfn,
9450             funopen2_flushfn flushfn, funopen2_closefn closefn) {
9451   void *ctx;
9452   COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
9453                            flushfn, closefn);
9454
9455   WrappedFunopen2Cookie *wrapped_cookie =
9456       (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
9457   wrapped_cookie->real_cookie = cookie;
9458   wrapped_cookie->real_read = readfn;
9459   wrapped_cookie->real_write = writefn;
9460   wrapped_cookie->real_seek = seekfn;
9461   wrapped_cookie->real_flush = flushfn;
9462   wrapped_cookie->real_close = closefn;
9463
9464   __sanitizer_FILE *res =
9465       REAL(funopen2)(wrapped_cookie,
9466                      readfn  ? wrapped_funopen2_read  : nullptr,
9467                      writefn ? wrapped_funopen2_write : nullptr,
9468                      seekfn  ? wrapped_funopen2_seek  : nullptr,
9469                      flushfn ? wrapped_funopen2_flush : nullptr,
9470                      closefn ? wrapped_funopen2_close : nullptr);
9471   if (res)
9472     unpoison_file(res);
9473   return res;
9474 }
9475 #define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
9476 #else
9477 #define INIT_FUNOPEN2
9478 #endif
9479
9480 #if SANITIZER_INTERCEPT_FDEVNAME
9481 INTERCEPTOR(char *, fdevname,  int fd) {
9482   void *ctx;
9483   COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
9484   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
9485   char *name = REAL(fdevname)(fd);
9486   if (name) {
9487     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
9488     if (fd > 0)
9489       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
9490   }
9491   return name;
9492 }
9493
9494 INTERCEPTOR(char *, fdevname_r,  int fd, char *buf, SIZE_T len) {
9495   void *ctx;
9496   COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
9497   COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
9498   char *name = REAL(fdevname_r)(fd, buf, len);
9499   if (name && buf && len > 0) {
9500     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
9501     if (fd > 0)
9502       COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
9503   }
9504   return name;
9505 }
9506
9507 #define INIT_FDEVNAME \
9508   COMMON_INTERCEPT_FUNCTION(fdevname); \
9509   COMMON_INTERCEPT_FUNCTION(fdevname_r);
9510 #else
9511 #define INIT_FDEVNAME
9512 #endif
9513
9514 #if SANITIZER_INTERCEPT_GETUSERSHELL
9515 INTERCEPTOR(char *, getusershell) {
9516   void *ctx;
9517   COMMON_INTERCEPTOR_ENTER(ctx, getusershell);
9518   char *res = REAL(getusershell)();
9519   if (res)
9520     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
9521   return res;
9522 }
9523
9524 #define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
9525 #else
9526 #define INIT_GETUSERSHELL
9527 #endif
9528
9529 #if SANITIZER_INTERCEPT_SL_INIT
9530 INTERCEPTOR(void *, sl_init) {
9531   void *ctx;
9532   COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
9533   void *res = REAL(sl_init)();
9534   if (res)
9535     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
9536   return res;
9537 }
9538
9539 INTERCEPTOR(int, sl_add, void *sl, char *item) {
9540   void *ctx;
9541   COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
9542   if (sl)
9543     COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9544   if (item)
9545     COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
9546   int res = REAL(sl_add)(sl, item);
9547   if (!res)
9548     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9549   return res;
9550 }
9551
9552 INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
9553   void *ctx;
9554   COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
9555   if (sl)
9556     COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9557   if (item)
9558     COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
9559   char *res = REAL(sl_find)(sl, item);
9560   if (res)
9561     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
9562   return res;
9563 }
9564
9565 INTERCEPTOR(void, sl_free, void *sl, int freeall) {
9566   void *ctx;
9567   COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
9568   if (sl)
9569     COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9570   REAL(sl_free)(sl, freeall);
9571 }
9572
9573 #define INIT_SL_INIT                  \
9574   COMMON_INTERCEPT_FUNCTION(sl_init); \
9575   COMMON_INTERCEPT_FUNCTION(sl_add);  \
9576   COMMON_INTERCEPT_FUNCTION(sl_find); \
9577   COMMON_INTERCEPT_FUNCTION(sl_free);
9578 #else
9579 #define INIT_SL_INIT
9580 #endif
9581
9582 #if SANITIZER_INTERCEPT_GETRANDOM
9583 INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
9584   void *ctx;
9585   COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);
9586   SSIZE_T n = REAL(getrandom)(buf, buflen, flags);
9587   if (n > 0) {
9588     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);
9589   }
9590   return n;
9591 }
9592 #define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)
9593 #else
9594 #define INIT_GETRANDOM
9595 #endif
9596
9597 #if SANITIZER_INTERCEPT_CRYPT
9598 INTERCEPTOR(char *, crypt, char *key, char *salt) {
9599   void *ctx;
9600   COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt);
9601   COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
9602   COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
9603   char *res = REAL(crypt)(key, salt);
9604   if (res != nullptr)
9605     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
9606   return res;
9607 }
9608 #define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt);
9609 #else
9610 #define INIT_CRYPT
9611 #endif
9612
9613 #if SANITIZER_INTERCEPT_CRYPT_R
9614 INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) {
9615   void *ctx;
9616   COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data);
9617   COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
9618   COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
9619   char *res = REAL(crypt_r)(key, salt, data);
9620   if (res != nullptr) {
9621     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data,
9622                                    __sanitizer::struct_crypt_data_sz);
9623     COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
9624   }
9625   return res;
9626 }
9627 #define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r);
9628 #else
9629 #define INIT_CRYPT_R
9630 #endif
9631
9632 #if SANITIZER_INTERCEPT_GETENTROPY
9633 INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
9634   void *ctx;
9635   COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);
9636   int r = REAL(getentropy)(buf, buflen);
9637   if (r == 0) {
9638     COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
9639   }
9640   return r;
9641 }
9642 #define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)
9643 #else
9644 #define INIT_GETENTROPY
9645 #endif
9646
9647 #if SANITIZER_INTERCEPT_QSORT
9648 // Glibc qsort uses a temporary buffer allocated either on stack or on heap.
9649 // Poisoned memory from there may get copied into the comparator arguments,
9650 // where it needs to be dealt with. But even that is not enough - the results of
9651 // the sort may be copied into the input/output array based on the results of
9652 // the comparator calls, but directly from the temp memory, bypassing the
9653 // unpoisoning done in wrapped_qsort_compar. We deal with this by, again,
9654 // unpoisoning the entire array after the sort is done.
9655 //
9656 // We can not check that the entire array is initialized at the beginning. IMHO,
9657 // it's fine for parts of the sorted objects to contain uninitialized memory,
9658 // ex. as padding in structs.
9659 typedef int (*qsort_compar_f)(const void *, const void *);
9660 static THREADLOCAL qsort_compar_f qsort_compar;
9661 static THREADLOCAL SIZE_T qsort_size;
9662 int wrapped_qsort_compar(const void *a, const void *b) {
9663   COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
9664   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);
9665   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);
9666   return qsort_compar(a, b);
9667 }
9668
9669 INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
9670             qsort_compar_f compar) {
9671   void *ctx;
9672   COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
9673   // Run the comparator over all array elements to detect any memory issues.
9674   if (nmemb > 1) {
9675     for (SIZE_T i = 0; i < nmemb - 1; ++i) {
9676       void *p = (void *)((char *)base + i * size);
9677       void *q = (void *)((char *)base + (i + 1) * size);
9678       COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
9679       compar(p, q);
9680     }
9681   }
9682   qsort_compar_f old_compar = qsort_compar;
9683   qsort_compar = compar;
9684   SIZE_T old_size = qsort_size;
9685   qsort_size = size;
9686   REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);
9687   qsort_compar = old_compar;
9688   qsort_size = old_size;
9689   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
9690 }
9691 #define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
9692 #else
9693 #define INIT_QSORT
9694 #endif
9695
9696 #if SANITIZER_INTERCEPT_QSORT_R
9697 typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
9698 static THREADLOCAL qsort_r_compar_f qsort_r_compar;
9699 static THREADLOCAL SIZE_T qsort_r_size;
9700 int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
9701   COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9702   COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_r_size);
9703   COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_r_size);
9704   return qsort_r_compar(a, b, arg);
9705 }
9706
9707 INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
9708             qsort_r_compar_f compar, void *arg) {
9709   void *ctx;
9710   COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
9711   // Run the comparator over all array elements to detect any memory issues.
9712   if (nmemb > 1) {
9713     for (SIZE_T i = 0; i < nmemb - 1; ++i) {
9714       void *p = (void *)((char *)base + i * size);
9715       void *q = (void *)((char *)base + (i + 1) * size);
9716       COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9717       compar(p, q, arg);
9718     }
9719   }
9720   qsort_r_compar_f old_compar = qsort_r_compar;
9721   qsort_r_compar = compar;
9722   SIZE_T old_size = qsort_r_size;
9723   qsort_r_size = size;
9724   REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg);
9725   qsort_r_compar = old_compar;
9726   qsort_r_size = old_size;
9727   COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
9728 }
9729 #define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
9730 #else
9731 #define INIT_QSORT_R
9732 #endif
9733
9734 #include "sanitizer_common_interceptors_netbsd_compat.inc"
9735
9736 static void InitializeCommonInterceptors() {
9737 #if SI_POSIX
9738   static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
9739   interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();
9740 #endif
9741
9742   INIT_MMAP;
9743   INIT_MMAP64;
9744   INIT_TEXTDOMAIN;
9745   INIT_STRLEN;
9746   INIT_STRNLEN;
9747   INIT_STRNDUP;
9748   INIT___STRNDUP;
9749   INIT_STRCMP;
9750   INIT_STRNCMP;
9751   INIT_STRCASECMP;
9752   INIT_STRNCASECMP;
9753   INIT_STRSTR;
9754   INIT_STRCASESTR;
9755   INIT_STRCHR;
9756   INIT_STRCHRNUL;
9757   INIT_STRRCHR;
9758   INIT_STRSPN;
9759   INIT_STRTOK;
9760   INIT_STRPBRK;
9761   INIT_STRXFRM;
9762   INIT___STRXFRM_L;
9763   INIT_MEMSET;
9764   INIT_MEMMOVE;
9765   INIT_MEMCPY;
9766   INIT_MEMCHR;
9767   INIT_MEMCMP;
9768   INIT_BCMP;
9769   INIT_MEMRCHR;
9770   INIT_MEMMEM;
9771   INIT_READ;
9772   INIT_FREAD;
9773   INIT_PREAD;
9774   INIT_PREAD64;
9775   INIT_READV;
9776   INIT_PREADV;
9777   INIT_PREADV64;
9778   INIT_WRITE;
9779   INIT_FWRITE;
9780   INIT_PWRITE;
9781   INIT_PWRITE64;
9782   INIT_WRITEV;
9783   INIT_PWRITEV;
9784   INIT_PWRITEV64;
9785   INIT_FGETS;
9786   INIT_FPUTS;
9787   INIT_PUTS;
9788   INIT_PRCTL;
9789   INIT_LOCALTIME_AND_FRIENDS;
9790   INIT_STRPTIME;
9791   INIT_SCANF;
9792   INIT_ISOC99_SCANF;
9793   INIT_PRINTF;
9794   INIT_PRINTF_L;
9795   INIT_ISOC99_PRINTF;
9796   INIT_FREXP;
9797   INIT_FREXPF_FREXPL;
9798   INIT_GETPWNAM_AND_FRIENDS;
9799   INIT_GETPWNAM_R_AND_FRIENDS;
9800   INIT_GETPWENT;
9801   INIT_FGETPWENT;
9802   INIT_GETPWENT_R;
9803   INIT_FGETPWENT_R;
9804   INIT_FGETGRENT_R;
9805   INIT_SETPWENT;
9806   INIT_CLOCK_GETTIME;
9807   INIT_GETITIMER;
9808   INIT_TIME;
9809   INIT_GLOB;
9810   INIT_GLOB64;
9811   INIT_WAIT;
9812   INIT_WAIT4;
9813   INIT_INET;
9814   INIT_PTHREAD_GETSCHEDPARAM;
9815   INIT_GETADDRINFO;
9816   INIT_GETNAMEINFO;
9817   INIT_GETSOCKNAME;
9818   INIT_GETHOSTBYNAME;
9819   INIT_GETHOSTBYNAME2;
9820   INIT_GETHOSTBYNAME_R;
9821   INIT_GETHOSTBYNAME2_R;
9822   INIT_GETHOSTBYADDR_R;
9823   INIT_GETHOSTENT_R;
9824   INIT_GETSOCKOPT;
9825   INIT_ACCEPT;
9826   INIT_ACCEPT4;
9827   INIT_PACCEPT;
9828   INIT_MODF;
9829   INIT_RECVMSG;
9830   INIT_SENDMSG;
9831   INIT_RECVMMSG;
9832   INIT_SENDMMSG;
9833   INIT_GETPEERNAME;
9834   INIT_IOCTL;
9835   INIT_INET_ATON;
9836   INIT_SYSINFO;
9837   INIT_READDIR;
9838   INIT_READDIR64;
9839   INIT_PTRACE;
9840   INIT_SETLOCALE;
9841   INIT_GETCWD;
9842   INIT_GET_CURRENT_DIR_NAME;
9843   INIT_STRTOIMAX;
9844   INIT_MBSTOWCS;
9845   INIT_MBSNRTOWCS;
9846   INIT_WCSTOMBS;
9847   INIT_WCSNRTOMBS;
9848   INIT_WCRTOMB;
9849   INIT_WCTOMB;
9850   INIT_TCGETATTR;
9851   INIT_REALPATH;
9852   INIT_CANONICALIZE_FILE_NAME;
9853   INIT_CONFSTR;
9854   INIT_SCHED_GETAFFINITY;
9855   INIT_SCHED_GETPARAM;
9856   INIT_STRERROR;
9857   INIT_STRERROR_R;
9858   INIT_XPG_STRERROR_R;
9859   INIT_SCANDIR;
9860   INIT_SCANDIR64;
9861   INIT_GETGROUPS;
9862   INIT_POLL;
9863   INIT_PPOLL;
9864   INIT_WORDEXP;
9865   INIT_SIGWAIT;
9866   INIT_SIGWAITINFO;
9867   INIT_SIGTIMEDWAIT;
9868   INIT_SIGSETOPS;
9869   INIT_SIGPENDING;
9870   INIT_SIGPROCMASK;
9871   INIT_PTHREAD_SIGMASK;
9872   INIT_BACKTRACE;
9873   INIT__EXIT;
9874   INIT_PTHREAD_MUTEX_LOCK;
9875   INIT_PTHREAD_MUTEX_UNLOCK;
9876   INIT___PTHREAD_MUTEX_LOCK;
9877   INIT___PTHREAD_MUTEX_UNLOCK;
9878   INIT___LIBC_MUTEX_LOCK;
9879   INIT___LIBC_MUTEX_UNLOCK;
9880   INIT___LIBC_THR_SETCANCELSTATE;
9881   INIT_GETMNTENT;
9882   INIT_GETMNTENT_R;
9883   INIT_STATFS;
9884   INIT_STATFS64;
9885   INIT_STATVFS;
9886   INIT_STATVFS64;
9887   INIT_INITGROUPS;
9888   INIT_ETHER_NTOA_ATON;
9889   INIT_ETHER_HOST;
9890   INIT_ETHER_R;
9891   INIT_SHMCTL;
9892   INIT_RANDOM_R;
9893   INIT_PTHREAD_ATTR_GET;
9894   INIT_PTHREAD_ATTR_GET_SCHED;
9895   INIT_PTHREAD_ATTR_GETINHERITSCHED;
9896   INIT_PTHREAD_ATTR_GETAFFINITY_NP;
9897   INIT_PTHREAD_MUTEXATTR_GETPSHARED;
9898   INIT_PTHREAD_MUTEXATTR_GETTYPE;
9899   INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
9900   INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
9901   INIT_PTHREAD_MUTEXATTR_GETROBUST;
9902   INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
9903   INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
9904   INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
9905   INIT_PTHREAD_CONDATTR_GETPSHARED;
9906   INIT_PTHREAD_CONDATTR_GETCLOCK;
9907   INIT_PTHREAD_BARRIERATTR_GETPSHARED;
9908   INIT_TMPNAM;
9909   INIT_TMPNAM_R;
9910   INIT_TTYNAME;
9911   INIT_TTYNAME_R;
9912   INIT_TEMPNAM;
9913   INIT_PTHREAD_SETNAME_NP;
9914   INIT_PTHREAD_GETNAME_NP;
9915   INIT_SINCOS;
9916   INIT_REMQUO;
9917   INIT_REMQUOL;
9918   INIT_LGAMMA;
9919   INIT_LGAMMAL;
9920   INIT_LGAMMA_R;
9921   INIT_LGAMMAL_R;
9922   INIT_DRAND48_R;
9923   INIT_RAND_R;
9924   INIT_GETLINE;
9925   INIT_ICONV;
9926   INIT_TIMES;
9927   INIT_TLS_GET_ADDR;
9928   INIT_LISTXATTR;
9929   INIT_GETXATTR;
9930   INIT_GETRESID;
9931   INIT_GETIFADDRS;
9932   INIT_IF_INDEXTONAME;
9933   INIT_CAPGET;
9934   INIT_AEABI_MEM;
9935   INIT___BZERO;
9936   INIT_BZERO;
9937   INIT_FTIME;
9938   INIT_XDR;
9939   INIT_TSEARCH;
9940   INIT_LIBIO_INTERNALS;
9941   INIT_FOPEN;
9942   INIT_FOPEN64;
9943   INIT_OPEN_MEMSTREAM;
9944   INIT_OBSTACK;
9945   INIT_FFLUSH;
9946   INIT_FCLOSE;
9947   INIT_DLOPEN_DLCLOSE;
9948   INIT_GETPASS;
9949   INIT_TIMERFD;
9950   INIT_MLOCKX;
9951   INIT_FOPENCOOKIE;
9952   INIT_SEM;
9953   INIT_PTHREAD_SETCANCEL;
9954   INIT_MINCORE;
9955   INIT_PROCESS_VM_READV;
9956   INIT_CTERMID;
9957   INIT_CTERMID_R;
9958   INIT_RECV_RECVFROM;
9959   INIT_SEND_SENDTO;
9960   INIT_STAT;
9961   INIT_EVENTFD_READ_WRITE;
9962   INIT_LSTAT;
9963   INIT___XSTAT;
9964   INIT___XSTAT64;
9965   INIT___LXSTAT;
9966   INIT___LXSTAT64;
9967   // FIXME: add other *stat interceptors.
9968   INIT_UTMP;
9969   INIT_UTMPX;
9970   INIT_GETLOADAVG;
9971   INIT_WCSLEN;
9972   INIT_WCSCAT;
9973   INIT_WCSDUP;
9974   INIT_WCSXFRM;
9975   INIT___WCSXFRM_L;
9976   INIT_ACCT;
9977   INIT_USER_FROM_UID;
9978   INIT_UID_FROM_USER;
9979   INIT_GROUP_FROM_GID;
9980   INIT_GID_FROM_GROUP;
9981   INIT_ACCESS;
9982   INIT_FACCESSAT;
9983   INIT_GETGROUPLIST;
9984   INIT_GETGROUPMEMBERSHIP;
9985   INIT_READLINK;
9986   INIT_READLINKAT;
9987   INIT_NAME_TO_HANDLE_AT;
9988   INIT_OPEN_BY_HANDLE_AT;
9989   INIT_STRLCPY;
9990   INIT_DEVNAME;
9991   INIT_DEVNAME_R;
9992   INIT_FGETLN;
9993   INIT_STRMODE;
9994   INIT_TTYENT;
9995   INIT_PROTOENT;
9996   INIT_NETENT;
9997   INIT_GETMNTINFO;
9998   INIT_MI_VECTOR_HASH;
9999   INIT_SETVBUF;
10000   INIT_GETVFSSTAT;
10001   INIT_REGEX;
10002   INIT_REGEXSUB;
10003   INIT_FTS;
10004   INIT_SYSCTL;
10005   INIT_ASYSCTL;
10006   INIT_SYSCTLGETMIBINFO;
10007   INIT_NL_LANGINFO;
10008   INIT_MODCTL;
10009   INIT_STRTONUM;
10010   INIT_FPARSELN;
10011   INIT_STATVFS1;
10012   INIT_STRTOI;
10013   INIT_CAPSICUM;
10014   INIT_SHA1;
10015   INIT_MD4;
10016   INIT_RMD160;
10017   INIT_MD5;
10018   INIT_FSEEK;
10019   INIT_MD2;
10020   INIT_SHA2;
10021   INIT_VIS;
10022   INIT_CDB;
10023   INIT_GETFSENT;
10024   INIT_ARC4RANDOM;
10025   INIT_POPEN;
10026   INIT_POPENVE;
10027   INIT_PCLOSE;
10028   INIT_FUNOPEN;
10029   INIT_FUNOPEN2;
10030   INIT_FDEVNAME;
10031   INIT_GETUSERSHELL;
10032   INIT_SL_INIT;
10033   INIT_GETRANDOM;
10034   INIT_CRYPT;
10035   INIT_CRYPT_R;
10036   INIT_GETENTROPY;
10037   INIT_QSORT;
10038   INIT_QSORT_R;
10039
10040   INIT___PRINTF_CHK;
10041 }