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

source code of compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors.inc