1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// Common function interceptors for tools like AddressSanitizer,
10// ThreadSanitizer, MemorySanitizer, etc.
11//
12// This file should be included into the tool's interceptor file,
13// which has to define its own macros:
14//   COMMON_INTERCEPTOR_ENTER
15//   COMMON_INTERCEPTOR_ENTER_NOIGNORE
16//   COMMON_INTERCEPTOR_READ_RANGE
17//   COMMON_INTERCEPTOR_WRITE_RANGE
18//   COMMON_INTERCEPTOR_INITIALIZE_RANGE
19//   COMMON_INTERCEPTOR_DIR_ACQUIRE
20//   COMMON_INTERCEPTOR_FD_ACQUIRE
21//   COMMON_INTERCEPTOR_FD_RELEASE
22//   COMMON_INTERCEPTOR_FD_ACCESS
23//   COMMON_INTERCEPTOR_SET_THREAD_NAME
24//   COMMON_INTERCEPTOR_ON_DLOPEN
25//   COMMON_INTERCEPTOR_ON_EXIT
26//   COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
27//   COMMON_INTERCEPTOR_MUTEX_POST_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//   COMMON_INTERCEPTOR_MEMSET_IMPL
34//   COMMON_INTERCEPTOR_MEMMOVE_IMPL
35//   COMMON_INTERCEPTOR_MEMCPY_IMPL
36//   COMMON_INTERCEPTOR_MMAP_IMPL
37//   COMMON_INTERCEPTOR_COPY_STRING
38//   COMMON_INTERCEPTOR_STRNDUP_IMPL
39//   COMMON_INTERCEPTOR_STRERROR
40//===----------------------------------------------------------------------===//
41
42#include "interception/interception.h"
43#include "sanitizer_addrhashmap.h"
44#include "sanitizer_errno.h"
45#include "sanitizer_placement_new.h"
46#include "sanitizer_platform_interceptors.h"
47#include "sanitizer_symbolizer.h"
48#include "sanitizer_tls_get_addr.h"
49
50#include <stdarg.h>
51
52#if SANITIZER_INTERCEPTOR_HOOKS
53#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);
54#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
55  SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}
56#else
57#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
58#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
59
60#endif  // SANITIZER_INTERCEPTOR_HOOKS
61
62#if SANITIZER_WINDOWS && !defined(va_copy)
63#define va_copy(dst, src) ((dst) = (src))
64#endif // _WIN32
65
66#if SANITIZER_FREEBSD
67#define pthread_setname_np pthread_set_name_np
68#define inet_aton __inet_aton
69#define inet_pton __inet_pton
70#define iconv __bsd_iconv
71#endif
72
73#if SANITIZER_NETBSD
74#define clock_getres __clock_getres50
75#define clock_gettime __clock_gettime50
76#define clock_settime __clock_settime50
77#define ctime __ctime50
78#define ctime_r __ctime_r50
79#define devname __devname50
80#define fgetpos __fgetpos50
81#define fsetpos __fsetpos50
82#define fstatvfs __fstatvfs90
83#define fstatvfs1 __fstatvfs190
84#define fts_children __fts_children60
85#define fts_close __fts_close60
86#define fts_open __fts_open60
87#define fts_read __fts_read60
88#define fts_set __fts_set60
89#define getitimer __getitimer50
90#define getmntinfo __getmntinfo90
91#define getpwent __getpwent50
92#define getpwnam __getpwnam50
93#define getpwnam_r __getpwnam_r50
94#define getpwuid __getpwuid50
95#define getpwuid_r __getpwuid_r50
96#define getutent __getutent50
97#define getutxent __getutxent50
98#define getutxid __getutxid50
99#define getutxline __getutxline50
100#define getvfsstat __getvfsstat90
101#define pututxline __pututxline50
102#define glob __glob30
103#define gmtime __gmtime50
104#define gmtime_r __gmtime_r50
105#define localtime __locatime50
106#define localtime_r __localtime_r50
107#define mktime __mktime50
108#define lstat __lstat50
109#define opendir __opendir30
110#define readdir __readdir30
111#define readdir_r __readdir_r30
112#define scandir __scandir30
113#define setitimer __setitimer50
114#define setlocale __setlocale50
115#define shmctl __shmctl50
116#define sigaltstack __sigaltstack14
117#define sigemptyset __sigemptyset14
118#define sigfillset __sigfillset14
119#define sigpending __sigpending14
120#define sigprocmask __sigprocmask14
121#define sigtimedwait __sigtimedwait50
122#define stat __stat50
123#define statvfs __statvfs90
124#define statvfs1 __statvfs190
125#define time __time50
126#define times __times13
127#define unvis __unvis50
128#define wait3 __wait350
129#define wait4 __wait450
130extern const unsigned short *_ctype_tab_;
131extern const short *_toupper_tab_;
132extern const short *_tolower_tab_;
133#endif
134
135// Platform-specific options.
136#if SANITIZER_MAC
137#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
138#elif SANITIZER_WINDOWS64
139#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
140#else
141#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
142#endif  // SANITIZER_MAC
143
144#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
145#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
146#endif
147
148#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
149#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
150#endif
151
152#ifndef COMMON_INTERCEPTOR_FD_ACCESS
153#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
154#endif
155
156#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
157#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {}
158#endif
159
160#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK
161#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {}
162#endif
163
164#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
165#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
166#endif
167
168#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
169#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
170#endif
171
172#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
173#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
174#endif
175
176#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
177#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
178#endif
179
180#ifndef COMMON_INTERCEPTOR_FILE_OPEN
181#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
182#endif
183
184#ifndef COMMON_INTERCEPTOR_FILE_CLOSE
185#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
186#endif
187
188#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
189#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
190#endif
191
192#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
193#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
194#endif
195
196#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
197#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
198  COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
199#endif
200
201#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
202#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
203#endif
204
205#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n)                   \
206    COMMON_INTERCEPTOR_READ_RANGE((ctx), (s),                       \
207      common_flags()->strict_string_checks ? (internal_strlen(s)) + 1 : (n) )
208
209#ifndef COMMON_INTERCEPTOR_ON_DLOPEN
210#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
211  CheckNoDeepBind(filename, flag);
212#endif
213
214#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
215#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
216#endif
217
218#ifndef COMMON_INTERCEPTOR_ACQUIRE
219#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
220#endif
221
222#ifndef COMMON_INTERCEPTOR_RELEASE
223#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
224#endif
225
226#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
227#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
228#endif
229
230#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
231#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
232#endif
233
234#ifdef SANITIZER_NLDBL_VERSION
235#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
236    COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
237#else
238#define COMMON_INTERCEPT_FUNCTION_LDBL(fn)                          \
239    COMMON_INTERCEPT_FUNCTION(fn)
240#endif
241
242#if SANITIZER_GLIBC
243// If we could not find the versioned symbol, fall back to an unversioned
244// lookup. This is needed to work around a GLibc bug that causes dlsym
245// with RTLD_NEXT to return the oldest versioned symbol.
246// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932.
247// For certain symbols (e.g. regexec) we have to perform a versioned lookup,
248// but that versioned symbol will only exist for architectures where the
249// oldest Glibc version pre-dates support for that architecture.
250// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V.
251// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920.
252#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
253  COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver)
254#else
255#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
256  COMMON_INTERCEPT_FUNCTION(fn)
257#endif
258
259#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
260#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
261  {                                                       \
262    if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)        \
263      return internal_memset(dst, v, size);               \
264    COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size);  \
265    if (common_flags()->intercept_intrin)                 \
266      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);     \
267    return REAL(memset)(dst, v, size);                    \
268  }
269#endif
270
271#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
272#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \
273  {                                                          \
274    if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)           \
275      return internal_memmove(dst, src, size);               \
276    COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size);  \
277    if (common_flags()->intercept_intrin) {                  \
278      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);        \
279      COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);         \
280    }                                                        \
281    return REAL(memmove)(dst, src, size);                    \
282  }
283#endif
284
285#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
286#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \
287  {                                                         \
288    if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) {        \
289      return internal_memmove(dst, src, size);              \
290    }                                                       \
291    COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size);  \
292    if (common_flags()->intercept_intrin) {                 \
293      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size);       \
294      COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size);        \
295    }                                                       \
296    return REAL(memcpy)(dst, src, size);                    \
297  }
298#endif
299
300#ifndef COMMON_INTERCEPTOR_MMAP_IMPL
301#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
302                                     off)                                  \
303  { return REAL(mmap)(addr, sz, prot, flags, fd, off); }
304#endif
305
306#ifndef COMMON_INTERCEPTOR_COPY_STRING
307#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
308#endif
309
310#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
311#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size)                         \
312  COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size);                            \
313  uptr copy_length = internal_strnlen(s, size);                               \
314  char *new_mem = (char *)WRAP(malloc)(copy_length + 1);                      \
315  if (common_flags()->intercept_strndup) {                                    \
316    COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1));       \
317  }                                                                           \
318  COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length);               \
319  internal_memcpy(new_mem, s, copy_length);                                   \
320  new_mem[copy_length] = '\0';                                                \
321  return new_mem;
322#endif
323
324#ifndef COMMON_INTERCEPTOR_STRERROR
325#define COMMON_INTERCEPTOR_STRERROR() {}
326#endif
327
328struct FileMetadata {
329  // For open_memstream().
330  char **addr;
331  SIZE_T *size;
332};
333
334struct CommonInterceptorMetadata {
335  enum {
336    CIMT_INVALID = 0,
337    CIMT_FILE
338  } type;
339  union {
340    FileMetadata file;
341  };
342};
343
344#if SI_POSIX
345typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
346
347static MetadataHashMap *interceptor_metadata_map;
348
349UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
350                                          const FileMetadata &file) {
351  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
352  CHECK(h.created());
353  h->type = CommonInterceptorMetadata::CIMT_FILE;
354  h->file = file;
355}
356
357UNUSED static const FileMetadata *GetInterceptorMetadata(
358    __sanitizer_FILE *addr) {
359  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
360                            /* remove */ false,
361                            /* create */ false);
362  if (addr && h.exists()) {
363    CHECK(!h.created());
364    CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
365    return &h->file;
366  } else {
367    return 0;
368  }
369}
370
371UNUSED static void DeleteInterceptorMetadata(void *addr) {
372  MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
373  CHECK(h.exists());
374}
375#endif  // SI_POSIX
376
377#if SANITIZER_INTERCEPT_STRLEN
378INTERCEPTOR(SIZE_T, strlen, const char *s) {
379  // Sometimes strlen is called prior to InitializeCommonInterceptors,
380  // in which case the REAL(strlen) typically used in
381  // COMMON_INTERCEPTOR_ENTER will fail.  We use internal_strlen here
382  // to handle that.
383  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
384    return internal_strlen(s);
385  void *ctx;
386  COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
387  SIZE_T result = REAL(strlen)(s);
388  if (common_flags()->intercept_strlen)
389    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
390  return result;
391}
392#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
393#else
394#define INIT_STRLEN
395#endif
396
397#if SANITIZER_INTERCEPT_STRNLEN
398INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
399  void *ctx;
400  COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
401  SIZE_T length = REAL(strnlen)(s, maxlen);
402  if (common_flags()->intercept_strlen)
403    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
404  return length;
405}
406#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
407#else
408#define INIT_STRNLEN
409#endif
410
411#if SANITIZER_INTERCEPT_STRNDUP
412INTERCEPTOR(char*, strndup, const char *s, uptr size) {
413  void *ctx;
414  COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
415}
416#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
417#else
418#define INIT_STRNDUP
419#endif // SANITIZER_INTERCEPT_STRNDUP
420
421#if SANITIZER_INTERCEPT___STRNDUP
422INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
423  void *ctx;
424  COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
425}
426#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
427#else
428#define INIT___STRNDUP
429#endif // SANITIZER_INTERCEPT___STRNDUP
430
431#if SANITIZER_INTERCEPT_TEXTDOMAIN
432INTERCEPTOR(char*, textdomain, const char *domainname) {
433  void *ctx;
434  COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
435  if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
436  char *domain = REAL(textdomain)(domainname);
437  if (domain) {
438    COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, internal_strlen(domain) + 1);
439  }
440  return domain;
441}
442#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
443#else
444#define INIT_TEXTDOMAIN
445#endif
446
447#if SANITIZER_INTERCEPT_STRCMP
448static inline int CharCmpX(unsigned char c1, unsigned char c2) {
449  return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
450}
451
452DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
453                              const char *s1, const char *s2, int result)
454
455INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
456  void *ctx;
457  COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
458  unsigned char c1, c2;
459  uptr i;
460  for (i = 0;; i++) {
461    c1 = (unsigned char)s1[i];
462    c2 = (unsigned char)s2[i];
463    if (c1 != c2 || c1 == '\0') break;
464  }
465  if (common_flags()->intercept_strcmp) {
466    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
467    COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
468  }
469  int result = CharCmpX(c1, c2);
470  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
471                             s2, result);
472  return result;
473}
474
475DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
476                              const char *s1, const char *s2, uptr n,
477                              int result)
478
479INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
480  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
481    return internal_strncmp(s1, s2, size);
482  void *ctx;
483  COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
484  unsigned char c1 = 0, c2 = 0;
485  uptr i;
486  for (i = 0; i < size; i++) {
487    c1 = (unsigned char)s1[i];
488    c2 = (unsigned char)s2[i];
489    if (c1 != c2 || c1 == '\0') break;
490  }
491  uptr i1 = i;
492  uptr i2 = i;
493  if (common_flags()->strict_string_checks) {
494    for (; i1 < size && s1[i1]; i1++) {}
495    for (; i2 < size && s2[i2]; i2++) {}
496  }
497  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
498  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
499  int result = CharCmpX(c1, c2);
500  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
501                             s2, size, result);
502  return result;
503}
504
505#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
506#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
507#else
508#define INIT_STRCMP
509#define INIT_STRNCMP
510#endif
511
512#if SANITIZER_INTERCEPT_STRCASECMP
513static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
514  int c1_low = ToLower(c1);
515  int c2_low = ToLower(c2);
516  return c1_low - c2_low;
517}
518
519DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
520                              const char *s1, const char *s2, int result)
521
522INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
523  void *ctx;
524  COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
525  unsigned char c1 = 0, c2 = 0;
526  uptr i;
527  for (i = 0;; i++) {
528    c1 = (unsigned char)s1[i];
529    c2 = (unsigned char)s2[i];
530    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
531  }
532  COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
533  COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
534  int result = CharCaseCmp(c1, c2);
535  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
536                             s1, s2, result);
537  return result;
538}
539
540DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
541                              const char *s1, const char *s2, uptr size,
542                              int result)
543
544INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {
545  void *ctx;
546  COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
547  unsigned char c1 = 0, c2 = 0;
548  uptr i;
549  for (i = 0; i < size; i++) {
550    c1 = (unsigned char)s1[i];
551    c2 = (unsigned char)s2[i];
552    if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
553  }
554  uptr i1 = i;
555  uptr i2 = i;
556  if (common_flags()->strict_string_checks) {
557    for (; i1 < size && s1[i1]; i1++) {}
558    for (; i2 < size && s2[i2]; i2++) {}
559  }
560  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
561  COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
562  int result = CharCaseCmp(c1, c2);
563  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
564                             s1, s2, size, result);
565  return result;
566}
567
568#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
569#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
570#else
571#define INIT_STRCASECMP
572#define INIT_STRNCASECMP
573#endif
574
575#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
576static inline void StrstrCheck(void *ctx, char *r, const char *s1,
577                               const char *s2) {
578    uptr len1 = internal_strlen(s1);
579    uptr len2 = internal_strlen(s2);
580    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
581    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
582}
583#endif
584
585#if SANITIZER_INTERCEPT_STRSTR
586
587DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
588                              const char *s1, const char *s2, char *result)
589
590INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
591  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
592    return internal_strstr(s1, s2);
593  void *ctx;
594  COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
595  char *r = REAL(strstr)(s1, s2);
596  if (common_flags()->intercept_strstr)
597    StrstrCheck(ctx, r, s1, s2);
598  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
599                             s2, r);
600  return r;
601}
602
603#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
604#else
605#define INIT_STRSTR
606#endif
607
608#if SANITIZER_INTERCEPT_STRCASESTR
609
610DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
611                              const char *s1, const char *s2, char *result)
612
613INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
614  void *ctx;
615  COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
616  char *r = REAL(strcasestr)(s1, s2);
617  if (common_flags()->intercept_strstr)
618    StrstrCheck(ctx, r, s1, s2);
619  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
620                             s1, s2, r);
621  return r;
622}
623
624#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
625#else
626#define INIT_STRCASESTR
627#endif
628
629#if SANITIZER_INTERCEPT_STRTOK
630
631INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
632  void *ctx;
633  COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);
634  if (!common_flags()->intercept_strtok) {
635    return REAL(strtok)(str, delimiters);
636  }
637  if (common_flags()->strict_string_checks) {
638    // If strict_string_checks is enabled, we check the whole first argument
639    // string on the first call (strtok saves this string in a static buffer
640    // for subsequent calls). We do not need to check strtok's result.
641    // As the delimiters can change, we check them every call.
642    if (str != nullptr) {
643      COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
644    }
645    COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,
646                                  internal_strlen(delimiters) + 1);
647    return REAL(strtok)(str, delimiters);
648  } else {
649    // However, when strict_string_checks is disabled we cannot check the
650    // whole string on the first call. Instead, we check the result string
651    // which is guaranteed to be a NULL-terminated substring of the first
652    // argument. We also conservatively check one character of str and the
653    // delimiters.
654    if (str != nullptr) {
655      COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);
656    }
657    COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);
658    char *result = REAL(strtok)(str, delimiters);
659    if (result != nullptr) {
660      COMMON_INTERCEPTOR_READ_RANGE(ctx, result, internal_strlen(result) + 1);
661    } else if (str != nullptr) {
662      // No delimiter were found, it's safe to assume that the entire str was
663      // scanned.
664      COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
665    }
666    return result;
667  }
668}
669
670#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)
671#else
672#define INIT_STRTOK
673#endif
674
675#if SANITIZER_INTERCEPT_MEMMEM
676DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
677                              const void *s1, SIZE_T len1, const void *s2,
678                              SIZE_T len2, void *result)
679
680INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
681            SIZE_T len2) {
682  void *ctx;
683  COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
684  void *r = REAL(memmem)(s1, len1, s2, len2);
685  if (common_flags()->intercept_memmem) {
686    COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
687    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
688  }
689  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
690                             s1, len1, s2, len2, r);
691  return r;
692}
693
694#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
695#else
696#define INIT_MEMMEM
697#endif  // SANITIZER_INTERCEPT_MEMMEM
698
699#if SANITIZER_INTERCEPT_STRCHR
700INTERCEPTOR(char*, strchr, const char *s, int c) {
701  void *ctx;
702  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
703    return internal_strchr(s, c);
704  COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
705  char *result = REAL(strchr)(s, c);
706  if (common_flags()->intercept_strchr) {
707    // Keep strlen as macro argument, as macro may ignore it.
708    COMMON_INTERCEPTOR_READ_STRING(ctx, s,
709      (result ? result - s : internal_strlen(s)) + 1);
710  }
711  return result;
712}
713#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
714#else
715#define INIT_STRCHR
716#endif
717
718#if SANITIZER_INTERCEPT_STRCHRNUL
719INTERCEPTOR(char*, strchrnul, const char *s, int c) {
720  void *ctx;
721  COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
722  char *result = REAL(strchrnul)(s, c);
723  uptr len = result - s + 1;
724  if (common_flags()->intercept_strchr)
725    COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
726  return result;
727}
728#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
729#else
730#define INIT_STRCHRNUL
731#endif
732
733#if SANITIZER_INTERCEPT_STRRCHR
734INTERCEPTOR(char*, strrchr, const char *s, int c) {
735  void *ctx;
736  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
737    return internal_strrchr(s, c);
738  COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
739  if (common_flags()->intercept_strchr)
740    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
741  return REAL(strrchr)(s, c);
742}
743#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
744#else
745#define INIT_STRRCHR
746#endif
747
748#if SANITIZER_INTERCEPT_STRSPN
749INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
750  void *ctx;
751  COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
752  SIZE_T r = REAL(strspn)(s1, s2);
753  if (common_flags()->intercept_strspn) {
754    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
755    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
756  }
757  return r;
758}
759
760INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
761  void *ctx;
762  COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
763  SIZE_T r = REAL(strcspn)(s1, s2);
764  if (common_flags()->intercept_strspn) {
765    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
766    COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
767  }
768  return r;
769}
770
771#define INIT_STRSPN \
772  COMMON_INTERCEPT_FUNCTION(strspn); \
773  COMMON_INTERCEPT_FUNCTION(strcspn);
774#else
775#define INIT_STRSPN
776#endif
777
778#if SANITIZER_INTERCEPT_STRPBRK
779INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
780  void *ctx;
781  COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
782  char *r = REAL(strpbrk)(s1, s2);
783  if (common_flags()->intercept_strpbrk) {
784    COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
785    COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
786        r ? r - s1 + 1 : internal_strlen(s1) + 1);
787  }
788  return r;
789}
790
791#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
792#else
793#define INIT_STRPBRK
794#endif
795
796#if SANITIZER_INTERCEPT_MEMSET
797INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
798  void *ctx;
799  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);
800}
801
802#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
803#else
804#define INIT_MEMSET
805#endif
806
807#if SANITIZER_INTERCEPT_MEMMOVE
808INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
809  void *ctx;
810  COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
811}
812
813#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
814#else
815#define INIT_MEMMOVE
816#endif
817
818#if SANITIZER_INTERCEPT_MEMCPY
819INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
820  // On OS X, calling internal_memcpy here will cause memory corruptions,
821  // because memcpy and memmove are actually aliases of the same
822  // implementation.  We need to use internal_memmove here.
823  // N.B.: If we switch this to internal_ we'll have to use internal_memmove
824  // due to memcpy being an alias of memmove on OS X.
825  void *ctx;
826#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
827    COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
828#else
829    COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
830#endif
831}
832
833#define INIT_MEMCPY                                  \
834  do {                                               \
835    if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \
836      COMMON_INTERCEPT_FUNCTION(memcpy);             \
837    } else {                                         \
838      ASSIGN_REAL(memcpy, memmove);                  \
839    }                                                \
840    CHECK(REAL(memcpy));                             \
841  } while (false)
842
843#else
844#define INIT_MEMCPY
845#endif
846
847#if SANITIZER_INTERCEPT_MEMCMP
848DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
849                              const void *s1, const void *s2, uptr n,
850                              int result)
851
852// Common code for `memcmp` and `bcmp`.
853int MemcmpInterceptorCommon(void *ctx,
854                            int (*real_fn)(const void *, const void *, uptr),
855                            const void *a1, const void *a2, uptr size) {
856  if (common_flags()->intercept_memcmp) {
857    if (common_flags()->strict_memcmp) {
858      // Check the entire regions even if the first bytes of the buffers are
859      // different.
860      COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
861      COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
862      // Fallthrough to REAL(memcmp) below.
863    } else {
864      unsigned char c1 = 0, c2 = 0;
865      const unsigned char *s1 = (const unsigned char*)a1;
866      const unsigned char *s2 = (const unsigned char*)a2;
867      uptr i;
868      for (i = 0; i < size; i++) {
869        c1 = s1[i];
870        c2 = s2[i];
871        if (c1 != c2) break;
872      }
873      COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
874      COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
875      int r = CharCmpX(c1, c2);
876      CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
877                                 a1, a2, size, r);
878      return r;
879    }
880  }
881  int result = real_fn(a1, a2, size);
882  CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
883                             a2, size, result);
884  return result;
885}
886
887INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
888  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
889    return internal_memcmp(a1, a2, size);
890  void *ctx;
891  COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
892  return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
893}
894
895#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
896#else
897#define INIT_MEMCMP
898#endif
899
900#if SANITIZER_INTERCEPT_BCMP
901INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) {
902  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
903    return internal_memcmp(a1, a2, size);
904  void *ctx;
905  COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
906  return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
907}
908
909#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
910#else
911#define INIT_BCMP
912#endif
913
914#if SANITIZER_INTERCEPT_MEMCHR
915INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
916  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
917    return internal_memchr(s, c, n);
918  void *ctx;
919  COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
920#if SANITIZER_WINDOWS
921  void *res;
922  if (REAL(memchr)) {
923    res = REAL(memchr)(s, c, n);
924  } else {
925    res = internal_memchr(s, c, n);
926  }
927#else
928  void *res = REAL(memchr)(s, c, n);
929#endif
930  uptr len = res ? (char *)res - (const char *)s + 1 : n;
931  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
932  return res;
933}
934
935#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
936#else
937#define INIT_MEMCHR
938#endif
939
940#if SANITIZER_INTERCEPT_MEMRCHR
941INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
942  void *ctx;
943  COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
944  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
945  return REAL(memrchr)(s, c, n);
946}
947
948#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
949#else
950#define INIT_MEMRCHR
951#endif
952
953#if SANITIZER_INTERCEPT_FREXP
954INTERCEPTOR(double, frexp, double x, int *exp) {
955  void *ctx;
956  COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
957  // Assuming frexp() always writes to |exp|.
958  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
959  double res = REAL(frexp)(x, exp);
960  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
961  return res;
962}
963
964#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
965#else
966#define INIT_FREXP
967#endif  // SANITIZER_INTERCEPT_FREXP
968
969#if SANITIZER_INTERCEPT_FREXPF_FREXPL
970INTERCEPTOR(float, frexpf, float x, int *exp) {
971  void *ctx;
972  COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
973  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
974  float res = REAL(frexpf)(x, exp);
975  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
976  return res;
977}
978
979INTERCEPTOR(long double, frexpl, long double x, int *exp) {
980  void *ctx;
981  COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
982  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
983  long double res = REAL(frexpl)(x, exp);
984  COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
985  return res;
986}
987
988#define INIT_FREXPF_FREXPL           \
989  COMMON_INTERCEPT_FUNCTION(frexpf); \
990  COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
991#else
992#define INIT_FREXPF_FREXPL
993#endif  // SANITIZER_INTERCEPT_FREXPF_FREXPL
994
995#if SI_POSIX
996static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
997                        SIZE_T iovlen, SIZE_T maxlen) {
998  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
999    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
1000    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
1001    maxlen -= sz;
1002  }
1003}
1004
1005static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
1006                       SIZE_T iovlen, SIZE_T maxlen) {
1007  COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
1008  for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
1009    SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
1010    COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
1011    maxlen -= sz;
1012  }
1013}
1014#endif
1015
1016#if SANITIZER_INTERCEPT_READ
1017INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
1018  void *ctx;
1019  COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
1020  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
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  SSIZE_T res = REAL(read)(fd, ptr, count);
1025  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1026  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1027  return res;
1028}
1029#define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
1030#else
1031#define INIT_READ
1032#endif
1033
1034#if SANITIZER_INTERCEPT_FREAD
1035INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
1036  // libc file streams can call user-supplied functions, see fopencookie.
1037  void *ctx;
1038  COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
1039  // FIXME: under ASan the call below may write to freed memory and corrupt
1040  // its metadata. See
1041  // https://github.com/google/sanitizers/issues/321.
1042  SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
1043  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
1044  return res;
1045}
1046#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
1047#else
1048#define INIT_FREAD
1049#endif
1050
1051#if SANITIZER_INTERCEPT_PREAD
1052INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1053  void *ctx;
1054  COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
1055  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1056  // FIXME: under ASan the call below may write to freed memory and corrupt
1057  // its metadata. See
1058  // https://github.com/google/sanitizers/issues/321.
1059  SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
1060  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1061  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1062  return res;
1063}
1064#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
1065#else
1066#define INIT_PREAD
1067#endif
1068
1069#if SANITIZER_INTERCEPT_PREAD64
1070INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
1071  void *ctx;
1072  COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
1073  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1074  // FIXME: under ASan the call below may write to freed memory and corrupt
1075  // its metadata. See
1076  // https://github.com/google/sanitizers/issues/321.
1077  SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
1078  if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1079  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1080  return res;
1081}
1082#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
1083#else
1084#define INIT_PREAD64
1085#endif
1086
1087#if SANITIZER_INTERCEPT_READV
1088INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
1089                        int iovcnt) {
1090  void *ctx;
1091  COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
1092  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1093  SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
1094  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1095  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1096  return res;
1097}
1098#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
1099#else
1100#define INIT_READV
1101#endif
1102
1103#if SANITIZER_INTERCEPT_PREADV
1104INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
1105            OFF_T offset) {
1106  void *ctx;
1107  COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
1108  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1109  SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
1110  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1111  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1112  return res;
1113}
1114#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
1115#else
1116#define INIT_PREADV
1117#endif
1118
1119#if SANITIZER_INTERCEPT_PREADV64
1120INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
1121            OFF64_T offset) {
1122  void *ctx;
1123  COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
1124  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1125  SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
1126  if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1127  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1128  return res;
1129}
1130#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
1131#else
1132#define INIT_PREADV64
1133#endif
1134
1135#if SANITIZER_INTERCEPT_WRITE
1136INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
1137  void *ctx;
1138  COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
1139  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1140  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1141  SSIZE_T res = REAL(write)(fd, ptr, count);
1142  // FIXME: this check should be _before_ the call to REAL(write), not after
1143  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1144  return res;
1145}
1146#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
1147#else
1148#define INIT_WRITE
1149#endif
1150
1151#if SANITIZER_INTERCEPT_FWRITE
1152INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) {
1153  // libc file streams can call user-supplied functions, see fopencookie.
1154  void *ctx;
1155  COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
1156  SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
1157  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
1158  return res;
1159}
1160#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
1161#else
1162#define INIT_FWRITE
1163#endif
1164
1165#if SANITIZER_INTERCEPT_PWRITE
1166INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1167  void *ctx;
1168  COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
1169  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1170  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1171  SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
1172  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1173  return res;
1174}
1175#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
1176#else
1177#define INIT_PWRITE
1178#endif
1179
1180#if SANITIZER_INTERCEPT_PWRITE64
1181INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
1182            OFF64_T offset) {
1183  void *ctx;
1184  COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
1185  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1186  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1187  SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
1188  if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1189  return res;
1190}
1191#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
1192#else
1193#define INIT_PWRITE64
1194#endif
1195
1196#if SANITIZER_INTERCEPT_WRITEV
1197INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
1198                        int iovcnt) {
1199  void *ctx;
1200  COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
1201  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1202  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1203  SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
1204  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1205  return res;
1206}
1207#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
1208#else
1209#define INIT_WRITEV
1210#endif
1211
1212#if SANITIZER_INTERCEPT_PWRITEV
1213INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
1214            OFF_T offset) {
1215  void *ctx;
1216  COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
1217  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1218  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1219  SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
1220  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1221  return res;
1222}
1223#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
1224#else
1225#define INIT_PWRITEV
1226#endif
1227
1228#if SANITIZER_INTERCEPT_PWRITEV64
1229INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
1230            OFF64_T offset) {
1231  void *ctx;
1232  COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
1233  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1234  if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1235  SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
1236  if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1237  return res;
1238}
1239#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
1240#else
1241#define INIT_PWRITEV64
1242#endif
1243
1244#if SANITIZER_INTERCEPT_FGETS
1245INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {
1246  // libc file streams can call user-supplied functions, see fopencookie.
1247  void *ctx;
1248  COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);
1249  // FIXME: under ASan the call below may write to freed memory and corrupt
1250  // its metadata. See
1251  // https://github.com/google/sanitizers/issues/321.
1252  char *res = REAL(fgets)(s, size, file);
1253  if (res)
1254    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
1255  return res;
1256}
1257#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)
1258#else
1259#define INIT_FGETS
1260#endif
1261
1262#if SANITIZER_INTERCEPT_FPUTS
1263INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
1264  // libc file streams can call user-supplied functions, see fopencookie.
1265  void *ctx;
1266  COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
1267  if (!SANITIZER_MAC || s) {  // `fputs(NULL, file)` is supported on Darwin.
1268    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
1269  }
1270  return REAL(fputs)(s, file);
1271}
1272#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
1273#else
1274#define INIT_FPUTS
1275#endif
1276
1277#if SANITIZER_INTERCEPT_PUTS
1278INTERCEPTOR(int, puts, char *s) {
1279  // libc file streams can call user-supplied functions, see fopencookie.
1280  void *ctx;
1281  COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
1282  if (!SANITIZER_MAC || s) {  // `puts(NULL)` is supported on Darwin.
1283    COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
1284  }
1285  return REAL(puts)(s);
1286}
1287#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
1288#else
1289#define INIT_PUTS
1290#endif
1291
1292#if SANITIZER_INTERCEPT_PRCTL
1293INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
1294            unsigned long arg4, unsigned long arg5) {
1295  void *ctx;
1296  COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
1297  static const int PR_SET_NAME = 15;
1298  int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
1299  if (option == PR_SET_NAME) {
1300    char buff[16];
1301    internal_strncpy(buff, (char *)arg2, 15);
1302    buff[15] = 0;
1303    COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
1304  }
1305  return res;
1306}
1307#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
1308#else
1309#define INIT_PRCTL
1310#endif  // SANITIZER_INTERCEPT_PRCTL
1311
1312#if SANITIZER_INTERCEPT_TIME
1313INTERCEPTOR(unsigned long, time, unsigned long *t) {
1314  void *ctx;
1315  COMMON_INTERCEPTOR_ENTER(ctx, time, t);
1316  unsigned long local_t;
1317  unsigned long res = REAL(time)(&local_t);
1318  if (t && res != (unsigned long)-1) {
1319    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
1320    *t = local_t;
1321  }
1322  return res;
1323}
1324#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
1325#else
1326#define INIT_TIME
1327#endif  // SANITIZER_INTERCEPT_TIME
1328
1329#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1330static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
1331  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1332#if !SANITIZER_SOLARIS
1333  if (tm->tm_zone) {
1334    // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
1335    // can point to shared memory and tsan would report a data race.
1336    COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
1337                                        internal_strlen(tm->tm_zone) + 1);
1338  }
1339#endif
1340}
1341INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
1342  void *ctx;
1343  COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
1344  __sanitizer_tm *res = REAL(localtime)(timep);
1345  if (res) {
1346    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1347    unpoison_tm(ctx, res);
1348  }
1349  return res;
1350}
1351INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
1352  void *ctx;
1353  COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1354  __sanitizer_tm *res = REAL(localtime_r)(timep, result);
1355  if (res) {
1356    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1357    unpoison_tm(ctx, res);
1358  }
1359  return res;
1360}
1361INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
1362  void *ctx;
1363  COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
1364  __sanitizer_tm *res = REAL(gmtime)(timep);
1365  if (res) {
1366    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1367    unpoison_tm(ctx, res);
1368  }
1369  return res;
1370}
1371INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
1372  void *ctx;
1373  COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
1374  __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
1375  if (res) {
1376    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1377    unpoison_tm(ctx, res);
1378  }
1379  return res;
1380}
1381INTERCEPTOR(char *, ctime, unsigned long *timep) {
1382  void *ctx;
1383  COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
1384  // FIXME: under ASan the call below may write to freed memory and corrupt
1385  // its metadata. See
1386  // https://github.com/google/sanitizers/issues/321.
1387  char *res = REAL(ctime)(timep);
1388  if (res) {
1389    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1390    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1391  }
1392  return res;
1393}
1394INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
1395  void *ctx;
1396  COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
1397  // FIXME: under ASan the call below may write to freed memory and corrupt
1398  // its metadata. See
1399  // https://github.com/google/sanitizers/issues/321.
1400  char *res = REAL(ctime_r)(timep, result);
1401  if (res) {
1402    COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1403    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1404  }
1405  return res;
1406}
1407INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
1408  void *ctx;
1409  COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
1410  // FIXME: under ASan the call below may write to freed memory and corrupt
1411  // its metadata. See
1412  // https://github.com/google/sanitizers/issues/321.
1413  char *res = REAL(asctime)(tm);
1414  if (res) {
1415    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1416    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1417  }
1418  return res;
1419}
1420INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
1421  void *ctx;
1422  COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
1423  // FIXME: under ASan the call below may write to freed memory and corrupt
1424  // its metadata. See
1425  // https://github.com/google/sanitizers/issues/321.
1426  char *res = REAL(asctime_r)(tm, result);
1427  if (res) {
1428    COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1429    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1430  }
1431  return res;
1432}
1433INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
1434  void *ctx;
1435  COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
1436  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
1437  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
1438  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
1439  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
1440  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
1441  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
1442  COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
1443  long res = REAL(mktime)(tm);
1444  if (res != -1) unpoison_tm(ctx, tm);
1445  return res;
1446}
1447#define INIT_LOCALTIME_AND_FRIENDS        \
1448  COMMON_INTERCEPT_FUNCTION(localtime);   \
1449  COMMON_INTERCEPT_FUNCTION(localtime_r); \
1450  COMMON_INTERCEPT_FUNCTION(gmtime);      \
1451  COMMON_INTERCEPT_FUNCTION(gmtime_r);    \
1452  COMMON_INTERCEPT_FUNCTION(ctime);       \
1453  COMMON_INTERCEPT_FUNCTION(ctime_r);     \
1454  COMMON_INTERCEPT_FUNCTION(asctime);     \
1455  COMMON_INTERCEPT_FUNCTION(asctime_r);   \
1456  COMMON_INTERCEPT_FUNCTION(mktime);
1457#else
1458#define INIT_LOCALTIME_AND_FRIENDS
1459#endif  // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1460
1461#if SANITIZER_INTERCEPT_STRPTIME
1462INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
1463  void *ctx;
1464  COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
1465  if (format)
1466    COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);
1467  // FIXME: under ASan the call below may write to freed memory and corrupt
1468  // its metadata. See
1469  // https://github.com/google/sanitizers/issues/321.
1470  char *res = REAL(strptime)(s, format, tm);
1471  COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
1472  if (res && tm) {
1473    // Do not call unpoison_tm here, because strptime does not, in fact,
1474    // initialize the entire struct tm. For example, tm_zone pointer is left
1475    // uninitialized.
1476    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1477  }
1478  return res;
1479}
1480#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
1481#else
1482#define INIT_STRPTIME
1483#endif
1484
1485#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
1486#include "sanitizer_common_interceptors_format.inc"
1487
1488#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...)                              \
1489  {                                                                            \
1490    void *ctx;                                                                 \
1491    va_list ap;                                                                \
1492    va_start(ap, format);                                                      \
1493    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap);                     \
1494    int res = WRAP(vname)(__VA_ARGS__, ap);                                    \
1495    va_end(ap);                                                                \
1496    return res;                                                                \
1497  }
1498
1499#endif
1500
1501#if SANITIZER_INTERCEPT_SCANF
1502
1503#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...)                    \
1504  {                                                                            \
1505    void *ctx;                                                                 \
1506    COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                         \
1507    va_list aq;                                                                \
1508    va_copy(aq, ap);                                                           \
1509    int res = REAL(vname)(__VA_ARGS__);                                        \
1510    if (res > 0)                                                               \
1511      scanf_common(ctx, res, allowGnuMalloc, format, aq);                      \
1512    va_end(aq);                                                                \
1513    return res;                                                                \
1514  }
1515
1516INTERCEPTOR(int, vscanf, const char *format, va_list ap)
1517VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
1518
1519INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
1520VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
1521
1522INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
1523VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
1524
1525#if SANITIZER_INTERCEPT_ISOC99_SCANF
1526INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
1527VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
1528
1529INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
1530            va_list ap)
1531VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
1532
1533INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
1534VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
1535#endif  // SANITIZER_INTERCEPT_ISOC99_SCANF
1536
1537INTERCEPTOR(int, scanf, const char *format, ...)
1538FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
1539
1540INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
1541FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
1542
1543INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
1544FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
1545
1546#if SANITIZER_INTERCEPT_ISOC99_SCANF
1547INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
1548FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
1549
1550INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
1551FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
1552
1553INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
1554FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
1555#endif
1556
1557#endif
1558
1559#if SANITIZER_INTERCEPT_SCANF
1560#define INIT_SCANF                    \
1561  COMMON_INTERCEPT_FUNCTION_LDBL(scanf);   \
1562  COMMON_INTERCEPT_FUNCTION_LDBL(sscanf);  \
1563  COMMON_INTERCEPT_FUNCTION_LDBL(fscanf);  \
1564  COMMON_INTERCEPT_FUNCTION_LDBL(vscanf);  \
1565  COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \
1566  COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);
1567#else
1568#define INIT_SCANF
1569#endif
1570
1571#if SANITIZER_INTERCEPT_ISOC99_SCANF
1572#define INIT_ISOC99_SCANF                      \
1573  COMMON_INTERCEPT_FUNCTION(__isoc99_scanf);   \
1574  COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf);  \
1575  COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf);  \
1576  COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf);  \
1577  COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1578  COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1579#else
1580#define INIT_ISOC99_SCANF
1581#endif
1582
1583#if SANITIZER_INTERCEPT_PRINTF
1584
1585#define VPRINTF_INTERCEPTOR_ENTER(vname, ...)                                  \
1586  void *ctx;                                                                   \
1587  COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__);                           \
1588  va_list aq;                                                                  \
1589  va_copy(aq, ap);
1590
1591#define VPRINTF_INTERCEPTOR_RETURN()                                           \
1592  va_end(aq);
1593
1594#define VPRINTF_INTERCEPTOR_IMPL(vname, ...)                                   \
1595  {                                                                            \
1596    VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__);                             \
1597    if (common_flags()->check_printf)                                          \
1598      printf_common(ctx, format, aq);                                          \
1599    int res = REAL(vname)(__VA_ARGS__);                                        \
1600    VPRINTF_INTERCEPTOR_RETURN();                                              \
1601    return res;                                                                \
1602  }
1603
1604// FIXME: under ASan the REAL() call below may write to freed memory and
1605// corrupt its metadata. See
1606// https://github.com/google/sanitizers/issues/321.
1607#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...)                             \
1608  {                                                                            \
1609    VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__)                         \
1610    if (common_flags()->check_printf) {                                        \
1611      printf_common(ctx, format, aq);                                          \
1612    }                                                                          \
1613    int res = REAL(vname)(str, __VA_ARGS__);                                   \
1614    if (res >= 0) {                                                            \
1615      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1);                       \
1616    }                                                                          \
1617    VPRINTF_INTERCEPTOR_RETURN();                                              \
1618    return res;                                                                \
1619  }
1620
1621// FIXME: under ASan the REAL() call below may write to freed memory and
1622// corrupt its metadata. See
1623// https://github.com/google/sanitizers/issues/321.
1624#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...)                      \
1625  {                                                                            \
1626    VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__)                   \
1627    if (common_flags()->check_printf) {                                        \
1628      printf_common(ctx, format, aq);                                          \
1629    }                                                                          \
1630    int res = REAL(vname)(str, size, __VA_ARGS__);                             \
1631    if (res >= 0) {                                                            \
1632      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1)));  \
1633    }                                                                          \
1634    VPRINTF_INTERCEPTOR_RETURN();                                              \
1635    return res;                                                                \
1636  }
1637
1638// FIXME: under ASan the REAL() call below may write to freed memory and
1639// corrupt its metadata. See
1640// https://github.com/google/sanitizers/issues/321.
1641#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...)                           \
1642  {                                                                            \
1643    VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__)                        \
1644    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *));                 \
1645    if (common_flags()->check_printf) {                                        \
1646      printf_common(ctx, format, aq);                                          \
1647    }                                                                          \
1648    int res = REAL(vname)(strp, __VA_ARGS__);                                  \
1649    if (res >= 0) {                                                            \
1650      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1);                     \
1651    }                                                                          \
1652    VPRINTF_INTERCEPTOR_RETURN();                                              \
1653    return res;                                                                \
1654  }
1655
1656INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1657VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1658
1659INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1660            va_list ap)
1661VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1662
1663INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1664            va_list ap)
1665VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1666
1667#if SANITIZER_INTERCEPT___PRINTF_CHK
1668INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
1669            SIZE_T size_to, const char *format, va_list ap)
1670VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1671#endif
1672
1673#if SANITIZER_INTERCEPT_PRINTF_L
1674INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1675            const char *format, va_list ap)
1676VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1677
1678INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1679            const char *format, ...)
1680FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1681#endif  // SANITIZER_INTERCEPT_PRINTF_L
1682
1683INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1684VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1685
1686#if SANITIZER_INTERCEPT___PRINTF_CHK
1687INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
1688            const char *format, va_list ap)
1689VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1690#endif
1691
1692INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1693VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1694
1695#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1696INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1697VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1698
1699INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1700            const char *format, va_list ap)
1701VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1702
1703INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1704            va_list ap)
1705VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1706
1707INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1708            va_list ap)
1709VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1710                          ap)
1711
1712#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1713
1714INTERCEPTOR(int, printf, const char *format, ...)
1715FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1716
1717INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1718FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1719
1720#if SANITIZER_INTERCEPT___PRINTF_CHK
1721INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
1722            const char *format, ...)
1723FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
1724#endif
1725
1726INTERCEPTOR(int, sprintf, char *str, const char *format, ...)
1727FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)
1728
1729#if SANITIZER_INTERCEPT___PRINTF_CHK
1730INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
1731            const char *format, ...)
1732FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)
1733#endif
1734
1735INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1736FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1737
1738#if SANITIZER_INTERCEPT___PRINTF_CHK
1739INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
1740            SIZE_T size_to, const char *format, ...)
1741FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
1742#endif
1743
1744INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1745FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1746
1747#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1748INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1749FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1750
1751INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1752            ...)
1753FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1754
1755INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1756FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1757
1758INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1759            const char *format, ...)
1760FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1761                        format)
1762
1763#endif  // SANITIZER_INTERCEPT_ISOC99_PRINTF
1764
1765#endif  // SANITIZER_INTERCEPT_PRINTF
1766
1767#if SANITIZER_INTERCEPT_PRINTF
1768#define INIT_PRINTF                     \
1769  COMMON_INTERCEPT_FUNCTION_LDBL(printf);    \
1770  COMMON_INTERCEPT_FUNCTION_LDBL(sprintf);   \
1771  COMMON_INTERCEPT_FUNCTION_LDBL(snprintf);  \
1772  COMMON_INTERCEPT_FUNCTION_LDBL(asprintf);  \
1773  COMMON_INTERCEPT_FUNCTION_LDBL(fprintf);   \
1774  COMMON_INTERCEPT_FUNCTION_LDBL(vprintf);   \
1775  COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf);  \
1776  COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1777  COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
1778  COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1779#else
1780#define INIT_PRINTF
1781#endif
1782
1783#if SANITIZER_INTERCEPT___PRINTF_CHK
1784#define INIT___PRINTF_CHK                     \
1785  COMMON_INTERCEPT_FUNCTION(__sprintf_chk);   \
1786  COMMON_INTERCEPT_FUNCTION(__snprintf_chk);  \
1787  COMMON_INTERCEPT_FUNCTION(__vsprintf_chk);  \
1788  COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
1789  COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
1790#else
1791#define INIT___PRINTF_CHK
1792#endif
1793
1794#if SANITIZER_INTERCEPT_PRINTF_L
1795#define INIT_PRINTF_L                     \
1796  COMMON_INTERCEPT_FUNCTION(snprintf_l);  \
1797  COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1798#else
1799#define INIT_PRINTF_L
1800#endif
1801
1802#if SANITIZER_INTERCEPT_ISOC99_PRINTF
1803#define INIT_ISOC99_PRINTF                       \
1804  COMMON_INTERCEPT_FUNCTION(__isoc99_printf);    \
1805  COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf);   \
1806  COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf);  \
1807  COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf);   \
1808  COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf);   \
1809  COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf);  \
1810  COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1811  COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1812#else
1813#define INIT_ISOC99_PRINTF
1814#endif
1815
1816#if SANITIZER_INTERCEPT_IOCTL
1817#include "sanitizer_common_interceptors_ioctl.inc"
1818#include "sanitizer_interceptors_ioctl_netbsd.inc"
1819INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1820  // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1821  // can trigger a report and we need to be able to unwind through this
1822  // function.  On Mac in debug mode we might not have a frame pointer, because
1823  // ioctl_common_[pre|post] doesn't get inlined here.
1824  ENABLE_FRAME_POINTER;
1825
1826  void *ctx;
1827  va_list ap;
1828  va_start(ap, request);
1829  void *arg = va_arg(ap, void *);
1830  va_end(ap);
1831  COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1832
1833  CHECK(ioctl_initialized);
1834
1835  // Note: TSan does not use common flags, and they are zero-initialized.
1836  // This effectively disables ioctl handling in TSan.
1837  if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1838
1839  // Although request is unsigned long, the rest of the interceptor uses it
1840  // as just "unsigned" to save space, because we know that all values fit in
1841  // "unsigned" - they are compile-time constants.
1842
1843  const ioctl_desc *desc = ioctl_lookup(request);
1844  ioctl_desc decoded_desc;
1845  if (!desc) {
1846    VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request);
1847    if (!ioctl_decode(request, &decoded_desc))
1848      Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request);
1849    else
1850      desc = &decoded_desc;
1851  }
1852
1853  if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1854  int res = REAL(ioctl)(d, request, arg);
1855  // FIXME: some ioctls have different return values for success and failure.
1856  if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1857  return res;
1858}
1859#define INIT_IOCTL \
1860  ioctl_init();    \
1861  COMMON_INTERCEPT_FUNCTION(ioctl);
1862#else
1863#define INIT_IOCTL
1864#endif
1865
1866#if SANITIZER_POSIX
1867UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1868  if (pwd) {
1869    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1870    if (pwd->pw_name)
1871      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,
1872                                     internal_strlen(pwd->pw_name) + 1);
1873    if (pwd->pw_passwd)
1874      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,
1875                                     internal_strlen(pwd->pw_passwd) + 1);
1876#if !SANITIZER_ANDROID
1877    if (pwd->pw_gecos)
1878      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
1879                                     internal_strlen(pwd->pw_gecos) + 1);
1880#endif
1881#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD
1882    if (pwd->pw_class)
1883      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
1884                                     internal_strlen(pwd->pw_class) + 1);
1885#endif
1886    if (pwd->pw_dir)
1887      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,
1888                                     internal_strlen(pwd->pw_dir) + 1);
1889    if (pwd->pw_shell)
1890      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,
1891                                     internal_strlen(pwd->pw_shell) + 1);
1892  }
1893}
1894
1895UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1896  if (grp) {
1897    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1898    if (grp->gr_name)
1899      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,
1900                                     internal_strlen(grp->gr_name) + 1);
1901    if (grp->gr_passwd)
1902      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,
1903                                     internal_strlen(grp->gr_passwd) + 1);
1904    char **p = grp->gr_mem;
1905    for (; *p; ++p) {
1906      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
1907    }
1908    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,
1909                                   (p - grp->gr_mem + 1) * sizeof(*p));
1910  }
1911}
1912#endif  // SANITIZER_POSIX
1913
1914#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1915INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1916  void *ctx;
1917  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
1918  if (name)
1919    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
1920  __sanitizer_passwd *res = REAL(getpwnam)(name);
1921  unpoison_passwd(ctx, res);
1922  return res;
1923}
1924INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
1925  void *ctx;
1926  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
1927  __sanitizer_passwd *res = REAL(getpwuid)(uid);
1928  unpoison_passwd(ctx, res);
1929  return res;
1930}
1931INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
1932  void *ctx;
1933  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
1934  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
1935  __sanitizer_group *res = REAL(getgrnam)(name);
1936  unpoison_group(ctx, res);
1937  return res;
1938}
1939INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
1940  void *ctx;
1941  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
1942  __sanitizer_group *res = REAL(getgrgid)(gid);
1943  unpoison_group(ctx, res);
1944  return res;
1945}
1946#define INIT_GETPWNAM_AND_FRIENDS      \
1947  COMMON_INTERCEPT_FUNCTION(getpwnam); \
1948  COMMON_INTERCEPT_FUNCTION(getpwuid); \
1949  COMMON_INTERCEPT_FUNCTION(getgrnam); \
1950  COMMON_INTERCEPT_FUNCTION(getgrgid);
1951#else
1952#define INIT_GETPWNAM_AND_FRIENDS
1953#endif
1954
1955#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
1956INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
1957            char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
1958  void *ctx;
1959  COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
1960  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
1961  // FIXME: under ASan the call below may write to freed memory and corrupt
1962  // its metadata. See
1963  // https://github.com/google/sanitizers/issues/321.
1964  int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
1965  if (!res && result)
1966    unpoison_passwd(ctx, *result);
1967  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1968  return res;
1969}
1970INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
1971            SIZE_T buflen, __sanitizer_passwd **result) {
1972  void *ctx;
1973  COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
1974  // FIXME: under ASan the call below may write to freed memory and corrupt
1975  // its metadata. See
1976  // https://github.com/google/sanitizers/issues/321.
1977  int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
1978  if (!res && result)
1979    unpoison_passwd(ctx, *result);
1980  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1981  return res;
1982}
1983INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
1984            char *buf, SIZE_T buflen, __sanitizer_group **result) {
1985  void *ctx;
1986  COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
1987  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
1988  // FIXME: under ASan the call below may write to freed memory and corrupt
1989  // its metadata. See
1990  // https://github.com/google/sanitizers/issues/321.
1991  int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
1992  if (!res && result)
1993    unpoison_group(ctx, *result);
1994  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
1995  return res;
1996}
1997INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
1998            SIZE_T buflen, __sanitizer_group **result) {
1999  void *ctx;
2000  COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
2001  // FIXME: under ASan the call below may write to freed memory and corrupt
2002  // its metadata. See
2003  // https://github.com/google/sanitizers/issues/321.
2004  int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
2005  if (!res && result)
2006    unpoison_group(ctx, *result);
2007  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2008  return res;
2009}
2010#define INIT_GETPWNAM_R_AND_FRIENDS      \
2011  COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
2012  COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
2013  COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
2014  COMMON_INTERCEPT_FUNCTION(getgrgid_r);
2015#else
2016#define INIT_GETPWNAM_R_AND_FRIENDS
2017#endif
2018
2019#if SANITIZER_INTERCEPT_GETPWENT
2020INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
2021  void *ctx;
2022  COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
2023  __sanitizer_passwd *res = REAL(getpwent)(dummy);
2024  unpoison_passwd(ctx, res);
2025  return res;
2026}
2027INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
2028  void *ctx;
2029  COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
2030  __sanitizer_group *res = REAL(getgrent)(dummy);
2031  unpoison_group(ctx, res);
2032  return res;
2033}
2034#define INIT_GETPWENT                  \
2035  COMMON_INTERCEPT_FUNCTION(getpwent); \
2036  COMMON_INTERCEPT_FUNCTION(getgrent);
2037#else
2038#define INIT_GETPWENT
2039#endif
2040
2041#if SANITIZER_INTERCEPT_FGETPWENT
2042INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
2043  void *ctx;
2044  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
2045  __sanitizer_passwd *res = REAL(fgetpwent)(fp);
2046  unpoison_passwd(ctx, res);
2047  return res;
2048}
2049INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
2050  void *ctx;
2051  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
2052  __sanitizer_group *res = REAL(fgetgrent)(fp);
2053  unpoison_group(ctx, res);
2054  return res;
2055}
2056#define INIT_FGETPWENT                  \
2057  COMMON_INTERCEPT_FUNCTION(fgetpwent); \
2058  COMMON_INTERCEPT_FUNCTION(fgetgrent);
2059#else
2060#define INIT_FGETPWENT
2061#endif
2062
2063#if SANITIZER_INTERCEPT_GETPWENT_R
2064INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
2065            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2066  void *ctx;
2067  COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
2068  // FIXME: under ASan the call below may write to freed memory and corrupt
2069  // its metadata. See
2070  // https://github.com/google/sanitizers/issues/321.
2071  int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
2072  if (!res && pwbufp)
2073    unpoison_passwd(ctx, *pwbufp);
2074  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2075  return res;
2076}
2077INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
2078            __sanitizer_group **pwbufp) {
2079  void *ctx;
2080  COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
2081  // FIXME: under ASan the call below may write to freed memory and corrupt
2082  // its metadata. See
2083  // https://github.com/google/sanitizers/issues/321.
2084  int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
2085  if (!res && pwbufp)
2086    unpoison_group(ctx, *pwbufp);
2087  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2088  return res;
2089}
2090#define INIT_GETPWENT_R                   \
2091  COMMON_INTERCEPT_FUNCTION(getpwent_r);  \
2092  COMMON_INTERCEPT_FUNCTION(getgrent_r);
2093#else
2094#define INIT_GETPWENT_R
2095#endif
2096
2097#if SANITIZER_INTERCEPT_FGETPWENT_R
2098INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
2099            SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2100  void *ctx;
2101  COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
2102  // FIXME: under ASan the call below may write to freed memory and corrupt
2103  // its metadata. See
2104  // https://github.com/google/sanitizers/issues/321.
2105  int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
2106  if (!res && pwbufp)
2107    unpoison_passwd(ctx, *pwbufp);
2108  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2109  return res;
2110}
2111#define INIT_FGETPWENT_R                  \
2112  COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
2113#else
2114#define INIT_FGETPWENT_R
2115#endif
2116
2117#if SANITIZER_INTERCEPT_FGETGRENT_R
2118INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
2119            SIZE_T buflen, __sanitizer_group **pwbufp) {
2120  void *ctx;
2121  COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
2122  // FIXME: under ASan the call below may write to freed memory and corrupt
2123  // its metadata. See
2124  // https://github.com/google/sanitizers/issues/321.
2125  int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
2126  if (!res && pwbufp)
2127    unpoison_group(ctx, *pwbufp);
2128  if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2129  return res;
2130}
2131#define INIT_FGETGRENT_R                  \
2132  COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
2133#else
2134#define INIT_FGETGRENT_R
2135#endif
2136
2137#if SANITIZER_INTERCEPT_SETPWENT
2138// The only thing these interceptors do is disable any nested interceptors.
2139// These functions may open nss modules and call uninstrumented functions from
2140// them, and we don't want things like strlen() to trigger.
2141INTERCEPTOR(void, setpwent, int dummy) {
2142  void *ctx;
2143  COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
2144  REAL(setpwent)(dummy);
2145}
2146INTERCEPTOR(void, endpwent, int dummy) {
2147  void *ctx;
2148  COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
2149  REAL(endpwent)(dummy);
2150}
2151INTERCEPTOR(void, setgrent, int dummy) {
2152  void *ctx;
2153  COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
2154  REAL(setgrent)(dummy);
2155}
2156INTERCEPTOR(void, endgrent, int dummy) {
2157  void *ctx;
2158  COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
2159  REAL(endgrent)(dummy);
2160}
2161#define INIT_SETPWENT                  \
2162  COMMON_INTERCEPT_FUNCTION(setpwent); \
2163  COMMON_INTERCEPT_FUNCTION(endpwent); \
2164  COMMON_INTERCEPT_FUNCTION(setgrent); \
2165  COMMON_INTERCEPT_FUNCTION(endgrent);
2166#else
2167#define INIT_SETPWENT
2168#endif
2169
2170#if SANITIZER_INTERCEPT_CLOCK_GETTIME
2171INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
2172  void *ctx;
2173  COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
2174  // FIXME: under ASan the call below may write to freed memory and corrupt
2175  // its metadata. See
2176  // https://github.com/google/sanitizers/issues/321.
2177  int res = REAL(clock_getres)(clk_id, tp);
2178  if (!res && tp) {
2179    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2180  }
2181  return res;
2182}
2183INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
2184  void *ctx;
2185  COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
2186  // FIXME: under ASan the call below may write to freed memory and corrupt
2187  // its metadata. See
2188  // https://github.com/google/sanitizers/issues/321.
2189  int res = REAL(clock_gettime)(clk_id, tp);
2190  if (!res) {
2191    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2192  }
2193  return res;
2194}
2195#if SANITIZER_GLIBC
2196namespace __sanitizer {
2197extern "C" {
2198int real_clock_gettime(u32 clk_id, void *tp) {
2199  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
2200    return internal_clock_gettime(clk_id, tp);
2201  return REAL(clock_gettime)(clk_id, tp);
2202}
2203}  // extern "C"
2204}  // namespace __sanitizer
2205#endif
2206INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
2207  void *ctx;
2208  COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
2209  COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
2210  return REAL(clock_settime)(clk_id, tp);
2211}
2212#define INIT_CLOCK_GETTIME                  \
2213  COMMON_INTERCEPT_FUNCTION(clock_getres);  \
2214  COMMON_INTERCEPT_FUNCTION(clock_gettime); \
2215  COMMON_INTERCEPT_FUNCTION(clock_settime);
2216#else
2217#define INIT_CLOCK_GETTIME
2218#endif
2219
2220#if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID
2221INTERCEPTOR(int, clock_getcpuclockid, pid_t pid,
2222            __sanitizer_clockid_t *clockid) {
2223  void *ctx;
2224  COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid);
2225  int res = REAL(clock_getcpuclockid)(pid, clockid);
2226  if (!res && clockid) {
2227    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
2228  }
2229  return res;
2230}
2231
2232INTERCEPTOR(int, pthread_getcpuclockid, uptr thread,
2233            __sanitizer_clockid_t *clockid) {
2234  void *ctx;
2235  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid);
2236  int res = REAL(pthread_getcpuclockid)(thread, clockid);
2237  if (!res && clockid) {
2238    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
2239  }
2240  return res;
2241}
2242
2243#define INIT_CLOCK_GETCPUCLOCKID                   \
2244  COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid);  \
2245  COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid);
2246#else
2247#define INIT_CLOCK_GETCPUCLOCKID
2248#endif
2249
2250#if SANITIZER_INTERCEPT_GETITIMER
2251INTERCEPTOR(int, getitimer, int which, void *curr_value) {
2252  void *ctx;
2253  COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
2254  // FIXME: under ASan the call below may write to freed memory and corrupt
2255  // its metadata. See
2256  // https://github.com/google/sanitizers/issues/321.
2257  int res = REAL(getitimer)(which, curr_value);
2258  if (!res && curr_value) {
2259    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
2260  }
2261  return res;
2262}
2263INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
2264  void *ctx;
2265  COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
2266  if (new_value) {
2267    // itimerval can contain padding that may be legitimately uninitialized
2268    const struct __sanitizer_itimerval *nv =
2269        (const struct __sanitizer_itimerval *)new_value;
2270    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
2271                                  sizeof(__sanitizer_time_t));
2272    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
2273                                  sizeof(__sanitizer_suseconds_t));
2274    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
2275                                  sizeof(__sanitizer_time_t));
2276    COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
2277                                  sizeof(__sanitizer_suseconds_t));
2278  }
2279  // FIXME: under ASan the call below may write to freed memory and corrupt
2280  // its metadata. See
2281  // https://github.com/google/sanitizers/issues/321.
2282  int res = REAL(setitimer)(which, new_value, old_value);
2283  if (!res && old_value) {
2284    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
2285  }
2286  return res;
2287}
2288#define INIT_GETITIMER                  \
2289  COMMON_INTERCEPT_FUNCTION(getitimer); \
2290  COMMON_INTERCEPT_FUNCTION(setitimer);
2291#else
2292#define INIT_GETITIMER
2293#endif
2294
2295#if SANITIZER_INTERCEPT_GLOB
2296static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
2297  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
2298  // +1 for NULL pointer at the end.
2299  if (pglob->gl_pathv)
2300    COMMON_INTERCEPTOR_WRITE_RANGE(
2301        ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
2302  for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
2303    char *p = pglob->gl_pathv[i];
2304    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);
2305  }
2306}
2307
2308#if SANITIZER_SOLARIS
2309INTERCEPTOR(int, glob, const char *pattern, int flags,
2310            int (*errfunc)(const char *epath, int eerrno),
2311            __sanitizer_glob_t *pglob) {
2312  void *ctx;
2313  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2314  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2315  int res = REAL(glob)(pattern, flags, errfunc, pglob);
2316  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2317  return res;
2318}
2319#else
2320static THREADLOCAL __sanitizer_glob_t *pglob_copy;
2321
2322static void wrapped_gl_closedir(void *dir) {
2323  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2324  pglob_copy->gl_closedir(dir);
2325}
2326
2327static void *wrapped_gl_readdir(void *dir) {
2328  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2329  return pglob_copy->gl_readdir(dir);
2330}
2331
2332static void *wrapped_gl_opendir(const char *s) {
2333  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2334  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2335  return pglob_copy->gl_opendir(s);
2336}
2337
2338static int wrapped_gl_lstat(const char *s, void *st) {
2339  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2340  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2341  return pglob_copy->gl_lstat(s, st);
2342}
2343
2344static int wrapped_gl_stat(const char *s, void *st) {
2345  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2346  COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2347  return pglob_copy->gl_stat(s, st);
2348}
2349
2350static const __sanitizer_glob_t kGlobCopy = {
2351      0,                  0,                   0,
2352      0,                  wrapped_gl_closedir, wrapped_gl_readdir,
2353      wrapped_gl_opendir, wrapped_gl_lstat,    wrapped_gl_stat};
2354
2355INTERCEPTOR(int, glob, const char *pattern, int flags,
2356            int (*errfunc)(const char *epath, int eerrno),
2357            __sanitizer_glob_t *pglob) {
2358  void *ctx;
2359  COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2360  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2361  __sanitizer_glob_t glob_copy;
2362  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2363  if (flags & glob_altdirfunc) {
2364    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2365    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2366    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2367    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2368    Swap(pglob->gl_stat, glob_copy.gl_stat);
2369    pglob_copy = &glob_copy;
2370  }
2371  int res = REAL(glob)(pattern, flags, errfunc, pglob);
2372  if (flags & glob_altdirfunc) {
2373    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2374    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2375    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2376    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2377    Swap(pglob->gl_stat, glob_copy.gl_stat);
2378  }
2379  pglob_copy = 0;
2380  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2381  return res;
2382}
2383#endif  // SANITIZER_SOLARIS
2384#define INIT_GLOB                  \
2385  COMMON_INTERCEPT_FUNCTION(glob);
2386#else  // SANITIZER_INTERCEPT_GLOB
2387#define INIT_GLOB
2388#endif  // SANITIZER_INTERCEPT_GLOB
2389
2390#if SANITIZER_INTERCEPT_GLOB64
2391INTERCEPTOR(int, glob64, const char *pattern, int flags,
2392            int (*errfunc)(const char *epath, int eerrno),
2393            __sanitizer_glob_t *pglob) {
2394  void *ctx;
2395  COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
2396  COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2397  __sanitizer_glob_t glob_copy;
2398  internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2399  if (flags & glob_altdirfunc) {
2400    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2401    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2402    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2403    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2404    Swap(pglob->gl_stat, glob_copy.gl_stat);
2405    pglob_copy = &glob_copy;
2406  }
2407  int res = REAL(glob64)(pattern, flags, errfunc, pglob);
2408  if (flags & glob_altdirfunc) {
2409    Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2410    Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2411    Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2412    Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2413    Swap(pglob->gl_stat, glob_copy.gl_stat);
2414  }
2415  pglob_copy = 0;
2416  if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2417  return res;
2418}
2419#define INIT_GLOB64                \
2420  COMMON_INTERCEPT_FUNCTION(glob64);
2421#else  // SANITIZER_INTERCEPT_GLOB64
2422#define INIT_GLOB64
2423#endif  // SANITIZER_INTERCEPT_GLOB64
2424
2425#if SANITIZER_INTERCEPT_POSIX_SPAWN
2426
2427template <class RealSpawnPtr>
2428static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,
2429                          const char *file_or_path, const void *file_actions,
2430                          const void *attrp, char *const argv[],
2431                          char *const envp[]) {
2432  COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,
2433                                internal_strlen(file_or_path) + 1);
2434  if (argv) {
2435    for (char *const *s = argv; ; ++s) {
2436      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
2437      if (!*s) break;
2438      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2439    }
2440  }
2441  if (envp) {
2442    for (char *const *s = envp; ; ++s) {
2443      COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
2444      if (!*s) break;
2445      COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2446    }
2447  }
2448  int res =
2449      real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);
2450  if (res == 0)
2451    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));
2452  return res;
2453}
2454INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,
2455            const void *file_actions, const void *attrp, char *const argv[],
2456            char *const envp[]) {
2457  void *ctx;
2458  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,
2459                           argv, envp);
2460  return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,
2461                        argv, envp);
2462}
2463INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,
2464            const void *file_actions, const void *attrp, char *const argv[],
2465            char *const envp[]) {
2466  void *ctx;
2467  COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,
2468                           argv, envp);
2469  return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,
2470                        argv, envp);
2471}
2472#  define INIT_POSIX_SPAWN                  \
2473    COMMON_INTERCEPT_FUNCTION(posix_spawn); \
2474    COMMON_INTERCEPT_FUNCTION(posix_spawnp);
2475#else  // SANITIZER_INTERCEPT_POSIX_SPAWN
2476#  define INIT_POSIX_SPAWN
2477#endif  // SANITIZER_INTERCEPT_POSIX_SPAWN
2478
2479#if SANITIZER_INTERCEPT_WAIT
2480// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
2481// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
2482// details.
2483INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
2484  void *ctx;
2485  COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
2486  // FIXME: under ASan the call below may write to freed memory and corrupt
2487  // its metadata. See
2488  // https://github.com/google/sanitizers/issues/321.
2489  int res = REAL(wait)(status);
2490  if (res != -1 && status)
2491    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2492  return res;
2493}
2494// On FreeBSD id_t is always 64-bit wide.
2495#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
2496INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
2497                        int options) {
2498#else
2499INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
2500                        int options) {
2501#endif
2502  void *ctx;
2503  COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
2504  // FIXME: under ASan the call below may write to freed memory and corrupt
2505  // its metadata. See
2506  // https://github.com/google/sanitizers/issues/321.
2507  int res = REAL(waitid)(idtype, id, infop, options);
2508  if (res != -1 && infop)
2509    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
2510  return res;
2511}
2512INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
2513  void *ctx;
2514  COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
2515  // FIXME: under ASan the call below may write to freed memory and corrupt
2516  // its metadata. See
2517  // https://github.com/google/sanitizers/issues/321.
2518  int res = REAL(waitpid)(pid, status, options);
2519  if (res != -1 && status)
2520    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2521  return res;
2522}
2523INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
2524  void *ctx;
2525  COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
2526  // FIXME: under ASan the call below may write to freed memory and corrupt
2527  // its metadata. See
2528  // https://github.com/google/sanitizers/issues/321.
2529  int res = REAL(wait3)(status, options, rusage);
2530  if (res != -1) {
2531    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2532    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2533  }
2534  return res;
2535}
2536#if SANITIZER_ANDROID
2537INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
2538  void *ctx;
2539  COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
2540  // FIXME: under ASan the call below may write to freed memory and corrupt
2541  // its metadata. See
2542  // https://github.com/google/sanitizers/issues/321.
2543  int res = REAL(__wait4)(pid, status, options, rusage);
2544  if (res != -1) {
2545    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2546    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2547  }
2548  return res;
2549}
2550#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
2551#else
2552INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
2553  void *ctx;
2554  COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
2555  // FIXME: under ASan the call below may write to freed memory and corrupt
2556  // its metadata. See
2557  // https://github.com/google/sanitizers/issues/321.
2558  int res = REAL(wait4)(pid, status, options, rusage);
2559  if (res != -1) {
2560    if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2561    if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2562  }
2563  return res;
2564}
2565#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
2566#endif  // SANITIZER_ANDROID
2567#define INIT_WAIT                     \
2568  COMMON_INTERCEPT_FUNCTION(wait);    \
2569  COMMON_INTERCEPT_FUNCTION(waitid);  \
2570  COMMON_INTERCEPT_FUNCTION(waitpid); \
2571  COMMON_INTERCEPT_FUNCTION(wait3);
2572#else
2573#define INIT_WAIT
2574#define INIT_WAIT4
2575#endif
2576
2577#if SANITIZER_INTERCEPT_INET
2578INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
2579  void *ctx;
2580  COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
2581  uptr sz = __sanitizer_in_addr_sz(af);
2582  if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
2583  // FIXME: figure out read size based on the address family.
2584  // FIXME: under ASan the call below may write to freed memory and corrupt
2585  // its metadata. See
2586  // https://github.com/google/sanitizers/issues/321.
2587  char *res = REAL(inet_ntop)(af, src, dst, size);
2588  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
2589  return res;
2590}
2591INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
2592  void *ctx;
2593  COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
2594  COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
2595  // FIXME: figure out read size based on the address family.
2596  // FIXME: under ASan the call below may write to freed memory and corrupt
2597  // its metadata. See
2598  // https://github.com/google/sanitizers/issues/321.
2599  int res = REAL(inet_pton)(af, src, dst);
2600  if (res == 1) {
2601    uptr sz = __sanitizer_in_addr_sz(af);
2602    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2603  }
2604  return res;
2605}
2606#define INIT_INET                       \
2607  COMMON_INTERCEPT_FUNCTION(inet_ntop); \
2608  COMMON_INTERCEPT_FUNCTION(inet_pton);
2609#else
2610#define INIT_INET
2611#endif
2612
2613#if SANITIZER_INTERCEPT_INET
2614INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
2615  void *ctx;
2616  COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
2617  if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1);
2618  // FIXME: under ASan the call below may write to freed memory and corrupt
2619  // its metadata. See
2620  // https://github.com/google/sanitizers/issues/321.
2621  int res = REAL(inet_aton)(cp, dst);
2622  if (res != 0) {
2623    uptr sz = __sanitizer_in_addr_sz(af_inet);
2624    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2625  }
2626  return res;
2627}
2628#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
2629#else
2630#define INIT_INET_ATON
2631#endif
2632
2633#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
2634INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
2635  void *ctx;
2636  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
2637  // FIXME: under ASan the call below may write to freed memory and corrupt
2638  // its metadata. See
2639  // https://github.com/google/sanitizers/issues/321.
2640  int res = REAL(pthread_getschedparam)(thread, policy, param);
2641  if (res == 0) {
2642    if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
2643    if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
2644  }
2645  return res;
2646}
2647#define INIT_PTHREAD_GETSCHEDPARAM \
2648  COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
2649#else
2650#define INIT_PTHREAD_GETSCHEDPARAM
2651#endif
2652
2653#if SANITIZER_INTERCEPT_GETADDRINFO
2654INTERCEPTOR(int, getaddrinfo, char *node, char *service,
2655            struct __sanitizer_addrinfo *hints,
2656            struct __sanitizer_addrinfo **out) {
2657  void *ctx;
2658  COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
2659  if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1);
2660  if (service)
2661    COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1);
2662  if (hints)
2663    COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
2664  // FIXME: under ASan the call below may write to freed memory and corrupt
2665  // its metadata. See
2666  // https://github.com/google/sanitizers/issues/321.
2667  int res = REAL(getaddrinfo)(node, service, hints, out);
2668  if (res == 0 && out) {
2669    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
2670    struct __sanitizer_addrinfo *p = *out;
2671    while (p) {
2672      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2673      if (p->ai_addr)
2674        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
2675      if (p->ai_canonname)
2676        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
2677                                       internal_strlen(p->ai_canonname) + 1);
2678      p = p->ai_next;
2679    }
2680  }
2681  return res;
2682}
2683#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
2684#else
2685#define INIT_GETADDRINFO
2686#endif
2687
2688#if SANITIZER_INTERCEPT_GETNAMEINFO
2689INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
2690            unsigned hostlen, char *serv, unsigned servlen, int flags) {
2691  void *ctx;
2692  COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
2693                           serv, servlen, flags);
2694  // FIXME: consider adding READ_RANGE(sockaddr, salen)
2695  // There is padding in in_addr that may make this too noisy
2696  // FIXME: under ASan the call below may write to freed memory and corrupt
2697  // its metadata. See
2698  // https://github.com/google/sanitizers/issues/321.
2699  int res =
2700      REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
2701  if (res == 0) {
2702    if (host && hostlen)
2703      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1);
2704    if (serv && servlen)
2705      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1);
2706  }
2707  return res;
2708}
2709#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
2710#else
2711#define INIT_GETNAMEINFO
2712#endif
2713
2714#if SANITIZER_INTERCEPT_GETSOCKNAME
2715INTERCEPTOR(int, getsockname, int sock_fd, void *addr, unsigned *addrlen) {
2716  void *ctx;
2717  COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
2718  unsigned addr_sz;
2719  if (addrlen) {
2720    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2721    addr_sz = *addrlen;
2722  }
2723  // FIXME: under ASan the call below may write to freed memory and corrupt
2724  // its metadata. See
2725  // https://github.com/google/sanitizers/issues/321.
2726  int res = REAL(getsockname)(sock_fd, addr, addrlen);
2727  if (!res && addr && addrlen) {
2728    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2729  }
2730  return res;
2731}
2732#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2733#else
2734#define INIT_GETSOCKNAME
2735#endif
2736
2737#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2738static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2739  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2740  if (h->h_name)
2741    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1);
2742  char **p = h->h_aliases;
2743  while (*p) {
2744    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
2745    ++p;
2746  }
2747  COMMON_INTERCEPTOR_WRITE_RANGE(
2748      ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2749  p = h->h_addr_list;
2750  while (*p) {
2751    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2752    ++p;
2753  }
2754  COMMON_INTERCEPTOR_WRITE_RANGE(
2755      ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2756}
2757#endif
2758
2759#if SANITIZER_INTERCEPT_GETHOSTBYNAME
2760INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2761  void *ctx;
2762  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2763  struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2764  if (res) write_hostent(ctx, res);
2765  return res;
2766}
2767
2768INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2769            int type) {
2770  void *ctx;
2771  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2772  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2773  struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2774  if (res) write_hostent(ctx, res);
2775  return res;
2776}
2777
2778INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2779  void *ctx;
2780  COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2781  struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2782  if (res) write_hostent(ctx, res);
2783  return res;
2784}
2785#define INIT_GETHOSTBYNAME                  \
2786  COMMON_INTERCEPT_FUNCTION(gethostent);    \
2787  COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2788  COMMON_INTERCEPT_FUNCTION(gethostbyname);
2789#else
2790#define INIT_GETHOSTBYNAME
2791#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME
2792
2793#if SANITIZER_INTERCEPT_GETHOSTBYNAME2
2794INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2795  void *ctx;
2796  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2797  struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2798  if (res) write_hostent(ctx, res);
2799  return res;
2800}
2801#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2802#else
2803#define INIT_GETHOSTBYNAME2
2804#endif  // SANITIZER_INTERCEPT_GETHOSTBYNAME2
2805
2806#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2807INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2808            char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2809            int *h_errnop) {
2810  void *ctx;
2811  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2812                           h_errnop);
2813  // FIXME: under ASan the call below may write to freed memory and corrupt
2814  // its metadata. See
2815  // https://github.com/google/sanitizers/issues/321.
2816  int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2817  if (result) {
2818    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2819    if (res == 0 && *result) write_hostent(ctx, *result);
2820  }
2821  if (h_errnop)
2822    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2823  return res;
2824}
2825#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2826#else
2827#define INIT_GETHOSTBYNAME_R
2828#endif
2829
2830#if SANITIZER_INTERCEPT_GETHOSTENT_R
2831INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2832            SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2833  void *ctx;
2834  COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2835                           h_errnop);
2836  // FIXME: under ASan the call below may write to freed memory and corrupt
2837  // its metadata. See
2838  // https://github.com/google/sanitizers/issues/321.
2839  int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2840  if (result) {
2841    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2842    if (res == 0 && *result) write_hostent(ctx, *result);
2843  }
2844  if (h_errnop)
2845    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2846  return res;
2847}
2848#define INIT_GETHOSTENT_R                  \
2849  COMMON_INTERCEPT_FUNCTION(gethostent_r);
2850#else
2851#define INIT_GETHOSTENT_R
2852#endif
2853
2854#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
2855INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
2856            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2857            __sanitizer_hostent **result, int *h_errnop) {
2858  void *ctx;
2859  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
2860                           buflen, result, h_errnop);
2861  COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2862  // FIXME: under ASan the call below may write to freed memory and corrupt
2863  // its metadata. See
2864  // https://github.com/google/sanitizers/issues/321.
2865  int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
2866                                  h_errnop);
2867  if (result) {
2868    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2869    if (res == 0 && *result) write_hostent(ctx, *result);
2870  }
2871  if (h_errnop)
2872    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2873  return res;
2874}
2875#define INIT_GETHOSTBYADDR_R                  \
2876  COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
2877#else
2878#define INIT_GETHOSTBYADDR_R
2879#endif
2880
2881#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
2882INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
2883            struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
2884            __sanitizer_hostent **result, int *h_errnop) {
2885  void *ctx;
2886  COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
2887                           result, h_errnop);
2888  // FIXME: under ASan the call below may write to freed memory and corrupt
2889  // its metadata. See
2890  // https://github.com/google/sanitizers/issues/321.
2891  int res =
2892      REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
2893  if (result) {
2894    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2895    if (res == 0 && *result) write_hostent(ctx, *result);
2896  }
2897  if (h_errnop)
2898    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2899  return res;
2900}
2901#define INIT_GETHOSTBYNAME2_R                  \
2902  COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
2903#else
2904#define INIT_GETHOSTBYNAME2_R
2905#endif
2906
2907#if SANITIZER_INTERCEPT_GETSOCKOPT
2908INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
2909            int *optlen) {
2910  void *ctx;
2911  COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
2912                           optlen);
2913  if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
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  int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
2918  if (res == 0)
2919    if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
2920  return res;
2921}
2922#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
2923#else
2924#define INIT_GETSOCKOPT
2925#endif
2926
2927#if SANITIZER_INTERCEPT_ACCEPT
2928INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
2929  void *ctx;
2930  COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
2931  unsigned addrlen0 = 0;
2932  if (addrlen) {
2933    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2934    addrlen0 = *addrlen;
2935  }
2936  int fd2 = REAL(accept)(fd, addr, addrlen);
2937  if (fd2 >= 0) {
2938    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2939    if (addr && addrlen)
2940      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2941  }
2942  return fd2;
2943}
2944#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
2945#else
2946#define INIT_ACCEPT
2947#endif
2948
2949#if SANITIZER_INTERCEPT_ACCEPT4
2950INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
2951  void *ctx;
2952  COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
2953  unsigned addrlen0 = 0;
2954  if (addrlen) {
2955    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2956    addrlen0 = *addrlen;
2957  }
2958  // FIXME: under ASan the call below may write to freed memory and corrupt
2959  // its metadata. See
2960  // https://github.com/google/sanitizers/issues/321.
2961  int fd2 = REAL(accept4)(fd, addr, addrlen, f);
2962  if (fd2 >= 0) {
2963    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2964    if (addr && addrlen)
2965      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2966  }
2967  return fd2;
2968}
2969#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
2970#else
2971#define INIT_ACCEPT4
2972#endif
2973
2974#if SANITIZER_INTERCEPT_PACCEPT
2975INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,
2976            __sanitizer_sigset_t *set, int f) {
2977  void *ctx;
2978  COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);
2979  unsigned addrlen0 = 0;
2980  if (addrlen) {
2981    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2982    addrlen0 = *addrlen;
2983  }
2984  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
2985  int fd2 = REAL(paccept)(fd, addr, addrlen, set, f);
2986  if (fd2 >= 0) {
2987    if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
2988    if (addr && addrlen)
2989      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
2990  }
2991  return fd2;
2992}
2993#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);
2994#else
2995#define INIT_PACCEPT
2996#endif
2997
2998#if SANITIZER_INTERCEPT_MODF
2999INTERCEPTOR(double, modf, double x, double *iptr) {
3000  void *ctx;
3001  COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
3002  // FIXME: under ASan the call below may write to freed memory and corrupt
3003  // its metadata. See
3004  // https://github.com/google/sanitizers/issues/321.
3005  double res = REAL(modf)(x, iptr);
3006  if (iptr) {
3007    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3008  }
3009  return res;
3010}
3011INTERCEPTOR(float, modff, float x, float *iptr) {
3012  void *ctx;
3013  COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
3014  // FIXME: under ASan the call below may write to freed memory and corrupt
3015  // its metadata. See
3016  // https://github.com/google/sanitizers/issues/321.
3017  float res = REAL(modff)(x, iptr);
3018  if (iptr) {
3019    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3020  }
3021  return res;
3022}
3023INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
3024  void *ctx;
3025  COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
3026  // FIXME: under ASan the call below may write to freed memory and corrupt
3027  // its metadata. See
3028  // https://github.com/google/sanitizers/issues/321.
3029  long double res = REAL(modfl)(x, iptr);
3030  if (iptr) {
3031    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3032  }
3033  return res;
3034}
3035#define INIT_MODF                   \
3036  COMMON_INTERCEPT_FUNCTION(modf);  \
3037  COMMON_INTERCEPT_FUNCTION(modff); \
3038  COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
3039#else
3040#define INIT_MODF
3041#endif
3042
3043#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG
3044static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
3045                         SSIZE_T maxlen) {
3046  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
3047  if (msg->msg_name && msg->msg_namelen)
3048    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
3049  if (msg->msg_iov && msg->msg_iovlen)
3050    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
3051                                   sizeof(*msg->msg_iov) * msg->msg_iovlen);
3052  write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
3053  if (msg->msg_control && msg->msg_controllen)
3054    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
3055}
3056#endif
3057
3058#if SANITIZER_INTERCEPT_RECVMSG
3059INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
3060            int flags) {
3061  void *ctx;
3062  COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
3063  // FIXME: under ASan the call below may write to freed memory and corrupt
3064  // its metadata. See
3065  // https://github.com/google/sanitizers/issues/321.
3066  SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
3067  if (res >= 0) {
3068    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3069    if (msg) {
3070      write_msghdr(ctx, msg, res);
3071      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
3072    }
3073  }
3074  return res;
3075}
3076#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
3077#else
3078#define INIT_RECVMSG
3079#endif
3080
3081#if SANITIZER_INTERCEPT_RECVMMSG
3082INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
3083            unsigned int vlen, int flags, void *timeout) {
3084  void *ctx;
3085  COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);
3086  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
3087  int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);
3088  if (res >= 0) {
3089    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3090    for (int i = 0; i < res; ++i) {
3091      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
3092                                     sizeof(msgvec[i].msg_len));
3093      write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
3094      COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);
3095    }
3096  }
3097  return res;
3098}
3099#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);
3100#else
3101#define INIT_RECVMMSG
3102#endif
3103
3104#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG
3105static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
3106  const unsigned kCmsgDataOffset =
3107      RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
3108
3109  char *p = (char *)control;
3110  char *const control_end = p + controllen;
3111  while (true) {
3112    if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
3113    __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
3114    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
3115
3116    if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
3117
3118    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
3119                                  sizeof(cmsg->cmsg_level));
3120    COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
3121                                  sizeof(cmsg->cmsg_type));
3122
3123    if (cmsg->cmsg_len > kCmsgDataOffset) {
3124      char *data = p + kCmsgDataOffset;
3125      unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
3126      if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
3127    }
3128
3129    p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
3130  }
3131}
3132
3133static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
3134                        SSIZE_T maxlen) {
3135#define R(f) \
3136  COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
3137  R(name);
3138  R(namelen);
3139  R(iov);
3140  R(iovlen);
3141  R(control);
3142  R(controllen);
3143  R(flags);
3144#undef R
3145  if (msg->msg_name && msg->msg_namelen)
3146    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
3147  if (msg->msg_iov && msg->msg_iovlen)
3148    COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
3149                                  sizeof(*msg->msg_iov) * msg->msg_iovlen);
3150  read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
3151  if (msg->msg_control && msg->msg_controllen)
3152    read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
3153}
3154#endif
3155
3156#if SANITIZER_INTERCEPT_SENDMSG
3157INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
3158            int flags) {
3159  void *ctx;
3160  COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
3161  if (fd >= 0) {
3162    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3163    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3164  }
3165  SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
3166  if (common_flags()->intercept_send && res >= 0 && msg)
3167    read_msghdr(ctx, msg, res);
3168  return res;
3169}
3170#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
3171#else
3172#define INIT_SENDMSG
3173#endif
3174
3175#if SANITIZER_INTERCEPT_SENDMMSG
3176INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
3177            unsigned vlen, int flags) {
3178  void *ctx;
3179  COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);
3180  if (fd >= 0) {
3181    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3182    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3183  }
3184  int res = REAL(sendmmsg)(fd, msgvec, vlen, flags);
3185  if (res >= 0 && msgvec) {
3186    for (int i = 0; i < res; ++i) {
3187      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
3188                                     sizeof(msgvec[i].msg_len));
3189      if (common_flags()->intercept_send)
3190        read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
3191    }
3192  }
3193  return res;
3194}
3195#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);
3196#else
3197#define INIT_SENDMMSG
3198#endif
3199
3200#if SANITIZER_INTERCEPT_SYSMSG
3201INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz,
3202            int msgflg) {
3203  void *ctx;
3204  COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg);
3205  if (msgp)
3206    COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz);
3207  int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg);
3208  return res;
3209}
3210
3211INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz,
3212            long msgtyp, int msgflg) {
3213  void *ctx;
3214  COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg);
3215  SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg);
3216  if (len != -1)
3217    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len);
3218  return len;
3219}
3220
3221#define INIT_SYSMSG                  \
3222  COMMON_INTERCEPT_FUNCTION(msgsnd); \
3223  COMMON_INTERCEPT_FUNCTION(msgrcv);
3224#else
3225#define INIT_SYSMSG
3226#endif
3227
3228#if SANITIZER_INTERCEPT_GETPEERNAME
3229INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
3230  void *ctx;
3231  COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
3232  unsigned addr_sz;
3233  if (addrlen) {
3234    COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
3235    addr_sz = *addrlen;
3236  }
3237  // FIXME: under ASan the call below may write to freed memory and corrupt
3238  // its metadata. See
3239  // https://github.com/google/sanitizers/issues/321.
3240  int res = REAL(getpeername)(sockfd, addr, addrlen);
3241  if (!res && addr && addrlen) {
3242    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
3243  }
3244  return res;
3245}
3246#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
3247#else
3248#define INIT_GETPEERNAME
3249#endif
3250
3251#if SANITIZER_INTERCEPT_SYSINFO
3252INTERCEPTOR(int, sysinfo, void *info) {
3253  void *ctx;
3254  // FIXME: under ASan the call below may write to freed memory and corrupt
3255  // its metadata. See
3256  // https://github.com/google/sanitizers/issues/321.
3257  COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
3258  int res = REAL(sysinfo)(info);
3259  if (!res && info)
3260    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
3261  return res;
3262}
3263#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
3264#else
3265#define INIT_SYSINFO
3266#endif
3267
3268#if SANITIZER_INTERCEPT_READDIR
3269INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
3270  void *ctx;
3271  COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
3272  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3273  __sanitizer_dirent *res = REAL(opendir)(path);
3274  if (res)
3275    COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
3276  return res;
3277}
3278
3279INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
3280  void *ctx;
3281  COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
3282  // FIXME: under ASan the call below may write to freed memory and corrupt
3283  // its metadata. See
3284  // https://github.com/google/sanitizers/issues/321.
3285  __sanitizer_dirent *res = REAL(readdir)(dirp);
3286  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3287  return res;
3288}
3289
3290INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
3291            __sanitizer_dirent **result) {
3292  void *ctx;
3293  COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
3294  // FIXME: under ASan the call below may write to freed memory and corrupt
3295  // its metadata. See
3296  // https://github.com/google/sanitizers/issues/321.
3297  int res = REAL(readdir_r)(dirp, entry, result);
3298  if (!res) {
3299    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3300    if (*result)
3301      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3302  }
3303  return res;
3304}
3305
3306#define INIT_READDIR                  \
3307  COMMON_INTERCEPT_FUNCTION(opendir); \
3308  COMMON_INTERCEPT_FUNCTION(readdir); \
3309  COMMON_INTERCEPT_FUNCTION(readdir_r);
3310#else
3311#define INIT_READDIR
3312#endif
3313
3314#if SANITIZER_INTERCEPT_READDIR64
3315INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
3316  void *ctx;
3317  COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
3318  // FIXME: under ASan the call below may write to freed memory and corrupt
3319  // its metadata. See
3320  // https://github.com/google/sanitizers/issues/321.
3321  __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
3322  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3323  return res;
3324}
3325
3326INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
3327            __sanitizer_dirent64 **result) {
3328  void *ctx;
3329  COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
3330  // FIXME: under ASan the call below may write to freed memory and corrupt
3331  // its metadata. See
3332  // https://github.com/google/sanitizers/issues/321.
3333  int res = REAL(readdir64_r)(dirp, entry, result);
3334  if (!res) {
3335    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3336    if (*result)
3337      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3338  }
3339  return res;
3340}
3341#define INIT_READDIR64                  \
3342  COMMON_INTERCEPT_FUNCTION(readdir64); \
3343  COMMON_INTERCEPT_FUNCTION(readdir64_r);
3344#else
3345#define INIT_READDIR64
3346#endif
3347
3348#if SANITIZER_INTERCEPT_PTRACE
3349INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
3350  void *ctx;
3351  COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
3352  __sanitizer_iovec local_iovec;
3353
3354  if (data) {
3355    if (request == ptrace_setregs) {
3356      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
3357    } else if (request == ptrace_setfpregs) {
3358      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3359    } else if (request == ptrace_setfpxregs) {
3360      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3361    } else if (request == ptrace_setvfpregs) {
3362      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3363    } else if (request == ptrace_setsiginfo) {
3364      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
3365
3366    // Some kernel might zero the iovec::iov_base in case of invalid
3367    // write access.  In this case copy the invalid address for further
3368    // inspection.
3369    } else if (request == ptrace_setregset || request == ptrace_getregset) {
3370      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3371      COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
3372      local_iovec = *iovec;
3373      if (request == ptrace_setregset)
3374        COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
3375    }
3376  }
3377
3378  // FIXME: under ASan the call below may write to freed memory and corrupt
3379  // its metadata. See
3380  // https://github.com/google/sanitizers/issues/321.
3381  uptr res = REAL(ptrace)(request, pid, addr, data);
3382
3383  if (!res && data) {
3384    // Note that PEEK* requests assign different meaning to the return value.
3385    // This function does not handle them (nor does it need to).
3386    if (request == ptrace_getregs) {
3387      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
3388    } else if (request == ptrace_getfpregs) {
3389      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3390    } else if (request == ptrace_getfpxregs) {
3391      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3392    } else if (request == ptrace_getvfpregs) {
3393      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3394    } else if (request == ptrace_getsiginfo) {
3395      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
3396    } else if (request == ptrace_geteventmsg) {
3397      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
3398    } else if (request == ptrace_getregset) {
3399      __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3400      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
3401      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
3402                                     local_iovec.iov_len);
3403    }
3404  }
3405  return res;
3406}
3407
3408#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
3409#else
3410#define INIT_PTRACE
3411#endif
3412
3413#if SANITIZER_INTERCEPT_SETLOCALE
3414static void unpoison_ctype_arrays(void *ctx) {
3415#if SANITIZER_NETBSD
3416  // These arrays contain 256 regular elements in unsigned char range + 1 EOF
3417  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
3418  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
3419  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
3420#endif
3421}
3422
3423INTERCEPTOR(char *, setlocale, int category, char *locale) {
3424  void *ctx;
3425  COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
3426  if (locale)
3427    COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1);
3428  char *res = REAL(setlocale)(category, locale);
3429  if (res) {
3430    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
3431    unpoison_ctype_arrays(ctx);
3432  }
3433  return res;
3434}
3435
3436#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
3437#else
3438#define INIT_SETLOCALE
3439#endif
3440
3441#if SANITIZER_INTERCEPT_GETCWD
3442INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
3443  void *ctx;
3444  COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
3445  // FIXME: under ASan the call below may write to freed memory and corrupt
3446  // its metadata. See
3447  // https://github.com/google/sanitizers/issues/321.
3448  char *res = REAL(getcwd)(buf, size);
3449  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3450  return res;
3451}
3452#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
3453#else
3454#define INIT_GETCWD
3455#endif
3456
3457#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
3458INTERCEPTOR(char *, get_current_dir_name, int fake) {
3459  void *ctx;
3460  COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
3461  // FIXME: under ASan the call below may write to freed memory and corrupt
3462  // its metadata. See
3463  // https://github.com/google/sanitizers/issues/321.
3464  char *res = REAL(get_current_dir_name)(fake);
3465  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3466  return res;
3467}
3468
3469#define INIT_GET_CURRENT_DIR_NAME \
3470  COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
3471#else
3472#define INIT_GET_CURRENT_DIR_NAME
3473#endif
3474
3475UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
3476  CHECK(endptr);
3477  if (nptr == *endptr) {
3478    // No digits were found at strtol call, we need to find out the last
3479    // symbol accessed by strtoll on our own.
3480    // We get this symbol by skipping leading blanks and optional +/- sign.
3481    while (IsSpace(*nptr)) nptr++;
3482    if (*nptr == '+' || *nptr == '-') nptr++;
3483    *endptr = const_cast<char *>(nptr);
3484  }
3485  CHECK(*endptr >= nptr);
3486}
3487
3488UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
3489                             char **endptr, char *real_endptr, int base) {
3490  if (endptr) {
3491    *endptr = real_endptr;
3492    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
3493  }
3494  // If base has unsupported value, strtol can exit with EINVAL
3495  // without reading any characters. So do additional checks only
3496  // if base is valid.
3497  bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
3498  if (is_valid_base) {
3499    FixRealStrtolEndptr(nptr, &real_endptr);
3500  }
3501  COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
3502                                 (real_endptr - nptr) + 1 : 0);
3503}
3504
3505
3506#if SANITIZER_INTERCEPT_STRTOIMAX
3507INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
3508  void *ctx;
3509  COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
3510  // FIXME: under ASan the call below may write to freed memory and corrupt
3511  // its metadata. See
3512  // https://github.com/google/sanitizers/issues/321.
3513  char *real_endptr;
3514  INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
3515  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3516  return res;
3517}
3518
3519INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
3520  void *ctx;
3521  COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
3522  // FIXME: under ASan the call below may write to freed memory and corrupt
3523  // its metadata. See
3524  // https://github.com/google/sanitizers/issues/321.
3525  char *real_endptr;
3526  UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
3527  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3528  return res;
3529}
3530
3531#define INIT_STRTOIMAX                  \
3532  COMMON_INTERCEPT_FUNCTION(strtoimax); \
3533  COMMON_INTERCEPT_FUNCTION(strtoumax);
3534#else
3535#define INIT_STRTOIMAX
3536#endif
3537
3538#if SANITIZER_INTERCEPT_MBSTOWCS
3539INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
3540  void *ctx;
3541  COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
3542  // FIXME: under ASan the call below may write to freed memory and corrupt
3543  // its metadata. See
3544  // https://github.com/google/sanitizers/issues/321.
3545  SIZE_T res = REAL(mbstowcs)(dest, src, len);
3546  if (res != (SIZE_T) - 1 && dest) {
3547    SIZE_T write_cnt = res + (res < len);
3548    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3549  }
3550  return res;
3551}
3552
3553INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
3554            void *ps) {
3555  void *ctx;
3556  COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
3557  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3558  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3559  // FIXME: under ASan the call below may write to freed memory and corrupt
3560  // its metadata. See
3561  // https://github.com/google/sanitizers/issues/321.
3562  SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
3563  if (res != (SIZE_T)(-1) && dest && src) {
3564    // This function, and several others, may or may not write the terminating
3565    // \0 character. They write it iff they clear *src.
3566    SIZE_T write_cnt = res + !*src;
3567    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3568  }
3569  return res;
3570}
3571
3572#define INIT_MBSTOWCS                  \
3573  COMMON_INTERCEPT_FUNCTION(mbstowcs); \
3574  COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
3575#else
3576#define INIT_MBSTOWCS
3577#endif
3578
3579#if SANITIZER_INTERCEPT_MBSNRTOWCS
3580INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
3581            SIZE_T len, void *ps) {
3582  void *ctx;
3583  COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
3584  if (src) {
3585    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3586    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3587  }
3588  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3589  // FIXME: under ASan the call below may write to freed memory and corrupt
3590  // its metadata. See
3591  // https://github.com/google/sanitizers/issues/321.
3592  SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
3593  if (res != (SIZE_T)(-1) && dest && src) {
3594    SIZE_T write_cnt = res + !*src;
3595    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3596  }
3597  return res;
3598}
3599
3600#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
3601#else
3602#define INIT_MBSNRTOWCS
3603#endif
3604
3605#if SANITIZER_INTERCEPT_WCSTOMBS
3606INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
3607  void *ctx;
3608  COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
3609  // FIXME: under ASan the call below may write to freed memory and corrupt
3610  // its metadata. See
3611  // https://github.com/google/sanitizers/issues/321.
3612  SIZE_T res = REAL(wcstombs)(dest, src, len);
3613  if (res != (SIZE_T) - 1 && dest) {
3614    SIZE_T write_cnt = res + (res < len);
3615    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3616  }
3617  return res;
3618}
3619
3620INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
3621            void *ps) {
3622  void *ctx;
3623  COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
3624  if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3625  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3626  // FIXME: under ASan the call below may write to freed memory and corrupt
3627  // its metadata. See
3628  // https://github.com/google/sanitizers/issues/321.
3629  SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
3630  if (res != (SIZE_T) - 1 && dest && src) {
3631    SIZE_T write_cnt = res + !*src;
3632    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3633  }
3634  return res;
3635}
3636
3637#define INIT_WCSTOMBS                  \
3638  COMMON_INTERCEPT_FUNCTION(wcstombs); \
3639  COMMON_INTERCEPT_FUNCTION(wcsrtombs);
3640#else
3641#define INIT_WCSTOMBS
3642#endif
3643
3644#if SANITIZER_INTERCEPT_WCSNRTOMBS
3645INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
3646            SIZE_T len, void *ps) {
3647  void *ctx;
3648  COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
3649  if (src) {
3650    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3651    if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3652  }
3653  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3654  // FIXME: under ASan the call below may write to freed memory and corrupt
3655  // its metadata. See
3656  // https://github.com/google/sanitizers/issues/321.
3657  SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
3658  if (res != ((SIZE_T)-1) && dest && src) {
3659    SIZE_T write_cnt = res + !*src;
3660    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3661  }
3662  return res;
3663}
3664
3665#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
3666#else
3667#define INIT_WCSNRTOMBS
3668#endif
3669
3670
3671#if SANITIZER_INTERCEPT_WCRTOMB
3672INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
3673  void *ctx;
3674  COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
3675  if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3676
3677  if (!dest)
3678    return REAL(wcrtomb)(dest, src, ps);
3679
3680  char local_dest[32];
3681  SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
3682  if (res != ((SIZE_T)-1)) {
3683    CHECK_LE(res, sizeof(local_dest));
3684    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3685    REAL(memcpy)(dest, local_dest, res);
3686  }
3687  return res;
3688}
3689
3690#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
3691#else
3692#define INIT_WCRTOMB
3693#endif
3694
3695#if SANITIZER_INTERCEPT_WCTOMB
3696INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
3697  void *ctx;
3698  COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
3699  if (!dest)
3700    return REAL(wctomb)(dest, src);
3701
3702  char local_dest[32];
3703  int res = REAL(wctomb)(local_dest, src);
3704  if (res != -1) {
3705    CHECK_LE(res, sizeof(local_dest));
3706    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3707    REAL(memcpy)(dest, local_dest, res);
3708  }
3709  return res;
3710}
3711
3712#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
3713#else
3714#define INIT_WCTOMB
3715#endif
3716
3717#if SANITIZER_INTERCEPT_TCGETATTR
3718INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
3719  void *ctx;
3720  COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
3721  // FIXME: under ASan the call below may write to freed memory and corrupt
3722  // its metadata. See
3723  // https://github.com/google/sanitizers/issues/321.
3724  int res = REAL(tcgetattr)(fd, termios_p);
3725  if (!res && termios_p)
3726    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
3727  return res;
3728}
3729
3730#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
3731#else
3732#define INIT_TCGETATTR
3733#endif
3734
3735#if SANITIZER_INTERCEPT_REALPATH
3736INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
3737  void *ctx;
3738  COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
3739  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3740
3741  // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
3742  // version of a versioned symbol. For realpath(), this gives us something
3743  // (called __old_realpath) that does not handle NULL in the second argument.
3744  // Handle it as part of the interceptor.
3745  char *allocated_path = nullptr;
3746  if (!resolved_path)
3747    allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
3748
3749  char *res = REAL(realpath)(path, resolved_path);
3750  if (allocated_path && !res)
3751    WRAP(free)(allocated_path);
3752  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3753  return res;
3754}
3755#  define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
3756#else
3757#define INIT_REALPATH
3758#endif
3759
3760#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
3761INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
3762  void *ctx;
3763  COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
3764  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3765  char *res = REAL(canonicalize_file_name)(path);
3766  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3767  return res;
3768}
3769#define INIT_CANONICALIZE_FILE_NAME \
3770  COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
3771#else
3772#define INIT_CANONICALIZE_FILE_NAME
3773#endif
3774
3775#if SANITIZER_INTERCEPT_CONFSTR
3776INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
3777  void *ctx;
3778  COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
3779  // FIXME: under ASan the call below may write to freed memory and corrupt
3780  // its metadata. See
3781  // https://github.com/google/sanitizers/issues/321.
3782  SIZE_T res = REAL(confstr)(name, buf, len);
3783  if (buf && res)
3784    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
3785  return res;
3786}
3787#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
3788#else
3789#define INIT_CONFSTR
3790#endif
3791
3792#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
3793INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
3794  void *ctx;
3795  COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
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(sched_getaffinity)(pid, cpusetsize, mask);
3800  if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
3801  return res;
3802}
3803#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
3804#else
3805#define INIT_SCHED_GETAFFINITY
3806#endif
3807
3808#if SANITIZER_INTERCEPT_SCHED_GETPARAM
3809INTERCEPTOR(int, sched_getparam, int pid, void *param) {
3810  void *ctx;
3811  COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
3812  int res = REAL(sched_getparam)(pid, param);
3813  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
3814  return res;
3815}
3816#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
3817#else
3818#define INIT_SCHED_GETPARAM
3819#endif
3820
3821#if SANITIZER_INTERCEPT_STRERROR
3822INTERCEPTOR(char *, strerror, int errnum) {
3823  void *ctx;
3824  COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
3825  COMMON_INTERCEPTOR_STRERROR();
3826  char *res = REAL(strerror)(errnum);
3827  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
3828  return res;
3829}
3830#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
3831#else
3832#define INIT_STRERROR
3833#endif
3834
3835#if SANITIZER_INTERCEPT_STRERROR_R
3836// There are 2 versions of strerror_r:
3837//  * POSIX version returns 0 on success, negative error code on failure,
3838//    writes message to buf.
3839//  * GNU version returns message pointer, which points to either buf or some
3840//    static storage.
3841#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
3842    SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD ||                 \
3843    SANITIZER_FREEBSD
3844// POSIX version. Spec is not clear on whether buf is NULL-terminated.
3845// At least on OSX, buf contents are valid even when the call fails.
3846INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
3847  void *ctx;
3848  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
3849  // FIXME: under ASan the call below may write to freed memory and corrupt
3850  // its metadata. See
3851  // https://github.com/google/sanitizers/issues/321.
3852  int res = REAL(strerror_r)(errnum, buf, buflen);
3853
3854  SIZE_T sz = internal_strnlen(buf, buflen);
3855  if (sz < buflen) ++sz;
3856  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
3857  return res;
3858}
3859#else
3860// GNU version.
3861INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
3862  void *ctx;
3863  COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
3864  // FIXME: under ASan the call below may write to freed memory and corrupt
3865  // its metadata. See
3866  // https://github.com/google/sanitizers/issues/321.
3867  char *res = REAL(strerror_r)(errnum, buf, buflen);
3868  if (res == buf)
3869    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3870  else
3871    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
3872  return res;
3873}
3874#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
3875       //SANITIZER_MAC
3876#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
3877#else
3878#define INIT_STRERROR_R
3879#endif
3880
3881#if SANITIZER_INTERCEPT_XPG_STRERROR_R
3882INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
3883  void *ctx;
3884  COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
3885  // FIXME: under ASan the call below may write to freed memory and corrupt
3886  // its metadata. See
3887  // https://github.com/google/sanitizers/issues/321.
3888  int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
3889  // This version always returns a null-terminated string.
3890  if (buf && buflen)
3891    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
3892  return res;
3893}
3894#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
3895#else
3896#define INIT_XPG_STRERROR_R
3897#endif
3898
3899#if SANITIZER_INTERCEPT_SCANDIR
3900typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
3901typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
3902                                const struct __sanitizer_dirent **);
3903
3904static THREADLOCAL scandir_filter_f scandir_filter;
3905static THREADLOCAL scandir_compar_f scandir_compar;
3906
3907static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
3908  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3909  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3910  return scandir_filter(dir);
3911}
3912
3913static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
3914                                  const struct __sanitizer_dirent **b) {
3915  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3916  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3917  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3918  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3919  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3920  return scandir_compar(a, b);
3921}
3922
3923INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
3924            scandir_filter_f filter, scandir_compar_f compar) {
3925  void *ctx;
3926  COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
3927  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
3928  scandir_filter = filter;
3929  scandir_compar = compar;
3930  // FIXME: under ASan the call below may write to freed memory and corrupt
3931  // its metadata. See
3932  // https://github.com/google/sanitizers/issues/321.
3933  int res = REAL(scandir)(dirp, namelist,
3934                          filter ? wrapped_scandir_filter : nullptr,
3935                          compar ? wrapped_scandir_compar : nullptr);
3936  scandir_filter = nullptr;
3937  scandir_compar = nullptr;
3938  if (namelist && res > 0) {
3939    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3940    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3941    for (int i = 0; i < res; ++i)
3942      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3943                                     (*namelist)[i]->d_reclen);
3944  }
3945  return res;
3946}
3947#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
3948#else
3949#define INIT_SCANDIR
3950#endif
3951
3952#if SANITIZER_INTERCEPT_SCANDIR64
3953typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
3954typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
3955                                  const struct __sanitizer_dirent64 **);
3956
3957static THREADLOCAL scandir64_filter_f scandir64_filter;
3958static THREADLOCAL scandir64_compar_f scandir64_compar;
3959
3960static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
3961  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
3962  COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
3963  return scandir64_filter(dir);
3964}
3965
3966static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
3967                                    const struct __sanitizer_dirent64 **b) {
3968  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
3969  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
3970  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
3971  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
3972  COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
3973  return scandir64_compar(a, b);
3974}
3975
3976INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
3977            scandir64_filter_f filter, scandir64_compar_f compar) {
3978  void *ctx;
3979  COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
3980  if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
3981  scandir64_filter = filter;
3982  scandir64_compar = compar;
3983  // FIXME: under ASan the call below may write to freed memory and corrupt
3984  // its metadata. See
3985  // https://github.com/google/sanitizers/issues/321.
3986  int res =
3987      REAL(scandir64)(dirp, namelist,
3988                      filter ? wrapped_scandir64_filter : nullptr,
3989                      compar ? wrapped_scandir64_compar : nullptr);
3990  scandir64_filter = nullptr;
3991  scandir64_compar = nullptr;
3992  if (namelist && res > 0) {
3993    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
3994    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
3995    for (int i = 0; i < res; ++i)
3996      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
3997                                     (*namelist)[i]->d_reclen);
3998  }
3999  return res;
4000}
4001#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
4002#else
4003#define INIT_SCANDIR64
4004#endif
4005
4006#if SANITIZER_INTERCEPT_GETGROUPS
4007INTERCEPTOR(int, getgroups, int size, u32 *lst) {
4008  void *ctx;
4009  COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
4010  // FIXME: under ASan the call below may write to freed memory and corrupt
4011  // its metadata. See
4012  // https://github.com/google/sanitizers/issues/321.
4013  int res = REAL(getgroups)(size, lst);
4014  if (res >= 0 && lst && size > 0)
4015    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
4016  return res;
4017}
4018#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
4019#else
4020#define INIT_GETGROUPS
4021#endif
4022
4023#if SANITIZER_INTERCEPT_POLL
4024static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
4025                        __sanitizer_nfds_t nfds) {
4026  for (unsigned i = 0; i < nfds; ++i) {
4027    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
4028    COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
4029  }
4030}
4031
4032static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
4033                         __sanitizer_nfds_t nfds) {
4034  for (unsigned i = 0; i < nfds; ++i)
4035    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
4036                                   sizeof(fds[i].revents));
4037}
4038
4039INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
4040            int timeout) {
4041  void *ctx;
4042  COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
4043  if (fds && nfds) read_pollfd(ctx, fds, nfds);
4044  int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
4045  if (fds && nfds) write_pollfd(ctx, fds, nfds);
4046  return res;
4047}
4048#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
4049#else
4050#define INIT_POLL
4051#endif
4052
4053#if SANITIZER_INTERCEPT_PPOLL
4054INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
4055            void *timeout_ts, __sanitizer_sigset_t *sigmask) {
4056  void *ctx;
4057  COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
4058  if (fds && nfds) read_pollfd(ctx, fds, nfds);
4059  if (timeout_ts)
4060    COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
4061  if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));
4062  int res =
4063      COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
4064  if (fds && nfds) write_pollfd(ctx, fds, nfds);
4065  return res;
4066}
4067#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
4068#else
4069#define INIT_PPOLL
4070#endif
4071
4072#if SANITIZER_INTERCEPT_WORDEXP
4073INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
4074  void *ctx;
4075  COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
4076  if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
4077  // FIXME: under ASan the call below may write to freed memory and corrupt
4078  // its metadata. See
4079  // https://github.com/google/sanitizers/issues/321.
4080  int res = REAL(wordexp)(s, p, flags);
4081  if (!res && p) {
4082    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4083    uptr we_wordc =
4084        ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc;
4085    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
4086                                   sizeof(*p->we_wordv) * (we_wordc + 1));
4087    for (uptr i = 0; i < we_wordc; ++i) {
4088      char *w = p->we_wordv[i];
4089      if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);
4090    }
4091  }
4092  return res;
4093}
4094#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
4095#else
4096#define INIT_WORDEXP
4097#endif
4098
4099#if SANITIZER_INTERCEPT_SIGWAIT
4100INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
4101  void *ctx;
4102  COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
4103  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4104  // FIXME: under ASan the call below may write to freed memory and corrupt
4105  // its metadata. See
4106  // https://github.com/google/sanitizers/issues/321.
4107  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);
4108  if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
4109  return res;
4110}
4111#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
4112#else
4113#define INIT_SIGWAIT
4114#endif
4115
4116#if SANITIZER_INTERCEPT_SIGWAITINFO
4117INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
4118  void *ctx;
4119  COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
4120  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4121  // FIXME: under ASan the call below may write to freed memory and corrupt
4122  // its metadata. See
4123  // https://github.com/google/sanitizers/issues/321.
4124  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);
4125  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
4126  return res;
4127}
4128#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
4129#else
4130#define INIT_SIGWAITINFO
4131#endif
4132
4133#if SANITIZER_INTERCEPT_SIGTIMEDWAIT
4134INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
4135            void *timeout) {
4136  void *ctx;
4137  COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
4138  if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
4139  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4140  // FIXME: under ASan the call below may write to freed memory and corrupt
4141  // its metadata. See
4142  // https://github.com/google/sanitizers/issues/321.
4143  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);
4144  if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
4145  return res;
4146}
4147#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
4148#else
4149#define INIT_SIGTIMEDWAIT
4150#endif
4151
4152#if SANITIZER_INTERCEPT_SIGSETOPS
4153INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
4154  void *ctx;
4155  COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
4156  // FIXME: under ASan the call below may write to freed memory and corrupt
4157  // its metadata. See
4158  // https://github.com/google/sanitizers/issues/321.
4159  int res = REAL(sigemptyset)(set);
4160  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4161  return res;
4162}
4163
4164INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
4165  void *ctx;
4166  COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
4167  // FIXME: under ASan the call below may write to freed memory and corrupt
4168  // its metadata. See
4169  // https://github.com/google/sanitizers/issues/321.
4170  int res = REAL(sigfillset)(set);
4171  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4172  return res;
4173}
4174#define INIT_SIGSETOPS                    \
4175  COMMON_INTERCEPT_FUNCTION(sigemptyset); \
4176  COMMON_INTERCEPT_FUNCTION(sigfillset);
4177#else
4178#define INIT_SIGSETOPS
4179#endif
4180
4181#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS
4182INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,
4183            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4184  void *ctx;
4185  COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);
4186  if (src1)
4187    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4188  if (src2)
4189    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4190  int res = REAL(sigandset)(dst, src1, src2);
4191  if (!res && dst)
4192    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4193  return res;
4194}
4195
4196INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,
4197            __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4198  void *ctx;
4199  COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);
4200  if (src1)
4201    COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4202  if (src2)
4203    COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4204  int res = REAL(sigorset)(dst, src1, src2);
4205  if (!res && dst)
4206    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4207  return res;
4208}
4209#define INIT_SIGSET_LOGICOPS                    \
4210  COMMON_INTERCEPT_FUNCTION(sigandset);   \
4211  COMMON_INTERCEPT_FUNCTION(sigorset);
4212#else
4213#define INIT_SIGSET_LOGICOPS
4214#endif
4215
4216#if SANITIZER_INTERCEPT_SIGPENDING
4217INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
4218  void *ctx;
4219  COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
4220  // FIXME: under ASan the call below may write to freed memory and corrupt
4221  // its metadata. See
4222  // https://github.com/google/sanitizers/issues/321.
4223  int res = REAL(sigpending)(set);
4224  if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4225  return res;
4226}
4227#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
4228#else
4229#define INIT_SIGPENDING
4230#endif
4231
4232#if SANITIZER_INTERCEPT_SIGPROCMASK
4233INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
4234            __sanitizer_sigset_t *oldset) {
4235  void *ctx;
4236  COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
4237  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4238  // FIXME: under ASan the call below may write to freed memory and corrupt
4239  // its metadata. See
4240  // https://github.com/google/sanitizers/issues/321.
4241  int res = REAL(sigprocmask)(how, set, oldset);
4242  if (!res && oldset)
4243    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4244  return res;
4245}
4246#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
4247#else
4248#define INIT_SIGPROCMASK
4249#endif
4250
4251#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
4252INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
4253            __sanitizer_sigset_t *oldset) {
4254  void *ctx;
4255  COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
4256  if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4257  // FIXME: under ASan the call below may write to freed memory and corrupt
4258  // its metadata. See
4259  // https://github.com/google/sanitizers/issues/321.
4260  int res = REAL(pthread_sigmask)(how, set, oldset);
4261  if (!res && oldset)
4262    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4263  return res;
4264}
4265#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
4266#else
4267#define INIT_PTHREAD_SIGMASK
4268#endif
4269
4270#if SANITIZER_INTERCEPT_BACKTRACE
4271INTERCEPTOR(int, backtrace, void **buffer, int size) {
4272  void *ctx;
4273  COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
4274  // FIXME: under ASan the call below may write to freed memory and corrupt
4275  // its metadata. See
4276  // https://github.com/google/sanitizers/issues/321.
4277  int res = REAL(backtrace)(buffer, size);
4278  if (res && buffer)
4279    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
4280  return res;
4281}
4282
4283INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
4284  void *ctx;
4285  COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
4286  if (buffer && size)
4287    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
4288  // FIXME: under ASan the call below may write to freed memory and corrupt
4289  // its metadata. See
4290  // https://github.com/google/sanitizers/issues/321.
4291  char **res = REAL(backtrace_symbols)(buffer, size);
4292  if (res && size) {
4293    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
4294    for (int i = 0; i < size; ++i)
4295      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1);
4296  }
4297  return res;
4298}
4299#define INIT_BACKTRACE                  \
4300  COMMON_INTERCEPT_FUNCTION(backtrace); \
4301  COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
4302#else
4303#define INIT_BACKTRACE
4304#endif
4305
4306#if SANITIZER_INTERCEPT__EXIT
4307INTERCEPTOR(void, _exit, int status) {
4308  void *ctx;
4309  COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
4310  COMMON_INTERCEPTOR_USER_CALLBACK_START();
4311  int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
4312  COMMON_INTERCEPTOR_USER_CALLBACK_END();
4313  if (status == 0) status = status1;
4314  REAL(_exit)(status);
4315}
4316#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
4317#else
4318#define INIT__EXIT
4319#endif
4320
4321#if SANITIZER_INTERCEPT_PTHREAD_MUTEX
4322INTERCEPTOR(int, pthread_mutex_lock, void *m) {
4323  void *ctx;
4324  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
4325  COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4326  int res = REAL(pthread_mutex_lock)(m);
4327  if (res == errno_EOWNERDEAD)
4328    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4329  if (res == 0 || res == errno_EOWNERDEAD)
4330    COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4331  if (res == errno_EINVAL)
4332    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4333  return res;
4334}
4335
4336INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
4337  void *ctx;
4338  COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
4339  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4340  int res = REAL(pthread_mutex_unlock)(m);
4341  if (res == errno_EINVAL)
4342    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4343  return res;
4344}
4345
4346#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
4347#define INIT_PTHREAD_MUTEX_UNLOCK \
4348  COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
4349#else
4350#define INIT_PTHREAD_MUTEX_LOCK
4351#define INIT_PTHREAD_MUTEX_UNLOCK
4352#endif
4353
4354#if SANITIZER_INTERCEPT___PTHREAD_MUTEX
4355INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
4356  void *ctx;
4357  COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m);
4358  COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4359  int res = REAL(__pthread_mutex_lock)(m);
4360  if (res == errno_EOWNERDEAD)
4361    COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4362  if (res == 0 || res == errno_EOWNERDEAD)
4363    COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4364  if (res == errno_EINVAL)
4365    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4366  return res;
4367}
4368
4369INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
4370  void *ctx;
4371  COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m);
4372  COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4373  int res = REAL(__pthread_mutex_unlock)(m);
4374  if (res == errno_EINVAL)
4375    COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4376  return res;
4377}
4378
4379#define INIT___PTHREAD_MUTEX_LOCK \
4380  COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock)
4381#define INIT___PTHREAD_MUTEX_UNLOCK \
4382  COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock)
4383#else
4384#define INIT___PTHREAD_MUTEX_LOCK
4385#define INIT___PTHREAD_MUTEX_UNLOCK
4386#endif
4387
4388#if SANITIZER_INTERCEPT___LIBC_MUTEX
4389INTERCEPTOR(int, __libc_mutex_lock, void *m)
4390ALIAS(WRAPPER_NAME(pthread_mutex_lock));
4391
4392INTERCEPTOR(int, __libc_mutex_unlock, void *m)
4393ALIAS(WRAPPER_NAME(pthread_mutex_unlock));
4394
4395INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
4396ALIAS(WRAPPER_NAME(pthread_setcancelstate));
4397
4398#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock)
4399#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock)
4400#define INIT___LIBC_THR_SETCANCELSTATE \
4401  COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
4402#else
4403#define INIT___LIBC_MUTEX_LOCK
4404#define INIT___LIBC_MUTEX_UNLOCK
4405#define INIT___LIBC_THR_SETCANCELSTATE
4406#endif
4407
4408#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
4409static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
4410  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
4411  if (mnt->mnt_fsname)
4412    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
4413                                   internal_strlen(mnt->mnt_fsname) + 1);
4414  if (mnt->mnt_dir)
4415    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
4416                                   internal_strlen(mnt->mnt_dir) + 1);
4417  if (mnt->mnt_type)
4418    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
4419                                   internal_strlen(mnt->mnt_type) + 1);
4420  if (mnt->mnt_opts)
4421    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
4422                                   internal_strlen(mnt->mnt_opts) + 1);
4423}
4424#endif
4425
4426#if SANITIZER_INTERCEPT_GETMNTENT
4427INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
4428  void *ctx;
4429  COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
4430  __sanitizer_mntent *res = REAL(getmntent)(fp);
4431  if (res) write_mntent(ctx, res);
4432  return res;
4433}
4434#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
4435#else
4436#define INIT_GETMNTENT
4437#endif
4438
4439#if SANITIZER_INTERCEPT_GETMNTENT_R
4440INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
4441            __sanitizer_mntent *mntbuf, char *buf, int buflen) {
4442  void *ctx;
4443  COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
4444  __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
4445  if (res) write_mntent(ctx, res);
4446  return res;
4447}
4448#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
4449#else
4450#define INIT_GETMNTENT_R
4451#endif
4452
4453#if SANITIZER_INTERCEPT_STATFS
4454INTERCEPTOR(int, statfs, char *path, void *buf) {
4455  void *ctx;
4456  COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
4457  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4458  // FIXME: under ASan the call below may write to freed memory and corrupt
4459  // its metadata. See
4460  // https://github.com/google/sanitizers/issues/321.
4461  int res = REAL(statfs)(path, buf);
4462  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4463  return res;
4464}
4465INTERCEPTOR(int, fstatfs, int fd, void *buf) {
4466  void *ctx;
4467  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
4468  // FIXME: under ASan the call below may write to freed memory and corrupt
4469  // its metadata. See
4470  // https://github.com/google/sanitizers/issues/321.
4471  int res = REAL(fstatfs)(fd, buf);
4472  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4473  return res;
4474}
4475#define INIT_STATFS                  \
4476  COMMON_INTERCEPT_FUNCTION(statfs); \
4477  COMMON_INTERCEPT_FUNCTION(fstatfs);
4478#else
4479#define INIT_STATFS
4480#endif
4481
4482#if SANITIZER_INTERCEPT_STATFS64
4483INTERCEPTOR(int, statfs64, char *path, void *buf) {
4484  void *ctx;
4485  COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
4486  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4487  // FIXME: under ASan the call below may write to freed memory and corrupt
4488  // its metadata. See
4489  // https://github.com/google/sanitizers/issues/321.
4490  int res = REAL(statfs64)(path, buf);
4491  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4492  return res;
4493}
4494INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
4495  void *ctx;
4496  COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
4497  // FIXME: under ASan the call below may write to freed memory and corrupt
4498  // its metadata. See
4499  // https://github.com/google/sanitizers/issues/321.
4500  int res = REAL(fstatfs64)(fd, buf);
4501  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4502  return res;
4503}
4504#define INIT_STATFS64                  \
4505  COMMON_INTERCEPT_FUNCTION(statfs64); \
4506  COMMON_INTERCEPT_FUNCTION(fstatfs64);
4507#else
4508#define INIT_STATFS64
4509#endif
4510
4511#if SANITIZER_INTERCEPT_STATVFS
4512INTERCEPTOR(int, statvfs, char *path, void *buf) {
4513  void *ctx;
4514  COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
4515  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4516  // FIXME: under ASan the call below may write to freed memory and corrupt
4517  // its metadata. See
4518  // https://github.com/google/sanitizers/issues/321.
4519  int res = REAL(statvfs)(path, buf);
4520  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4521  return res;
4522}
4523INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
4524  void *ctx;
4525  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
4526  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
4527  // FIXME: under ASan the call below may write to freed memory and corrupt
4528  // its metadata. See
4529  // https://github.com/google/sanitizers/issues/321.
4530  int res = REAL(fstatvfs)(fd, buf);
4531  if (!res) {
4532    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4533    if (fd >= 0)
4534      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
4535  }
4536  return res;
4537}
4538#define INIT_STATVFS                  \
4539  COMMON_INTERCEPT_FUNCTION(statvfs); \
4540  COMMON_INTERCEPT_FUNCTION(fstatvfs);
4541#else
4542#define INIT_STATVFS
4543#endif
4544
4545#if SANITIZER_INTERCEPT_STATVFS64
4546INTERCEPTOR(int, statvfs64, char *path, void *buf) {
4547  void *ctx;
4548  COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
4549  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4550  // FIXME: under ASan the call below may write to freed memory and corrupt
4551  // its metadata. See
4552  // https://github.com/google/sanitizers/issues/321.
4553  int res = REAL(statvfs64)(path, buf);
4554  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4555  return res;
4556}
4557INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
4558  void *ctx;
4559  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
4560  // FIXME: under ASan the call below may write to freed memory and corrupt
4561  // its metadata. See
4562  // https://github.com/google/sanitizers/issues/321.
4563  int res = REAL(fstatvfs64)(fd, buf);
4564  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4565  return res;
4566}
4567#define INIT_STATVFS64                  \
4568  COMMON_INTERCEPT_FUNCTION(statvfs64); \
4569  COMMON_INTERCEPT_FUNCTION(fstatvfs64);
4570#else
4571#define INIT_STATVFS64
4572#endif
4573
4574#if SANITIZER_INTERCEPT_INITGROUPS
4575INTERCEPTOR(int, initgroups, char *user, u32 group) {
4576  void *ctx;
4577  COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
4578  if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1);
4579  int res = REAL(initgroups)(user, group);
4580  return res;
4581}
4582#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
4583#else
4584#define INIT_INITGROUPS
4585#endif
4586
4587#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
4588INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
4589  void *ctx;
4590  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
4591  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4592  char *res = REAL(ether_ntoa)(addr);
4593  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
4594  return res;
4595}
4596INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
4597  void *ctx;
4598  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
4599  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
4600  __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
4601  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
4602  return res;
4603}
4604#define INIT_ETHER_NTOA_ATON             \
4605  COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
4606  COMMON_INTERCEPT_FUNCTION(ether_aton);
4607#else
4608#define INIT_ETHER_NTOA_ATON
4609#endif
4610
4611#if SANITIZER_INTERCEPT_ETHER_HOST
4612INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
4613  void *ctx;
4614  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
4615  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4616  // FIXME: under ASan the call below may write to freed memory and corrupt
4617  // its metadata. See
4618  // https://github.com/google/sanitizers/issues/321.
4619  int res = REAL(ether_ntohost)(hostname, addr);
4620  if (!res && hostname)
4621    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4622  return res;
4623}
4624INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
4625  void *ctx;
4626  COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
4627  if (hostname)
4628    COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4629  // FIXME: under ASan the call below may write to freed memory and corrupt
4630  // its metadata. See
4631  // https://github.com/google/sanitizers/issues/321.
4632  int res = REAL(ether_hostton)(hostname, addr);
4633  if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4634  return res;
4635}
4636INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
4637            char *hostname) {
4638  void *ctx;
4639  COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
4640  if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1);
4641  // FIXME: under ASan the call below may write to freed memory and corrupt
4642  // its metadata. See
4643  // https://github.com/google/sanitizers/issues/321.
4644  int res = REAL(ether_line)(line, addr, hostname);
4645  if (!res) {
4646    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4647    if (hostname)
4648      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4649  }
4650  return res;
4651}
4652#define INIT_ETHER_HOST                     \
4653  COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
4654  COMMON_INTERCEPT_FUNCTION(ether_hostton); \
4655  COMMON_INTERCEPT_FUNCTION(ether_line);
4656#else
4657#define INIT_ETHER_HOST
4658#endif
4659
4660#if SANITIZER_INTERCEPT_ETHER_R
4661INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
4662  void *ctx;
4663  COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
4664  if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4665  // FIXME: under ASan the call below may write to freed memory and corrupt
4666  // its metadata. See
4667  // https://github.com/google/sanitizers/issues/321.
4668  char *res = REAL(ether_ntoa_r)(addr, buf);
4669  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
4670  return res;
4671}
4672INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
4673            __sanitizer_ether_addr *addr) {
4674  void *ctx;
4675  COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
4676  if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
4677  // FIXME: under ASan the call below may write to freed memory and corrupt
4678  // its metadata. See
4679  // https://github.com/google/sanitizers/issues/321.
4680  __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
4681  if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
4682  return res;
4683}
4684#define INIT_ETHER_R                       \
4685  COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
4686  COMMON_INTERCEPT_FUNCTION(ether_aton_r);
4687#else
4688#define INIT_ETHER_R
4689#endif
4690
4691#if SANITIZER_INTERCEPT_SHMCTL
4692INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
4693  void *ctx;
4694  COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
4695  // FIXME: under ASan the call below may write to freed memory and corrupt
4696  // its metadata. See
4697  // https://github.com/google/sanitizers/issues/321.
4698  int res = REAL(shmctl)(shmid, cmd, buf);
4699  if (res >= 0) {
4700    unsigned sz = 0;
4701    if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
4702      sz = sizeof(__sanitizer_shmid_ds);
4703    else if (cmd == shmctl_ipc_info)
4704      sz = struct_shminfo_sz;
4705    else if (cmd == shmctl_shm_info)
4706      sz = struct_shm_info_sz;
4707    if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
4708  }
4709  return res;
4710}
4711#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
4712#else
4713#define INIT_SHMCTL
4714#endif
4715
4716#if SANITIZER_INTERCEPT_RANDOM_R
4717INTERCEPTOR(int, random_r, void *buf, u32 *result) {
4718  void *ctx;
4719  COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
4720  // FIXME: under ASan the call below may write to freed memory and corrupt
4721  // its metadata. See
4722  // https://github.com/google/sanitizers/issues/321.
4723  int res = REAL(random_r)(buf, result);
4724  if (!res && result)
4725    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4726  return res;
4727}
4728#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
4729#else
4730#define INIT_RANDOM_R
4731#endif
4732
4733// FIXME: under ASan the REAL() call below may write to freed memory and corrupt
4734// its metadata. See
4735// https://github.com/google/sanitizers/issues/321.
4736#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET ||              \
4737    SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED ||        \
4738    SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
4739    SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET ||         \
4740    SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET ||        \
4741    SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET ||          \
4742    SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
4743#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz)            \
4744  INTERCEPTOR(int, fn, void *attr, void *r) {                  \
4745    void *ctx;                                                 \
4746    COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r);                \
4747    int res = REAL(fn)(attr, r);                               \
4748    if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
4749    return res;                                                \
4750  }
4751#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
4752  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
4753#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
4754  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
4755#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
4756  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
4757#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
4758  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
4759#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
4760  INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
4761#endif
4762
4763#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
4764INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
4765INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
4766INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
4767INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
4768INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
4769  void *ctx;
4770  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
4771  // FIXME: under ASan the call below may write to freed memory and corrupt
4772  // its metadata. See
4773  // https://github.com/google/sanitizers/issues/321.
4774  int res = REAL(pthread_attr_getstack)(attr, addr, size);
4775  if (!res) {
4776    if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4777    if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
4778  }
4779  return res;
4780}
4781
4782// We may need to call the real pthread_attr_getstack from the run-time
4783// in sanitizer_common, but we don't want to include the interception headers
4784// there. So, just define this function here.
4785namespace __sanitizer {
4786extern "C" {
4787int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
4788  return REAL(pthread_attr_getstack)(attr, addr, size);
4789}
4790}  // extern "C"
4791}  // namespace __sanitizer
4792
4793#define INIT_PTHREAD_ATTR_GET                             \
4794  COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
4795  COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize);   \
4796  COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope);       \
4797  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize);   \
4798  COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
4799#else
4800#define INIT_PTHREAD_ATTR_GET
4801#endif
4802
4803#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED
4804INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
4805INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
4806
4807#define INIT_PTHREAD_ATTR_GET_SCHED                      \
4808  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
4809  COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);
4810#else
4811#define INIT_PTHREAD_ATTR_GET_SCHED
4812#endif
4813
4814#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
4815INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
4816
4817#define INIT_PTHREAD_ATTR_GETINHERITSCHED \
4818  COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
4819#else
4820#define INIT_PTHREAD_ATTR_GETINHERITSCHED
4821#endif
4822
4823#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
4824INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
4825            void *cpuset) {
4826  void *ctx;
4827  COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
4828                           cpuset);
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(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
4833  if (!res && cpusetsize && cpuset)
4834    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
4835  return res;
4836}
4837
4838#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
4839  COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
4840#else
4841#define INIT_PTHREAD_ATTR_GETAFFINITY_NP
4842#endif
4843
4844#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
4845INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
4846#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
4847  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
4848#else
4849#define INIT_PTHREAD_MUTEXATTR_GETPSHARED
4850#endif
4851
4852#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
4853INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
4854#define INIT_PTHREAD_MUTEXATTR_GETTYPE \
4855  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
4856#else
4857#define INIT_PTHREAD_MUTEXATTR_GETTYPE
4858#endif
4859
4860#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
4861INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
4862#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
4863  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
4864#else
4865#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
4866#endif
4867
4868#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4869INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
4870#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
4871  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
4872#else
4873#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
4874#endif
4875
4876#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
4877INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
4878#define INIT_PTHREAD_MUTEXATTR_GETROBUST \
4879  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
4880#else
4881#define INIT_PTHREAD_MUTEXATTR_GETROBUST
4882#endif
4883
4884#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
4885INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
4886#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
4887  COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
4888#else
4889#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
4890#endif
4891
4892#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
4893INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
4894#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
4895  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
4896#else
4897#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
4898#endif
4899
4900#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
4901INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
4902#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
4903  COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
4904#else
4905#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
4906#endif
4907
4908#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
4909INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
4910#define INIT_PTHREAD_CONDATTR_GETPSHARED \
4911  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
4912#else
4913#define INIT_PTHREAD_CONDATTR_GETPSHARED
4914#endif
4915
4916#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
4917INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
4918#define INIT_PTHREAD_CONDATTR_GETCLOCK \
4919  COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
4920#else
4921#define INIT_PTHREAD_CONDATTR_GETCLOCK
4922#endif
4923
4924#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
4925INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
4926#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
4927  COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
4928#else
4929#define INIT_PTHREAD_BARRIERATTR_GETPSHARED
4930#endif
4931
4932#if SANITIZER_INTERCEPT_TMPNAM
4933INTERCEPTOR(char *, tmpnam, char *s) {
4934  void *ctx;
4935  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
4936  char *res = REAL(tmpnam)(s);
4937  if (res) {
4938    if (s)
4939      // FIXME: under ASan the call below may write to freed memory and corrupt
4940      // its metadata. See
4941      // https://github.com/google/sanitizers/issues/321.
4942      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
4943    else
4944      COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
4945  }
4946  return res;
4947}
4948#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
4949#else
4950#define INIT_TMPNAM
4951#endif
4952
4953#if SANITIZER_INTERCEPT_TMPNAM_R
4954INTERCEPTOR(char *, tmpnam_r, char *s) {
4955  void *ctx;
4956  COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
4957  // FIXME: under ASan the call below may write to freed memory and corrupt
4958  // its metadata. See
4959  // https://github.com/google/sanitizers/issues/321.
4960  char *res = REAL(tmpnam_r)(s);
4961  if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
4962  return res;
4963}
4964#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
4965#else
4966#define INIT_TMPNAM_R
4967#endif
4968
4969#if SANITIZER_INTERCEPT_PTSNAME
4970INTERCEPTOR(char *, ptsname, int fd) {
4971  void *ctx;
4972  COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);
4973  char *res = REAL(ptsname)(fd);
4974  if (res != nullptr)
4975    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
4976  return res;
4977}
4978#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);
4979#else
4980#define INIT_PTSNAME
4981#endif
4982
4983#if SANITIZER_INTERCEPT_PTSNAME_R
4984INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {
4985  void *ctx;
4986  COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);
4987  int res = REAL(ptsname_r)(fd, name, namesize);
4988  if (res == 0)
4989    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
4990  return res;
4991}
4992#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);
4993#else
4994#define INIT_PTSNAME_R
4995#endif
4996
4997#if SANITIZER_INTERCEPT_TTYNAME
4998INTERCEPTOR(char *, ttyname, int fd) {
4999  void *ctx;
5000  COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);
5001  char *res = REAL(ttyname)(fd);
5002  if (res != nullptr)
5003    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5004  return res;
5005}
5006#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);
5007#else
5008#define INIT_TTYNAME
5009#endif
5010
5011#if SANITIZER_INTERCEPT_TTYNAME_R
5012INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
5013  void *ctx;
5014  COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);
5015  int res = REAL(ttyname_r)(fd, name, namesize);
5016  if (res == 0)
5017    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
5018  return res;
5019}
5020#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);
5021#else
5022#define INIT_TTYNAME_R
5023#endif
5024
5025#if SANITIZER_INTERCEPT_TEMPNAM
5026INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
5027  void *ctx;
5028  COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
5029  if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1);
5030  if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1);
5031  char *res = REAL(tempnam)(dir, pfx);
5032  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5033  return res;
5034}
5035#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
5036#else
5037#define INIT_TEMPNAM
5038#endif
5039
5040#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
5041INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
5042  void *ctx;
5043  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
5044  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
5045  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
5046  return REAL(pthread_setname_np)(thread, name);
5047}
5048#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
5049#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
5050INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
5051  void *ctx;
5052  char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
5053  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
5054  COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
5055  internal_snprintf(newname, sizeof(newname), name, arg);
5056  COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
5057  return REAL(pthread_setname_np)(thread, name, arg);
5058}
5059#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
5060#else
5061#define INIT_PTHREAD_SETNAME_NP
5062#endif
5063
5064#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP
5065INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {
5066  void *ctx;
5067  COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);
5068  int res = REAL(pthread_getname_np)(thread, name, len);
5069  if (!res)
5070    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);
5071  return res;
5072}
5073#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);
5074#else
5075#define INIT_PTHREAD_GETNAME_NP
5076#endif
5077
5078#if SANITIZER_INTERCEPT_SINCOS
5079INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
5080  void *ctx;
5081  COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
5082  // FIXME: under ASan the call below may write to freed memory and corrupt
5083  // its metadata. See
5084  // https://github.com/google/sanitizers/issues/321.
5085  REAL(sincos)(x, sin, cos);
5086  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5087  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5088}
5089INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
5090  void *ctx;
5091  COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
5092  // FIXME: under ASan the call below may write to freed memory and corrupt
5093  // its metadata. See
5094  // https://github.com/google/sanitizers/issues/321.
5095  REAL(sincosf)(x, sin, cos);
5096  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5097  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5098}
5099INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
5100  void *ctx;
5101  COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
5102  // FIXME: under ASan the call below may write to freed memory and corrupt
5103  // its metadata. See
5104  // https://github.com/google/sanitizers/issues/321.
5105  REAL(sincosl)(x, sin, cos);
5106  if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5107  if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5108}
5109#define INIT_SINCOS                   \
5110  COMMON_INTERCEPT_FUNCTION(sincos);  \
5111  COMMON_INTERCEPT_FUNCTION(sincosf); \
5112  COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
5113#else
5114#define INIT_SINCOS
5115#endif
5116
5117#if SANITIZER_INTERCEPT_REMQUO
5118INTERCEPTOR(double, remquo, double x, double y, int *quo) {
5119  void *ctx;
5120  COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
5121  // FIXME: under ASan the call below may write to freed memory and corrupt
5122  // its metadata. See
5123  // https://github.com/google/sanitizers/issues/321.
5124  double res = REAL(remquo)(x, y, quo);
5125  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5126  return res;
5127}
5128INTERCEPTOR(float, remquof, float x, float y, int *quo) {
5129  void *ctx;
5130  COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
5131  // FIXME: under ASan the call below may write to freed memory and corrupt
5132  // its metadata. See
5133  // https://github.com/google/sanitizers/issues/321.
5134  float res = REAL(remquof)(x, y, quo);
5135  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5136  return res;
5137}
5138#define INIT_REMQUO                   \
5139  COMMON_INTERCEPT_FUNCTION(remquo);  \
5140  COMMON_INTERCEPT_FUNCTION(remquof);
5141#else
5142#define INIT_REMQUO
5143#endif
5144
5145#if SANITIZER_INTERCEPT_REMQUOL
5146INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
5147  void *ctx;
5148  COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
5149  // FIXME: under ASan the call below may write to freed memory and corrupt
5150  // its metadata. See
5151  // https://github.com/google/sanitizers/issues/321.
5152  long double res = REAL(remquol)(x, y, quo);
5153  if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5154  return res;
5155}
5156#define INIT_REMQUOL                  \
5157  COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
5158#else
5159#define INIT_REMQUOL
5160#endif
5161
5162#if SANITIZER_INTERCEPT_LGAMMA
5163extern int signgam;
5164INTERCEPTOR(double, lgamma, double x) {
5165  void *ctx;
5166  COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
5167  double res = REAL(lgamma)(x);
5168  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5169  return res;
5170}
5171INTERCEPTOR(float, lgammaf, float x) {
5172  void *ctx;
5173  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
5174  float res = REAL(lgammaf)(x);
5175  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5176  return res;
5177}
5178#define INIT_LGAMMA                   \
5179  COMMON_INTERCEPT_FUNCTION(lgamma);  \
5180  COMMON_INTERCEPT_FUNCTION(lgammaf);
5181#else
5182#define INIT_LGAMMA
5183#endif
5184
5185#if SANITIZER_INTERCEPT_LGAMMAL
5186INTERCEPTOR(long double, lgammal, long double x) {
5187  void *ctx;
5188  COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
5189  long double res = REAL(lgammal)(x);
5190  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5191  return res;
5192}
5193#define INIT_LGAMMAL                  \
5194  COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
5195#else
5196#define INIT_LGAMMAL
5197#endif
5198
5199#if SANITIZER_INTERCEPT_LGAMMA_R
5200INTERCEPTOR(double, lgamma_r, double x, int *signp) {
5201  void *ctx;
5202  COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
5203  // FIXME: under ASan the call below may write to freed memory and corrupt
5204  // its metadata. See
5205  // https://github.com/google/sanitizers/issues/321.
5206  double res = REAL(lgamma_r)(x, signp);
5207  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5208  return res;
5209}
5210INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
5211  void *ctx;
5212  COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
5213  // FIXME: under ASan the call below may write to freed memory and corrupt
5214  // its metadata. See
5215  // https://github.com/google/sanitizers/issues/321.
5216  float res = REAL(lgammaf_r)(x, signp);
5217  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5218  return res;
5219}
5220#define INIT_LGAMMA_R                   \
5221  COMMON_INTERCEPT_FUNCTION(lgamma_r);  \
5222  COMMON_INTERCEPT_FUNCTION(lgammaf_r);
5223#else
5224#define INIT_LGAMMA_R
5225#endif
5226
5227#if SANITIZER_INTERCEPT_LGAMMAL_R
5228INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
5229  void *ctx;
5230  COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
5231  // FIXME: under ASan the call below may write to freed memory and corrupt
5232  // its metadata. See
5233  // https://github.com/google/sanitizers/issues/321.
5234  long double res = REAL(lgammal_r)(x, signp);
5235  if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5236  return res;
5237}
5238#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
5239#else
5240#define INIT_LGAMMAL_R
5241#endif
5242
5243#if SANITIZER_INTERCEPT_DRAND48_R
5244INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
5245  void *ctx;
5246  COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
5247  // FIXME: under ASan the call below may write to freed memory and corrupt
5248  // its metadata. See
5249  // https://github.com/google/sanitizers/issues/321.
5250  int res = REAL(drand48_r)(buffer, result);
5251  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5252  return res;
5253}
5254INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
5255  void *ctx;
5256  COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
5257  // FIXME: under ASan the call below may write to freed memory and corrupt
5258  // its metadata. See
5259  // https://github.com/google/sanitizers/issues/321.
5260  int res = REAL(lrand48_r)(buffer, result);
5261  if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5262  return res;
5263}
5264#define INIT_DRAND48_R                  \
5265  COMMON_INTERCEPT_FUNCTION(drand48_r); \
5266  COMMON_INTERCEPT_FUNCTION(lrand48_r);
5267#else
5268#define INIT_DRAND48_R
5269#endif
5270
5271#if SANITIZER_INTERCEPT_RAND_R
5272INTERCEPTOR(int, rand_r, unsigned *seedp) {
5273  void *ctx;
5274  COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
5275  COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
5276  return REAL(rand_r)(seedp);
5277}
5278#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
5279#else
5280#define INIT_RAND_R
5281#endif
5282
5283#if SANITIZER_INTERCEPT_GETLINE
5284INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
5285  void *ctx;
5286  COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
5287  // FIXME: under ASan the call below may write to freed memory and corrupt
5288  // its metadata. See
5289  // https://github.com/google/sanitizers/issues/321.
5290  SSIZE_T res = REAL(getline)(lineptr, n, stream);
5291  if (res > 0) {
5292    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
5293    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
5294    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
5295  }
5296  return res;
5297}
5298
5299// FIXME: under ASan the call below may write to freed memory and corrupt its
5300// metadata. See
5301// https://github.com/google/sanitizers/issues/321.
5302#define GETDELIM_INTERCEPTOR_IMPL(vname)                                       \
5303  {                                                                            \
5304    void *ctx;                                                                 \
5305    COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream);           \
5306    SSIZE_T res = REAL(vname)(lineptr, n, delim, stream);                      \
5307    if (res > 0) {                                                             \
5308      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));          \
5309      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));                      \
5310      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);                  \
5311    }                                                                          \
5312    return res;                                                                \
5313  }
5314
5315INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
5316            void *stream)
5317GETDELIM_INTERCEPTOR_IMPL(__getdelim)
5318
5319// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
5320// with its own body.
5321INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
5322            void *stream)
5323GETDELIM_INTERCEPTOR_IMPL(getdelim)
5324
5325#define INIT_GETLINE                     \
5326  COMMON_INTERCEPT_FUNCTION(getline);    \
5327  COMMON_INTERCEPT_FUNCTION(__getdelim); \
5328  COMMON_INTERCEPT_FUNCTION(getdelim);
5329#else
5330#define INIT_GETLINE
5331#endif
5332
5333#if SANITIZER_INTERCEPT_ICONV
5334INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
5335            char **outbuf, SIZE_T *outbytesleft) {
5336  void *ctx;
5337  COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
5338                           outbytesleft);
5339  if (inbytesleft)
5340    COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
5341  if (inbuf && inbytesleft)
5342    COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
5343  if (outbytesleft)
5344    COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
5345  void *outbuf_orig = outbuf ? *outbuf : nullptr;
5346  // FIXME: under ASan the call below may write to freed memory and corrupt
5347  // its metadata. See
5348  // https://github.com/google/sanitizers/issues/321.
5349  SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
5350  if (outbuf && *outbuf > outbuf_orig) {
5351    SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
5352    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
5353  }
5354  return res;
5355}
5356#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
5357#else
5358#define INIT_ICONV
5359#endif
5360
5361#if SANITIZER_INTERCEPT_TIMES
5362INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
5363  void *ctx;
5364  COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
5365  // FIXME: under ASan the call below may write to freed memory and corrupt
5366  // its metadata. See
5367  // https://github.com/google/sanitizers/issues/321.
5368  __sanitizer_clock_t res = REAL(times)(tms);
5369  if (res != (__sanitizer_clock_t)-1 && tms)
5370    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
5371  return res;
5372}
5373#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
5374#else
5375#define INIT_TIMES
5376#endif
5377
5378#if SANITIZER_S390 && \
5379    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5380extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
5381DEFINE_REAL(uptr, __tls_get_offset, void *arg)
5382#endif
5383
5384#if SANITIZER_INTERCEPT_TLS_GET_ADDR
5385#if !SANITIZER_S390
5386#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
5387// If you see any crashes around this functions, there are 2 known issues with
5388// it: 1. __tls_get_addr can be called with mis-aligned stack due to:
5389// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
5390// 2. It can be called recursively if sanitizer code uses __tls_get_addr
5391// to access thread local variables (it should not happen normally,
5392// because sanitizers use initial-exec tls model).
5393INTERCEPTOR(void *, __tls_get_addr, void *arg) {
5394  void *ctx;
5395  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
5396  void *res = REAL(__tls_get_addr)(arg);
5397  uptr tls_begin, tls_end;
5398  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5399  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
5400  if (dtv) {
5401    // New DTLS block has been allocated.
5402    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5403  }
5404  return res;
5405}
5406#if SANITIZER_PPC
5407// On PowerPC, we also need to intercept __tls_get_addr_opt, which has
5408// mostly the same semantics as __tls_get_addr, but its presence enables
5409// some optimizations in linker (which are safe to ignore here).
5410extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
5411                          visibility("default")))
5412void *__tls_get_addr_opt(void *arg);
5413#endif
5414#else // SANITIZER_S390
5415// On s390, we have to intercept two functions here:
5416// - __tls_get_addr_internal, which is a glibc-internal function that is like
5417//   the usual __tls_get_addr, but returns a TP-relative offset instead of
5418//   a proper pointer.  It is used by dlsym for TLS symbols.
5419// - __tls_get_offset, which is like the above, but also takes a GOT-relative
5420//   descriptor offset as an argument instead of a pointer.  GOT address
5421//   is passed in r12, so it's necessary to write it in assembly.  This is
5422//   the function used by the compiler.
5423#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
5424INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
5425  void *ctx;
5426  COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
5427  uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
5428  uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
5429  void *ptr = reinterpret_cast<void *>(res + tp);
5430  uptr tls_begin, tls_end;
5431  COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5432  DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
5433  if (dtv) {
5434    // New DTLS block has been allocated.
5435    COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5436  }
5437  return res;
5438}
5439#endif // SANITIZER_S390
5440#else
5441#define INIT_TLS_GET_ADDR
5442#endif
5443
5444#if SANITIZER_S390 && \
5445    (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5446extern "C" uptr __tls_get_offset(void *arg);
5447extern "C" uptr __interceptor___tls_get_offset(void *arg);
5448// We need a hidden symbol aliasing the above, so that we can jump
5449// directly to it from the assembly below.
5450extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
5451                          visibility("hidden")))
5452uptr __tls_get_addr_hidden(void *arg);
5453// Now carefully intercept __tls_get_offset.
5454asm(
5455  ".text\n"
5456// The __intercept_ version has to exist, so that gen_dynamic_list.py
5457// exports our symbol.
5458  ".weak __tls_get_offset\n"
5459  ".type __tls_get_offset, @function\n"
5460  "__tls_get_offset:\n"
5461  ".global __interceptor___tls_get_offset\n"
5462  ".type __interceptor___tls_get_offset, @function\n"
5463  "__interceptor___tls_get_offset:\n"
5464#ifdef __s390x__
5465  "la %r2, 0(%r2,%r12)\n"
5466  "jg __tls_get_addr_hidden\n"
5467#else
5468  "basr %r3,0\n"
5469  "0: la %r2,0(%r2,%r12)\n"
5470  "l %r4,1f-0b(%r3)\n"
5471  "b 0(%r4,%r3)\n"
5472  "1: .long __tls_get_addr_hidden - 0b\n"
5473#endif
5474  ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
5475// Assembly wrapper to call REAL(__tls_get_offset)(arg)
5476  ".type __tls_get_offset_wrapper, @function\n"
5477  "__tls_get_offset_wrapper:\n"
5478#ifdef __s390x__
5479  "sgr %r2,%r12\n"
5480#else
5481  "sr %r2,%r12\n"
5482#endif
5483  "br %r3\n"
5484  ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
5485);
5486#endif
5487
5488#if SANITIZER_INTERCEPT_LISTXATTR
5489INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
5490  void *ctx;
5491  COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
5492  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5493  // FIXME: under ASan the call below may write to freed memory and corrupt
5494  // its metadata. See
5495  // https://github.com/google/sanitizers/issues/321.
5496  SSIZE_T res = REAL(listxattr)(path, list, size);
5497  // Here and below, size == 0 is a special case where nothing is written to the
5498  // buffer, and res contains the desired buffer size.
5499  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5500  return res;
5501}
5502INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
5503  void *ctx;
5504  COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
5505  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5506  // FIXME: under ASan the call below may write to freed memory and corrupt
5507  // its metadata. See
5508  // https://github.com/google/sanitizers/issues/321.
5509  SSIZE_T res = REAL(llistxattr)(path, list, size);
5510  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5511  return res;
5512}
5513INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
5514  void *ctx;
5515  COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
5516  // FIXME: under ASan the call below may write to freed memory and corrupt
5517  // its metadata. See
5518  // https://github.com/google/sanitizers/issues/321.
5519  SSIZE_T res = REAL(flistxattr)(fd, list, size);
5520  if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5521  return res;
5522}
5523#define INIT_LISTXATTR                   \
5524  COMMON_INTERCEPT_FUNCTION(listxattr);  \
5525  COMMON_INTERCEPT_FUNCTION(llistxattr); \
5526  COMMON_INTERCEPT_FUNCTION(flistxattr);
5527#else
5528#define INIT_LISTXATTR
5529#endif
5530
5531#if SANITIZER_INTERCEPT_GETXATTR
5532INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
5533            SIZE_T size) {
5534  void *ctx;
5535  COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
5536  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5537  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5538  // FIXME: under ASan the call below may write to freed memory and corrupt
5539  // its metadata. See
5540  // https://github.com/google/sanitizers/issues/321.
5541  SSIZE_T res = REAL(getxattr)(path, name, value, size);
5542  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5543  return res;
5544}
5545INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
5546            SIZE_T size) {
5547  void *ctx;
5548  COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
5549  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5550  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5551  // FIXME: under ASan the call below may write to freed memory and corrupt
5552  // its metadata. See
5553  // https://github.com/google/sanitizers/issues/321.
5554  SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
5555  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5556  return res;
5557}
5558INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
5559            SIZE_T size) {
5560  void *ctx;
5561  COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
5562  if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5563  // FIXME: under ASan the call below may write to freed memory and corrupt
5564  // its metadata. See
5565  // https://github.com/google/sanitizers/issues/321.
5566  SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
5567  if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5568  return res;
5569}
5570#define INIT_GETXATTR                   \
5571  COMMON_INTERCEPT_FUNCTION(getxattr);  \
5572  COMMON_INTERCEPT_FUNCTION(lgetxattr); \
5573  COMMON_INTERCEPT_FUNCTION(fgetxattr);
5574#else
5575#define INIT_GETXATTR
5576#endif
5577
5578#if SANITIZER_INTERCEPT_GETRESID
5579INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
5580  void *ctx;
5581  COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
5582  // FIXME: under ASan the call below may write to freed memory and corrupt
5583  // its metadata. See
5584  // https://github.com/google/sanitizers/issues/321.
5585  int res = REAL(getresuid)(ruid, euid, suid);
5586  if (res >= 0) {
5587    if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
5588    if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
5589    if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
5590  }
5591  return res;
5592}
5593INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
5594  void *ctx;
5595  COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
5596  // FIXME: under ASan the call below may write to freed memory and corrupt
5597  // its metadata. See
5598  // https://github.com/google/sanitizers/issues/321.
5599  int res = REAL(getresgid)(rgid, egid, sgid);
5600  if (res >= 0) {
5601    if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
5602    if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
5603    if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
5604  }
5605  return res;
5606}
5607#define INIT_GETRESID                   \
5608  COMMON_INTERCEPT_FUNCTION(getresuid); \
5609  COMMON_INTERCEPT_FUNCTION(getresgid);
5610#else
5611#define INIT_GETRESID
5612#endif
5613
5614#if SANITIZER_INTERCEPT_GETIFADDRS
5615// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
5616// intercept freeifaddrs(). If that ceases to be the case, we might need to
5617// intercept it to poison the memory again.
5618INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
5619  void *ctx;
5620  COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
5621  // FIXME: under ASan the call below may write to freed memory and corrupt
5622  // its metadata. See
5623  // https://github.com/google/sanitizers/issues/321.
5624  int res = REAL(getifaddrs)(ifap);
5625  if (res == 0 && ifap) {
5626    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
5627    __sanitizer_ifaddrs *p = *ifap;
5628    while (p) {
5629      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
5630      if (p->ifa_name)
5631        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
5632                                       internal_strlen(p->ifa_name) + 1);
5633      if (p->ifa_addr)
5634        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
5635      if (p->ifa_netmask)
5636        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
5637      // On Linux this is a union, but the other member also points to a
5638      // struct sockaddr, so the following is sufficient.
5639      if (p->ifa_dstaddr)
5640        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
5641      // FIXME(smatveev): Unpoison p->ifa_data as well.
5642      p = p->ifa_next;
5643    }
5644  }
5645  return res;
5646}
5647#define INIT_GETIFADDRS                  \
5648  COMMON_INTERCEPT_FUNCTION(getifaddrs);
5649#else
5650#define INIT_GETIFADDRS
5651#endif
5652
5653#if SANITIZER_INTERCEPT_IF_INDEXTONAME
5654INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
5655  void *ctx;
5656  COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
5657  // FIXME: under ASan the call below may write to freed memory and corrupt
5658  // its metadata. See
5659  // https://github.com/google/sanitizers/issues/321.
5660  char *res = REAL(if_indextoname)(ifindex, ifname);
5661  if (res && ifname)
5662    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
5663  return res;
5664}
5665INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
5666  void *ctx;
5667  COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
5668  if (ifname)
5669    COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
5670  return REAL(if_nametoindex)(ifname);
5671}
5672#define INIT_IF_INDEXTONAME                  \
5673  COMMON_INTERCEPT_FUNCTION(if_indextoname); \
5674  COMMON_INTERCEPT_FUNCTION(if_nametoindex);
5675#else
5676#define INIT_IF_INDEXTONAME
5677#endif
5678
5679#if SANITIZER_INTERCEPT_CAPGET
5680INTERCEPTOR(int, capget, void *hdrp, void *datap) {
5681  void *ctx;
5682  COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
5683  if (hdrp)
5684    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5685  // FIXME: under ASan the call below may write to freed memory and corrupt
5686  // its metadata. See
5687  // https://github.com/google/sanitizers/issues/321.
5688  int res = REAL(capget)(hdrp, datap);
5689  if (res == 0 && datap)
5690    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
5691  // We can also return -1 and write to hdrp->version if the version passed in
5692  // hdrp->version is unsupported. But that's not a trivial condition to check,
5693  // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
5694  return res;
5695}
5696INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
5697  void *ctx;
5698  COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
5699  if (hdrp)
5700    COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5701  if (datap)
5702    COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
5703  return REAL(capset)(hdrp, datap);
5704}
5705#define INIT_CAPGET                  \
5706  COMMON_INTERCEPT_FUNCTION(capget); \
5707  COMMON_INTERCEPT_FUNCTION(capset);
5708#else
5709#define INIT_CAPGET
5710#endif
5711
5712#if SANITIZER_INTERCEPT_AEABI_MEM
5713INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
5714  void *ctx;
5715  COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5716}
5717
5718INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
5719  void *ctx;
5720  COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5721}
5722
5723INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
5724  void *ctx;
5725  COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5726}
5727
5728INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
5729  void *ctx;
5730  COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5731}
5732
5733INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
5734  void *ctx;
5735  COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5736}
5737
5738INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
5739  void *ctx;
5740  COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5741}
5742
5743// Note the argument order.
5744INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
5745  void *ctx;
5746  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5747}
5748
5749INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
5750  void *ctx;
5751  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5752}
5753
5754INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
5755  void *ctx;
5756  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5757}
5758
5759INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
5760  void *ctx;
5761  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5762}
5763
5764INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
5765  void *ctx;
5766  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5767}
5768
5769INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
5770  void *ctx;
5771  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5772}
5773
5774#define INIT_AEABI_MEM                         \
5775  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove);  \
5776  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
5777  COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
5778  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy);   \
5779  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4);  \
5780  COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8);  \
5781  COMMON_INTERCEPT_FUNCTION(__aeabi_memset);   \
5782  COMMON_INTERCEPT_FUNCTION(__aeabi_memset4);  \
5783  COMMON_INTERCEPT_FUNCTION(__aeabi_memset8);  \
5784  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr);   \
5785  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4);  \
5786  COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
5787#else
5788#define INIT_AEABI_MEM
5789#endif  // SANITIZER_INTERCEPT_AEABI_MEM
5790
5791#if SANITIZER_INTERCEPT___BZERO
5792INTERCEPTOR(void *, __bzero, void *block, uptr size) {
5793  void *ctx;
5794  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5795}
5796#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
5797#else
5798#define INIT___BZERO
5799#endif  // SANITIZER_INTERCEPT___BZERO
5800
5801#if SANITIZER_INTERCEPT_BZERO
5802INTERCEPTOR(void *, bzero, void *block, uptr size) {
5803  void *ctx;
5804  COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5805}
5806#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);
5807#else
5808#define INIT_BZERO
5809#endif  // SANITIZER_INTERCEPT_BZERO
5810
5811#if SANITIZER_INTERCEPT_FTIME
5812INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
5813  void *ctx;
5814  COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
5815  // FIXME: under ASan the call below may write to freed memory and corrupt
5816  // its metadata. See
5817  // https://github.com/google/sanitizers/issues/321.
5818  int res = REAL(ftime)(tp);
5819  if (tp)
5820    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
5821  return res;
5822}
5823#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
5824#else
5825#define INIT_FTIME
5826#endif  // SANITIZER_INTERCEPT_FTIME
5827
5828#if SANITIZER_INTERCEPT_XDR
5829INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
5830            unsigned size, int op) {
5831  void *ctx;
5832  COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
5833  // FIXME: under ASan the call below may write to freed memory and corrupt
5834  // its metadata. See
5835  // https://github.com/google/sanitizers/issues/321.
5836  REAL(xdrmem_create)(xdrs, addr, size, op);
5837  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
5838  if (op == __sanitizer_XDR_ENCODE) {
5839    // It's not obvious how much data individual xdr_ routines write.
5840    // Simply unpoison the entire target buffer in advance.
5841    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
5842  }
5843}
5844
5845INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
5846  void *ctx;
5847  COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
5848  // FIXME: under ASan the call below may write to freed memory and corrupt
5849  // its metadata. See
5850  // https://github.com/google/sanitizers/issues/321.
5851  REAL(xdrstdio_create)(xdrs, file, op);
5852  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
5853}
5854
5855// FIXME: under ASan the call below may write to freed memory and corrupt
5856// its metadata. See
5857// https://github.com/google/sanitizers/issues/321.
5858#define XDR_INTERCEPTOR(F, T)                             \
5859  INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) {      \
5860    void *ctx;                                            \
5861    COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p);            \
5862    if (p && xdrs->x_op == __sanitizer_XDR_ENCODE)        \
5863      COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));  \
5864    int res = REAL(F)(xdrs, p);                           \
5865    if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
5866      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
5867    return res;                                           \
5868  }
5869
5870XDR_INTERCEPTOR(xdr_short, short)
5871XDR_INTERCEPTOR(xdr_u_short, unsigned short)
5872XDR_INTERCEPTOR(xdr_int, int)
5873XDR_INTERCEPTOR(xdr_u_int, unsigned)
5874XDR_INTERCEPTOR(xdr_long, long)
5875XDR_INTERCEPTOR(xdr_u_long, unsigned long)
5876XDR_INTERCEPTOR(xdr_hyper, long long)
5877XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
5878XDR_INTERCEPTOR(xdr_longlong_t, long long)
5879XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
5880XDR_INTERCEPTOR(xdr_int8_t, u8)
5881XDR_INTERCEPTOR(xdr_uint8_t, u8)
5882XDR_INTERCEPTOR(xdr_int16_t, u16)
5883XDR_INTERCEPTOR(xdr_uint16_t, u16)
5884XDR_INTERCEPTOR(xdr_int32_t, u32)
5885XDR_INTERCEPTOR(xdr_uint32_t, u32)
5886XDR_INTERCEPTOR(xdr_int64_t, u64)
5887XDR_INTERCEPTOR(xdr_uint64_t, u64)
5888XDR_INTERCEPTOR(xdr_quad_t, long long)
5889XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
5890XDR_INTERCEPTOR(xdr_bool, bool)
5891XDR_INTERCEPTOR(xdr_enum, int)
5892XDR_INTERCEPTOR(xdr_char, char)
5893XDR_INTERCEPTOR(xdr_u_char, unsigned char)
5894XDR_INTERCEPTOR(xdr_float, float)
5895XDR_INTERCEPTOR(xdr_double, double)
5896
5897// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
5898// wrapstring, sizeof
5899
5900INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
5901            unsigned maxsize) {
5902  void *ctx;
5903  COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
5904  if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
5905    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
5906    COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
5907    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
5908  }
5909  // FIXME: under ASan the call below may write to freed memory and corrupt
5910  // its metadata. See
5911  // https://github.com/google/sanitizers/issues/321.
5912  int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
5913  if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
5914    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
5915    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
5916    if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
5917  }
5918  return res;
5919}
5920
5921INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
5922            unsigned maxsize) {
5923  void *ctx;
5924  COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
5925  if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
5926    COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
5927    COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1);
5928  }
5929  // FIXME: under ASan the call below may write to freed memory and corrupt
5930  // its metadata. See
5931  // https://github.com/google/sanitizers/issues/321.
5932  int res = REAL(xdr_string)(xdrs, p, maxsize);
5933  if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
5934    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
5935    if (res && *p)
5936      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
5937  }
5938  return res;
5939}
5940
5941#define INIT_XDR                               \
5942  COMMON_INTERCEPT_FUNCTION(xdrmem_create);    \
5943  COMMON_INTERCEPT_FUNCTION(xdrstdio_create);  \
5944  COMMON_INTERCEPT_FUNCTION(xdr_short);        \
5945  COMMON_INTERCEPT_FUNCTION(xdr_u_short);      \
5946  COMMON_INTERCEPT_FUNCTION(xdr_int);          \
5947  COMMON_INTERCEPT_FUNCTION(xdr_u_int);        \
5948  COMMON_INTERCEPT_FUNCTION(xdr_long);         \
5949  COMMON_INTERCEPT_FUNCTION(xdr_u_long);       \
5950  COMMON_INTERCEPT_FUNCTION(xdr_hyper);        \
5951  COMMON_INTERCEPT_FUNCTION(xdr_u_hyper);      \
5952  COMMON_INTERCEPT_FUNCTION(xdr_longlong_t);   \
5953  COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
5954  COMMON_INTERCEPT_FUNCTION(xdr_int8_t);       \
5955  COMMON_INTERCEPT_FUNCTION(xdr_uint8_t);      \
5956  COMMON_INTERCEPT_FUNCTION(xdr_int16_t);      \
5957  COMMON_INTERCEPT_FUNCTION(xdr_uint16_t);     \
5958  COMMON_INTERCEPT_FUNCTION(xdr_int32_t);      \
5959  COMMON_INTERCEPT_FUNCTION(xdr_uint32_t);     \
5960  COMMON_INTERCEPT_FUNCTION(xdr_int64_t);      \
5961  COMMON_INTERCEPT_FUNCTION(xdr_uint64_t);     \
5962  COMMON_INTERCEPT_FUNCTION(xdr_quad_t);       \
5963  COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t);     \
5964  COMMON_INTERCEPT_FUNCTION(xdr_bool);         \
5965  COMMON_INTERCEPT_FUNCTION(xdr_enum);         \
5966  COMMON_INTERCEPT_FUNCTION(xdr_char);         \
5967  COMMON_INTERCEPT_FUNCTION(xdr_u_char);       \
5968  COMMON_INTERCEPT_FUNCTION(xdr_float);        \
5969  COMMON_INTERCEPT_FUNCTION(xdr_double);       \
5970  COMMON_INTERCEPT_FUNCTION(xdr_bytes);        \
5971  COMMON_INTERCEPT_FUNCTION(xdr_string);
5972#else
5973#define INIT_XDR
5974#endif  // SANITIZER_INTERCEPT_XDR
5975
5976#if SANITIZER_INTERCEPT_XDRREC
5977typedef int (*xdrrec_cb)(char*, char*, int);
5978struct XdrRecWrapper {
5979  char *handle;
5980  xdrrec_cb rd, wr;
5981};
5982typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;
5983static XdrRecWrapMap *xdrrec_wrap_map;
5984
5985static int xdrrec_wr_wrap(char *handle, char *buf, int count) {
5986  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5987  COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);
5988  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
5989  return wrap->wr(wrap->handle, buf, count);
5990}
5991
5992static int xdrrec_rd_wrap(char *handle, char *buf, int count) {
5993  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
5994  XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
5995  return wrap->rd(wrap->handle, buf, count);
5996}
5997
5998// This doesn't apply to the solaris version as it has a different function
5999// signature.
6000INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,
6001            unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),
6002            int (*wr)(char*, char*, int)) {
6003  void *ctx;
6004  COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,
6005                           handle, rd, wr);
6006  COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);
6007
6008  // We can't allocate a wrapper on the stack, as the handle is used outside
6009  // this stack frame. So we put it on the heap, and keep track of it with
6010  // the HashMap (keyed by x_private). When we later need to xdr_destroy,
6011  // we can index the map, free the wrapper, and then clean the map entry.
6012  XdrRecWrapper *wrap_data =
6013      (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));
6014  wrap_data->handle = handle;
6015  wrap_data->rd = rd;
6016  wrap_data->wr = wr;
6017  if (wr)
6018    wr = xdrrec_wr_wrap;
6019  if (rd)
6020    rd = xdrrec_rd_wrap;
6021  handle = (char *)wrap_data;
6022
6023  REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);
6024  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);
6025
6026  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);
6027  *wrap = wrap_data;
6028}
6029
6030// We have to intercept this to be able to free wrapper memory;
6031// otherwise it's not necessary.
6032INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {
6033  void *ctx;
6034  COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);
6035
6036  XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);
6037  InternalFree(*wrap);
6038  REAL(xdr_destroy)(xdr);
6039}
6040#define INIT_XDRREC_LINUX \
6041  static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \
6042  xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \
6043  COMMON_INTERCEPT_FUNCTION(xdrrec_create); \
6044  COMMON_INTERCEPT_FUNCTION(xdr_destroy);
6045#else
6046#define INIT_XDRREC_LINUX
6047#endif
6048
6049#if SANITIZER_INTERCEPT_TSEARCH
6050INTERCEPTOR(void *, tsearch, void *key, void **rootp,
6051            int (*compar)(const void *, const void *)) {
6052  void *ctx;
6053  COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
6054  // FIXME: under ASan the call below may write to freed memory and corrupt
6055  // its metadata. See
6056  // https://github.com/google/sanitizers/issues/321.
6057  void *res = REAL(tsearch)(key, rootp, compar);
6058  if (res && *(void **)res == key)
6059    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
6060  return res;
6061}
6062#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
6063#else
6064#define INIT_TSEARCH
6065#endif
6066
6067#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
6068    SANITIZER_INTERCEPT_OPEN_MEMSTREAM
6069void unpoison_file(__sanitizer_FILE *fp) {
6070#if SANITIZER_HAS_STRUCT_FILE
6071  COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
6072#if SANITIZER_NETBSD
6073  if (fp->_bf._base && fp->_bf._size > 0)
6074    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
6075                                        fp->_bf._size);
6076#else
6077  if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
6078    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
6079                                        fp->_IO_read_end - fp->_IO_read_base);
6080  if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)
6081    COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,
6082                                        fp->_IO_write_end - fp->_IO_write_base);
6083#endif
6084#endif  // SANITIZER_HAS_STRUCT_FILE
6085}
6086#endif
6087
6088#if SANITIZER_INTERCEPT_LIBIO_INTERNALS
6089// These guys are called when a .c source is built with -O2.
6090INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
6091  void *ctx;
6092  COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
6093  int res = REAL(__uflow)(fp);
6094  unpoison_file(fp);
6095  return res;
6096}
6097INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
6098  void *ctx;
6099  COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
6100  int res = REAL(__underflow)(fp);
6101  unpoison_file(fp);
6102  return res;
6103}
6104INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
6105  void *ctx;
6106  COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
6107  int res = REAL(__overflow)(fp, ch);
6108  unpoison_file(fp);
6109  return res;
6110}
6111INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
6112  void *ctx;
6113  COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
6114  int res = REAL(__wuflow)(fp);
6115  unpoison_file(fp);
6116  return res;
6117}
6118INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
6119  void *ctx;
6120  COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
6121  int res = REAL(__wunderflow)(fp);
6122  unpoison_file(fp);
6123  return res;
6124}
6125INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
6126  void *ctx;
6127  COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
6128  int res = REAL(__woverflow)(fp, ch);
6129  unpoison_file(fp);
6130  return res;
6131}
6132#define INIT_LIBIO_INTERNALS               \
6133  COMMON_INTERCEPT_FUNCTION(__uflow);      \
6134  COMMON_INTERCEPT_FUNCTION(__underflow);  \
6135  COMMON_INTERCEPT_FUNCTION(__overflow);   \
6136  COMMON_INTERCEPT_FUNCTION(__wuflow);     \
6137  COMMON_INTERCEPT_FUNCTION(__wunderflow); \
6138  COMMON_INTERCEPT_FUNCTION(__woverflow);
6139#else
6140#define INIT_LIBIO_INTERNALS
6141#endif
6142
6143#if SANITIZER_INTERCEPT_FOPEN
6144INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
6145  void *ctx;
6146  COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
6147  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6148  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6149  __sanitizer_FILE *res = REAL(fopen)(path, mode);
6150  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6151  if (res) unpoison_file(res);
6152  return res;
6153}
6154INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
6155  void *ctx;
6156  COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
6157  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6158  __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
6159  if (res) unpoison_file(res);
6160  return res;
6161}
6162INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
6163            __sanitizer_FILE *fp) {
6164  void *ctx;
6165  COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
6166  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6167  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6168  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6169  __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
6170  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6171  if (res) unpoison_file(res);
6172  return res;
6173}
6174#define INIT_FOPEN                   \
6175  COMMON_INTERCEPT_FUNCTION(fopen);  \
6176  COMMON_INTERCEPT_FUNCTION(fdopen); \
6177  COMMON_INTERCEPT_FUNCTION(freopen);
6178#else
6179#define INIT_FOPEN
6180#endif
6181
6182#if SANITIZER_INTERCEPT_FLOPEN
6183INTERCEPTOR(int, flopen, const char *path, int flags, ...) {
6184  void *ctx;
6185  va_list ap;
6186  va_start(ap, flags);
6187  u16 mode = static_cast<u16>(va_arg(ap, u32));
6188  va_end(ap);
6189  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6190  if (path) {
6191    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6192  }
6193  return REAL(flopen)(path, flags, mode);
6194}
6195
6196INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {
6197  void *ctx;
6198  va_list ap;
6199  va_start(ap, flags);
6200  u16 mode = static_cast<u16>(va_arg(ap, u32));
6201  va_end(ap);
6202  COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6203  if (path) {
6204    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6205  }
6206  return REAL(flopenat)(dirfd, path, flags, mode);
6207}
6208
6209#define INIT_FLOPEN    \
6210  COMMON_INTERCEPT_FUNCTION(flopen); \
6211  COMMON_INTERCEPT_FUNCTION(flopenat);
6212#else
6213#define INIT_FLOPEN
6214#endif
6215
6216#if SANITIZER_INTERCEPT_FOPEN64
6217INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
6218  void *ctx;
6219  COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
6220  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6221  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6222  __sanitizer_FILE *res = REAL(fopen64)(path, mode);
6223  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6224  if (res) unpoison_file(res);
6225  return res;
6226}
6227INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
6228            __sanitizer_FILE *fp) {
6229  void *ctx;
6230  COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
6231  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6232  COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6233  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6234  __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
6235  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6236  if (res) unpoison_file(res);
6237  return res;
6238}
6239#define INIT_FOPEN64                  \
6240  COMMON_INTERCEPT_FUNCTION(fopen64); \
6241  COMMON_INTERCEPT_FUNCTION(freopen64);
6242#else
6243#define INIT_FOPEN64
6244#endif
6245
6246#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
6247INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
6248  void *ctx;
6249  COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
6250  // FIXME: under ASan the call below may write to freed memory and corrupt
6251  // its metadata. See
6252  // https://github.com/google/sanitizers/issues/321.
6253  __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
6254  if (res) {
6255    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
6256    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
6257    unpoison_file(res);
6258    FileMetadata file = {ptr, sizeloc};
6259    SetInterceptorMetadata(res, file);
6260  }
6261  return res;
6262}
6263INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
6264            SIZE_T *sizeloc) {
6265  void *ctx;
6266  COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
6267  __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
6268  if (res) {
6269    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
6270    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
6271    unpoison_file(res);
6272    FileMetadata file = {(char **)ptr, sizeloc};
6273    SetInterceptorMetadata(res, file);
6274  }
6275  return res;
6276}
6277INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
6278            const char *mode) {
6279  void *ctx;
6280  COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
6281  // FIXME: under ASan the call below may write to freed memory and corrupt
6282  // its metadata. See
6283  // https://github.com/google/sanitizers/issues/321.
6284  __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
6285  if (res) unpoison_file(res);
6286  return res;
6287}
6288#define INIT_OPEN_MEMSTREAM                   \
6289  COMMON_INTERCEPT_FUNCTION(open_memstream);  \
6290  COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
6291  COMMON_INTERCEPT_FUNCTION(fmemopen);
6292#else
6293#define INIT_OPEN_MEMSTREAM
6294#endif
6295
6296#if SANITIZER_INTERCEPT_OBSTACK
6297static void initialize_obstack(__sanitizer_obstack *obstack) {
6298  COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
6299  if (obstack->chunk)
6300    COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
6301                                        sizeof(*obstack->chunk));
6302}
6303
6304INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
6305            int align, void *(*alloc_fn)(uptr arg, uptr sz),
6306            void (*free_fn)(uptr arg, void *p)) {
6307  void *ctx;
6308  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
6309                           free_fn);
6310  int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
6311  if (res) initialize_obstack(obstack);
6312  return res;
6313}
6314INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
6315            int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
6316  void *ctx;
6317  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
6318                           free_fn);
6319  int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
6320  if (res) initialize_obstack(obstack);
6321  return res;
6322}
6323INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
6324  void *ctx;
6325  COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
6326  REAL(_obstack_newchunk)(obstack, length);
6327  if (obstack->chunk)
6328    COMMON_INTERCEPTOR_INITIALIZE_RANGE(
6329        obstack->chunk, obstack->next_free - (char *)obstack->chunk);
6330}
6331#define INIT_OBSTACK                           \
6332  COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
6333  COMMON_INTERCEPT_FUNCTION(_obstack_begin);   \
6334  COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
6335#else
6336#define INIT_OBSTACK
6337#endif
6338
6339#if SANITIZER_INTERCEPT_FFLUSH
6340INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
6341  void *ctx;
6342  COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
6343  if (fp)
6344    unpoison_file(fp);
6345  int res = REAL(fflush)(fp);
6346  // FIXME: handle fp == NULL
6347  if (fp) {
6348    const FileMetadata *m = GetInterceptorMetadata(fp);
6349    if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6350  }
6351  return res;
6352}
6353#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
6354#else
6355#define INIT_FFLUSH
6356#endif
6357
6358#if SANITIZER_INTERCEPT_FCLOSE
6359INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
6360  void *ctx;
6361  COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
6362  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6363  const FileMetadata *m = GetInterceptorMetadata(fp);
6364  if (fp)
6365    unpoison_file(fp);
6366  int res = REAL(fclose)(fp);
6367  if (m) {
6368    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6369    DeleteInterceptorMetadata(fp);
6370  }
6371  return res;
6372}
6373#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
6374#else
6375#define INIT_FCLOSE
6376#endif
6377
6378#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
6379INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
6380  void *ctx;
6381  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
6382  if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
6383  COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag);
6384  void *res = REAL(dlopen)(filename, flag);
6385  Symbolizer::GetOrInit()->InvalidateModuleList();
6386  COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
6387  return res;
6388}
6389
6390INTERCEPTOR(int, dlclose, void *handle) {
6391  void *ctx;
6392  COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
6393  int res = REAL(dlclose)(handle);
6394  Symbolizer::GetOrInit()->InvalidateModuleList();
6395  COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
6396  return res;
6397}
6398#define INIT_DLOPEN_DLCLOSE          \
6399  COMMON_INTERCEPT_FUNCTION(dlopen); \
6400  COMMON_INTERCEPT_FUNCTION(dlclose);
6401#else
6402#define INIT_DLOPEN_DLCLOSE
6403#endif
6404
6405#if SANITIZER_INTERCEPT_GETPASS
6406INTERCEPTOR(char *, getpass, const char *prompt) {
6407  void *ctx;
6408  COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
6409  if (prompt)
6410    COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1);
6411  char *res = REAL(getpass)(prompt);
6412  if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1);
6413  return res;
6414}
6415
6416#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
6417#else
6418#define INIT_GETPASS
6419#endif
6420
6421#if SANITIZER_INTERCEPT_TIMERFD
6422INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
6423            void *old_value) {
6424  void *ctx;
6425  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
6426                           old_value);
6427  COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
6428  int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
6429  if (res != -1 && old_value)
6430    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
6431  return res;
6432}
6433
6434INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
6435  void *ctx;
6436  COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
6437  int res = REAL(timerfd_gettime)(fd, curr_value);
6438  if (res != -1 && curr_value)
6439    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
6440  return res;
6441}
6442#define INIT_TIMERFD                          \
6443  COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
6444  COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
6445#else
6446#define INIT_TIMERFD
6447#endif
6448
6449#if SANITIZER_INTERCEPT_MLOCKX
6450// Linux kernel has a bug that leads to kernel deadlock if a process
6451// maps TBs of memory and then calls mlock().
6452static void MlockIsUnsupported() {
6453  static atomic_uint8_t printed;
6454  if (atomic_exchange(&printed, 1, memory_order_relaxed))
6455    return;
6456  VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
6457          SanitizerToolName);
6458}
6459
6460INTERCEPTOR(int, mlock, const void *addr, uptr len) {
6461  MlockIsUnsupported();
6462  return 0;
6463}
6464
6465INTERCEPTOR(int, munlock, const void *addr, uptr len) {
6466  MlockIsUnsupported();
6467  return 0;
6468}
6469
6470INTERCEPTOR(int, mlockall, int flags) {
6471  MlockIsUnsupported();
6472  return 0;
6473}
6474
6475INTERCEPTOR(int, munlockall, void) {
6476  MlockIsUnsupported();
6477  return 0;
6478}
6479
6480#define INIT_MLOCKX                                                            \
6481  COMMON_INTERCEPT_FUNCTION(mlock);                                            \
6482  COMMON_INTERCEPT_FUNCTION(munlock);                                          \
6483  COMMON_INTERCEPT_FUNCTION(mlockall);                                         \
6484  COMMON_INTERCEPT_FUNCTION(munlockall);
6485
6486#else
6487#define INIT_MLOCKX
6488#endif  // SANITIZER_INTERCEPT_MLOCKX
6489
6490#if SANITIZER_INTERCEPT_FOPENCOOKIE
6491struct WrappedCookie {
6492  void *real_cookie;
6493  __sanitizer_cookie_io_functions_t real_io_funcs;
6494};
6495
6496static uptr wrapped_read(void *cookie, char *buf, uptr size) {
6497  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6498  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6499  __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
6500  return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
6501}
6502
6503static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
6504  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6505  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6506  __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
6507  return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
6508}
6509
6510static int wrapped_seek(void *cookie, u64 *offset, int whence) {
6511  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6512  COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
6513  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6514  __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
6515  return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
6516                   : -1;
6517}
6518
6519static int wrapped_close(void *cookie) {
6520  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
6521  WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6522  __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
6523  int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
6524  InternalFree(wrapped_cookie);
6525  return res;
6526}
6527
6528INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
6529            __sanitizer_cookie_io_functions_t io_funcs) {
6530  void *ctx;
6531  COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
6532  WrappedCookie *wrapped_cookie =
6533      (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
6534  wrapped_cookie->real_cookie = cookie;
6535  wrapped_cookie->real_io_funcs = io_funcs;
6536  __sanitizer_FILE *res =
6537      REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
6538                                               wrapped_seek, wrapped_close});
6539  return res;
6540}
6541
6542#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
6543#else
6544#define INIT_FOPENCOOKIE
6545#endif  // SANITIZER_INTERCEPT_FOPENCOOKIE
6546
6547#if SANITIZER_INTERCEPT_SEM
6548INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
6549  void *ctx;
6550  COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
6551  // Workaround a bug in glibc's "old" semaphore implementation by
6552  // zero-initializing the sem_t contents. This has to be done here because
6553  // interceptors bind to the lowest symbols version by default, hitting the
6554  // buggy code path while the non-sanitized build of the same code works fine.
6555  REAL(memset)(s, 0, sizeof(*s));
6556  int res = REAL(sem_init)(s, pshared, value);
6557  return res;
6558}
6559
6560INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
6561  void *ctx;
6562  COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
6563  int res = REAL(sem_destroy)(s);
6564  return res;
6565}
6566
6567INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
6568  void *ctx;
6569  COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
6570  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
6571  if (res == 0) {
6572    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6573  }
6574  return res;
6575}
6576
6577INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
6578  void *ctx;
6579  COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
6580  int res = REAL(sem_trywait)(s);
6581  if (res == 0) {
6582    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6583  }
6584  return res;
6585}
6586
6587INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
6588  void *ctx;
6589  COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
6590  COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
6591  int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
6592  if (res == 0) {
6593    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6594  }
6595  return res;
6596}
6597
6598INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
6599  void *ctx;
6600  COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
6601  COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
6602  int res = REAL(sem_post)(s);
6603  return res;
6604}
6605
6606INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
6607  void *ctx;
6608  COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
6609  int res = REAL(sem_getvalue)(s, sval);
6610  if (res == 0) {
6611    COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6612    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
6613  }
6614  return res;
6615}
6616
6617INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {
6618  void *ctx;
6619  va_list ap;
6620  va_start(ap, oflag);
6621  u32 mode = va_arg(ap, u32);
6622  u32 value = va_arg(ap, u32);
6623  COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);
6624  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
6625  __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);
6626  if (s)
6627    COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));
6628  va_end(ap);
6629  return s;
6630}
6631
6632INTERCEPTOR(int, sem_unlink, const char *name) {
6633  void *ctx;
6634  COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);
6635  COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
6636  return REAL(sem_unlink)(name);
6637}
6638
6639#  define INIT_SEM                            \
6640    COMMON_INTERCEPT_FUNCTION(sem_init);      \
6641    COMMON_INTERCEPT_FUNCTION(sem_destroy);   \
6642    COMMON_INTERCEPT_FUNCTION(sem_wait);      \
6643    COMMON_INTERCEPT_FUNCTION(sem_trywait);   \
6644    COMMON_INTERCEPT_FUNCTION(sem_timedwait); \
6645    COMMON_INTERCEPT_FUNCTION(sem_post);      \
6646    COMMON_INTERCEPT_FUNCTION(sem_getvalue);  \
6647    COMMON_INTERCEPT_FUNCTION(sem_open);      \
6648    COMMON_INTERCEPT_FUNCTION(sem_unlink);
6649#else
6650#  define INIT_SEM
6651#endif  // SANITIZER_INTERCEPT_SEM
6652
6653#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
6654INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
6655  void *ctx;
6656  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
6657  int res = REAL(pthread_setcancelstate)(state, oldstate);
6658  if (res == 0 && oldstate != nullptr)
6659    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
6660  return res;
6661}
6662
6663INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
6664  void *ctx;
6665  COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
6666  int res = REAL(pthread_setcanceltype)(type, oldtype);
6667  if (res == 0 && oldtype != nullptr)
6668    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
6669  return res;
6670}
6671#define INIT_PTHREAD_SETCANCEL                                                 \
6672  COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate);                           \
6673  COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
6674#else
6675#define INIT_PTHREAD_SETCANCEL
6676#endif
6677
6678#if SANITIZER_INTERCEPT_MINCORE
6679INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
6680  void *ctx;
6681  COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
6682  int res = REAL(mincore)(addr, length, vec);
6683  if (res == 0) {
6684    uptr page_size = GetPageSizeCached();
6685    uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
6686    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
6687  }
6688  return res;
6689}
6690#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
6691#else
6692#define INIT_MINCORE
6693#endif
6694
6695#if SANITIZER_INTERCEPT_PROCESS_VM_READV
6696INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
6697            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6698            uptr flags) {
6699  void *ctx;
6700  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
6701                           remote_iov, riovcnt, flags);
6702  SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
6703                                       riovcnt, flags);
6704  if (res > 0)
6705    write_iovec(ctx, local_iov, liovcnt, res);
6706  return res;
6707}
6708
6709INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
6710            uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6711            uptr flags) {
6712  void *ctx;
6713  COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
6714                           remote_iov, riovcnt, flags);
6715  SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
6716                                        riovcnt, flags);
6717  if (res > 0)
6718    read_iovec(ctx, local_iov, liovcnt, res);
6719  return res;
6720}
6721#define INIT_PROCESS_VM_READV                                                  \
6722  COMMON_INTERCEPT_FUNCTION(process_vm_readv);                                 \
6723  COMMON_INTERCEPT_FUNCTION(process_vm_writev);
6724#else
6725#define INIT_PROCESS_VM_READV
6726#endif
6727
6728#if SANITIZER_INTERCEPT_CTERMID
6729INTERCEPTOR(char *, ctermid, char *s) {
6730  void *ctx;
6731  COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
6732  char *res = REAL(ctermid)(s);
6733  if (res) {
6734    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
6735  }
6736  return res;
6737}
6738#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
6739#else
6740#define INIT_CTERMID
6741#endif
6742
6743#if SANITIZER_INTERCEPT_CTERMID_R
6744INTERCEPTOR(char *, ctermid_r, char *s) {
6745  void *ctx;
6746  COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
6747  char *res = REAL(ctermid_r)(s);
6748  if (res) {
6749    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
6750  }
6751  return res;
6752}
6753#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
6754#else
6755#define INIT_CTERMID_R
6756#endif
6757
6758#if SANITIZER_INTERCEPT_RECV_RECVFROM
6759INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
6760  void *ctx;
6761  COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
6762  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6763  SSIZE_T res = REAL(recv)(fd, buf, len, flags);
6764  if (res > 0) {
6765    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6766  }
6767  if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
6768  return res;
6769}
6770
6771INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
6772            void *srcaddr, int *addrlen) {
6773  void *ctx;
6774  COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
6775                           addrlen);
6776  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6777  SIZE_T srcaddr_sz;
6778  if (srcaddr) srcaddr_sz = *addrlen;
6779  (void)srcaddr_sz;  // prevent "set but not used" warning
6780  SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
6781  if (res > 0)
6782    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6783  if (res >= 0 && srcaddr)
6784    COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
6785                                        Min((SIZE_T)*addrlen, srcaddr_sz));
6786  return res;
6787}
6788#define INIT_RECV_RECVFROM          \
6789  COMMON_INTERCEPT_FUNCTION(recv);  \
6790  COMMON_INTERCEPT_FUNCTION(recvfrom);
6791#else
6792#define INIT_RECV_RECVFROM
6793#endif
6794
6795#if SANITIZER_INTERCEPT_SEND_SENDTO
6796INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
6797  void *ctx;
6798  COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
6799  if (fd >= 0) {
6800    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6801    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6802  }
6803  SSIZE_T res = REAL(send)(fd, buf, len, flags);
6804  if (common_flags()->intercept_send && res > 0)
6805    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
6806  return res;
6807}
6808
6809INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
6810            void *dstaddr, int addrlen) {
6811  void *ctx;
6812  COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
6813  if (fd >= 0) {
6814    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6815    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6816  }
6817  // Can't check dstaddr as it may have uninitialized padding at the end.
6818  SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
6819  if (common_flags()->intercept_send && res > 0)
6820    COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
6821  return res;
6822}
6823#define INIT_SEND_SENDTO           \
6824  COMMON_INTERCEPT_FUNCTION(send); \
6825  COMMON_INTERCEPT_FUNCTION(sendto);
6826#else
6827#define INIT_SEND_SENDTO
6828#endif
6829
6830#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
6831INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
6832  void *ctx;
6833  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
6834  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6835  int res = REAL(eventfd_read)(fd, value);
6836  if (res == 0) {
6837    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
6838    if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
6839  }
6840  return res;
6841}
6842INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
6843  void *ctx;
6844  COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
6845  if (fd >= 0) {
6846    COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6847    COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6848  }
6849  int res = REAL(eventfd_write)(fd, value);
6850  return res;
6851}
6852#define INIT_EVENTFD_READ_WRITE            \
6853  COMMON_INTERCEPT_FUNCTION(eventfd_read); \
6854  COMMON_INTERCEPT_FUNCTION(eventfd_write)
6855#else
6856#define INIT_EVENTFD_READ_WRITE
6857#endif
6858
6859#if SANITIZER_INTERCEPT_STAT
6860INTERCEPTOR(int, stat, const char *path, void *buf) {
6861  void *ctx;
6862  COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
6863  if (common_flags()->intercept_stat)
6864    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6865  int res = REAL(stat)(path, buf);
6866  if (!res)
6867    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6868  return res;
6869}
6870#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
6871#else
6872#define INIT_STAT
6873#endif
6874
6875#if SANITIZER_INTERCEPT_LSTAT
6876INTERCEPTOR(int, lstat, const char *path, void *buf) {
6877  void *ctx;
6878  COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);
6879  if (common_flags()->intercept_stat)
6880    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6881  int res = REAL(lstat)(path, buf);
6882  if (!res)
6883    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6884  return res;
6885}
6886#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)
6887#else
6888#define INIT_LSTAT
6889#endif
6890
6891#if SANITIZER_INTERCEPT___XSTAT
6892INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
6893  void *ctx;
6894  COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
6895  if (common_flags()->intercept_stat)
6896    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6897  int res = REAL(__xstat)(version, path, buf);
6898  if (!res)
6899    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6900  return res;
6901}
6902#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
6903#else
6904#define INIT___XSTAT
6905#endif
6906
6907#if SANITIZER_INTERCEPT___XSTAT64
6908INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
6909  void *ctx;
6910  COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
6911  if (common_flags()->intercept_stat)
6912    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6913  int res = REAL(__xstat64)(version, path, buf);
6914  if (!res)
6915    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
6916  return res;
6917}
6918#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
6919#else
6920#define INIT___XSTAT64
6921#endif
6922
6923#if SANITIZER_INTERCEPT___LXSTAT
6924INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
6925  void *ctx;
6926  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
6927  if (common_flags()->intercept_stat)
6928    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6929  int res = REAL(__lxstat)(version, path, buf);
6930  if (!res)
6931    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
6932  return res;
6933}
6934#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
6935#else
6936#define INIT___LXSTAT
6937#endif
6938
6939#if SANITIZER_INTERCEPT___LXSTAT64
6940INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
6941  void *ctx;
6942  COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
6943  if (common_flags()->intercept_stat)
6944    COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
6945  int res = REAL(__lxstat64)(version, path, buf);
6946  if (!res)
6947    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
6948  return res;
6949}
6950#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
6951#else
6952#define INIT___LXSTAT64
6953#endif
6954
6955// FIXME: add other *stat interceptor
6956
6957#if SANITIZER_INTERCEPT_UTMP
6958INTERCEPTOR(void *, getutent, int dummy) {
6959  void *ctx;
6960  COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);
6961  void *res = REAL(getutent)(dummy);
6962  if (res)
6963    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6964  return res;
6965}
6966INTERCEPTOR(void *, getutid, void *ut) {
6967  void *ctx;
6968  COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);
6969  void *res = REAL(getutid)(ut);
6970  if (res)
6971    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6972  return res;
6973}
6974INTERCEPTOR(void *, getutline, void *ut) {
6975  void *ctx;
6976  COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);
6977  void *res = REAL(getutline)(ut);
6978  if (res)
6979    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
6980  return res;
6981}
6982#define INIT_UTMP                      \
6983  COMMON_INTERCEPT_FUNCTION(getutent); \
6984  COMMON_INTERCEPT_FUNCTION(getutid);  \
6985  COMMON_INTERCEPT_FUNCTION(getutline);
6986#else
6987#define INIT_UTMP
6988#endif
6989
6990#if SANITIZER_INTERCEPT_UTMPX
6991INTERCEPTOR(void *, getutxent, int dummy) {
6992  void *ctx;
6993  COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);
6994  void *res = REAL(getutxent)(dummy);
6995  if (res)
6996    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
6997  return res;
6998}
6999INTERCEPTOR(void *, getutxid, void *ut) {
7000  void *ctx;
7001  COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);
7002  void *res = REAL(getutxid)(ut);
7003  if (res)
7004    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
7005  return res;
7006}
7007INTERCEPTOR(void *, getutxline, void *ut) {
7008  void *ctx;
7009  COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);
7010  void *res = REAL(getutxline)(ut);
7011  if (res)
7012    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
7013  return res;
7014}
7015INTERCEPTOR(void *, pututxline, const void *ut) {
7016  void *ctx;
7017  COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
7018  if (ut)
7019    COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
7020  void *res = REAL(pututxline)(ut);
7021  if (res)
7022    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
7023  return res;
7024}
7025#define INIT_UTMPX                      \
7026  COMMON_INTERCEPT_FUNCTION(getutxent); \
7027  COMMON_INTERCEPT_FUNCTION(getutxid);  \
7028  COMMON_INTERCEPT_FUNCTION(getutxline); \
7029  COMMON_INTERCEPT_FUNCTION(pututxline);
7030#else
7031#define INIT_UTMPX
7032#endif
7033
7034#if SANITIZER_INTERCEPT_GETLOADAVG
7035INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {
7036  void *ctx;
7037  COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);
7038  int res = REAL(getloadavg)(loadavg, nelem);
7039  if (res > 0)
7040    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));
7041  return res;
7042}
7043#define INIT_GETLOADAVG                      \
7044  COMMON_INTERCEPT_FUNCTION(getloadavg);
7045#else
7046#define INIT_GETLOADAVG
7047#endif
7048
7049#if SANITIZER_INTERCEPT_MCHECK_MPROBE
7050INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
7051  return 0;
7052}
7053
7054INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
7055  return 0;
7056}
7057
7058INTERCEPTOR(int, mprobe, void *ptr) {
7059  return 0;
7060}
7061#endif
7062
7063INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
7064  void *ctx;
7065  COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
7066  SIZE_T res = REAL(wcslen)(s);
7067  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
7068  return res;
7069}
7070
7071INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
7072  void *ctx;
7073  COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
7074  SIZE_T res = REAL(wcsnlen)(s, n);
7075  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
7076  return res;
7077}
7078#define INIT_WCSLEN                  \
7079  COMMON_INTERCEPT_FUNCTION(wcslen); \
7080  COMMON_INTERCEPT_FUNCTION(wcsnlen);
7081
7082#if SANITIZER_INTERCEPT_WCSCAT
7083INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
7084  void *ctx;
7085  COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
7086  SIZE_T src_size = internal_wcslen(src);
7087  SIZE_T dst_size = internal_wcslen(dst);
7088  COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
7089  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
7090  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
7091                                 (src_size + 1) * sizeof(wchar_t));
7092  return REAL(wcscat)(dst, src);
7093}
7094
7095INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
7096  void *ctx;
7097  COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
7098  SIZE_T src_size = internal_wcsnlen(src, n);
7099  SIZE_T dst_size = internal_wcslen(dst);
7100  COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
7101                                Min(src_size + 1, n) * sizeof(wchar_t));
7102  COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
7103  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
7104                                 (src_size + 1) * sizeof(wchar_t));
7105  return REAL(wcsncat)(dst, src, n);
7106}
7107#define INIT_WCSCAT                  \
7108  COMMON_INTERCEPT_FUNCTION(wcscat); \
7109  COMMON_INTERCEPT_FUNCTION(wcsncat);
7110#else
7111#define INIT_WCSCAT
7112#endif
7113
7114#if SANITIZER_INTERCEPT_WCSDUP
7115INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {
7116  void *ctx;
7117  COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);
7118  SIZE_T len = internal_wcslen(s);
7119  COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));
7120  wchar_t *result = REAL(wcsdup)(s);
7121  if (result)
7122    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));
7123  return result;
7124}
7125
7126#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);
7127#else
7128#define INIT_WCSDUP
7129#endif
7130
7131#if SANITIZER_INTERCEPT_STRXFRM
7132static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); }
7133
7134static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); }
7135
7136#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...)             \
7137  {                                                                        \
7138    void *ctx;                                                             \
7139    COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \
7140    COMMON_INTERCEPTOR_READ_RANGE(ctx, src,                                \
7141                                  sizeof(*src) * (RealStrLen(src) + 1));   \
7142    SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__);             \
7143    if (res < len)                                                         \
7144      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \
7145    return res;                                                            \
7146  }
7147
7148INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {
7149  STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);
7150}
7151
7152INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,
7153            void *locale) {
7154  STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);
7155}
7156
7157#define INIT_STRXFRM                  \
7158  COMMON_INTERCEPT_FUNCTION(strxfrm); \
7159  COMMON_INTERCEPT_FUNCTION(strxfrm_l);
7160#else
7161#define INIT_STRXFRM
7162#endif
7163
7164#if SANITIZER_INTERCEPT___STRXFRM_L
7165INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,
7166            void *locale) {
7167  STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);
7168}
7169
7170#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);
7171#else
7172#define INIT___STRXFRM_L
7173#endif
7174
7175#if SANITIZER_INTERCEPT_WCSXFRM
7176INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {
7177  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);
7178}
7179
7180INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
7181            void *locale) {
7182  STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);
7183}
7184
7185#define INIT_WCSXFRM                  \
7186  COMMON_INTERCEPT_FUNCTION(wcsxfrm); \
7187  COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);
7188#else
7189#define INIT_WCSXFRM
7190#endif
7191
7192#if SANITIZER_INTERCEPT___WCSXFRM_L
7193INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
7194            void *locale) {
7195  STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);
7196}
7197
7198#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);
7199#else
7200#define INIT___WCSXFRM_L
7201#endif
7202
7203#if SANITIZER_INTERCEPT_ACCT
7204INTERCEPTOR(int, acct, const char *file) {
7205  void *ctx;
7206  COMMON_INTERCEPTOR_ENTER(ctx, acct, file);
7207  if (file)
7208    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
7209  return REAL(acct)(file);
7210}
7211#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)
7212#else
7213#define INIT_ACCT
7214#endif
7215
7216#if SANITIZER_INTERCEPT_USER_FROM_UID
7217INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {
7218  void *ctx;
7219  const char *user;
7220  COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);
7221  user = REAL(user_from_uid)(uid, nouser);
7222  if (user)
7223    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1);
7224  return user;
7225}
7226#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)
7227#else
7228#define INIT_USER_FROM_UID
7229#endif
7230
7231#if SANITIZER_INTERCEPT_UID_FROM_USER
7232INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {
7233  void *ctx;
7234  int res;
7235  COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);
7236  if (name)
7237    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7238  res = REAL(uid_from_user)(name, uid);
7239  if (uid)
7240    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));
7241  return res;
7242}
7243#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)
7244#else
7245#define INIT_UID_FROM_USER
7246#endif
7247
7248#if SANITIZER_INTERCEPT_GROUP_FROM_GID
7249INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {
7250  void *ctx;
7251  const char *group;
7252  COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);
7253  group = REAL(group_from_gid)(gid, nogroup);
7254  if (group)
7255    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1);
7256  return group;
7257}
7258#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)
7259#else
7260#define INIT_GROUP_FROM_GID
7261#endif
7262
7263#if SANITIZER_INTERCEPT_GID_FROM_GROUP
7264INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {
7265  void *ctx;
7266  int res;
7267  COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);
7268  if (group)
7269    COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1);
7270  res = REAL(gid_from_group)(group, gid);
7271  if (gid)
7272    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));
7273  return res;
7274}
7275#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)
7276#else
7277#define INIT_GID_FROM_GROUP
7278#endif
7279
7280#if SANITIZER_INTERCEPT_ACCESS
7281INTERCEPTOR(int, access, const char *path, int mode) {
7282  void *ctx;
7283  COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);
7284  if (path)
7285    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7286  return REAL(access)(path, mode);
7287}
7288#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)
7289#else
7290#define INIT_ACCESS
7291#endif
7292
7293#if SANITIZER_INTERCEPT_FACCESSAT
7294INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
7295  void *ctx;
7296  COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);
7297  if (path)
7298    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7299  return REAL(faccessat)(fd, path, mode, flags);
7300}
7301#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)
7302#else
7303#define INIT_FACCESSAT
7304#endif
7305
7306#if SANITIZER_INTERCEPT_GETGROUPLIST
7307INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
7308            int *ngroups) {
7309  void *ctx;
7310  int res;
7311  COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
7312  if (name)
7313    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7314  if (ngroups)
7315    COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
7316  res = REAL(getgrouplist)(name, basegid, groups, ngroups);
7317  if (!res && groups && ngroups) {
7318    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
7319    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
7320  }
7321  return res;
7322}
7323
7324#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);
7325#else
7326#define INIT_GETGROUPLIST
7327#endif
7328
7329#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP
7330INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
7331            int maxgrp, int *ngroups) {
7332  void *ctx;
7333  int res;
7334  COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,
7335                           maxgrp, ngroups);
7336  if (name)
7337    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7338  res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
7339  if (!res && groups && ngroups) {
7340    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
7341    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
7342  }
7343  return res;
7344}
7345
7346#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);
7347#else
7348#define INIT_GETGROUPMEMBERSHIP
7349#endif
7350
7351#if SANITIZER_INTERCEPT_READLINK
7352INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
7353  void* ctx;
7354  COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
7355  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7356  SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
7357  if (res > 0)
7358    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7359  return res;
7360}
7361
7362#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
7363#else
7364#define INIT_READLINK
7365#endif
7366
7367#if SANITIZER_INTERCEPT_READLINKAT
7368INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
7369            SIZE_T bufsiz) {
7370  void* ctx;
7371  COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
7372  COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7373  SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
7374  if (res > 0)
7375    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7376  return res;
7377}
7378
7379#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
7380#else
7381#define INIT_READLINKAT
7382#endif
7383
7384#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
7385INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
7386            struct file_handle *handle, int *mount_id, int flags) {
7387  void* ctx;
7388  COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
7389                           mount_id, flags);
7390  COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1);
7391
7392  __sanitizer_file_handle *sanitizer_handle =
7393      reinterpret_cast<__sanitizer_file_handle*>(handle);
7394  COMMON_INTERCEPTOR_READ_RANGE(
7395      ctx, &sanitizer_handle->handle_bytes,
7396      sizeof(sanitizer_handle->handle_bytes));
7397
7398  int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
7399  if (!res) {
7400    COMMON_INTERCEPTOR_WRITE_RANGE(
7401        ctx, &sanitizer_handle->handle_bytes,
7402        sizeof(sanitizer_handle->handle_bytes));
7403    COMMON_INTERCEPTOR_WRITE_RANGE(
7404        ctx, &sanitizer_handle->handle_type,
7405        sizeof(sanitizer_handle->handle_type));
7406    COMMON_INTERCEPTOR_WRITE_RANGE(
7407        ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7408    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
7409  }
7410  return res;
7411}
7412
7413#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
7414#else
7415#define INIT_NAME_TO_HANDLE_AT
7416#endif
7417
7418#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
7419INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
7420            int flags) {
7421  void* ctx;
7422  COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
7423
7424  __sanitizer_file_handle *sanitizer_handle =
7425      reinterpret_cast<__sanitizer_file_handle*>(handle);
7426  COMMON_INTERCEPTOR_READ_RANGE(
7427      ctx, &sanitizer_handle->handle_bytes,
7428      sizeof(sanitizer_handle->handle_bytes));
7429  COMMON_INTERCEPTOR_READ_RANGE(
7430      ctx, &sanitizer_handle->handle_type,
7431      sizeof(sanitizer_handle->handle_type));
7432  COMMON_INTERCEPTOR_READ_RANGE(
7433      ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7434
7435  return REAL(open_by_handle_at)(mount_fd, handle, flags);
7436}
7437
7438#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
7439#else
7440#define INIT_OPEN_BY_HANDLE_AT
7441#endif
7442
7443#if SANITIZER_INTERCEPT_STRLCPY
7444INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {
7445  void *ctx;
7446  SIZE_T res;
7447  COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);
7448  if (src) {
7449    // Keep strnlen as macro argument, as macro may ignore it.
7450    COMMON_INTERCEPTOR_READ_STRING(
7451        ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);
7452  }
7453  res = REAL(strlcpy)(dst, src, size);
7454  COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1);
7455  return res;
7456}
7457
7458INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {
7459  void *ctx;
7460  SIZE_T len = 0;
7461  COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);
7462  // src is checked in the strlcpy() interceptor
7463  if (dst) {
7464    len = internal_strnlen(dst, size);
7465    COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);
7466  }
7467  // Reuse the rest of the code in the strlcpy() interceptor
7468  return WRAP(strlcpy)(dst + len, src, size - len) + len;
7469}
7470#define INIT_STRLCPY \
7471  COMMON_INTERCEPT_FUNCTION(strlcpy); \
7472  COMMON_INTERCEPT_FUNCTION(strlcat);
7473#else
7474#define INIT_STRLCPY
7475#endif
7476
7477#if SANITIZER_INTERCEPT_MMAP
7478INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,
7479            OFF_T off) {
7480  void *ctx;
7481  if (common_flags()->detect_write_exec)
7482    ReportMmapWriteExec(prot, flags);
7483  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7484    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7485  COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
7486  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);
7487}
7488
7489INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {
7490  void *ctx;
7491  if (common_flags()->detect_write_exec)
7492    ReportMmapWriteExec(prot, 0);
7493  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7494    return (int)internal_mprotect(addr, sz, prot);
7495  COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);
7496  MprotectMallocZones(addr, prot);
7497  return REAL(mprotect)(addr, sz, prot);
7498}
7499#define INIT_MMAP                                                              \
7500  COMMON_INTERCEPT_FUNCTION(mmap);                                             \
7501  COMMON_INTERCEPT_FUNCTION(mprotect);
7502#else
7503#define INIT_MMAP
7504#endif
7505
7506#if SANITIZER_INTERCEPT_MMAP64
7507INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,
7508            OFF64_T off) {
7509  void *ctx;
7510  if (common_flags()->detect_write_exec)
7511    ReportMmapWriteExec(prot, flags);
7512  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7513    return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7514  COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
7515  COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);
7516}
7517#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);
7518#else
7519#define INIT_MMAP64
7520#endif
7521
7522#if SANITIZER_INTERCEPT_DEVNAME
7523INTERCEPTOR(char *, devname, u64 dev, u32 type) {
7524  void *ctx;
7525  char *name;
7526  COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);
7527  name = REAL(devname)(dev, type);
7528  if (name)
7529    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
7530  return name;
7531}
7532#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);
7533#else
7534#define INIT_DEVNAME
7535#endif
7536
7537#if SANITIZER_INTERCEPT_DEVNAME_R
7538#if SANITIZER_NETBSD
7539#define DEVNAME_R_RETTYPE int
7540#define DEVNAME_R_SUCCESS(x) (!(x))
7541#else
7542#define DEVNAME_R_RETTYPE char*
7543#define DEVNAME_R_SUCCESS(x) (x)
7544#endif
7545INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
7546            uptr len) {
7547  void *ctx;
7548  COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
7549  DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
7550  if (DEVNAME_R_SUCCESS(res))
7551    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1);
7552  return res;
7553}
7554#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);
7555#else
7556#define INIT_DEVNAME_R
7557#endif
7558
7559#if SANITIZER_INTERCEPT_FGETLN
7560INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {
7561  void *ctx;
7562  COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);
7563  char *str = REAL(fgetln)(stream, len);
7564  if (str && len) {
7565    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7566    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);
7567  }
7568  return str;
7569}
7570#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)
7571#else
7572#define INIT_FGETLN
7573#endif
7574
7575#if SANITIZER_INTERCEPT_STRMODE
7576INTERCEPTOR(void, strmode, u32 mode, char *bp) {
7577  void *ctx;
7578  COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);
7579  REAL(strmode)(mode, bp);
7580  if (bp)
7581    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1);
7582}
7583#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)
7584#else
7585#define INIT_STRMODE
7586#endif
7587
7588#if SANITIZER_INTERCEPT_TTYENT
7589INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {
7590  void *ctx;
7591  COMMON_INTERCEPTOR_ENTER(ctx, getttyent);
7592  struct __sanitizer_ttyent *ttyent = REAL(getttyent)();
7593  if (ttyent)
7594    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7595  return ttyent;
7596}
7597INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
7598  void *ctx;
7599  COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);
7600  if (name)
7601    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7602  struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);
7603  if (ttyent)
7604    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7605  return ttyent;
7606}
7607#define INIT_TTYENT \
7608  COMMON_INTERCEPT_FUNCTION(getttyent); \
7609  COMMON_INTERCEPT_FUNCTION(getttynam);
7610#else
7611#define INIT_TTYENT
7612#endif
7613
7614#if SANITIZER_INTERCEPT_TTYENTPATH
7615INTERCEPTOR(int, setttyentpath, char *path) {
7616  void *ctx;
7617  COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
7618  if (path)
7619    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7620  return REAL(setttyentpath)(path);
7621}
7622#define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);
7623#else
7624#define INIT_TTYENTPATH
7625#endif
7626
7627#if SANITIZER_INTERCEPT_PROTOENT
7628static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {
7629  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
7630
7631  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1);
7632
7633  SIZE_T pp_size = 1; // One handles the trailing \0
7634
7635  for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
7636      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1);
7637
7638  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
7639                                  pp_size * sizeof(char **));
7640}
7641
7642INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
7643  void *ctx;
7644  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
7645  struct __sanitizer_protoent *p = REAL(getprotoent)();
7646  if (p)
7647    write_protoent(ctx, p);
7648  return p;
7649}
7650
7651INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
7652  void *ctx;
7653  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);
7654  if (name)
7655    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7656  struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
7657  if (p)
7658    write_protoent(ctx, p);
7659  return p;
7660}
7661
7662INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
7663  void *ctx;
7664  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
7665  struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
7666  if (p)
7667    write_protoent(ctx, p);
7668  return p;
7669}
7670#define INIT_PROTOENT \
7671  COMMON_INTERCEPT_FUNCTION(getprotoent); \
7672  COMMON_INTERCEPT_FUNCTION(getprotobyname); \
7673  COMMON_INTERCEPT_FUNCTION(getprotobynumber)
7674#else
7675#define INIT_PROTOENT
7676#endif
7677
7678#if SANITIZER_INTERCEPT_PROTOENT_R
7679INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,
7680            char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {
7681  void *ctx;
7682  COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,
7683                           result);
7684  int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);
7685
7686  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7687  if (!res && *result)
7688    write_protoent(ctx, *result);
7689  return res;
7690}
7691
7692INTERCEPTOR(int, getprotobyname_r, const char *name,
7693            struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,
7694            struct __sanitizer_protoent **result) {
7695  void *ctx;
7696  COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,
7697                           buflen, result);
7698  if (name)
7699    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7700  int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);
7701
7702  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7703  if (!res && *result)
7704    write_protoent(ctx, *result);
7705  return res;
7706}
7707
7708INTERCEPTOR(int, getprotobynumber_r, int num,
7709            struct __sanitizer_protoent *result_buf, char *buf,
7710            SIZE_T buflen, struct __sanitizer_protoent **result) {
7711  void *ctx;
7712  COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,
7713                           buflen, result);
7714  int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);
7715
7716  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7717  if (!res && *result)
7718    write_protoent(ctx, *result);
7719  return res;
7720}
7721
7722#define INIT_PROTOENT_R \
7723  COMMON_INTERCEPT_FUNCTION(getprotoent_r); \
7724  COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \
7725  COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);
7726#else
7727#define INIT_PROTOENT_R
7728#endif
7729
7730#if SANITIZER_INTERCEPT_NETENT
7731INTERCEPTOR(struct __sanitizer_netent *, getnetent) {
7732  void *ctx;
7733  COMMON_INTERCEPTOR_ENTER(ctx, getnetent);
7734  struct __sanitizer_netent *n = REAL(getnetent)();
7735  if (n) {
7736    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7737
7738    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7739
7740    SIZE_T nn_size = 1; // One handles the trailing \0
7741
7742    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7743      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7744
7745    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7746                                   nn_size * sizeof(char **));
7747  }
7748  return n;
7749}
7750
7751INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {
7752  void *ctx;
7753  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);
7754  if (name)
7755    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7756  struct __sanitizer_netent *n = REAL(getnetbyname)(name);
7757  if (n) {
7758    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7759
7760    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7761
7762    SIZE_T nn_size = 1; // One handles the trailing \0
7763
7764    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7765      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7766
7767    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7768                                   nn_size * sizeof(char **));
7769  }
7770  return n;
7771}
7772
7773INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
7774  void *ctx;
7775  COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);
7776  struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);
7777  if (n) {
7778    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7779
7780    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7781
7782    SIZE_T nn_size = 1; // One handles the trailing \0
7783
7784    for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7785      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7786
7787    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7788                                   nn_size * sizeof(char **));
7789  }
7790  return n;
7791}
7792#define INIT_NETENT \
7793  COMMON_INTERCEPT_FUNCTION(getnetent); \
7794  COMMON_INTERCEPT_FUNCTION(getnetbyname); \
7795  COMMON_INTERCEPT_FUNCTION(getnetbyaddr)
7796#else
7797#define INIT_NETENT
7798#endif
7799
7800#if SANITIZER_INTERCEPT_GETMNTINFO
7801INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
7802  void *ctx;
7803  COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
7804  int cnt = REAL(getmntinfo)(mntbufp, flags);
7805  if (cnt > 0 && mntbufp) {
7806    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
7807    if (*mntbufp)
7808#if SANITIZER_NETBSD
7809      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
7810#else
7811      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
7812#endif
7813  }
7814  return cnt;
7815}
7816#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
7817#else
7818#define INIT_GETMNTINFO
7819#endif
7820
7821#if SANITIZER_INTERCEPT_MI_VECTOR_HASH
7822INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
7823            u32 hashes[3]) {
7824  void *ctx;
7825  COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
7826  if (key)
7827    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
7828  REAL(mi_vector_hash)(key, len, seed, hashes);
7829  if (hashes)
7830    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
7831}
7832#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
7833#else
7834#define INIT_MI_VECTOR_HASH
7835#endif
7836
7837#if SANITIZER_INTERCEPT_SETVBUF
7838INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
7839  SIZE_T size) {
7840  void *ctx;
7841  COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
7842  int ret = REAL(setvbuf)(stream, buf, mode, size);
7843  if (buf)
7844    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
7845  if (stream)
7846      unpoison_file(stream);
7847  return ret;
7848}
7849
7850INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
7851  void *ctx;
7852  COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
7853  REAL(setbuf)(stream, buf);
7854  if (buf) {
7855    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
7856  }
7857  if (stream)
7858      unpoison_file(stream);
7859}
7860
7861INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) {
7862  void *ctx;
7863  COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode);
7864  REAL(setbuffer)(stream, buf, mode);
7865  if (buf) {
7866    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
7867  }
7868  if (stream)
7869    unpoison_file(stream);
7870}
7871
7872INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
7873  void *ctx;
7874  COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
7875  REAL(setlinebuf)(stream);
7876  if (stream)
7877    unpoison_file(stream);
7878}
7879#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
7880    COMMON_INTERCEPT_FUNCTION(setbuf); \
7881    COMMON_INTERCEPT_FUNCTION(setbuffer); \
7882    COMMON_INTERCEPT_FUNCTION(setlinebuf)
7883#else
7884#define INIT_SETVBUF
7885#endif
7886
7887#if SANITIZER_INTERCEPT_GETVFSSTAT
7888INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
7889  void *ctx;
7890  COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
7891  int ret = REAL(getvfsstat)(buf, bufsize, flags);
7892  if (buf && ret > 0)
7893    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
7894  return ret;
7895}
7896#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
7897#else
7898#define INIT_GETVFSSTAT
7899#endif
7900
7901#if SANITIZER_INTERCEPT_REGEX
7902INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
7903  void *ctx;
7904  COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
7905  if (pattern)
7906    COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1);
7907  int res = REAL(regcomp)(preg, pattern, cflags);
7908  if (!res)
7909    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
7910  return res;
7911}
7912INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
7913            struct __sanitizer_regmatch *pmatch[], int eflags) {
7914  void *ctx;
7915  COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
7916  if (preg)
7917    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7918  if (string)
7919    COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1);
7920  int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
7921  if (!res && pmatch)
7922    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
7923  return res;
7924}
7925INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
7926            SIZE_T errbuf_size) {
7927  void *ctx;
7928  COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
7929  if (preg)
7930    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7931  SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
7932  if (errbuf)
7933    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1);
7934  return res;
7935}
7936INTERCEPTOR(void, regfree, const void *preg) {
7937  void *ctx;
7938  COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
7939  if (preg)
7940    COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
7941  REAL(regfree)(preg);
7942}
7943#define INIT_REGEX                                                             \
7944  COMMON_INTERCEPT_FUNCTION(regcomp);                                          \
7945  COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4");             \
7946  COMMON_INTERCEPT_FUNCTION(regerror);                                         \
7947  COMMON_INTERCEPT_FUNCTION(regfree);
7948#else
7949#define INIT_REGEX
7950#endif
7951
7952#if SANITIZER_INTERCEPT_REGEXSUB
7953INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
7954            const struct __sanitizer_regmatch *rm, const char *str) {
7955  void *ctx;
7956  COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
7957  if (sub)
7958    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
7959  // The implementation demands and hardcodes 10 elements
7960  if (rm)
7961    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
7962  if (str)
7963    COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
7964  SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
7965  if (res > 0 && buf)
7966    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
7967  return res;
7968}
7969INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
7970            const struct __sanitizer_regmatch *rm, const char *sstr) {
7971  void *ctx;
7972  COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
7973  if (sub)
7974    COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
7975  // Hardcode 10 elements as this is hardcoded size
7976  if (rm)
7977    COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
7978  if (sstr)
7979    COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1);
7980  SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
7981  if (res > 0 && buf) {
7982    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
7983    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1);
7984  }
7985  return res;
7986}
7987
7988#define INIT_REGEXSUB                                                          \
7989  COMMON_INTERCEPT_FUNCTION(regnsub);                                          \
7990  COMMON_INTERCEPT_FUNCTION(regasub);
7991#else
7992#define INIT_REGEXSUB
7993#endif
7994
7995#if SANITIZER_INTERCEPT_FTS
7996INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
7997            int (*compar)(void **, void **)) {
7998  void *ctx;
7999  COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
8000  if (path_argv) {
8001    for (char *const *pa = path_argv; ; ++pa) {
8002      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
8003      if (!*pa)
8004        break;
8005      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
8006    }
8007  }
8008  // TODO(kamil): handle compar callback
8009  void *fts = REAL(fts_open)(path_argv, options, compar);
8010  if (fts)
8011    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
8012  return fts;
8013}
8014
8015INTERCEPTOR(void *, fts_read, void *ftsp) {
8016  void *ctx;
8017  COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
8018  if (ftsp)
8019    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8020  void *ftsent = REAL(fts_read)(ftsp);
8021  if (ftsent)
8022    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
8023  return ftsent;
8024}
8025
8026INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
8027  void *ctx;
8028  COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
8029  if (ftsp)
8030    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8031  void *ftsent = REAL(fts_children)(ftsp, options);
8032  if (ftsent)
8033    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
8034  return ftsent;
8035}
8036
8037INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
8038  void *ctx;
8039  COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
8040  if (ftsp)
8041    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8042  if (f)
8043    COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
8044  return REAL(fts_set)(ftsp, f, options);
8045}
8046
8047INTERCEPTOR(int, fts_close, void *ftsp) {
8048  void *ctx;
8049  COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
8050  if (ftsp)
8051    COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8052  return REAL(fts_close)(ftsp);
8053}
8054#define INIT_FTS                                                               \
8055  COMMON_INTERCEPT_FUNCTION(fts_open);                                         \
8056  COMMON_INTERCEPT_FUNCTION(fts_read);                                         \
8057  COMMON_INTERCEPT_FUNCTION(fts_children);                                     \
8058  COMMON_INTERCEPT_FUNCTION(fts_set);                                          \
8059  COMMON_INTERCEPT_FUNCTION(fts_close);
8060#else
8061#define INIT_FTS
8062#endif
8063
8064#if SANITIZER_INTERCEPT_SYSCTL
8065INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
8066            SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
8067  void *ctx;
8068  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
8069    return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
8070  COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
8071                           newlen);
8072  if (name)
8073    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
8074  if (oldlenp)
8075    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8076  if (newp && newlen)
8077    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
8078  int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
8079  if (!res) {
8080    if (oldlenp) {
8081      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8082      if (oldp)
8083        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
8084    }
8085  }
8086  return res;
8087}
8088
8089INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
8090            void *newp, SIZE_T newlen) {
8091  void *ctx;
8092  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
8093    return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
8094  COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
8095                           newlen);
8096  if (sname)
8097    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8098  if (oldlenp)
8099    COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8100  if (newp && newlen)
8101    COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
8102  int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
8103  if (!res) {
8104    if (oldlenp) {
8105      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8106      if (oldp)
8107        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
8108    }
8109  }
8110  return res;
8111}
8112
8113INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
8114            SIZE_T *namelenp) {
8115  void *ctx;
8116  COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
8117  if (sname)
8118    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8119  if (namelenp)
8120    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
8121  int res = REAL(sysctlnametomib)(sname, name, namelenp);
8122  if (!res) {
8123    if (namelenp) {
8124      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
8125      if (name)
8126        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
8127    }
8128  }
8129  return res;
8130}
8131
8132#define INIT_SYSCTL                        \
8133  COMMON_INTERCEPT_FUNCTION(sysctl);       \
8134  COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
8135  COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
8136#else
8137#define INIT_SYSCTL
8138#endif
8139
8140#if SANITIZER_INTERCEPT_ASYSCTL
8141INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
8142  void *ctx;
8143  COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
8144  if (name)
8145    COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
8146  void *res = REAL(asysctl)(name, namelen, len);
8147  if (res && len) {
8148    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8149    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
8150  }
8151  return res;
8152}
8153
8154INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
8155  void *ctx;
8156  COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
8157  if (sname)
8158    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8159  void *res = REAL(asysctlbyname)(sname, len);
8160  if (res && len) {
8161    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8162    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
8163  }
8164  return res;
8165}
8166#define INIT_ASYSCTL                           \
8167  COMMON_INTERCEPT_FUNCTION(asysctl);          \
8168  COMMON_INTERCEPT_FUNCTION(asysctlbyname);
8169#else
8170#define INIT_ASYSCTL
8171#endif
8172
8173#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
8174INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
8175            unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
8176            int v) {
8177  void *ctx;
8178  COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
8179                           csz, rnode, v);
8180  if (sname)
8181    COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8182  if (namelenp)
8183    COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
8184  if (csz)
8185    COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
8186  // Skip rnode, it's rarely used and not trivial to sanitize
8187  // It's also used mostly internally
8188  int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
8189  if (!res) {
8190    if (namelenp) {
8191      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
8192      if (name)
8193        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
8194    }
8195    if (csz) {
8196      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
8197      if (cname)
8198        COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
8199    }
8200  }
8201  return res;
8202}
8203#define INIT_SYSCTLGETMIBINFO                  \
8204  COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
8205#else
8206#define INIT_SYSCTLGETMIBINFO
8207#endif
8208
8209#if SANITIZER_INTERCEPT_NL_LANGINFO
8210INTERCEPTOR(char *, nl_langinfo, long item) {
8211  void *ctx;
8212  COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
8213  char *ret = REAL(nl_langinfo)(item);
8214  if (ret)
8215    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
8216  return ret;
8217}
8218#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
8219#else
8220#define INIT_NL_LANGINFO
8221#endif
8222
8223#if SANITIZER_INTERCEPT_MODCTL
8224INTERCEPTOR(int, modctl, int operation, void *argp) {
8225  void *ctx;
8226  int ret;
8227  COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
8228
8229  if (operation == modctl_load) {
8230    if (argp) {
8231      __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
8232      COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
8233      if (ml->ml_filename)
8234        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
8235                                      internal_strlen(ml->ml_filename) + 1);
8236      if (ml->ml_props)
8237        COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
8238    }
8239    ret = REAL(modctl)(operation, argp);
8240  } else if (operation == modctl_unload) {
8241    if (argp) {
8242      const char *name = (const char *)argp;
8243      COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
8244    }
8245    ret = REAL(modctl)(operation, argp);
8246  } else if (operation == modctl_stat) {
8247    uptr iov_len;
8248    struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
8249    if (iov) {
8250      COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
8251      iov_len = iov->iov_len;
8252    }
8253    ret = REAL(modctl)(operation, argp);
8254    if (iov)
8255      COMMON_INTERCEPTOR_WRITE_RANGE(
8256          ctx, iov->iov_base, Min(iov_len,  iov->iov_len));
8257  } else if (operation == modctl_exists) {
8258    ret = REAL(modctl)(operation, argp);
8259  } else {
8260    ret = REAL(modctl)(operation, argp);
8261  }
8262
8263  return ret;
8264}
8265#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
8266#else
8267#define INIT_MODCTL
8268#endif
8269
8270#if SANITIZER_INTERCEPT_STRTONUM
8271INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
8272            long long maxval, const char **errstr) {
8273  void *ctx;
8274  COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
8275
8276  // TODO(kamil): Implement strtoll as a common inteceptor
8277  char *real_endptr;
8278  long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
8279  StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
8280
8281  ret = REAL(strtonum)(nptr, minval, maxval, errstr);
8282  if (errstr) {
8283    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
8284     if (*errstr)
8285      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1);
8286  }
8287  return ret;
8288}
8289#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
8290#else
8291#define INIT_STRTONUM
8292#endif
8293
8294#if SANITIZER_INTERCEPT_FPARSELN
8295INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
8296            SIZE_T *lineno, const char delim[3], int flags) {
8297  void *ctx;
8298  COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
8299  if (lineno)
8300    COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
8301  if (delim)
8302    COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
8303  char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
8304  if (ret) {
8305    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
8306    if (len)
8307      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8308    if (lineno)
8309      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
8310  }
8311  return ret;
8312}
8313#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
8314#else
8315#define INIT_FPARSELN
8316#endif
8317
8318#if SANITIZER_INTERCEPT_STATVFS1
8319INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
8320  void *ctx;
8321  COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
8322  if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
8323  int res = REAL(statvfs1)(path, buf, flags);
8324  if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
8325  return res;
8326}
8327INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
8328  void *ctx;
8329  COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
8330  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
8331  int res = REAL(fstatvfs1)(fd, buf, flags);
8332  if (!res) {
8333    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
8334    if (fd >= 0)
8335      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
8336  }
8337  return res;
8338}
8339#define INIT_STATVFS1                  \
8340  COMMON_INTERCEPT_FUNCTION(statvfs1);  \
8341  COMMON_INTERCEPT_FUNCTION(fstatvfs1);
8342#else
8343#define INIT_STATVFS1
8344#endif
8345
8346#if SANITIZER_INTERCEPT_STRTOI
8347INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
8348            INTMAX_T low, INTMAX_T high, int *rstatus) {
8349  void *ctx;
8350  COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
8351  char *real_endptr;
8352  INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
8353  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
8354  if (rstatus)
8355    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
8356  return ret;
8357}
8358
8359INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
8360            UINTMAX_T low, UINTMAX_T high, int *rstatus) {
8361  void *ctx;
8362  COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
8363  char *real_endptr;
8364  UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
8365  StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
8366  if (rstatus)
8367    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
8368  return ret;
8369}
8370#define INIT_STRTOI                                                            \
8371  COMMON_INTERCEPT_FUNCTION(strtoi);                                           \
8372  COMMON_INTERCEPT_FUNCTION(strtou)
8373#else
8374#define INIT_STRTOI
8375#endif
8376
8377#if SANITIZER_INTERCEPT_CAPSICUM
8378#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...)          \
8379  {                                                                        \
8380    void *ctx;                                                             \
8381    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
8382    if (rights)                                                            \
8383      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));         \
8384    __sanitizer_cap_rights_t *ret =                                        \
8385        REAL(cap_rights_init)(rights, ##__VA_ARGS__);                      \
8386    if (ret)                                                               \
8387      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));              \
8388    return ret;                                                            \
8389  }
8390
8391#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...)           \
8392  {                                                                       \
8393    void *ctx;                                                            \
8394    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
8395    if (rights)                                                           \
8396      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));        \
8397    __sanitizer_cap_rights_t *ret =                                       \
8398        REAL(cap_rights_set)(rights, ##__VA_ARGS__);                      \
8399    if (ret)                                                              \
8400      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));             \
8401    return ret;                                                           \
8402  }
8403
8404#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...)         \
8405  {                                                                         \
8406    void *ctx;                                                              \
8407    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
8408    if (rights)                                                             \
8409      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));          \
8410    __sanitizer_cap_rights_t *ret =                                         \
8411        REAL(cap_rights_clear)(rights, ##__VA_ARGS__);                      \
8412    if (ret)                                                                \
8413      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));               \
8414    return ret;                                                             \
8415  }
8416
8417#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...)        \
8418  {                                                                          \
8419    void *ctx;                                                               \
8420    COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
8421    if (rights)                                                              \
8422      COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));           \
8423    return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__);                   \
8424  }
8425
8426INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
8427            __sanitizer_cap_rights_t *rights) {
8428  CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
8429}
8430
8431INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
8432            __sanitizer_cap_rights_t *rights) {
8433  CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
8434}
8435
8436INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
8437            __sanitizer_cap_rights_t *rights) {
8438  CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
8439}
8440
8441INTERCEPTOR(bool, cap_rights_is_set,
8442            __sanitizer_cap_rights_t *rights) {
8443  CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
8444}
8445
8446INTERCEPTOR(int, cap_rights_limit, int fd,
8447            const __sanitizer_cap_rights_t *rights) {
8448  void *ctx;
8449  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
8450  if (rights)
8451    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8452
8453  return REAL(cap_rights_limit)(fd, rights);
8454}
8455
8456INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
8457  void *ctx;
8458  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
8459  int ret = REAL(cap_rights_get)(fd, rights);
8460  if (!ret && rights)
8461    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
8462
8463  return ret;
8464}
8465
8466INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
8467  void *ctx;
8468  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
8469  if (rights)
8470    COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8471
8472  return REAL(cap_rights_is_valid(rights));
8473}
8474
8475INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
8476  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8477  void *ctx;
8478  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
8479  if (src)
8480    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8481
8482  __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
8483  if (dst)
8484    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8485
8486  return ret;
8487}
8488
8489INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
8490  __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8491  void *ctx;
8492  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
8493  if (src)
8494    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8495
8496  __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
8497  if (dst)
8498    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8499
8500  return ret;
8501}
8502
8503INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
8504  const __sanitizer_cap_rights *little) {
8505  void *ctx;
8506  COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
8507  if (little)
8508    COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
8509  if (big)
8510    COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
8511
8512  return REAL(cap_rights_contains)(big, little);
8513}
8514
8515INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
8516  void *ctx;
8517  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
8518  if (cmds)
8519    COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
8520
8521  return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
8522}
8523
8524INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
8525  void *ctx;
8526  COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
8527  int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
8528  if (!ret && cmds)
8529    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
8530
8531  return ret;
8532}
8533#define INIT_CAPSICUM                          \
8534  COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
8535  COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
8536  COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
8537  COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
8538  COMMON_INTERCEPT_FUNCTION(cap_rights_get);   \
8539  COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
8540  COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
8541  COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
8542  COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
8543  COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
8544  COMMON_INTERCEPT_FUNCTION(cap_ioctls_get);   \
8545  COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
8546#else
8547#define INIT_CAPSICUM
8548#endif
8549
8550#if SANITIZER_INTERCEPT_SHA1
8551INTERCEPTOR(void, SHA1Init, void *context) {
8552  void *ctx;
8553  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
8554  REAL(SHA1Init)(context);
8555  if (context)
8556    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8557}
8558INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
8559  void *ctx;
8560  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
8561  if (data && len > 0)
8562    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8563  if (context)
8564    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8565  REAL(SHA1Update)(context, data, len);
8566  if (context)
8567    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8568}
8569INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
8570  void *ctx;
8571  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
8572  if (context)
8573    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8574  REAL(SHA1Final)(digest, context);
8575  if (digest)
8576    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8577}
8578INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
8579  void *ctx;
8580  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
8581  if (state)
8582    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8583  if (buffer)
8584    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
8585  REAL(SHA1Transform)(state, buffer);
8586  if (state)
8587    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8588}
8589INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
8590  void *ctx;
8591  COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
8592  if (context)
8593    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8594  char *ret = REAL(SHA1End)(context, buf);
8595  if (ret)
8596    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8597  return ret;
8598}
8599INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
8600  void *ctx;
8601  COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
8602  if (filename)
8603    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8604  char *ret = REAL(SHA1File)(filename, buf);
8605  if (ret)
8606    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8607  return ret;
8608}
8609INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
8610  OFF_T length) {
8611  void *ctx;
8612  COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
8613  if (filename)
8614    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8615  char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
8616  if (ret)
8617    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8618  return ret;
8619}
8620INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
8621  void *ctx;
8622  COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
8623  if (data)
8624    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8625  char *ret = REAL(SHA1Data)(data, len, buf);
8626  if (ret)
8627    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8628  return ret;
8629}
8630#define INIT_SHA1                                                              \
8631  COMMON_INTERCEPT_FUNCTION(SHA1Init);                                         \
8632  COMMON_INTERCEPT_FUNCTION(SHA1Update);                                       \
8633  COMMON_INTERCEPT_FUNCTION(SHA1Final);                                        \
8634  COMMON_INTERCEPT_FUNCTION(SHA1Transform);                                    \
8635  COMMON_INTERCEPT_FUNCTION(SHA1End);                                          \
8636  COMMON_INTERCEPT_FUNCTION(SHA1File);                                         \
8637  COMMON_INTERCEPT_FUNCTION(SHA1FileChunk);                                    \
8638  COMMON_INTERCEPT_FUNCTION(SHA1Data)
8639#else
8640#define INIT_SHA1
8641#endif
8642
8643#if SANITIZER_INTERCEPT_MD4
8644INTERCEPTOR(void, MD4Init, void *context) {
8645  void *ctx;
8646  COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
8647  REAL(MD4Init)(context);
8648  if (context)
8649    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8650}
8651
8652INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
8653            unsigned int len) {
8654  void *ctx;
8655  COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
8656  if (data && len > 0)
8657    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8658  if (context)
8659    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8660  REAL(MD4Update)(context, data, len);
8661  if (context)
8662    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8663}
8664
8665INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
8666  void *ctx;
8667  COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
8668  if (context)
8669    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8670  REAL(MD4Final)(digest, context);
8671  if (digest)
8672    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8673}
8674
8675INTERCEPTOR(char *, MD4End, void *context, char *buf) {
8676  void *ctx;
8677  COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
8678  if (context)
8679    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8680  char *ret = REAL(MD4End)(context, buf);
8681  if (ret)
8682    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8683  return ret;
8684}
8685
8686INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
8687  void *ctx;
8688  COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
8689  if (filename)
8690    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8691  char *ret = REAL(MD4File)(filename, buf);
8692  if (ret)
8693    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8694  return ret;
8695}
8696
8697INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
8698            char *buf) {
8699  void *ctx;
8700  COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
8701  if (data && len > 0)
8702    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8703  char *ret = REAL(MD4Data)(data, len, buf);
8704  if (ret)
8705    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8706  return ret;
8707}
8708
8709#define INIT_MD4                                                               \
8710  COMMON_INTERCEPT_FUNCTION(MD4Init);                                          \
8711  COMMON_INTERCEPT_FUNCTION(MD4Update);                                        \
8712  COMMON_INTERCEPT_FUNCTION(MD4Final);                                         \
8713  COMMON_INTERCEPT_FUNCTION(MD4End);                                           \
8714  COMMON_INTERCEPT_FUNCTION(MD4File);                                          \
8715  COMMON_INTERCEPT_FUNCTION(MD4Data)
8716#else
8717#define INIT_MD4
8718#endif
8719
8720#if SANITIZER_INTERCEPT_RMD160
8721INTERCEPTOR(void, RMD160Init, void *context) {
8722  void *ctx;
8723  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
8724  REAL(RMD160Init)(context);
8725  if (context)
8726    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8727}
8728INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
8729  void *ctx;
8730  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
8731  if (data && len > 0)
8732    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8733  if (context)
8734    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8735  REAL(RMD160Update)(context, data, len);
8736  if (context)
8737    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8738}
8739INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
8740  void *ctx;
8741  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
8742  if (context)
8743    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8744  REAL(RMD160Final)(digest, context);
8745  if (digest)
8746    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8747}
8748INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
8749  void *ctx;
8750  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
8751  if (state)
8752    COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8753  if (buffer)
8754    COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
8755  REAL(RMD160Transform)(state, buffer);
8756  if (state)
8757    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8758}
8759INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
8760  void *ctx;
8761  COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
8762  if (context)
8763    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8764  char *ret = REAL(RMD160End)(context, buf);
8765  if (ret)
8766    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8767  return ret;
8768}
8769INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
8770  void *ctx;
8771  COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
8772  if (filename)
8773    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8774  char *ret = REAL(RMD160File)(filename, buf);
8775  if (ret)
8776    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8777  return ret;
8778}
8779INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
8780  OFF_T length) {
8781  void *ctx;
8782  COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
8783  if (filename)
8784    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8785  char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
8786  if (ret)
8787    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8788  return ret;
8789}
8790INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
8791  void *ctx;
8792  COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
8793  if (data && len > 0)
8794    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8795  char *ret = REAL(RMD160Data)(data, len, buf);
8796  if (ret)
8797    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8798  return ret;
8799}
8800#define INIT_RMD160                                                            \
8801  COMMON_INTERCEPT_FUNCTION(RMD160Init);                                       \
8802  COMMON_INTERCEPT_FUNCTION(RMD160Update);                                     \
8803  COMMON_INTERCEPT_FUNCTION(RMD160Final);                                      \
8804  COMMON_INTERCEPT_FUNCTION(RMD160Transform);                                  \
8805  COMMON_INTERCEPT_FUNCTION(RMD160End);                                        \
8806  COMMON_INTERCEPT_FUNCTION(RMD160File);                                       \
8807  COMMON_INTERCEPT_FUNCTION(RMD160FileChunk);                                  \
8808  COMMON_INTERCEPT_FUNCTION(RMD160Data)
8809#else
8810#define INIT_RMD160
8811#endif
8812
8813#if SANITIZER_INTERCEPT_MD5
8814INTERCEPTOR(void, MD5Init, void *context) {
8815  void *ctx;
8816  COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context);
8817  REAL(MD5Init)(context);
8818  if (context)
8819    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
8820}
8821
8822INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data,
8823            unsigned int len) {
8824  void *ctx;
8825  COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len);
8826  if (data && len > 0)
8827    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8828  if (context)
8829    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8830  REAL(MD5Update)(context, data, len);
8831  if (context)
8832    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
8833}
8834
8835INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) {
8836  void *ctx;
8837  COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context);
8838  if (context)
8839    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8840  REAL(MD5Final)(digest, context);
8841  if (digest)
8842    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8843}
8844
8845INTERCEPTOR(char *, MD5End, void *context, char *buf) {
8846  void *ctx;
8847  COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf);
8848  if (context)
8849    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
8850  char *ret = REAL(MD5End)(context, buf);
8851  if (ret)
8852    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8853  return ret;
8854}
8855
8856INTERCEPTOR(char *, MD5File, const char *filename, char *buf) {
8857  void *ctx;
8858  COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf);
8859  if (filename)
8860    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8861  char *ret = REAL(MD5File)(filename, buf);
8862  if (ret)
8863    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8864  return ret;
8865}
8866
8867INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len,
8868            char *buf) {
8869  void *ctx;
8870  COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf);
8871  if (data && len > 0)
8872    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8873  char *ret = REAL(MD5Data)(data, len, buf);
8874  if (ret)
8875    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
8876  return ret;
8877}
8878
8879#define INIT_MD5                                                               \
8880  COMMON_INTERCEPT_FUNCTION(MD5Init);                                          \
8881  COMMON_INTERCEPT_FUNCTION(MD5Update);                                        \
8882  COMMON_INTERCEPT_FUNCTION(MD5Final);                                         \
8883  COMMON_INTERCEPT_FUNCTION(MD5End);                                           \
8884  COMMON_INTERCEPT_FUNCTION(MD5File);                                          \
8885  COMMON_INTERCEPT_FUNCTION(MD5Data)
8886#else
8887#define INIT_MD5
8888#endif
8889
8890#if SANITIZER_INTERCEPT_FSEEK
8891INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
8892  void *ctx;
8893  COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
8894  return REAL(fseek)(stream, offset, whence);
8895}
8896INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
8897  void *ctx;
8898  COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
8899  return REAL(fseeko)(stream, offset, whence);
8900}
8901INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
8902  void *ctx;
8903  COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
8904  return REAL(ftell)(stream);
8905}
8906INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
8907  void *ctx;
8908  COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
8909  return REAL(ftello)(stream);
8910}
8911INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
8912  void *ctx;
8913  COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
8914  return REAL(rewind)(stream);
8915}
8916INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
8917  void *ctx;
8918  COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
8919  int ret = REAL(fgetpos)(stream, pos);
8920  if (pos && !ret)
8921    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
8922  return ret;
8923}
8924INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
8925  void *ctx;
8926  COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
8927  if (pos)
8928    COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
8929  return REAL(fsetpos)(stream, pos);
8930}
8931#define INIT_FSEEK \
8932  COMMON_INTERCEPT_FUNCTION(fseek); \
8933  COMMON_INTERCEPT_FUNCTION(fseeko); \
8934  COMMON_INTERCEPT_FUNCTION(ftell); \
8935  COMMON_INTERCEPT_FUNCTION(ftello); \
8936  COMMON_INTERCEPT_FUNCTION(rewind); \
8937  COMMON_INTERCEPT_FUNCTION(fgetpos); \
8938  COMMON_INTERCEPT_FUNCTION(fsetpos)
8939#else
8940#define INIT_FSEEK
8941#endif
8942
8943#if SANITIZER_INTERCEPT_MD2
8944INTERCEPTOR(void, MD2Init, void *context) {
8945  void *ctx;
8946  COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
8947  REAL(MD2Init)(context);
8948  if (context)
8949    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
8950}
8951
8952INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
8953            unsigned int len) {
8954  void *ctx;
8955  COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
8956  if (data && len > 0)
8957    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8958  if (context)
8959    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8960  REAL(MD2Update)(context, data, len);
8961  if (context)
8962    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
8963}
8964
8965INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
8966  void *ctx;
8967  COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
8968  if (context)
8969    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8970  REAL(MD2Final)(digest, context);
8971  if (digest)
8972    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8973}
8974
8975INTERCEPTOR(char *, MD2End, void *context, char *buf) {
8976  void *ctx;
8977  COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
8978  if (context)
8979    COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
8980  char *ret = REAL(MD2End)(context, buf);
8981  if (ret)
8982    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
8983  return ret;
8984}
8985
8986INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
8987  void *ctx;
8988  COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
8989  if (filename)
8990    COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8991  char *ret = REAL(MD2File)(filename, buf);
8992  if (ret)
8993    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
8994  return ret;
8995}
8996
8997INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
8998            char *buf) {
8999  void *ctx;
9000  COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
9001  if (data && len > 0)
9002    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9003  char *ret = REAL(MD2Data)(data, len, buf);
9004  if (ret)
9005    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
9006  return ret;
9007}
9008
9009#define INIT_MD2                                                               \
9010  COMMON_INTERCEPT_FUNCTION(MD2Init);                                          \
9011  COMMON_INTERCEPT_FUNCTION(MD2Update);                                        \
9012  COMMON_INTERCEPT_FUNCTION(MD2Final);                                         \
9013  COMMON_INTERCEPT_FUNCTION(MD2End);                                           \
9014  COMMON_INTERCEPT_FUNCTION(MD2File);                                          \
9015  COMMON_INTERCEPT_FUNCTION(MD2Data)
9016#else
9017#define INIT_MD2
9018#endif
9019
9020#if SANITIZER_INTERCEPT_SHA2
9021#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \
9022  INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \
9023    void *ctx; \
9024    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \
9025    REAL(SHA##LEN##_Init)(context); \
9026    if (context) \
9027      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9028  } \
9029  INTERCEPTOR(void, SHA##LEN##_Update, void *context, \
9030              const u8 *data, SIZE_T len) { \
9031    void *ctx; \
9032    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \
9033    if (data && len > 0) \
9034      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
9035    if (context) \
9036      COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9037    REAL(SHA##LEN##_Update)(context, data, len); \
9038    if (context) \
9039      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9040  } \
9041  INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
9042  void *context) { \
9043    void *ctx; \
9044    CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
9045    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
9046    if (context) \
9047      COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9048    REAL(SHA##LEN##_Final)(digest, context); \
9049    if (digest) \
9050      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \
9051                                     sizeof(digest[0]) * \
9052  SHA##LEN##_digest_length); \
9053  } \
9054  INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \
9055    void *ctx; \
9056    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \
9057    if (context) \
9058      COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9059    char *ret = REAL(SHA##LEN##_End)(context, buf); \
9060    if (ret) \
9061      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9062    return ret; \
9063  } \
9064  INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \
9065    void *ctx; \
9066    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \
9067    if (filename) \
9068      COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\
9069    char *ret = REAL(SHA##LEN##_File)(filename, buf); \
9070    if (ret) \
9071      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9072    return ret; \
9073  } \
9074  INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \
9075              OFF_T offset, OFF_T length) { \
9076    void *ctx; \
9077    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \
9078  length); \
9079    if (filename) \
9080      COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\
9081    char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \
9082    if (ret) \
9083      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9084    return ret; \
9085  } \
9086  INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \
9087    void *ctx; \
9088    COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \
9089    if (data && len > 0) \
9090      COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
9091    char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \
9092    if (ret) \
9093      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9094    return ret; \
9095  }
9096
9097SHA2_INTERCEPTORS(224, u32)
9098SHA2_INTERCEPTORS(256, u32)
9099SHA2_INTERCEPTORS(384, u64)
9100SHA2_INTERCEPTORS(512, u64)
9101
9102#define INIT_SHA2_INTECEPTORS(LEN) \
9103  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \
9104  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \
9105  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \
9106  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \
9107  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \
9108  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \
9109  COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data)
9110
9111#define INIT_SHA2 \
9112  INIT_SHA2_INTECEPTORS(224); \
9113  INIT_SHA2_INTECEPTORS(256); \
9114  INIT_SHA2_INTECEPTORS(384); \
9115  INIT_SHA2_INTECEPTORS(512)
9116#undef SHA2_INTERCEPTORS
9117#else
9118#define INIT_SHA2
9119#endif
9120
9121#if SANITIZER_INTERCEPT_VIS
9122INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
9123  void *ctx;
9124  COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
9125  char *end = REAL(vis)(dst, c, flag, nextc);
9126  // dst is NULL terminated and end points to the NULL char
9127  if (dst && end)
9128    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9129  return end;
9130}
9131INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
9132  void *ctx;
9133  COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
9134  char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
9135  // nvis cannot make sure the dst is NULL terminated
9136  if (dst && end)
9137    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9138  return end;
9139}
9140INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
9141  void *ctx;
9142  COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
9143  if (src)
9144    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9145  int len = REAL(strvis)(dst, src, flag);
9146  if (dst)
9147    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9148  return len;
9149}
9150INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
9151  void *ctx;
9152  COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
9153  if (src)
9154    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9155  int len = REAL(stravis)(dst, src, flag);
9156  if (dst) {
9157    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
9158    if (*dst)
9159      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
9160  }
9161  return len;
9162}
9163INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
9164  void *ctx;
9165  COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
9166  if (src)
9167    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9168  int len = REAL(strnvis)(dst, dlen, src, flag);
9169  // The interface will be valid even if there is no space for NULL char
9170  if (dst && len > 0)
9171    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9172  return len;
9173}
9174INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
9175  void *ctx;
9176  COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
9177  if (src)
9178    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9179  int ret = REAL(strvisx)(dst, src, len, flag);
9180  if (dst)
9181    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9182  return ret;
9183}
9184INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9185            int flag) {
9186  void *ctx;
9187  COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
9188  if (src)
9189    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9190  int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
9191  if (dst && ret >= 0)
9192    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9193  return ret;
9194}
9195INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9196            int flag, int *cerr_ptr) {
9197  void *ctx;
9198  COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
9199  if (src)
9200    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9201  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
9202  // according to the implementation
9203  if (cerr_ptr)
9204    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
9205  int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
9206  if (dst && ret >= 0)
9207    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9208  if (cerr_ptr)
9209    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
9210  return ret;
9211}
9212INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
9213            const char *extra) {
9214  void *ctx;
9215  COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
9216  if (extra)
9217    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9218  char *end = REAL(svis)(dst, c, flag, nextc, extra);
9219  if (dst && end)
9220    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9221  return end;
9222}
9223INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
9224            const char *extra) {
9225  void *ctx;
9226  COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
9227  if (extra)
9228    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9229  char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
9230  if (dst && end)
9231    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
9232                                   Min((SIZE_T)(end - dst + 1), dlen));
9233  return end;
9234}
9235INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
9236            const char *extra) {
9237  void *ctx;
9238  COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
9239  if (src)
9240    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9241  if (extra)
9242    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9243  int len = REAL(strsvis)(dst, src, flag, extra);
9244  if (dst)
9245    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9246  return len;
9247}
9248INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
9249            const char *extra) {
9250  void *ctx;
9251  COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
9252  if (src)
9253    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9254  if (extra)
9255    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9256  int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
9257  // The interface will be valid even if there is no space for NULL char
9258  if (dst && len >= 0)
9259    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9260  return len;
9261}
9262INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
9263            const char *extra) {
9264  void *ctx;
9265  COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
9266  if (src)
9267    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9268  if (extra)
9269    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9270  int ret = REAL(strsvisx)(dst, src, len, flag, extra);
9271  if (dst)
9272    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9273  return ret;
9274}
9275INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9276            int flag, const char *extra) {
9277  void *ctx;
9278  COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
9279  if (src)
9280    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9281  if (extra)
9282    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9283  int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
9284  if (dst && ret >= 0)
9285    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9286  return ret;
9287}
9288INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
9289            SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
9290  void *ctx;
9291  COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
9292                           cerr_ptr);
9293  if (src)
9294    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9295  if (extra)
9296    COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9297  // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
9298  // according to the implementation
9299  if (cerr_ptr)
9300    COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
9301  int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
9302  if (dst && ret >= 0)
9303    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9304  if (cerr_ptr)
9305    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
9306  return ret;
9307}
9308INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
9309  void *ctx;
9310  COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
9311  if (astate)
9312    COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
9313  int ret = REAL(unvis)(cp, c, astate, flag);
9314  if (ret == unvis_valid || ret == unvis_validpush) {
9315    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
9316  }
9317  return ret;
9318}
9319INTERCEPTOR(int, strunvis, char *dst, const char *src) {
9320  void *ctx;
9321  COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
9322  if (src)
9323    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9324  int ret = REAL(strunvis)(dst, src);
9325  if (ret != -1)
9326    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9327  return ret;
9328}
9329INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
9330  void *ctx;
9331  COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
9332  if (src)
9333    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9334  int ret = REAL(strnunvis)(dst, dlen, src);
9335  if (ret != -1)
9336    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9337  return ret;
9338}
9339INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
9340  void *ctx;
9341  COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
9342  if (src)
9343    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9344  int ret = REAL(strunvisx)(dst, src, flag);
9345  if (ret != -1)
9346    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9347  return ret;
9348}
9349INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
9350            int flag) {
9351  void *ctx;
9352  COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
9353  if (src)
9354    COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9355  int ret = REAL(strnunvisx)(dst, dlen, src, flag);
9356  if (ret != -1)
9357    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9358  return ret;
9359}
9360#define INIT_VIS                                                               \
9361  COMMON_INTERCEPT_FUNCTION(vis);                                              \
9362  COMMON_INTERCEPT_FUNCTION(nvis);                                             \
9363  COMMON_INTERCEPT_FUNCTION(strvis);                                           \
9364  COMMON_INTERCEPT_FUNCTION(stravis);                                          \
9365  COMMON_INTERCEPT_FUNCTION(strnvis);                                          \
9366  COMMON_INTERCEPT_FUNCTION(strvisx);                                          \
9367  COMMON_INTERCEPT_FUNCTION(strnvisx);                                         \
9368  COMMON_INTERCEPT_FUNCTION(strenvisx);                                        \
9369  COMMON_INTERCEPT_FUNCTION(svis);                                             \
9370  COMMON_INTERCEPT_FUNCTION(snvis);                                            \
9371  COMMON_INTERCEPT_FUNCTION(strsvis);                                          \
9372  COMMON_INTERCEPT_FUNCTION(strsnvis);                                         \
9373  COMMON_INTERCEPT_FUNCTION(strsvisx);                                         \
9374  COMMON_INTERCEPT_FUNCTION(strsnvisx);                                        \
9375  COMMON_INTERCEPT_FUNCTION(strsenvisx);                                       \
9376  COMMON_INTERCEPT_FUNCTION(unvis);                                            \
9377  COMMON_INTERCEPT_FUNCTION(strunvis);                                         \
9378  COMMON_INTERCEPT_FUNCTION(strnunvis);                                        \
9379  COMMON_INTERCEPT_FUNCTION(strunvisx);                                        \
9380  COMMON_INTERCEPT_FUNCTION(strnunvisx)
9381#else
9382#define INIT_VIS
9383#endif
9384
9385#if SANITIZER_INTERCEPT_CDB
9386INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
9387  void *ctx;
9388  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
9389  if (path)
9390    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
9391  struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
9392  if (cdbr)
9393    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9394  return cdbr;
9395}
9396
9397INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
9398  int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
9399  void *ctx;
9400  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
9401    cookie);
9402  if (base && size)
9403    COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
9404  struct __sanitizer_cdbr *cdbr =
9405    REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
9406  if (cdbr)
9407    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9408  return cdbr;
9409}
9410
9411INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
9412  void *ctx;
9413  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
9414  if (cdbr)
9415    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9416  return REAL(cdbr_entries)(cdbr);
9417}
9418
9419INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
9420            const void **data, SIZE_T *datalen) {
9421  void *ctx;
9422  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
9423  if (cdbr)
9424    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9425  int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
9426  if (!ret) {
9427    if (data)
9428      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9429    if (datalen)
9430      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9431    if (data && datalen)
9432      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9433  }
9434  return ret;
9435}
9436
9437INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
9438            SIZE_T keylen, const void **data, SIZE_T *datalen) {
9439  void *ctx;
9440  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
9441  if (cdbr)
9442    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9443  if (key)
9444    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9445  int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
9446  if (!ret) {
9447    if (data)
9448      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9449    if (datalen)
9450      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9451    if (data && datalen)
9452      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9453  }
9454  return ret;
9455}
9456
9457INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
9458  void *ctx;
9459  COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
9460  if (cdbr)
9461    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9462  REAL(cdbr_close)(cdbr);
9463}
9464
9465INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
9466  void *ctx;
9467  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
9468  struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
9469  if (ret)
9470    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
9471  return ret;
9472}
9473
9474INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
9475  SIZE_T keylen, const void *data, SIZE_T datalen) {
9476  void *ctx;
9477  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
9478  if (cdbw)
9479    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9480  if (data && datalen)
9481    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9482  if (key && keylen)
9483    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9484  int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
9485  if (!ret && cdbw)
9486    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9487  return ret;
9488}
9489
9490INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
9491  SIZE_T datalen, u32 *index) {
9492  void *ctx;
9493  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
9494  if (cdbw)
9495    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9496  if (data && datalen)
9497    COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9498  int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
9499  if (!ret) {
9500    if (index)
9501      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
9502    if (cdbw)
9503      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9504  }
9505  return ret;
9506}
9507
9508INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
9509  SIZE_T keylen, u32 index) {
9510  void *ctx;
9511  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
9512  if (cdbw)
9513    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9514  if (key && keylen)
9515    COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9516  int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
9517  if (!ret && cdbw)
9518    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9519  return ret;
9520}
9521
9522INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
9523  const char descr[16], u32 (*seedgen)(void)) {
9524  void *ctx;
9525  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
9526  COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
9527  if (cdbw)
9528    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9529  if (descr)
9530    COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
9531  if (seedgen)
9532    COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
9533  int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
9534  if (!ret) {
9535    if (cdbw)
9536      COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9537    if (output >= 0)
9538      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
9539  }
9540  return ret;
9541}
9542
9543INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
9544  void *ctx;
9545  COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
9546  if (cdbw)
9547    COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9548  REAL(cdbw_close)(cdbw);
9549}
9550
9551#define INIT_CDB \
9552  COMMON_INTERCEPT_FUNCTION(cdbr_open); \
9553  COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
9554  COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
9555  COMMON_INTERCEPT_FUNCTION(cdbr_get); \
9556  COMMON_INTERCEPT_FUNCTION(cdbr_find); \
9557  COMMON_INTERCEPT_FUNCTION(cdbr_close); \
9558  COMMON_INTERCEPT_FUNCTION(cdbw_open); \
9559  COMMON_INTERCEPT_FUNCTION(cdbw_put); \
9560  COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
9561  COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
9562  COMMON_INTERCEPT_FUNCTION(cdbw_output); \
9563  COMMON_INTERCEPT_FUNCTION(cdbw_close)
9564#else
9565#define INIT_CDB
9566#endif
9567
9568#if SANITIZER_INTERCEPT_GETFSENT
9569INTERCEPTOR(void *, getfsent) {
9570  void *ctx;
9571  COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
9572  void *ret = REAL(getfsent)();
9573  if (ret)
9574    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9575  return ret;
9576}
9577
9578INTERCEPTOR(void *, getfsspec, const char *spec) {
9579  void *ctx;
9580  COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
9581  if (spec)
9582    COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1);
9583  void *ret = REAL(getfsspec)(spec);
9584  if (ret)
9585    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9586  return ret;
9587}
9588
9589INTERCEPTOR(void *, getfsfile, const char *file) {
9590  void *ctx;
9591  COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
9592  if (file)
9593    COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
9594  void *ret = REAL(getfsfile)(file);
9595  if (ret)
9596    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9597  return ret;
9598}
9599
9600#define INIT_GETFSENT \
9601  COMMON_INTERCEPT_FUNCTION(getfsent); \
9602  COMMON_INTERCEPT_FUNCTION(getfsspec); \
9603  COMMON_INTERCEPT_FUNCTION(getfsfile);
9604#else
9605#define INIT_GETFSENT
9606#endif
9607
9608#if SANITIZER_INTERCEPT_ARC4RANDOM
9609INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
9610  void *ctx;
9611  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
9612  REAL(arc4random_buf)(buf, len);
9613  if (buf && len)
9614    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
9615}
9616
9617INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
9618  void *ctx;
9619  COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
9620  if (dat && datlen)
9621    COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
9622  REAL(arc4random_addrandom)(dat, datlen);
9623}
9624
9625#define INIT_ARC4RANDOM \
9626  COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
9627  COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
9628#else
9629#define INIT_ARC4RANDOM
9630#endif
9631
9632#if SANITIZER_INTERCEPT_POPEN
9633INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
9634  void *ctx;
9635  COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
9636  if (command)
9637    COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1);
9638  if (type)
9639    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
9640  __sanitizer_FILE *res = REAL(popen)(command, type);
9641  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9642  if (res) unpoison_file(res);
9643  return res;
9644}
9645#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
9646#else
9647#define INIT_POPEN
9648#endif
9649
9650#if SANITIZER_INTERCEPT_POPENVE
9651INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
9652            char *const *argv, char *const *envp, const char *type) {
9653  void *ctx;
9654  COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
9655  if (path)
9656    COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
9657  if (argv) {
9658    for (char *const *pa = argv; ; ++pa) {
9659      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9660      if (!*pa)
9661        break;
9662      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
9663    }
9664  }
9665  if (envp) {
9666    for (char *const *pa = envp; ; ++pa) {
9667      COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9668      if (!*pa)
9669        break;
9670      COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
9671    }
9672  }
9673  if (type)
9674    COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
9675  __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
9676  COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9677  if (res) unpoison_file(res);
9678  return res;
9679}
9680#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
9681#else
9682#define INIT_POPENVE
9683#endif
9684
9685#if SANITIZER_INTERCEPT_PCLOSE
9686INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
9687  void *ctx;
9688  COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
9689  COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
9690  const FileMetadata *m = GetInterceptorMetadata(fp);
9691  int res = REAL(pclose)(fp);
9692  if (m) {
9693    COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
9694    DeleteInterceptorMetadata(fp);
9695  }
9696  return res;
9697}
9698#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
9699#else
9700#define INIT_PCLOSE
9701#endif
9702
9703#if SANITIZER_INTERCEPT_FUNOPEN
9704typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
9705typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
9706typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
9707typedef int (*funopen_closefn)(void *cookie);
9708
9709struct WrappedFunopenCookie {
9710  void *real_cookie;
9711  funopen_readfn real_read;
9712  funopen_writefn real_write;
9713  funopen_seekfn real_seek;
9714  funopen_closefn real_close;
9715};
9716
9717static int wrapped_funopen_read(void *cookie, char *buf, int len) {
9718  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9719  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9720  funopen_readfn real_read = wrapped_cookie->real_read;
9721  return real_read(wrapped_cookie->real_cookie, buf, len);
9722}
9723
9724static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
9725  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9726  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9727  funopen_writefn real_write = wrapped_cookie->real_write;
9728  return real_write(wrapped_cookie->real_cookie, buf, len);
9729}
9730
9731static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
9732  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9733  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9734  funopen_seekfn real_seek = wrapped_cookie->real_seek;
9735  return real_seek(wrapped_cookie->real_cookie, offset, whence);
9736}
9737
9738static int wrapped_funopen_close(void *cookie) {
9739  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9740  WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9741  funopen_closefn real_close = wrapped_cookie->real_close;
9742  int res = real_close(wrapped_cookie->real_cookie);
9743  InternalFree(wrapped_cookie);
9744  return res;
9745}
9746
9747INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
9748            funopen_writefn writefn, funopen_seekfn seekfn,
9749            funopen_closefn closefn) {
9750  void *ctx;
9751  COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
9752                           closefn);
9753
9754  WrappedFunopenCookie *wrapped_cookie =
9755      (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
9756  wrapped_cookie->real_cookie = cookie;
9757  wrapped_cookie->real_read = readfn;
9758  wrapped_cookie->real_write = writefn;
9759  wrapped_cookie->real_seek = seekfn;
9760  wrapped_cookie->real_close = closefn;
9761
9762  __sanitizer_FILE *res =
9763      REAL(funopen)(wrapped_cookie,
9764                    readfn  ? wrapped_funopen_read  : nullptr,
9765                    writefn ? wrapped_funopen_write : nullptr,
9766                    seekfn  ? wrapped_funopen_seek  : nullptr,
9767                    closefn ? wrapped_funopen_close : nullptr);
9768  if (res)
9769    unpoison_file(res);
9770  return res;
9771}
9772#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
9773#else
9774#define INIT_FUNOPEN
9775#endif
9776
9777#if SANITIZER_INTERCEPT_FUNOPEN2
9778typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
9779typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
9780typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
9781typedef int (*funopen2_flushfn)(void *cookie);
9782typedef int (*funopen2_closefn)(void *cookie);
9783
9784struct WrappedFunopen2Cookie {
9785  void *real_cookie;
9786  funopen2_readfn real_read;
9787  funopen2_writefn real_write;
9788  funopen2_seekfn real_seek;
9789  funopen2_flushfn real_flush;
9790  funopen2_closefn real_close;
9791};
9792
9793static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
9794  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9795  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9796  funopen2_readfn real_read = wrapped_cookie->real_read;
9797  return real_read(wrapped_cookie->real_cookie, buf, len);
9798}
9799
9800static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
9801                                      SIZE_T len) {
9802  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9803  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9804  funopen2_writefn real_write = wrapped_cookie->real_write;
9805  return real_write(wrapped_cookie->real_cookie, buf, len);
9806}
9807
9808static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
9809  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9810  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9811  funopen2_seekfn real_seek = wrapped_cookie->real_seek;
9812  return real_seek(wrapped_cookie->real_cookie, offset, whence);
9813}
9814
9815static int wrapped_funopen2_flush(void *cookie) {
9816  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9817  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9818  funopen2_flushfn real_flush = wrapped_cookie->real_flush;
9819  return real_flush(wrapped_cookie->real_cookie);
9820}
9821
9822static int wrapped_funopen2_close(void *cookie) {
9823  COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9824  WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
9825  funopen2_closefn real_close = wrapped_cookie->real_close;
9826  int res = real_close(wrapped_cookie->real_cookie);
9827  InternalFree(wrapped_cookie);
9828  return res;
9829}
9830
9831INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
9832            funopen2_writefn writefn, funopen2_seekfn seekfn,
9833            funopen2_flushfn flushfn, funopen2_closefn closefn) {
9834  void *ctx;
9835  COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
9836                           flushfn, closefn);
9837
9838  WrappedFunopen2Cookie *wrapped_cookie =
9839      (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
9840  wrapped_cookie->real_cookie = cookie;
9841  wrapped_cookie->real_read = readfn;
9842  wrapped_cookie->real_write = writefn;
9843  wrapped_cookie->real_seek = seekfn;
9844  wrapped_cookie->real_flush = flushfn;
9845  wrapped_cookie->real_close = closefn;
9846
9847  __sanitizer_FILE *res =
9848      REAL(funopen2)(wrapped_cookie,
9849                     readfn  ? wrapped_funopen2_read  : nullptr,
9850                     writefn ? wrapped_funopen2_write : nullptr,
9851                     seekfn  ? wrapped_funopen2_seek  : nullptr,
9852                     flushfn ? wrapped_funopen2_flush : nullptr,
9853                     closefn ? wrapped_funopen2_close : nullptr);
9854  if (res)
9855    unpoison_file(res);
9856  return res;
9857}
9858#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
9859#else
9860#define INIT_FUNOPEN2
9861#endif
9862
9863#if SANITIZER_INTERCEPT_FDEVNAME
9864INTERCEPTOR(char *, fdevname,  int fd) {
9865  void *ctx;
9866  COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
9867  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
9868  char *name = REAL(fdevname)(fd);
9869  if (name) {
9870    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
9871    if (fd > 0)
9872      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
9873  }
9874  return name;
9875}
9876
9877INTERCEPTOR(char *, fdevname_r,  int fd, char *buf, SIZE_T len) {
9878  void *ctx;
9879  COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
9880  COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
9881  char *name = REAL(fdevname_r)(fd, buf, len);
9882  if (name && buf && len > 0) {
9883    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
9884    if (fd > 0)
9885      COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
9886  }
9887  return name;
9888}
9889
9890#define INIT_FDEVNAME \
9891  COMMON_INTERCEPT_FUNCTION(fdevname); \
9892  COMMON_INTERCEPT_FUNCTION(fdevname_r);
9893#else
9894#define INIT_FDEVNAME
9895#endif
9896
9897#if SANITIZER_INTERCEPT_GETUSERSHELL
9898INTERCEPTOR(char *, getusershell) {
9899  void *ctx;
9900  COMMON_INTERCEPTOR_ENTER(ctx, getusershell);
9901  char *res = REAL(getusershell)();
9902  if (res)
9903    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
9904  return res;
9905}
9906
9907#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
9908#else
9909#define INIT_GETUSERSHELL
9910#endif
9911
9912#if SANITIZER_INTERCEPT_SL_INIT
9913INTERCEPTOR(void *, sl_init) {
9914  void *ctx;
9915  COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
9916  void *res = REAL(sl_init)();
9917  if (res)
9918    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
9919  return res;
9920}
9921
9922INTERCEPTOR(int, sl_add, void *sl, char *item) {
9923  void *ctx;
9924  COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
9925  if (sl)
9926    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9927  if (item)
9928    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
9929  int res = REAL(sl_add)(sl, item);
9930  if (!res)
9931    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9932  return res;
9933}
9934
9935INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
9936  void *ctx;
9937  COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
9938  if (sl)
9939    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9940  if (item)
9941    COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
9942  char *res = REAL(sl_find)(sl, item);
9943  if (res)
9944    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
9945  return res;
9946}
9947
9948INTERCEPTOR(void, sl_free, void *sl, int freeall) {
9949  void *ctx;
9950  COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
9951  if (sl)
9952    COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
9953  REAL(sl_free)(sl, freeall);
9954}
9955
9956#define INIT_SL_INIT                  \
9957  COMMON_INTERCEPT_FUNCTION(sl_init); \
9958  COMMON_INTERCEPT_FUNCTION(sl_add);  \
9959  COMMON_INTERCEPT_FUNCTION(sl_find); \
9960  COMMON_INTERCEPT_FUNCTION(sl_free);
9961#else
9962#define INIT_SL_INIT
9963#endif
9964
9965#if SANITIZER_INTERCEPT_GETRANDOM
9966INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
9967  void *ctx;
9968  COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);
9969  SSIZE_T n = REAL(getrandom)(buf, buflen, flags);
9970  if (n > 0) {
9971    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);
9972  }
9973  return n;
9974}
9975#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)
9976#else
9977#define INIT_GETRANDOM
9978#endif
9979
9980#if SANITIZER_INTERCEPT_CRYPT
9981INTERCEPTOR(char *, crypt, char *key, char *salt) {
9982  void *ctx;
9983  COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt);
9984  COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
9985  COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
9986  char *res = REAL(crypt)(key, salt);
9987  if (res != nullptr)
9988    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
9989  return res;
9990}
9991#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt);
9992#else
9993#define INIT_CRYPT
9994#endif
9995
9996#if SANITIZER_INTERCEPT_CRYPT_R
9997INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) {
9998  void *ctx;
9999  COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data);
10000  COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
10001  COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
10002  char *res = REAL(crypt_r)(key, salt, data);
10003  if (res != nullptr) {
10004    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data,
10005                                   __sanitizer::struct_crypt_data_sz);
10006    COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
10007  }
10008  return res;
10009}
10010#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r);
10011#else
10012#define INIT_CRYPT_R
10013#endif
10014
10015#if SANITIZER_INTERCEPT_GETENTROPY
10016INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
10017  void *ctx;
10018  COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);
10019  int r = REAL(getentropy)(buf, buflen);
10020  if (r == 0) {
10021    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
10022  }
10023  return r;
10024}
10025#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)
10026#else
10027#define INIT_GETENTROPY
10028#endif
10029
10030#if SANITIZER_INTERCEPT_QSORT_R
10031typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
10032struct qsort_r_compar_params {
10033  SIZE_T size;
10034  qsort_r_compar_f compar;
10035  void *arg;
10036};
10037static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
10038  qsort_r_compar_params *params = (qsort_r_compar_params *)arg;
10039  COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10040  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size);
10041  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size);
10042  return params->compar(a, b, params->arg);
10043}
10044
10045INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
10046            qsort_r_compar_f compar, void *arg) {
10047  void *ctx;
10048  COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
10049  // Run the comparator over all array elements to detect any memory issues.
10050  if (nmemb > 1) {
10051    for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10052      void *p = (void *)((char *)base + i * size);
10053      void *q = (void *)((char *)base + (i + 1) * size);
10054      COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10055      compar(p, q, arg);
10056    }
10057  }
10058  qsort_r_compar_params params = {size, compar, arg};
10059  REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, &params);
10060  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10061}
10062#  define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
10063#else
10064#  define INIT_QSORT_R
10065#endif
10066
10067#if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R
10068INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10069            qsort_r_compar_f compar) {
10070  void *ctx;
10071  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10072  WRAP(qsort_r)(base, nmemb, size, compar, nullptr);
10073}
10074#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10075#elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R
10076// Glibc qsort uses a temporary buffer allocated either on stack or on heap.
10077// Poisoned memory from there may get copied into the comparator arguments,
10078// where it needs to be dealt with. But even that is not enough - the results of
10079// the sort may be copied into the input/output array based on the results of
10080// the comparator calls, but directly from the temp memory, bypassing the
10081// unpoisoning done in wrapped_qsort_compar. We deal with this by, again,
10082// unpoisoning the entire array after the sort is done.
10083//
10084// We can not check that the entire array is initialized at the beginning. IMHO,
10085// it's fine for parts of the sorted objects to contain uninitialized memory,
10086// ex. as padding in structs.
10087typedef int (*qsort_compar_f)(const void *, const void *);
10088static THREADLOCAL qsort_compar_f qsort_compar;
10089static THREADLOCAL SIZE_T qsort_size;
10090static int wrapped_qsort_compar(const void *a, const void *b) {
10091  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10092  COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);
10093  COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);
10094  return qsort_compar(a, b);
10095}
10096
10097INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10098            qsort_compar_f compar) {
10099  void *ctx;
10100  COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10101  // Run the comparator over all array elements to detect any memory issues.
10102  if (nmemb > 1) {
10103    for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10104      void *p = (void *)((char *)base + i * size);
10105      void *q = (void *)((char *)base + (i + 1) * size);
10106      COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10107      compar(p, q);
10108    }
10109  }
10110  qsort_compar_f old_compar = qsort_compar;
10111  SIZE_T old_size = qsort_size;
10112  // Handle qsort() implementations that recurse using an
10113  // interposable function call:
10114  bool already_wrapped = compar == wrapped_qsort_compar;
10115  if (already_wrapped) {
10116    // This case should only happen if the qsort() implementation calls itself
10117    // using a preemptible function call (e.g. the FreeBSD libc version).
10118    // Check that the size and comparator arguments are as expected.
10119    CHECK_NE(compar, qsort_compar);
10120    CHECK_EQ(qsort_size, size);
10121  } else {
10122    qsort_compar = compar;
10123    qsort_size = size;
10124  }
10125  REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);
10126  if (!already_wrapped) {
10127    qsort_compar = old_compar;
10128    qsort_size = old_size;
10129  }
10130  COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10131}
10132#  define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10133#else
10134#  define INIT_QSORT
10135#endif
10136
10137#if SANITIZER_INTERCEPT_BSEARCH
10138typedef int (*bsearch_compar_f)(const void *, const void *);
10139struct bsearch_compar_params {
10140  const void *key;
10141  bsearch_compar_f compar;
10142};
10143
10144static int wrapped_bsearch_compar(const void *key, const void *b) {
10145  const bsearch_compar_params *params = (const bsearch_compar_params *)key;
10146  COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10147  return params->compar(params->key, b);
10148}
10149
10150INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb,
10151            SIZE_T size, bsearch_compar_f compar) {
10152  void *ctx;
10153  COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar);
10154  bsearch_compar_params params = {key, compar};
10155  return REAL(bsearch)(&params, base, nmemb, size, wrapped_bsearch_compar);
10156}
10157#  define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch)
10158#else
10159#  define INIT_BSEARCH
10160#endif
10161
10162#if SANITIZER_INTERCEPT_SIGALTSTACK
10163INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
10164  void *ctx;
10165  COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);
10166  int r = REAL(sigaltstack)(ss, oss);
10167  if (r == 0 && oss != nullptr) {
10168    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);
10169  }
10170  return r;
10171}
10172#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)
10173#else
10174#define INIT_SIGALTSTACK
10175#endif
10176
10177#if SANITIZER_INTERCEPT_UNAME
10178INTERCEPTOR(int, uname, struct utsname *utsname) {
10179#if SANITIZER_LINUX
10180  if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
10181    return internal_uname(utsname);
10182#endif
10183  void *ctx;
10184  COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);
10185  int res = REAL(uname)(utsname);
10186  if (!res)
10187    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10188                                   __sanitizer::struct_utsname_sz);
10189  return res;
10190}
10191#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)
10192#else
10193#define INIT_UNAME
10194#endif
10195
10196#if SANITIZER_INTERCEPT___XUNAME
10197// FreeBSD's <sys/utsname.h> define uname() as
10198// static __inline int uname(struct utsname *name) {
10199//   return __xuname(SYS_NMLN, (void*)name);
10200// }
10201INTERCEPTOR(int, __xuname, int size, void *utsname) {
10202  void *ctx;
10203  COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);
10204  int res = REAL(__xuname)(size, utsname);
10205  if (!res)
10206    COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10207                                   __sanitizer::struct_utsname_sz);
10208  return res;
10209}
10210#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)
10211#else
10212#define INIT___XUNAME
10213#endif
10214
10215#include "sanitizer_common_interceptors_netbsd_compat.inc"
10216
10217static void InitializeCommonInterceptors() {
10218#if SI_POSIX
10219  static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
10220  interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();
10221#endif
10222
10223  INIT_MMAP;
10224  INIT_MMAP64;
10225  INIT_TEXTDOMAIN;
10226  INIT_STRLEN;
10227  INIT_STRNLEN;
10228  INIT_STRNDUP;
10229  INIT___STRNDUP;
10230  INIT_STRCMP;
10231  INIT_STRNCMP;
10232  INIT_STRCASECMP;
10233  INIT_STRNCASECMP;
10234  INIT_STRSTR;
10235  INIT_STRCASESTR;
10236  INIT_STRCHR;
10237  INIT_STRCHRNUL;
10238  INIT_STRRCHR;
10239  INIT_STRSPN;
10240  INIT_STRTOK;
10241  INIT_STRPBRK;
10242  INIT_STRXFRM;
10243  INIT___STRXFRM_L;
10244  INIT_MEMSET;
10245  INIT_MEMMOVE;
10246  INIT_MEMCPY;
10247  INIT_MEMCHR;
10248  INIT_MEMCMP;
10249  INIT_BCMP;
10250  INIT_MEMRCHR;
10251  INIT_MEMMEM;
10252  INIT_READ;
10253  INIT_FREAD;
10254  INIT_PREAD;
10255  INIT_PREAD64;
10256  INIT_READV;
10257  INIT_PREADV;
10258  INIT_PREADV64;
10259  INIT_WRITE;
10260  INIT_FWRITE;
10261  INIT_PWRITE;
10262  INIT_PWRITE64;
10263  INIT_WRITEV;
10264  INIT_PWRITEV;
10265  INIT_PWRITEV64;
10266  INIT_FGETS;
10267  INIT_FPUTS;
10268  INIT_PUTS;
10269  INIT_PRCTL;
10270  INIT_LOCALTIME_AND_FRIENDS;
10271  INIT_STRPTIME;
10272  INIT_SCANF;
10273  INIT_ISOC99_SCANF;
10274  INIT_PRINTF;
10275  INIT_PRINTF_L;
10276  INIT_ISOC99_PRINTF;
10277  INIT_FREXP;
10278  INIT_FREXPF_FREXPL;
10279  INIT_GETPWNAM_AND_FRIENDS;
10280  INIT_GETPWNAM_R_AND_FRIENDS;
10281  INIT_GETPWENT;
10282  INIT_FGETPWENT;
10283  INIT_GETPWENT_R;
10284  INIT_FGETPWENT_R;
10285  INIT_FGETGRENT_R;
10286  INIT_SETPWENT;
10287  INIT_CLOCK_GETTIME;
10288  INIT_CLOCK_GETCPUCLOCKID;
10289  INIT_GETITIMER;
10290  INIT_TIME;
10291  INIT_GLOB;
10292  INIT_GLOB64;
10293  INIT_POSIX_SPAWN;
10294  INIT_WAIT;
10295  INIT_WAIT4;
10296  INIT_INET;
10297  INIT_PTHREAD_GETSCHEDPARAM;
10298  INIT_GETADDRINFO;
10299  INIT_GETNAMEINFO;
10300  INIT_GETSOCKNAME;
10301  INIT_GETHOSTBYNAME;
10302  INIT_GETHOSTBYNAME2;
10303  INIT_GETHOSTBYNAME_R;
10304  INIT_GETHOSTBYNAME2_R;
10305  INIT_GETHOSTBYADDR_R;
10306  INIT_GETHOSTENT_R;
10307  INIT_GETSOCKOPT;
10308  INIT_ACCEPT;
10309  INIT_ACCEPT4;
10310  INIT_PACCEPT;
10311  INIT_MODF;
10312  INIT_RECVMSG;
10313  INIT_SENDMSG;
10314  INIT_RECVMMSG;
10315  INIT_SENDMMSG;
10316  INIT_SYSMSG;
10317  INIT_GETPEERNAME;
10318  INIT_IOCTL;
10319  INIT_INET_ATON;
10320  INIT_SYSINFO;
10321  INIT_READDIR;
10322  INIT_READDIR64;
10323  INIT_PTRACE;
10324  INIT_SETLOCALE;
10325  INIT_GETCWD;
10326  INIT_GET_CURRENT_DIR_NAME;
10327  INIT_STRTOIMAX;
10328  INIT_MBSTOWCS;
10329  INIT_MBSNRTOWCS;
10330  INIT_WCSTOMBS;
10331  INIT_WCSNRTOMBS;
10332  INIT_WCRTOMB;
10333  INIT_WCTOMB;
10334  INIT_TCGETATTR;
10335  INIT_REALPATH;
10336  INIT_CANONICALIZE_FILE_NAME;
10337  INIT_CONFSTR;
10338  INIT_SCHED_GETAFFINITY;
10339  INIT_SCHED_GETPARAM;
10340  INIT_STRERROR;
10341  INIT_STRERROR_R;
10342  INIT_XPG_STRERROR_R;
10343  INIT_SCANDIR;
10344  INIT_SCANDIR64;
10345  INIT_GETGROUPS;
10346  INIT_POLL;
10347  INIT_PPOLL;
10348  INIT_WORDEXP;
10349  INIT_SIGWAIT;
10350  INIT_SIGWAITINFO;
10351  INIT_SIGTIMEDWAIT;
10352  INIT_SIGSETOPS;
10353  INIT_SIGSET_LOGICOPS;
10354  INIT_SIGPENDING;
10355  INIT_SIGPROCMASK;
10356  INIT_PTHREAD_SIGMASK;
10357  INIT_BACKTRACE;
10358  INIT__EXIT;
10359  INIT_PTHREAD_MUTEX_LOCK;
10360  INIT_PTHREAD_MUTEX_UNLOCK;
10361  INIT___PTHREAD_MUTEX_LOCK;
10362  INIT___PTHREAD_MUTEX_UNLOCK;
10363  INIT___LIBC_MUTEX_LOCK;
10364  INIT___LIBC_MUTEX_UNLOCK;
10365  INIT___LIBC_THR_SETCANCELSTATE;
10366  INIT_GETMNTENT;
10367  INIT_GETMNTENT_R;
10368  INIT_STATFS;
10369  INIT_STATFS64;
10370  INIT_STATVFS;
10371  INIT_STATVFS64;
10372  INIT_INITGROUPS;
10373  INIT_ETHER_NTOA_ATON;
10374  INIT_ETHER_HOST;
10375  INIT_ETHER_R;
10376  INIT_SHMCTL;
10377  INIT_RANDOM_R;
10378  INIT_PTHREAD_ATTR_GET;
10379  INIT_PTHREAD_ATTR_GET_SCHED;
10380  INIT_PTHREAD_ATTR_GETINHERITSCHED;
10381  INIT_PTHREAD_ATTR_GETAFFINITY_NP;
10382  INIT_PTHREAD_MUTEXATTR_GETPSHARED;
10383  INIT_PTHREAD_MUTEXATTR_GETTYPE;
10384  INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
10385  INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
10386  INIT_PTHREAD_MUTEXATTR_GETROBUST;
10387  INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
10388  INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
10389  INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
10390  INIT_PTHREAD_CONDATTR_GETPSHARED;
10391  INIT_PTHREAD_CONDATTR_GETCLOCK;
10392  INIT_PTHREAD_BARRIERATTR_GETPSHARED;
10393  INIT_TMPNAM;
10394  INIT_TMPNAM_R;
10395  INIT_PTSNAME;
10396  INIT_PTSNAME_R;
10397  INIT_TTYNAME;
10398  INIT_TTYNAME_R;
10399  INIT_TEMPNAM;
10400  INIT_PTHREAD_SETNAME_NP;
10401  INIT_PTHREAD_GETNAME_NP;
10402  INIT_SINCOS;
10403  INIT_REMQUO;
10404  INIT_REMQUOL;
10405  INIT_LGAMMA;
10406  INIT_LGAMMAL;
10407  INIT_LGAMMA_R;
10408  INIT_LGAMMAL_R;
10409  INIT_DRAND48_R;
10410  INIT_RAND_R;
10411  INIT_GETLINE;
10412  INIT_ICONV;
10413  INIT_TIMES;
10414  INIT_TLS_GET_ADDR;
10415  INIT_LISTXATTR;
10416  INIT_GETXATTR;
10417  INIT_GETRESID;
10418  INIT_GETIFADDRS;
10419  INIT_IF_INDEXTONAME;
10420  INIT_CAPGET;
10421  INIT_AEABI_MEM;
10422  INIT___BZERO;
10423  INIT_BZERO;
10424  INIT_FTIME;
10425  INIT_XDR;
10426  INIT_XDRREC_LINUX;
10427  INIT_TSEARCH;
10428  INIT_LIBIO_INTERNALS;
10429  INIT_FOPEN;
10430  INIT_FOPEN64;
10431  INIT_FLOPEN;
10432  INIT_OPEN_MEMSTREAM;
10433  INIT_OBSTACK;
10434  INIT_FFLUSH;
10435  INIT_FCLOSE;
10436  INIT_DLOPEN_DLCLOSE;
10437  INIT_GETPASS;
10438  INIT_TIMERFD;
10439  INIT_MLOCKX;
10440  INIT_FOPENCOOKIE;
10441  INIT_SEM;
10442  INIT_PTHREAD_SETCANCEL;
10443  INIT_MINCORE;
10444  INIT_PROCESS_VM_READV;
10445  INIT_CTERMID;
10446  INIT_CTERMID_R;
10447  INIT_RECV_RECVFROM;
10448  INIT_SEND_SENDTO;
10449  INIT_STAT;
10450  INIT_EVENTFD_READ_WRITE;
10451  INIT_LSTAT;
10452  INIT___XSTAT;
10453  INIT___XSTAT64;
10454  INIT___LXSTAT;
10455  INIT___LXSTAT64;
10456  // FIXME: add other *stat interceptors.
10457  INIT_UTMP;
10458  INIT_UTMPX;
10459  INIT_GETLOADAVG;
10460  INIT_WCSLEN;
10461  INIT_WCSCAT;
10462  INIT_WCSDUP;
10463  INIT_WCSXFRM;
10464  INIT___WCSXFRM_L;
10465  INIT_ACCT;
10466  INIT_USER_FROM_UID;
10467  INIT_UID_FROM_USER;
10468  INIT_GROUP_FROM_GID;
10469  INIT_GID_FROM_GROUP;
10470  INIT_ACCESS;
10471  INIT_FACCESSAT;
10472  INIT_GETGROUPLIST;
10473  INIT_GETGROUPMEMBERSHIP;
10474  INIT_READLINK;
10475  INIT_READLINKAT;
10476  INIT_NAME_TO_HANDLE_AT;
10477  INIT_OPEN_BY_HANDLE_AT;
10478  INIT_STRLCPY;
10479  INIT_DEVNAME;
10480  INIT_DEVNAME_R;
10481  INIT_FGETLN;
10482  INIT_STRMODE;
10483  INIT_TTYENT;
10484  INIT_PROTOENT;
10485  INIT_PROTOENT_R;
10486  INIT_NETENT;
10487  INIT_GETMNTINFO;
10488  INIT_MI_VECTOR_HASH;
10489  INIT_SETVBUF;
10490  INIT_GETVFSSTAT;
10491  INIT_REGEX;
10492  INIT_REGEXSUB;
10493  INIT_FTS;
10494  INIT_SYSCTL;
10495  INIT_ASYSCTL;
10496  INIT_SYSCTLGETMIBINFO;
10497  INIT_NL_LANGINFO;
10498  INIT_MODCTL;
10499  INIT_STRTONUM;
10500  INIT_FPARSELN;
10501  INIT_STATVFS1;
10502  INIT_STRTOI;
10503  INIT_CAPSICUM;
10504  INIT_SHA1;
10505  INIT_MD4;
10506  INIT_RMD160;
10507  INIT_MD5;
10508  INIT_FSEEK;
10509  INIT_MD2;
10510  INIT_SHA2;
10511  INIT_VIS;
10512  INIT_CDB;
10513  INIT_GETFSENT;
10514  INIT_ARC4RANDOM;
10515  INIT_POPEN;
10516  INIT_POPENVE;
10517  INIT_PCLOSE;
10518  INIT_FUNOPEN;
10519  INIT_FUNOPEN2;
10520  INIT_FDEVNAME;
10521  INIT_GETUSERSHELL;
10522  INIT_SL_INIT;
10523  INIT_GETRANDOM;
10524  INIT_CRYPT;
10525  INIT_CRYPT_R;
10526  INIT_GETENTROPY;
10527  INIT_QSORT;
10528  INIT_QSORT_R;
10529  INIT_BSEARCH;
10530  INIT_SIGALTSTACK;
10531  INIT_UNAME;
10532  INIT___XUNAME;
10533
10534  INIT___PRINTF_CHK;
10535}
10536