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