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