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