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