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