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