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