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