1 //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // Common function interceptors for tools like AddressSanitizer,
10 // ThreadSanitizer, MemorySanitizer, etc.
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_MUTEX_PRE_LOCK
27 // COMMON_INTERCEPTOR_MUTEX_POST_LOCK
28 // COMMON_INTERCEPTOR_MUTEX_UNLOCK
29 // COMMON_INTERCEPTOR_MUTEX_REPAIR
30 // COMMON_INTERCEPTOR_SET_PTHREAD_NAME
31 // COMMON_INTERCEPTOR_HANDLE_RECVMSG
32 // COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
33 // COMMON_INTERCEPTOR_MEMSET_IMPL
34 // COMMON_INTERCEPTOR_MEMMOVE_IMPL
35 // COMMON_INTERCEPTOR_MEMCPY_IMPL
36 // COMMON_INTERCEPTOR_MMAP_IMPL
37 // COMMON_INTERCEPTOR_COPY_STRING
38 // COMMON_INTERCEPTOR_STRNDUP_IMPL
39 // COMMON_INTERCEPTOR_STRERROR
40 //===----------------------------------------------------------------------===//
42 #include "interception/interception.h"
43 #include "sanitizer_addrhashmap.h"
44 #include "sanitizer_errno.h"
45 #include "sanitizer_placement_new.h"
46 #include "sanitizer_platform_interceptors.h"
47 #include "sanitizer_symbolizer.h"
48 #include "sanitizer_tls_get_addr.h"
52 #if SANITIZER_INTERCEPTOR_HOOKS
53 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__);
54 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \
55 SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {}
57 #define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...)
58 #define CALL_WEAK_INTERCEPTOR_HOOK(f, ...)
60 #endif // SANITIZER_INTERCEPTOR_HOOKS
62 #if SANITIZER_WINDOWS && !defined(va_copy)
63 #define va_copy(dst, src) ((dst) = (src))
67 #define pthread_setname_np pthread_set_name_np
68 #define inet_aton __inet_aton
69 #define inet_pton __inet_pton
70 #define iconv __bsd_iconv
74 #define clock_getres __clock_getres50
75 #define clock_gettime __clock_gettime50
76 #define clock_settime __clock_settime50
77 #define ctime __ctime50
78 #define ctime_r __ctime_r50
79 #define devname __devname50
80 #define fgetpos __fgetpos50
81 #define fsetpos __fsetpos50
82 #define fstatvfs __fstatvfs90
83 #define fstatvfs1 __fstatvfs190
84 #define fts_children __fts_children60
85 #define fts_close __fts_close60
86 #define fts_open __fts_open60
87 #define fts_read __fts_read60
88 #define fts_set __fts_set60
89 #define getitimer __getitimer50
90 #define getmntinfo __getmntinfo90
91 #define getpwent __getpwent50
92 #define getpwnam __getpwnam50
93 #define getpwnam_r __getpwnam_r50
94 #define getpwuid __getpwuid50
95 #define getpwuid_r __getpwuid_r50
96 #define getutent __getutent50
97 #define getutxent __getutxent50
98 #define getutxid __getutxid50
99 #define getutxline __getutxline50
100 #define getvfsstat __getvfsstat90
101 #define pututxline __pututxline50
102 #define glob __glob30
103 #define gmtime __gmtime50
104 #define gmtime_r __gmtime_r50
105 #define localtime __locatime50
106 #define localtime_r __localtime_r50
107 #define mktime __mktime50
108 #define lstat __lstat50
109 #define opendir __opendir30
110 #define readdir __readdir30
111 #define readdir_r __readdir_r30
112 #define scandir __scandir30
113 #define setitimer __setitimer50
114 #define setlocale __setlocale50
115 #define shmctl __shmctl50
116 #define sigaltstack __sigaltstack14
117 #define sigemptyset __sigemptyset14
118 #define sigfillset __sigfillset14
119 #define sigpending __sigpending14
120 #define sigprocmask __sigprocmask14
121 #define sigtimedwait __sigtimedwait50
122 #define stat __stat50
123 #define statvfs __statvfs90
124 #define statvfs1 __statvfs190
125 #define time __time50
126 #define times __times13
127 #define unvis __unvis50
128 #define wait3 __wait350
129 #define wait4 __wait450
130 extern const unsigned short *_ctype_tab_;
131 extern const short *_toupper_tab_;
132 extern const short *_tolower_tab_;
135 #if SANITIZER_MUSL && \
136 (defined(__i386__) || defined(__arm__) || SANITIZER_MIPS32 || SANITIZER_PPC32)
137 // musl 1.2.0 on existing 32-bit architectures uses new symbol names for the
138 // time-related functions that take 64-bit time_t values. See
139 // https://musl.libc.org/time64.html
140 #define adjtime __adjtime64
141 #define adjtimex __adjtimex_time64
142 #define aio_suspend __aio_suspend_time64
143 #define clock_adjtime __clock_adjtime64
144 #define clock_getres __clock_getres_time64
145 #define clock_gettime __clock_gettime64
146 #define clock_nanosleep __clock_nanosleep_time64
147 #define clock_settime __clock_settime64
148 #define cnd_timedwait __cnd_timedwait_time64
149 #define ctime __ctime64
150 #define ctime_r __ctime64_r
151 #define difftime __difftime64
152 #define dlsym __dlsym_time64
153 #define fstatat __fstatat_time64
154 #define fstat __fstat_time64
155 #define ftime __ftime64
156 #define futimens __futimens_time64
157 #define futimesat __futimesat_time64
158 #define futimes __futimes_time64
159 #define getitimer __getitimer_time64
160 #define getrusage __getrusage_time64
161 #define gettimeofday __gettimeofday_time64
162 #define gmtime __gmtime64
163 #define gmtime_r __gmtime64_r
164 #define localtime __localtime64
165 #define localtime_r __localtime64_r
166 #define lstat __lstat_time64
167 #define lutimes __lutimes_time64
168 #define mktime __mktime64
169 #define mq_timedreceive __mq_timedreceive_time64
170 #define mq_timedsend __mq_timedsend_time64
171 #define mtx_timedlock __mtx_timedlock_time64
172 #define nanosleep __nanosleep_time64
173 #define ppoll __ppoll_time64
174 #define pselect __pselect_time64
175 #define pthread_cond_timedwait __pthread_cond_timedwait_time64
176 #define pthread_mutex_timedlock __pthread_mutex_timedlock_time64
177 #define pthread_rwlock_timedrdlock __pthread_rwlock_timedrdlock_time64
178 #define pthread_rwlock_timedwrlock __pthread_rwlock_timedwrlock_time64
179 #define pthread_timedjoin_np __pthread_timedjoin_np_time64
180 #define recvmmsg __recvmmsg_time64
181 #define sched_rr_get_interval __sched_rr_get_interval_time64
182 #define select __select_time64
183 #define semtimedop __semtimedop_time64
184 #define sem_timedwait __sem_timedwait_time64
185 #define setitimer __setitimer_time64
186 #define settimeofday __settimeofday_time64
187 #define sigtimedwait __sigtimedwait_time64
188 #define stat __stat_time64
189 #define stime __stime64
190 #define thrd_sleep __thrd_sleep_time64
191 #define timegm __timegm_time64
192 #define timerfd_gettime __timerfd_gettime64
193 #define timerfd_settime __timerfd_settime64
194 #define timer_gettime __timer_gettime64
195 #define timer_settime __timer_settime64
196 #define timespec_get __timespec_get_time64
197 #define time __time64
198 #define utimensat __utimensat_time64
199 #define utimes __utimes_time64
200 #define utime __utime64
201 #define wait3 __wait3_time64
202 #define wait4 __wait4_time64
205 // Platform-specific options.
207 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
208 #elif SANITIZER_WINDOWS64
209 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 0
211 #define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE 1
212 #endif // SANITIZER_APPLE
214 #ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE
215 #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {}
218 #ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM
219 #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {}
222 #ifndef COMMON_INTERCEPTOR_FD_ACCESS
223 #define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {}
226 #ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK
227 #define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {}
230 #ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK
231 #define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {}
234 #ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK
235 #define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {}
238 #ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR
239 #define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {}
242 #ifndef COMMON_INTERCEPTOR_MUTEX_INVALID
243 #define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {}
246 #ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG
247 #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg))
250 #ifndef COMMON_INTERCEPTOR_FILE_OPEN
251 #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {}
254 #ifndef COMMON_INTERCEPTOR_FILE_CLOSE
255 #define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {}
258 #ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED
259 #define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {}
262 #ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED
263 #define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {}
266 #ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE
267 #define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \
268 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__)
271 #ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED
272 #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0)
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) )
279 #ifndef COMMON_INTERCEPTOR_DLOPEN
280 #define COMMON_INTERCEPTOR_DLOPEN(filename, flag) \
281 ({ CheckNoDeepBind(filename, flag); REAL(dlopen)(filename, flag); })
284 #ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE
285 #define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0;
288 #ifndef COMMON_INTERCEPTOR_ACQUIRE
289 #define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {}
292 #ifndef COMMON_INTERCEPTOR_RELEASE
293 #define COMMON_INTERCEPTOR_RELEASE(ctx, u) {}
296 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START
297 #define COMMON_INTERCEPTOR_USER_CALLBACK_START() {}
300 #ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END
301 #define COMMON_INTERCEPTOR_USER_CALLBACK_END() {}
304 #ifdef SANITIZER_NLDBL_VERSION
305 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \
306 COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION)
308 #define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \
309 COMMON_INTERCEPT_FUNCTION(fn)
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)
325 #define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \
326 COMMON_INTERCEPT_FUNCTION(fn)
329 #ifndef COMMON_INTERCEPTOR_MEMSET_IMPL
330 #define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \
332 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \
333 return internal_memset(dst, v, size); \
334 COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \
335 if (common_flags()->intercept_intrin) \
336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
337 return REAL(memset)(dst, v, size); \
341 #ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL
342 #define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \
344 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \
345 return internal_memmove(dst, src, size); \
346 COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \
347 if (common_flags()->intercept_intrin) { \
348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
349 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \
351 return REAL(memmove)(dst, src, size); \
355 #ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL
356 #define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \
358 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \
359 return internal_memmove(dst, src, size); \
361 COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \
362 if (common_flags()->intercept_intrin) { \
363 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \
364 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \
366 return REAL(memcpy)(dst, src, size); \
370 #ifndef COMMON_INTERCEPTOR_MMAP_IMPL
371 #define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \
373 { return REAL(mmap)(addr, sz, prot, flags, fd, off); }
376 #ifndef COMMON_INTERCEPTOR_COPY_STRING
377 #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {}
380 #ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL
381 #define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \
382 COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \
383 uptr copy_length = internal_strnlen(s, size); \
384 char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \
385 if (common_flags()->intercept_strndup) { \
386 COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \
389 COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \
390 internal_memcpy(new_mem, s, copy_length); \
391 new_mem[copy_length] = '\0'; \
396 #ifndef COMMON_INTERCEPTOR_STRERROR
397 #define COMMON_INTERCEPTOR_STRERROR() {}
400 struct FileMetadata {
401 // For open_memstream().
406 struct CommonInterceptorMetadata {
417 typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap;
419 static MetadataHashMap *interceptor_metadata_map;
421 UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr,
422 const FileMetadata &file) {
423 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr);
425 h->type = CommonInterceptorMetadata::CIMT_FILE;
429 UNUSED static const FileMetadata *GetInterceptorMetadata(
430 __sanitizer_FILE *addr) {
431 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr,
434 if (addr && h.exists()) {
436 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE);
443 UNUSED static void DeleteInterceptorMetadata(void *addr) {
444 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true);
449 #if SANITIZER_INTERCEPT_STRLEN
450 INTERCEPTOR(SIZE_T, strlen, const char *s) {
451 // Sometimes strlen is called prior to InitializeCommonInterceptors,
452 // in which case the REAL(strlen) typically used in
453 // COMMON_INTERCEPTOR_ENTER will fail. We use internal_strlen here
455 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
456 return internal_strlen(s);
458 COMMON_INTERCEPTOR_ENTER(ctx, strlen, s);
459 SIZE_T result = REAL(strlen)(s);
460 if (common_flags()->intercept_strlen)
461 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1);
464 #define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen)
469 #if SANITIZER_INTERCEPT_STRNLEN
470 INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) {
472 COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen);
473 SIZE_T length = REAL(strnlen)(s, maxlen);
474 if (common_flags()->intercept_strlen)
475 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen));
478 #define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen)
483 #if SANITIZER_INTERCEPT_STRNDUP
484 INTERCEPTOR(char*, strndup, const char *s, uptr size) {
486 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
488 #define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup)
491 #endif // SANITIZER_INTERCEPT_STRNDUP
493 #if SANITIZER_INTERCEPT___STRNDUP
494 INTERCEPTOR(char*, __strndup, const char *s, uptr size) {
496 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size);
498 #define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup)
500 #define INIT___STRNDUP
501 #endif // SANITIZER_INTERCEPT___STRNDUP
503 #if SANITIZER_INTERCEPT_TEXTDOMAIN
504 INTERCEPTOR(char*, textdomain, const char *domainname) {
506 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname);
507 if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0);
508 char *domain = REAL(textdomain)(domainname);
510 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, internal_strlen(domain) + 1);
514 #define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain)
516 #define INIT_TEXTDOMAIN
519 #if SANITIZER_INTERCEPT_STRCMP
520 static inline int CharCmpX(unsigned char c1, unsigned char c2) {
521 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1;
524 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc,
525 const char *s1, const char *s2, int result)
527 INTERCEPTOR(int, strcmp, const char *s1, const char *s2) {
529 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2);
530 unsigned char c1, c2;
533 c1 = (unsigned char)s1[i];
534 c2 = (unsigned char)s2[i];
535 if (c1 != c2 || c1 == '\0') break;
537 if (common_flags()->intercept_strcmp) {
538 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
539 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
541 int result = CharCmpX(c1, c2);
542 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1,
547 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc,
548 const char *s1, const char *s2, uptr n,
551 INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) {
552 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
553 return internal_strncmp(s1, s2, size);
555 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size);
556 unsigned char c1 = 0, c2 = 0;
558 for (i = 0; i < size; i++) {
559 c1 = (unsigned char)s1[i];
560 c2 = (unsigned char)s2[i];
561 if (c1 != c2 || c1 == '\0') break;
565 if (common_flags()->strict_string_checks) {
566 for (; i1 < size && s1[i1]; i1++) {}
567 for (; i2 < size && s2[i2]; i2++) {}
569 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
570 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
571 int result = CharCmpX(c1, c2);
572 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1,
577 #define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp)
578 #define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp)
584 #if SANITIZER_INTERCEPT_STRCASECMP
585 static inline int CharCaseCmp(unsigned char c1, unsigned char c2) {
586 int c1_low = ToLower(c1);
587 int c2_low = ToLower(c2);
588 return c1_low - c2_low;
591 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc,
592 const char *s1, const char *s2, int result)
594 INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) {
596 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2);
597 unsigned char c1 = 0, c2 = 0;
600 c1 = (unsigned char)s1[i];
601 c2 = (unsigned char)s2[i];
602 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
604 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1);
605 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1);
606 int result = CharCaseCmp(c1, c2);
607 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(),
612 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc,
613 const char *s1, const char *s2, uptr size,
616 INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) {
618 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size);
619 unsigned char c1 = 0, c2 = 0;
621 for (i = 0; i < size; i++) {
622 c1 = (unsigned char)s1[i];
623 c2 = (unsigned char)s2[i];
624 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break;
628 if (common_flags()->strict_string_checks) {
629 for (; i1 < size && s1[i1]; i1++) {}
630 for (; i2 < size && s2[i2]; i2++) {}
632 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size));
633 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size));
634 int result = CharCaseCmp(c1, c2);
635 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(),
636 s1, s2, size, result);
640 #define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp)
641 #define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp)
643 #define INIT_STRCASECMP
644 #define INIT_STRNCASECMP
647 #if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR
648 static inline void StrstrCheck(void *ctx, char *r, const char *s1,
650 uptr len1 = internal_strlen(s1);
651 uptr len2 = internal_strlen(s2);
652 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1);
653 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1);
657 #if SANITIZER_INTERCEPT_STRSTR
659 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc,
660 const char *s1, const char *s2, char *result)
662 INTERCEPTOR(char*, strstr, const char *s1, const char *s2) {
663 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
664 return internal_strstr(s1, s2);
666 COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2);
667 char *r = REAL(strstr)(s1, s2);
668 if (common_flags()->intercept_strstr)
669 StrstrCheck(ctx, r, s1, s2);
670 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1,
675 #define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr);
680 #if SANITIZER_INTERCEPT_STRCASESTR
682 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc,
683 const char *s1, const char *s2, char *result)
685 INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) {
687 COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2);
688 char *r = REAL(strcasestr)(s1, s2);
689 if (common_flags()->intercept_strstr)
690 StrstrCheck(ctx, r, s1, s2);
691 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(),
696 #define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr);
698 #define INIT_STRCASESTR
701 #if SANITIZER_INTERCEPT_STRTOK
703 INTERCEPTOR(char*, strtok, char *str, const char *delimiters) {
705 COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters);
706 if (!common_flags()->intercept_strtok) {
707 return REAL(strtok)(str, delimiters);
709 if (common_flags()->strict_string_checks) {
710 // If strict_string_checks is enabled, we check the whole first argument
711 // string on the first call (strtok saves this string in a static buffer
712 // for subsequent calls). We do not need to check strtok's result.
713 // As the delimiters can change, we check them every call.
714 if (str != nullptr) {
715 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
717 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters,
718 internal_strlen(delimiters) + 1);
719 return REAL(strtok)(str, delimiters);
721 // However, when strict_string_checks is disabled we cannot check the
722 // whole string on the first call. Instead, we check the result string
723 // which is guaranteed to be a NULL-terminated substring of the first
724 // argument. We also conservatively check one character of str and the
726 if (str != nullptr) {
727 COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1);
729 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1);
730 char *result = REAL(strtok)(str, delimiters);
731 if (result != nullptr) {
732 COMMON_INTERCEPTOR_READ_RANGE(ctx, result, internal_strlen(result) + 1);
733 } else if (str != nullptr) {
734 // No delimiter were found, it's safe to assume that the entire str was
736 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
742 #define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok)
747 #if SANITIZER_INTERCEPT_MEMMEM
748 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc,
749 const void *s1, SIZE_T len1, const void *s2,
750 SIZE_T len2, void *result)
752 INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2,
755 COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2);
756 void *r = REAL(memmem)(s1, len1, s2, len2);
757 if (common_flags()->intercept_memmem) {
758 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1);
759 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2);
761 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(),
762 s1, len1, s2, len2, r);
766 #define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem);
769 #endif // SANITIZER_INTERCEPT_MEMMEM
771 #if SANITIZER_INTERCEPT_STRCHR
772 INTERCEPTOR(char*, strchr, const char *s, int c) {
774 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
775 return internal_strchr(s, c);
776 COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c);
777 char *result = REAL(strchr)(s, c);
778 if (common_flags()->intercept_strchr) {
779 // Keep strlen as macro argument, as macro may ignore it.
780 COMMON_INTERCEPTOR_READ_STRING(ctx, s,
781 (result ? result - s : internal_strlen(s)) + 1);
785 #define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr)
790 #if SANITIZER_INTERCEPT_STRCHRNUL
791 INTERCEPTOR(char*, strchrnul, const char *s, int c) {
793 COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c);
794 char *result = REAL(strchrnul)(s, c);
795 uptr len = result - s + 1;
796 if (common_flags()->intercept_strchr)
797 COMMON_INTERCEPTOR_READ_STRING(ctx, s, len);
800 #define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul)
802 #define INIT_STRCHRNUL
805 #if SANITIZER_INTERCEPT_STRRCHR
806 INTERCEPTOR(char*, strrchr, const char *s, int c) {
808 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
809 return internal_strrchr(s, c);
810 COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c);
811 if (common_flags()->intercept_strchr)
812 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
813 return REAL(strrchr)(s, c);
815 #define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr)
820 #if SANITIZER_INTERCEPT_STRSPN
821 INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) {
823 COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2);
824 SIZE_T r = REAL(strspn)(s1, s2);
825 if (common_flags()->intercept_strspn) {
826 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
827 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
832 INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) {
834 COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2);
835 SIZE_T r = REAL(strcspn)(s1, s2);
836 if (common_flags()->intercept_strspn) {
837 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
838 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1);
843 #define INIT_STRSPN \
844 COMMON_INTERCEPT_FUNCTION(strspn); \
845 COMMON_INTERCEPT_FUNCTION(strcspn);
850 #if SANITIZER_INTERCEPT_STRPBRK
851 INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) {
853 COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2);
854 char *r = REAL(strpbrk)(s1, s2);
855 if (common_flags()->intercept_strpbrk) {
856 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, internal_strlen(s2) + 1);
857 COMMON_INTERCEPTOR_READ_STRING(ctx, s1,
858 r ? r - s1 + 1 : internal_strlen(s1) + 1);
863 #define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk);
868 #if SANITIZER_INTERCEPT_MEMSET
869 INTERCEPTOR(void *, memset, void *dst, int v, uptr size) {
871 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size);
874 #define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset)
879 #if SANITIZER_INTERCEPT_MEMMOVE
880 INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) {
882 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
885 #define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove)
890 #if SANITIZER_INTERCEPT_MEMCPY
891 INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) {
892 // On OS X, calling internal_memcpy here will cause memory corruptions,
893 // because memcpy and memmove are actually aliases of the same
894 // implementation. We need to use internal_memmove here.
895 // N.B.: If we switch this to internal_ we'll have to use internal_memmove
896 // due to memcpy being an alias of memmove on OS X.
898 #if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
899 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size);
901 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size);
905 #define INIT_MEMCPY \
907 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \
908 COMMON_INTERCEPT_FUNCTION(memcpy); \
910 ASSIGN_REAL(memcpy, memmove); \
912 CHECK(REAL(memcpy)); \
919 #if SANITIZER_INTERCEPT_MEMCMP
920 DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc,
921 const void *s1, const void *s2, uptr n,
924 // Common code for `memcmp` and `bcmp`.
925 int MemcmpInterceptorCommon(void *ctx,
926 int (*real_fn)(const void *, const void *, uptr),
927 const void *a1, const void *a2, uptr size) {
928 if (common_flags()->intercept_memcmp) {
929 if (common_flags()->strict_memcmp) {
930 // Check the entire regions even if the first bytes of the buffers are
932 COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size);
933 COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size);
934 // Fallthrough to REAL(memcmp) below.
936 unsigned char c1 = 0, c2 = 0;
937 const unsigned char *s1 = (const unsigned char*)a1;
938 const unsigned char *s2 = (const unsigned char*)a2;
940 for (i = 0; i < size; i++) {
945 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size));
946 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size));
947 int r = CharCmpX(c1, c2);
948 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(),
953 int result = real_fn(a1, a2, size);
954 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1,
959 INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) {
960 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
961 return internal_memcmp(a1, a2, size);
963 COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size);
964 return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size);
967 #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp)
972 #if SANITIZER_INTERCEPT_BCMP
973 INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) {
974 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
975 return internal_memcmp(a1, a2, size);
977 COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size);
978 return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size);
981 #define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp)
986 #if SANITIZER_INTERCEPT_MEMCHR
987 INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) {
988 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
989 return internal_memchr(s, c, n);
991 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n);
992 #if SANITIZER_WINDOWS
995 res = REAL(memchr)(s, c, n);
997 res = internal_memchr(s, c, n);
1000 void *res = REAL(memchr)(s, c, n);
1002 uptr len = res ? (char *)res - (const char *)s + 1 : n;
1003 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len);
1007 #define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr)
1012 #if SANITIZER_INTERCEPT_MEMRCHR
1013 INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) {
1015 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n);
1016 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n);
1017 return REAL(memrchr)(s, c, n);
1020 #define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr)
1022 #define INIT_MEMRCHR
1025 #if SANITIZER_INTERCEPT_FREXP
1026 INTERCEPTOR(double, frexp, double x, int *exp) {
1028 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp);
1029 // Assuming frexp() always writes to |exp|.
1030 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
1031 double res = REAL(frexp)(x, exp);
1032 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
1036 #define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp);
1039 #endif // SANITIZER_INTERCEPT_FREXP
1041 #if SANITIZER_INTERCEPT_FREXPF_FREXPL
1042 INTERCEPTOR(float, frexpf, float x, int *exp) {
1044 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp);
1045 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
1046 float res = REAL(frexpf)(x, exp);
1047 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
1051 INTERCEPTOR(long double, frexpl, long double x, int *exp) {
1053 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp);
1054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp));
1055 long double res = REAL(frexpl)(x, exp);
1056 COMMON_INTERCEPTOR_INITIALIZE_RANGE(exp, sizeof(*exp));
1060 #define INIT_FREXPF_FREXPL \
1061 COMMON_INTERCEPT_FUNCTION(frexpf); \
1062 COMMON_INTERCEPT_FUNCTION_LDBL(frexpl)
1064 #define INIT_FREXPF_FREXPL
1065 #endif // SANITIZER_INTERCEPT_FREXPF_FREXPL
1068 static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec,
1069 SIZE_T iovlen, SIZE_T maxlen) {
1070 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
1071 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
1072 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz);
1077 static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec,
1078 SIZE_T iovlen, SIZE_T maxlen) {
1079 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen);
1080 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) {
1081 SSIZE_T sz = Min(iovec[i].iov_len, maxlen);
1082 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz);
1088 #if SANITIZER_INTERCEPT_READ
1089 INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) {
1091 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count);
1092 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1093 // FIXME: under ASan the call below may write to freed memory and corrupt
1094 // its metadata. See
1095 // https://github.com/google/sanitizers/issues/321.
1096 SSIZE_T res = REAL(read)(fd, ptr, count);
1097 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1098 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1101 #define INIT_READ COMMON_INTERCEPT_FUNCTION(read)
1106 #if SANITIZER_INTERCEPT_FREAD
1107 INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) {
1108 // libc file streams can call user-supplied functions, see fopencookie.
1110 COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file);
1111 // FIXME: under ASan the call below may write to freed memory and corrupt
1112 // its metadata. See
1113 // https://github.com/google/sanitizers/issues/321.
1114 SIZE_T res = REAL(fread)(ptr, size, nmemb, file);
1115 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size);
1118 #define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread)
1123 #if SANITIZER_INTERCEPT_PREAD
1124 INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1126 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset);
1127 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1128 // FIXME: under ASan the call below may write to freed memory and corrupt
1129 // its metadata. See
1130 // https://github.com/google/sanitizers/issues/321.
1131 SSIZE_T res = REAL(pread)(fd, ptr, count, offset);
1132 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1133 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1136 #define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread)
1141 #if SANITIZER_INTERCEPT_PREAD64
1142 INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) {
1144 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset);
1145 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1146 // FIXME: under ASan the call below may write to freed memory and corrupt
1147 // its metadata. See
1148 // https://github.com/google/sanitizers/issues/321.
1149 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset);
1150 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res);
1151 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1154 #define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64)
1156 #define INIT_PREAD64
1159 #if SANITIZER_INTERCEPT_READV
1160 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov,
1163 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt);
1164 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1165 SSIZE_T res = REAL(readv)(fd, iov, iovcnt);
1166 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1167 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1170 #define INIT_READV COMMON_INTERCEPT_FUNCTION(readv)
1175 #if SANITIZER_INTERCEPT_PREADV
1176 INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt,
1179 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset);
1180 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1181 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset);
1182 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1183 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1186 #define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv)
1191 #if SANITIZER_INTERCEPT_PREADV64
1192 INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt,
1195 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset);
1196 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1197 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset);
1198 if (res > 0) write_iovec(ctx, iov, iovcnt, res);
1199 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
1202 #define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64)
1204 #define INIT_PREADV64
1207 #if SANITIZER_INTERCEPT_WRITE
1208 INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) {
1210 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count);
1211 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1212 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1213 SSIZE_T res = REAL(write)(fd, ptr, count);
1214 // FIXME: this check should be _before_ the call to REAL(write), not after
1215 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1218 #define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write)
1223 #if SANITIZER_INTERCEPT_FWRITE
1224 INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) {
1225 // libc file streams can call user-supplied functions, see fopencookie.
1227 COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file);
1228 SIZE_T res = REAL(fwrite)(p, size, nmemb, file);
1229 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size);
1232 #define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite)
1237 #if SANITIZER_INTERCEPT_PWRITE
1238 INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) {
1240 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset);
1241 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1242 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1243 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset);
1244 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1247 #define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite)
1252 #if SANITIZER_INTERCEPT_PWRITE64
1253 INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count,
1256 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset);
1257 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1258 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1259 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset);
1260 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res);
1263 #define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64)
1265 #define INIT_PWRITE64
1268 #if SANITIZER_INTERCEPT_WRITEV
1269 INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov,
1272 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt);
1273 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1274 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1275 SSIZE_T res = REAL(writev)(fd, iov, iovcnt);
1276 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1279 #define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev)
1284 #if SANITIZER_INTERCEPT_PWRITEV
1285 INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt,
1288 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset);
1289 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1290 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1291 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset);
1292 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1295 #define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev)
1297 #define INIT_PWRITEV
1300 #if SANITIZER_INTERCEPT_PWRITEV64
1301 INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt,
1304 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset);
1305 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
1306 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
1307 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset);
1308 if (res > 0) read_iovec(ctx, iov, iovcnt, res);
1311 #define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64)
1313 #define INIT_PWRITEV64
1316 #if SANITIZER_INTERCEPT_FGETS
1317 INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) {
1318 // libc file streams can call user-supplied functions, see fopencookie.
1320 COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file);
1321 // FIXME: under ASan the call below may write to freed memory and corrupt
1322 // its metadata. See
1323 // https://github.com/google/sanitizers/issues/321.
1324 char *res = REAL(fgets)(s, size, file);
1326 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
1329 #define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets)
1334 #if SANITIZER_INTERCEPT_FPUTS
1335 INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) {
1336 // libc file streams can call user-supplied functions, see fopencookie.
1338 COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file);
1339 if (!SANITIZER_APPLE || s) { // `fputs(NULL, file)` is supported on Darwin.
1340 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
1342 return REAL(fputs)(s, file);
1344 #define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs)
1349 #if SANITIZER_INTERCEPT_PUTS
1350 INTERCEPTOR(int, puts, char *s) {
1351 // libc file streams can call user-supplied functions, see fopencookie.
1353 COMMON_INTERCEPTOR_ENTER(ctx, puts, s);
1354 if (!SANITIZER_APPLE || s) { // `puts(NULL)` is supported on Darwin.
1355 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
1357 return REAL(puts)(s);
1359 #define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts)
1364 #if SANITIZER_INTERCEPT_PRCTL
1365 INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3,
1366 unsigned long arg4, unsigned long arg5) {
1368 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5);
1369 static const int PR_SET_NAME = 15;
1370 static const int PR_SET_VMA = 0x53564d41;
1371 static const int PR_SCHED_CORE = 62;
1372 static const int PR_SCHED_CORE_GET = 0;
1373 if (option == PR_SET_VMA && arg2 == 0UL) {
1374 char *name = (char *)arg5;
1375 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
1377 int res = REAL(prctl(option, arg2, arg3, arg4, arg5));
1378 if (option == PR_SET_NAME) {
1380 internal_strncpy(buff, (char *)arg2, 15);
1382 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff);
1383 } else if (res != -1 && option == PR_SCHED_CORE && arg2 == PR_SCHED_CORE_GET) {
1384 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (u64*)(arg5), sizeof(u64));
1388 #define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl)
1391 #endif // SANITIZER_INTERCEPT_PRCTL
1393 #if SANITIZER_INTERCEPT_TIME
1394 INTERCEPTOR(unsigned long, time, unsigned long *t) {
1396 COMMON_INTERCEPTOR_ENTER(ctx, time, t);
1397 unsigned long local_t;
1398 unsigned long res = REAL(time)(&local_t);
1399 if (t && res != (unsigned long)-1) {
1400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t));
1405 #define INIT_TIME COMMON_INTERCEPT_FUNCTION(time);
1408 #endif // SANITIZER_INTERCEPT_TIME
1410 #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1411 static void unpoison_tm(void *ctx, __sanitizer_tm *tm) {
1412 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1413 #if !SANITIZER_SOLARIS
1415 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone
1416 // can point to shared memory and tsan would report a data race.
1417 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone,
1418 internal_strlen(tm->tm_zone) + 1);
1422 INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) {
1424 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep);
1425 __sanitizer_tm *res = REAL(localtime)(timep);
1427 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1428 unpoison_tm(ctx, res);
1432 INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) {
1434 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result);
1435 __sanitizer_tm *res = REAL(localtime_r)(timep, result);
1437 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1438 unpoison_tm(ctx, res);
1442 INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) {
1444 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep);
1445 __sanitizer_tm *res = REAL(gmtime)(timep);
1447 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1448 unpoison_tm(ctx, res);
1452 INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) {
1454 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result);
1455 __sanitizer_tm *res = REAL(gmtime_r)(timep, result);
1457 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1458 unpoison_tm(ctx, res);
1462 INTERCEPTOR(char *, ctime, unsigned long *timep) {
1464 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep);
1465 // FIXME: under ASan the call below may write to freed memory and corrupt
1466 // its metadata. See
1467 // https://github.com/google/sanitizers/issues/321.
1468 char *res = REAL(ctime)(timep);
1470 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1471 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1475 INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) {
1477 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result);
1478 // FIXME: under ASan the call below may write to freed memory and corrupt
1479 // its metadata. See
1480 // https://github.com/google/sanitizers/issues/321.
1481 char *res = REAL(ctime_r)(timep, result);
1483 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep));
1484 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1488 INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) {
1490 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm);
1491 // FIXME: under ASan the call below may write to freed memory and corrupt
1492 // its metadata. See
1493 // https://github.com/google/sanitizers/issues/321.
1494 char *res = REAL(asctime)(tm);
1496 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1501 INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) {
1503 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result);
1504 // FIXME: under ASan the call below may write to freed memory and corrupt
1505 // its metadata. See
1506 // https://github.com/google/sanitizers/issues/321.
1507 char *res = REAL(asctime_r)(tm, result);
1509 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm));
1510 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
1514 INTERCEPTOR(long, mktime, __sanitizer_tm *tm) {
1516 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm);
1517 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec));
1518 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min));
1519 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour));
1520 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday));
1521 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon));
1522 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year));
1523 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst));
1524 long res = REAL(mktime)(tm);
1525 if (res != -1) unpoison_tm(ctx, tm);
1528 #define INIT_LOCALTIME_AND_FRIENDS \
1529 COMMON_INTERCEPT_FUNCTION(localtime); \
1530 COMMON_INTERCEPT_FUNCTION(localtime_r); \
1531 COMMON_INTERCEPT_FUNCTION(gmtime); \
1532 COMMON_INTERCEPT_FUNCTION(gmtime_r); \
1533 COMMON_INTERCEPT_FUNCTION(ctime); \
1534 COMMON_INTERCEPT_FUNCTION(ctime_r); \
1535 COMMON_INTERCEPT_FUNCTION(asctime); \
1536 COMMON_INTERCEPT_FUNCTION(asctime_r); \
1537 COMMON_INTERCEPT_FUNCTION(mktime);
1539 #define INIT_LOCALTIME_AND_FRIENDS
1540 #endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS
1542 #if SANITIZER_INTERCEPT_STRPTIME
1543 INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) {
1545 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm);
1547 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, internal_strlen(format) + 1);
1548 // FIXME: under ASan the call below may write to freed memory and corrupt
1549 // its metadata. See
1550 // https://github.com/google/sanitizers/issues/321.
1551 char *res = REAL(strptime)(s, format, tm);
1552 COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0);
1554 // Do not call unpoison_tm here, because strptime does not, in fact,
1555 // initialize the entire struct tm. For example, tm_zone pointer is left
1557 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm));
1561 #define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime);
1563 #define INIT_STRPTIME
1566 #if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF
1567 #include "sanitizer_common_interceptors_format.inc"
1569 #define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \
1573 va_start(ap, format); \
1574 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \
1575 int res = WRAP(vname)(__VA_ARGS__, ap); \
1582 #if SANITIZER_INTERCEPT_SCANF
1584 #define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \
1587 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
1590 int res = REAL(vname)(__VA_ARGS__); \
1592 scanf_common(ctx, res, allowGnuMalloc, format, aq); \
1597 INTERCEPTOR(int, vscanf, const char *format, va_list ap)
1598 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap)
1600 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap)
1601 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap)
1603 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap)
1604 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap)
1606 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1607 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap)
1608 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap)
1610 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format,
1612 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap)
1614 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap)
1615 VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap)
1616 #endif // SANITIZER_INTERCEPT_ISOC99_SCANF
1618 INTERCEPTOR(int, scanf, const char *format, ...)
1619 FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format)
1621 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...)
1622 FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format)
1624 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...)
1625 FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format)
1627 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1628 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...)
1629 FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format)
1631 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...)
1632 FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format)
1634 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...)
1635 FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format)
1640 #if SANITIZER_INTERCEPT_SCANF
1641 #define INIT_SCANF \
1642 COMMON_INTERCEPT_FUNCTION_LDBL(scanf); \
1643 COMMON_INTERCEPT_FUNCTION_LDBL(sscanf); \
1644 COMMON_INTERCEPT_FUNCTION_LDBL(fscanf); \
1645 COMMON_INTERCEPT_FUNCTION_LDBL(vscanf); \
1646 COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \
1647 COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf);
1652 #if SANITIZER_INTERCEPT_ISOC99_SCANF
1653 #define INIT_ISOC99_SCANF \
1654 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \
1655 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \
1656 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \
1657 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \
1658 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \
1659 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf);
1661 #define INIT_ISOC99_SCANF
1664 #if SANITIZER_INTERCEPT_PRINTF
1666 #define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \
1668 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \
1672 #define VPRINTF_INTERCEPTOR_RETURN() \
1675 #define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \
1677 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \
1678 if (common_flags()->check_printf) \
1679 printf_common(ctx, format, aq); \
1680 int res = REAL(vname)(__VA_ARGS__); \
1681 VPRINTF_INTERCEPTOR_RETURN(); \
1685 // FIXME: under ASan the REAL() call below may write to freed memory and
1686 // corrupt its metadata. See
1687 // https://github.com/google/sanitizers/issues/321.
1688 #define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \
1690 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \
1691 if (common_flags()->check_printf) { \
1692 printf_common(ctx, format, aq); \
1694 int res = REAL(vname)(str, __VA_ARGS__); \
1696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \
1698 VPRINTF_INTERCEPTOR_RETURN(); \
1702 // FIXME: under ASan the REAL() call below may write to freed memory and
1703 // corrupt its metadata. See
1704 // https://github.com/google/sanitizers/issues/321.
1705 #define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \
1707 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \
1708 if (common_flags()->check_printf) { \
1709 printf_common(ctx, format, aq); \
1711 int res = REAL(vname)(str, size, __VA_ARGS__); \
1713 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \
1715 VPRINTF_INTERCEPTOR_RETURN(); \
1719 // FIXME: under ASan the REAL() call below may write to freed memory and
1720 // corrupt its metadata. See
1721 // https://github.com/google/sanitizers/issues/321.
1722 #define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \
1724 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \
1725 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \
1726 if (common_flags()->check_printf) { \
1727 printf_common(ctx, format, aq); \
1729 int res = REAL(vname)(strp, __VA_ARGS__); \
1731 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \
1733 VPRINTF_INTERCEPTOR_RETURN(); \
1737 INTERCEPTOR(int, vprintf, const char *format, va_list ap)
1738 VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap)
1740 INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format,
1742 VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap)
1744 INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format,
1746 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1748 #if SANITIZER_INTERCEPT___PRINTF_CHK
1749 INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag,
1750 SIZE_T size_to, const char *format, va_list ap)
1751 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap)
1754 #if SANITIZER_INTERCEPT_PRINTF_L
1755 INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc,
1756 const char *format, va_list ap)
1757 VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap)
1759 INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc,
1760 const char *format, ...)
1761 FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format)
1762 #endif // SANITIZER_INTERCEPT_PRINTF_L
1764 INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap)
1765 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1767 #if SANITIZER_INTERCEPT___PRINTF_CHK
1768 INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to,
1769 const char *format, va_list ap)
1770 VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap)
1773 INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap)
1774 VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap)
1776 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1777 INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap)
1778 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap)
1780 INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream,
1781 const char *format, va_list ap)
1782 VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap)
1784 INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format,
1786 VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap)
1788 INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format,
1790 VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format,
1793 #endif // SANITIZER_INTERCEPT_ISOC99_PRINTF
1795 INTERCEPTOR(int, printf, const char *format, ...)
1796 FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format)
1798 INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...)
1799 FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format)
1801 #if SANITIZER_INTERCEPT___PRINTF_CHK
1802 INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size,
1803 const char *format, ...)
1804 FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format)
1807 INTERCEPTOR(int, sprintf, char *str, const char *format, ...)
1808 FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format)
1810 #if SANITIZER_INTERCEPT___PRINTF_CHK
1811 INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to,
1812 const char *format, ...)
1813 FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format)
1816 INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...)
1817 FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format)
1819 #if SANITIZER_INTERCEPT___PRINTF_CHK
1820 INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag,
1821 SIZE_T size_to, const char *format, ...)
1822 FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format)
1825 INTERCEPTOR(int, asprintf, char **strp, const char *format, ...)
1826 FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format)
1828 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1829 INTERCEPTOR(int, __isoc99_printf, const char *format, ...)
1830 FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format)
1832 INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format,
1834 FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format)
1836 INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...)
1837 FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format)
1839 INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size,
1840 const char *format, ...)
1841 FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size,
1844 #endif // SANITIZER_INTERCEPT_ISOC99_PRINTF
1846 #endif // SANITIZER_INTERCEPT_PRINTF
1848 #if SANITIZER_INTERCEPT_PRINTF
1849 #define INIT_PRINTF \
1850 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \
1851 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \
1852 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \
1853 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \
1854 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \
1855 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \
1856 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \
1857 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \
1858 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \
1859 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf);
1864 #if SANITIZER_INTERCEPT___PRINTF_CHK
1865 #define INIT___PRINTF_CHK \
1866 COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \
1867 COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \
1868 COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \
1869 COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \
1870 COMMON_INTERCEPT_FUNCTION(__fprintf_chk);
1872 #define INIT___PRINTF_CHK
1875 #if SANITIZER_INTERCEPT_PRINTF_L
1876 #define INIT_PRINTF_L \
1877 COMMON_INTERCEPT_FUNCTION(snprintf_l); \
1878 COMMON_INTERCEPT_FUNCTION(vsnprintf_l);
1880 #define INIT_PRINTF_L
1883 #if SANITIZER_INTERCEPT_ISOC99_PRINTF
1884 #define INIT_ISOC99_PRINTF \
1885 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \
1886 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \
1887 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \
1888 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \
1889 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \
1890 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \
1891 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \
1892 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf);
1894 #define INIT_ISOC99_PRINTF
1897 #if SANITIZER_INTERCEPT_IOCTL
1898 #include "sanitizer_common_interceptors_ioctl.inc"
1899 #include "sanitizer_interceptors_ioctl_netbsd.inc"
1900 INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) {
1901 // We need a frame pointer, because we call into ioctl_common_[pre|post] which
1902 // can trigger a report and we need to be able to unwind through this
1903 // function. On Mac in debug mode we might not have a frame pointer, because
1904 // ioctl_common_[pre|post] doesn't get inlined here.
1905 ENABLE_FRAME_POINTER;
1909 va_start(ap, request);
1910 void *arg = va_arg(ap, void *);
1912 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg);
1914 CHECK(ioctl_initialized);
1916 // Note: TSan does not use common flags, and they are zero-initialized.
1917 // This effectively disables ioctl handling in TSan.
1918 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg);
1920 // Although request is unsigned long, the rest of the interceptor uses it
1921 // as just "unsigned" to save space, because we know that all values fit in
1922 // "unsigned" - they are compile-time constants.
1924 const ioctl_desc *desc = ioctl_lookup(request);
1925 ioctl_desc decoded_desc;
1927 VPrintf(2, "Decoding unknown ioctl 0x%lx\n", request);
1928 if (!ioctl_decode(request, &decoded_desc))
1929 Printf("WARNING: failed decoding unknown ioctl 0x%lx\n", request);
1931 desc = &decoded_desc;
1934 if (desc) ioctl_common_pre(ctx, desc, d, request, arg);
1935 int res = REAL(ioctl)(d, request, arg);
1936 // FIXME: some ioctls have different return values for success and failure.
1937 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg);
1940 #define INIT_IOCTL \
1942 COMMON_INTERCEPT_FUNCTION(ioctl);
1948 UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) {
1950 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd));
1952 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name,
1953 internal_strlen(pwd->pw_name) + 1);
1955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd,
1956 internal_strlen(pwd->pw_passwd) + 1);
1957 #if !SANITIZER_ANDROID
1959 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos,
1960 internal_strlen(pwd->pw_gecos) + 1);
1962 #if SANITIZER_APPLE || SANITIZER_FREEBSD || SANITIZER_NETBSD
1964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class,
1965 internal_strlen(pwd->pw_class) + 1);
1968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir,
1969 internal_strlen(pwd->pw_dir) + 1);
1971 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell,
1972 internal_strlen(pwd->pw_shell) + 1);
1976 UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) {
1978 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp));
1980 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name,
1981 internal_strlen(grp->gr_name) + 1);
1983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd,
1984 internal_strlen(grp->gr_passwd) + 1);
1985 char **p = grp->gr_mem;
1987 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
1989 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem,
1990 (p - grp->gr_mem + 1) * sizeof(*p));
1993 #endif // SANITIZER_POSIX
1995 #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS
1996 INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) {
1998 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name);
2000 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
2001 __sanitizer_passwd *res = REAL(getpwnam)(name);
2002 unpoison_passwd(ctx, res);
2005 INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) {
2007 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid);
2008 __sanitizer_passwd *res = REAL(getpwuid)(uid);
2009 unpoison_passwd(ctx, res);
2012 INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) {
2014 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name);
2015 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
2016 __sanitizer_group *res = REAL(getgrnam)(name);
2017 unpoison_group(ctx, res);
2020 INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) {
2022 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid);
2023 __sanitizer_group *res = REAL(getgrgid)(gid);
2024 unpoison_group(ctx, res);
2027 #define INIT_GETPWNAM_AND_FRIENDS \
2028 COMMON_INTERCEPT_FUNCTION(getpwnam); \
2029 COMMON_INTERCEPT_FUNCTION(getpwuid); \
2030 COMMON_INTERCEPT_FUNCTION(getgrnam); \
2031 COMMON_INTERCEPT_FUNCTION(getgrgid);
2033 #define INIT_GETPWNAM_AND_FRIENDS
2036 #if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS
2037 INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd,
2038 char *buf, SIZE_T buflen, __sanitizer_passwd **result) {
2040 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result);
2041 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
2042 // FIXME: under ASan the call below may write to freed memory and corrupt
2043 // its metadata. See
2044 // https://github.com/google/sanitizers/issues/321.
2045 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result);
2047 unpoison_passwd(ctx, *result);
2048 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2051 INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf,
2052 SIZE_T buflen, __sanitizer_passwd **result) {
2054 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result);
2055 // FIXME: under ASan the call below may write to freed memory and corrupt
2056 // its metadata. See
2057 // https://github.com/google/sanitizers/issues/321.
2058 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result);
2060 unpoison_passwd(ctx, *result);
2061 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2064 INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp,
2065 char *buf, SIZE_T buflen, __sanitizer_group **result) {
2067 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result);
2068 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
2069 // FIXME: under ASan the call below may write to freed memory and corrupt
2070 // its metadata. See
2071 // https://github.com/google/sanitizers/issues/321.
2072 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result);
2074 unpoison_group(ctx, *result);
2075 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2078 INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf,
2079 SIZE_T buflen, __sanitizer_group **result) {
2081 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result);
2082 // FIXME: under ASan the call below may write to freed memory and corrupt
2083 // its metadata. See
2084 // https://github.com/google/sanitizers/issues/321.
2085 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result);
2087 unpoison_group(ctx, *result);
2088 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2091 #define INIT_GETPWNAM_R_AND_FRIENDS \
2092 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \
2093 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \
2094 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \
2095 COMMON_INTERCEPT_FUNCTION(getgrgid_r);
2097 #define INIT_GETPWNAM_R_AND_FRIENDS
2100 #if SANITIZER_INTERCEPT_GETPWENT
2101 INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) {
2103 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy);
2104 __sanitizer_passwd *res = REAL(getpwent)(dummy);
2105 unpoison_passwd(ctx, res);
2108 INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) {
2110 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy);
2111 __sanitizer_group *res = REAL(getgrent)(dummy);
2112 unpoison_group(ctx, res);
2115 #define INIT_GETPWENT \
2116 COMMON_INTERCEPT_FUNCTION(getpwent); \
2117 COMMON_INTERCEPT_FUNCTION(getgrent);
2119 #define INIT_GETPWENT
2122 #if SANITIZER_INTERCEPT_FGETPWENT
2123 INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) {
2125 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp);
2126 __sanitizer_passwd *res = REAL(fgetpwent)(fp);
2127 unpoison_passwd(ctx, res);
2130 INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) {
2132 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp);
2133 __sanitizer_group *res = REAL(fgetgrent)(fp);
2134 unpoison_group(ctx, res);
2137 #define INIT_FGETPWENT \
2138 COMMON_INTERCEPT_FUNCTION(fgetpwent); \
2139 COMMON_INTERCEPT_FUNCTION(fgetgrent);
2141 #define INIT_FGETPWENT
2144 #if SANITIZER_INTERCEPT_GETPWENT_R
2145 INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf,
2146 SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2148 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp);
2149 // FIXME: under ASan the call below may write to freed memory and corrupt
2150 // its metadata. See
2151 // https://github.com/google/sanitizers/issues/321.
2152 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp);
2154 unpoison_passwd(ctx, *pwbufp);
2155 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2158 INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen,
2159 __sanitizer_group **pwbufp) {
2161 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp);
2162 // FIXME: under ASan the call below may write to freed memory and corrupt
2163 // its metadata. See
2164 // https://github.com/google/sanitizers/issues/321.
2165 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp);
2167 unpoison_group(ctx, *pwbufp);
2168 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2171 #define INIT_GETPWENT_R \
2172 COMMON_INTERCEPT_FUNCTION(getpwent_r); \
2173 COMMON_INTERCEPT_FUNCTION(getgrent_r);
2175 #define INIT_GETPWENT_R
2178 #if SANITIZER_INTERCEPT_FGETPWENT_R
2179 INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf,
2180 SIZE_T buflen, __sanitizer_passwd **pwbufp) {
2182 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp);
2183 // FIXME: under ASan the call below may write to freed memory and corrupt
2184 // its metadata. See
2185 // https://github.com/google/sanitizers/issues/321.
2186 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp);
2188 unpoison_passwd(ctx, *pwbufp);
2189 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2192 #define INIT_FGETPWENT_R \
2193 COMMON_INTERCEPT_FUNCTION(fgetpwent_r);
2195 #define INIT_FGETPWENT_R
2198 #if SANITIZER_INTERCEPT_FGETGRENT_R
2199 INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf,
2200 SIZE_T buflen, __sanitizer_group **pwbufp) {
2202 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp);
2203 // FIXME: under ASan the call below may write to freed memory and corrupt
2204 // its metadata. See
2205 // https://github.com/google/sanitizers/issues/321.
2206 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp);
2208 unpoison_group(ctx, *pwbufp);
2209 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp));
2212 #define INIT_FGETGRENT_R \
2213 COMMON_INTERCEPT_FUNCTION(fgetgrent_r);
2215 #define INIT_FGETGRENT_R
2218 #if SANITIZER_INTERCEPT_SETPWENT
2219 // The only thing these interceptors do is disable any nested interceptors.
2220 // These functions may open nss modules and call uninstrumented functions from
2221 // them, and we don't want things like strlen() to trigger.
2222 INTERCEPTOR(void, setpwent, int dummy) {
2224 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy);
2225 REAL(setpwent)(dummy);
2227 INTERCEPTOR(void, endpwent, int dummy) {
2229 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy);
2230 REAL(endpwent)(dummy);
2232 INTERCEPTOR(void, setgrent, int dummy) {
2234 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy);
2235 REAL(setgrent)(dummy);
2237 INTERCEPTOR(void, endgrent, int dummy) {
2239 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy);
2240 REAL(endgrent)(dummy);
2242 #define INIT_SETPWENT \
2243 COMMON_INTERCEPT_FUNCTION(setpwent); \
2244 COMMON_INTERCEPT_FUNCTION(endpwent); \
2245 COMMON_INTERCEPT_FUNCTION(setgrent); \
2246 COMMON_INTERCEPT_FUNCTION(endgrent);
2248 #define INIT_SETPWENT
2251 #if SANITIZER_INTERCEPT_CLOCK_GETTIME
2252 INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) {
2254 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp);
2255 // FIXME: under ASan the call below may write to freed memory and corrupt
2256 // its metadata. See
2257 // https://github.com/google/sanitizers/issues/321.
2258 int res = REAL(clock_getres)(clk_id, tp);
2260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2264 INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) {
2266 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp);
2267 // FIXME: under ASan the call below may write to freed memory and corrupt
2268 // its metadata. See
2269 // https://github.com/google/sanitizers/issues/321.
2270 int res = REAL(clock_gettime)(clk_id, tp);
2272 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz);
2277 namespace __sanitizer {
2279 int real_clock_gettime(u32 clk_id, void *tp) {
2280 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
2281 return internal_clock_gettime(clk_id, tp);
2282 return REAL(clock_gettime)(clk_id, tp);
2285 } // namespace __sanitizer
2287 INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) {
2289 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp);
2290 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz);
2291 return REAL(clock_settime)(clk_id, tp);
2293 #define INIT_CLOCK_GETTIME \
2294 COMMON_INTERCEPT_FUNCTION(clock_getres); \
2295 COMMON_INTERCEPT_FUNCTION(clock_gettime); \
2296 COMMON_INTERCEPT_FUNCTION(clock_settime);
2298 #define INIT_CLOCK_GETTIME
2301 #if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID
2302 INTERCEPTOR(int, clock_getcpuclockid, pid_t pid,
2303 __sanitizer_clockid_t *clockid) {
2305 COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid);
2306 int res = REAL(clock_getcpuclockid)(pid, clockid);
2307 if (!res && clockid) {
2308 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
2313 INTERCEPTOR(int, pthread_getcpuclockid, uptr thread,
2314 __sanitizer_clockid_t *clockid) {
2316 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getcpuclockid, thread, clockid);
2317 int res = REAL(pthread_getcpuclockid)(thread, clockid);
2318 if (!res && clockid) {
2319 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid);
2324 #define INIT_CLOCK_GETCPUCLOCKID \
2325 COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); \
2326 COMMON_INTERCEPT_FUNCTION(pthread_getcpuclockid);
2328 #define INIT_CLOCK_GETCPUCLOCKID
2331 #if SANITIZER_INTERCEPT_GETITIMER
2332 INTERCEPTOR(int, getitimer, int which, void *curr_value) {
2334 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value);
2335 // FIXME: under ASan the call below may write to freed memory and corrupt
2336 // its metadata. See
2337 // https://github.com/google/sanitizers/issues/321.
2338 int res = REAL(getitimer)(which, curr_value);
2339 if (!res && curr_value) {
2340 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz);
2344 INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) {
2346 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value);
2348 // itimerval can contain padding that may be legitimately uninitialized
2349 const struct __sanitizer_itimerval *nv =
2350 (const struct __sanitizer_itimerval *)new_value;
2351 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec,
2352 sizeof(__sanitizer_time_t));
2353 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec,
2354 sizeof(__sanitizer_suseconds_t));
2355 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec,
2356 sizeof(__sanitizer_time_t));
2357 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec,
2358 sizeof(__sanitizer_suseconds_t));
2360 // FIXME: under ASan the call below may write to freed memory and corrupt
2361 // its metadata. See
2362 // https://github.com/google/sanitizers/issues/321.
2363 int res = REAL(setitimer)(which, new_value, old_value);
2364 if (!res && old_value) {
2365 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz);
2369 #define INIT_GETITIMER \
2370 COMMON_INTERCEPT_FUNCTION(getitimer); \
2371 COMMON_INTERCEPT_FUNCTION(setitimer);
2373 #define INIT_GETITIMER
2376 #if SANITIZER_INTERCEPT_GLOB
2377 static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) {
2378 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob));
2379 // +1 for NULL pointer at the end.
2380 if (pglob->gl_pathv)
2381 COMMON_INTERCEPTOR_WRITE_RANGE(
2382 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv));
2383 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) {
2384 char *p = pglob->gl_pathv[i];
2385 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, internal_strlen(p) + 1);
2389 #if SANITIZER_SOLARIS
2390 INTERCEPTOR(int, glob, const char *pattern, int flags,
2391 int (*errfunc)(const char *epath, int eerrno),
2392 __sanitizer_glob_t *pglob) {
2394 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2395 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2396 int res = REAL(glob)(pattern, flags, errfunc, pglob);
2397 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2401 static THREADLOCAL __sanitizer_glob_t *pglob_copy;
2403 static void wrapped_gl_closedir(void *dir) {
2404 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2405 pglob_copy->gl_closedir(dir);
2408 static void *wrapped_gl_readdir(void *dir) {
2409 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2410 return pglob_copy->gl_readdir(dir);
2413 static void *wrapped_gl_opendir(const char *s) {
2414 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
2415 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2416 return pglob_copy->gl_opendir(s);
2419 static int wrapped_gl_lstat(const char *s, void *st) {
2420 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2421 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2422 return pglob_copy->gl_lstat(s, st);
2425 static int wrapped_gl_stat(const char *s, void *st) {
2426 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
2427 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, internal_strlen(s) + 1);
2428 return pglob_copy->gl_stat(s, st);
2431 static const __sanitizer_glob_t kGlobCopy = {
2433 0, wrapped_gl_closedir, wrapped_gl_readdir,
2434 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat};
2436 INTERCEPTOR(int, glob, const char *pattern, int flags,
2437 int (*errfunc)(const char *epath, int eerrno),
2438 __sanitizer_glob_t *pglob) {
2440 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob);
2441 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2442 __sanitizer_glob_t glob_copy;
2443 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2444 if (flags & glob_altdirfunc) {
2445 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2446 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2447 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2448 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2449 Swap(pglob->gl_stat, glob_copy.gl_stat);
2450 pglob_copy = &glob_copy;
2452 int res = REAL(glob)(pattern, flags, errfunc, pglob);
2453 if (flags & glob_altdirfunc) {
2454 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2455 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2456 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2457 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2458 Swap(pglob->gl_stat, glob_copy.gl_stat);
2461 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2464 #endif // SANITIZER_SOLARIS
2466 COMMON_INTERCEPT_FUNCTION(glob);
2467 #else // SANITIZER_INTERCEPT_GLOB
2469 #endif // SANITIZER_INTERCEPT_GLOB
2471 #if SANITIZER_INTERCEPT_GLOB64
2472 INTERCEPTOR(int, glob64, const char *pattern, int flags,
2473 int (*errfunc)(const char *epath, int eerrno),
2474 __sanitizer_glob_t *pglob) {
2476 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob);
2477 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0);
2478 __sanitizer_glob_t glob_copy;
2479 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy));
2480 if (flags & glob_altdirfunc) {
2481 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2482 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2483 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2484 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2485 Swap(pglob->gl_stat, glob_copy.gl_stat);
2486 pglob_copy = &glob_copy;
2488 int res = REAL(glob64)(pattern, flags, errfunc, pglob);
2489 if (flags & glob_altdirfunc) {
2490 Swap(pglob->gl_closedir, glob_copy.gl_closedir);
2491 Swap(pglob->gl_readdir, glob_copy.gl_readdir);
2492 Swap(pglob->gl_opendir, glob_copy.gl_opendir);
2493 Swap(pglob->gl_lstat, glob_copy.gl_lstat);
2494 Swap(pglob->gl_stat, glob_copy.gl_stat);
2497 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob);
2500 #define INIT_GLOB64 \
2501 COMMON_INTERCEPT_FUNCTION(glob64);
2502 #else // SANITIZER_INTERCEPT_GLOB64
2504 #endif // SANITIZER_INTERCEPT_GLOB64
2506 #if SANITIZER_INTERCEPT___B64_TO
2507 INTERCEPTOR(int, __b64_ntop, unsigned char const *src, SIZE_T srclength,
2508 char *target, SIZE_T targsize) {
2510 COMMON_INTERCEPTOR_ENTER(ctx, __b64_ntop, src, srclength, target, targsize);
2511 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, srclength);
2512 int res = REAL(__b64_ntop)(src, srclength, target, targsize);
2514 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res + 1);
2517 INTERCEPTOR(int, __b64_pton, char const *src, char *target, SIZE_T targsize) {
2519 COMMON_INTERCEPTOR_ENTER(ctx, __b64_pton, src, target, targsize);
2520 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
2521 int res = REAL(__b64_pton)(src, target, targsize);
2523 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, target, res);
2526 #define INIT___B64_TO \
2527 COMMON_INTERCEPT_FUNCTION(__b64_ntop); \
2528 COMMON_INTERCEPT_FUNCTION(__b64_pton);
2529 #else // SANITIZER_INTERCEPT___B64_TO
2530 #define INIT___B64_TO
2531 #endif // SANITIZER_INTERCEPT___B64_TO
2533 #if SANITIZER_INTERCEPT_DN_COMP_EXPAND
2534 # if __GLIBC_PREREQ(2, 34)
2535 // Changed with https://sourceware.org/git/?p=glibc.git;h=640bbdf
2536 # define DN_COMP_INTERCEPTOR_NAME dn_comp
2537 # define DN_EXPAND_INTERCEPTOR_NAME dn_expand
2539 # define DN_COMP_INTERCEPTOR_NAME __dn_comp
2540 # define DN_EXPAND_INTERCEPTOR_NAME __dn_expand
2542 INTERCEPTOR(int, DN_COMP_INTERCEPTOR_NAME, unsigned char *exp_dn,
2543 unsigned char *comp_dn, int length, unsigned char **dnptrs,
2544 unsigned char **lastdnptr) {
2546 COMMON_INTERCEPTOR_ENTER(ctx, DN_COMP_INTERCEPTOR_NAME, exp_dn, comp_dn,
2547 length, dnptrs, lastdnptr);
2548 int res = REAL(DN_COMP_INTERCEPTOR_NAME)(exp_dn, comp_dn, length, dnptrs,
2551 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, comp_dn, res);
2552 if (dnptrs && lastdnptr) {
2553 unsigned char **p = dnptrs;
2554 for (; p != lastdnptr && *p; ++p)
2558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dnptrs, (p - dnptrs) * sizeof(*p));
2563 INTERCEPTOR(int, DN_EXPAND_INTERCEPTOR_NAME, unsigned char const *base,
2564 unsigned char const *end, unsigned char const *src, char *dest,
2567 COMMON_INTERCEPTOR_ENTER(ctx, DN_EXPAND_INTERCEPTOR_NAME, base, end, src,
2569 // TODO: add read check if __dn_comp intercept added
2570 int res = REAL(DN_EXPAND_INTERCEPTOR_NAME)(base, end, src, dest, space);
2572 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, internal_strlen(dest) + 1);
2575 # define INIT_DN_COMP_EXPAND \
2576 COMMON_INTERCEPT_FUNCTION(DN_COMP_INTERCEPTOR_NAME); \
2577 COMMON_INTERCEPT_FUNCTION(DN_EXPAND_INTERCEPTOR_NAME);
2578 #else // SANITIZER_INTERCEPT_DN_COMP_EXPAND
2579 # define INIT_DN_COMP_EXPAND
2580 #endif // SANITIZER_INTERCEPT_DN_COMP_EXPAND
2582 #if SANITIZER_INTERCEPT_POSIX_SPAWN
2584 template <class RealSpawnPtr>
2585 static int PosixSpawnImpl(void *ctx, RealSpawnPtr *real_posix_spawn, pid_t *pid,
2586 const char *file_or_path, const void *file_actions,
2587 const void *attrp, char *const argv[],
2588 char *const envp[]) {
2589 COMMON_INTERCEPTOR_READ_RANGE(ctx, file_or_path,
2590 internal_strlen(file_or_path) + 1);
2592 for (char *const *s = argv; ; ++s) {
2593 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
2595 COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2599 for (char *const *s = envp; ; ++s) {
2600 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(*s));
2602 COMMON_INTERCEPTOR_READ_RANGE(ctx, *s, internal_strlen(*s) + 1);
2606 real_posix_spawn(pid, file_or_path, file_actions, attrp, argv, envp);
2608 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pid, sizeof(*pid));
2611 INTERCEPTOR(int, posix_spawn, pid_t *pid, const char *path,
2612 const void *file_actions, const void *attrp, char *const argv[],
2613 char *const envp[]) {
2615 COMMON_INTERCEPTOR_ENTER(ctx, posix_spawn, pid, path, file_actions, attrp,
2617 return PosixSpawnImpl(ctx, REAL(posix_spawn), pid, path, file_actions, attrp,
2620 INTERCEPTOR(int, posix_spawnp, pid_t *pid, const char *file,
2621 const void *file_actions, const void *attrp, char *const argv[],
2622 char *const envp[]) {
2624 COMMON_INTERCEPTOR_ENTER(ctx, posix_spawnp, pid, file, file_actions, attrp,
2626 return PosixSpawnImpl(ctx, REAL(posix_spawnp), pid, file, file_actions, attrp,
2629 # define INIT_POSIX_SPAWN \
2630 COMMON_INTERCEPT_FUNCTION(posix_spawn); \
2631 COMMON_INTERCEPT_FUNCTION(posix_spawnp);
2632 #else // SANITIZER_INTERCEPT_POSIX_SPAWN
2633 # define INIT_POSIX_SPAWN
2634 #endif // SANITIZER_INTERCEPT_POSIX_SPAWN
2636 #if SANITIZER_INTERCEPT_WAIT
2637 // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version
2638 // suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for
2640 INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) {
2642 COMMON_INTERCEPTOR_ENTER(ctx, wait, status);
2643 // FIXME: under ASan the call below may write to freed memory and corrupt
2644 // its metadata. See
2645 // https://github.com/google/sanitizers/issues/321.
2646 int res = REAL(wait)(status);
2647 if (res != -1 && status)
2648 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2651 // On FreeBSD id_t is always 64-bit wide.
2652 #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32)
2653 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop,
2656 INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop,
2660 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options);
2661 // FIXME: under ASan the call below may write to freed memory and corrupt
2662 // its metadata. See
2663 // https://github.com/google/sanitizers/issues/321.
2664 int res = REAL(waitid)(idtype, id, infop, options);
2665 if (res != -1 && infop)
2666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz);
2669 INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) {
2671 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options);
2672 // FIXME: under ASan the call below may write to freed memory and corrupt
2673 // its metadata. See
2674 // https://github.com/google/sanitizers/issues/321.
2675 int res = REAL(waitpid)(pid, status, options);
2676 if (res != -1 && status)
2677 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2680 INTERCEPTOR(int, wait3, int *status, int options, void *rusage) {
2682 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage);
2683 // FIXME: under ASan the call below may write to freed memory and corrupt
2684 // its metadata. See
2685 // https://github.com/google/sanitizers/issues/321.
2686 int res = REAL(wait3)(status, options, rusage);
2688 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2689 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2693 #if SANITIZER_ANDROID
2694 INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) {
2696 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage);
2697 // FIXME: under ASan the call below may write to freed memory and corrupt
2698 // its metadata. See
2699 // https://github.com/google/sanitizers/issues/321.
2700 int res = REAL(__wait4)(pid, status, options, rusage);
2702 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2703 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2707 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4);
2709 INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) {
2711 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage);
2712 // FIXME: under ASan the call below may write to freed memory and corrupt
2713 // its metadata. See
2714 // https://github.com/google/sanitizers/issues/321.
2715 int res = REAL(wait4)(pid, status, options, rusage);
2717 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status));
2718 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz);
2722 #define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4);
2723 #endif // SANITIZER_ANDROID
2725 COMMON_INTERCEPT_FUNCTION(wait); \
2726 COMMON_INTERCEPT_FUNCTION(waitid); \
2727 COMMON_INTERCEPT_FUNCTION(waitpid); \
2728 COMMON_INTERCEPT_FUNCTION(wait3);
2734 #if SANITIZER_INTERCEPT_INET
2735 INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) {
2737 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size);
2738 uptr sz = __sanitizer_in_addr_sz(af);
2739 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz);
2740 // FIXME: figure out read size based on the address family.
2741 // FIXME: under ASan the call below may write to freed memory and corrupt
2742 // its metadata. See
2743 // https://github.com/google/sanitizers/issues/321.
2744 char *res = REAL(inet_ntop)(af, src, dst, size);
2745 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
2748 INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) {
2750 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst);
2751 COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0);
2752 // FIXME: figure out read size based on the address family.
2753 // FIXME: under ASan the call below may write to freed memory and corrupt
2754 // its metadata. See
2755 // https://github.com/google/sanitizers/issues/321.
2756 int res = REAL(inet_pton)(af, src, dst);
2758 uptr sz = __sanitizer_in_addr_sz(af);
2759 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2764 COMMON_INTERCEPT_FUNCTION(inet_ntop); \
2765 COMMON_INTERCEPT_FUNCTION(inet_pton);
2770 #if SANITIZER_INTERCEPT_INET
2771 INTERCEPTOR(int, inet_aton, const char *cp, void *dst) {
2773 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst);
2774 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, internal_strlen(cp) + 1);
2775 // FIXME: under ASan the call below may write to freed memory and corrupt
2776 // its metadata. See
2777 // https://github.com/google/sanitizers/issues/321.
2778 int res = REAL(inet_aton)(cp, dst);
2780 uptr sz = __sanitizer_in_addr_sz(af_inet);
2781 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz);
2785 #define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton);
2787 #define INIT_INET_ATON
2790 #if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM
2791 INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) {
2793 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param);
2794 // FIXME: under ASan the call below may write to freed memory and corrupt
2795 // its metadata. See
2796 // https://github.com/google/sanitizers/issues/321.
2797 int res = REAL(pthread_getschedparam)(thread, policy, param);
2799 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy));
2800 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param));
2804 #define INIT_PTHREAD_GETSCHEDPARAM \
2805 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam);
2807 #define INIT_PTHREAD_GETSCHEDPARAM
2810 #if SANITIZER_INTERCEPT_GETADDRINFO
2811 INTERCEPTOR(int, getaddrinfo, char *node, char *service,
2812 struct __sanitizer_addrinfo *hints,
2813 struct __sanitizer_addrinfo **out) {
2815 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out);
2816 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, internal_strlen(node) + 1);
2818 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, internal_strlen(service) + 1);
2820 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo));
2821 // FIXME: under ASan the call below may write to freed memory and corrupt
2822 // its metadata. See
2823 // https://github.com/google/sanitizers/issues/321.
2824 int res = REAL(getaddrinfo)(node, service, hints, out);
2825 if (res == 0 && out) {
2826 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out));
2827 struct __sanitizer_addrinfo *p = *out;
2829 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
2831 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen);
2832 if (p->ai_canonname)
2833 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname,
2834 internal_strlen(p->ai_canonname) + 1);
2840 #define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo);
2842 #define INIT_GETADDRINFO
2845 #if SANITIZER_INTERCEPT_GETNAMEINFO
2846 INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host,
2847 unsigned hostlen, char *serv, unsigned servlen, int flags) {
2849 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen,
2850 serv, servlen, flags);
2851 // FIXME: consider adding READ_RANGE(sockaddr, salen)
2852 // There is padding in in_addr that may make this too noisy
2853 // FIXME: under ASan the call below may write to freed memory and corrupt
2854 // its metadata. See
2855 // https://github.com/google/sanitizers/issues/321.
2857 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags);
2859 if (host && hostlen)
2860 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, internal_strlen(host) + 1);
2861 if (serv && servlen)
2862 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, internal_strlen(serv) + 1);
2866 #define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo);
2868 #define INIT_GETNAMEINFO
2871 #if SANITIZER_INTERCEPT_GETSOCKNAME
2872 INTERCEPTOR(int, getsockname, int sock_fd, void *addr, unsigned *addrlen) {
2874 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen);
2877 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
2880 // FIXME: under ASan the call below may write to freed memory and corrupt
2881 // its metadata. See
2882 // https://github.com/google/sanitizers/issues/321.
2883 int res = REAL(getsockname)(sock_fd, addr, addrlen);
2884 if (!res && addr && addrlen) {
2885 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
2889 #define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname);
2891 #define INIT_GETSOCKNAME
2894 #if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2895 static void write_hostent(void *ctx, struct __sanitizer_hostent *h) {
2896 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent));
2898 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, internal_strlen(h->h_name) + 1);
2899 char **p = h->h_aliases;
2901 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
2904 COMMON_INTERCEPTOR_WRITE_RANGE(
2905 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases));
2908 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length);
2911 COMMON_INTERCEPTOR_WRITE_RANGE(
2912 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list));
2916 #if SANITIZER_INTERCEPT_GETHOSTBYNAME
2917 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) {
2919 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name);
2920 struct __sanitizer_hostent *res = REAL(gethostbyname)(name);
2921 if (res) write_hostent(ctx, res);
2925 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len,
2928 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type);
2929 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
2930 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type);
2931 if (res) write_hostent(ctx, res);
2935 INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) {
2937 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake);
2938 struct __sanitizer_hostent *res = REAL(gethostent)(fake);
2939 if (res) write_hostent(ctx, res);
2942 #define INIT_GETHOSTBYNAME \
2943 COMMON_INTERCEPT_FUNCTION(gethostent); \
2944 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \
2945 COMMON_INTERCEPT_FUNCTION(gethostbyname);
2947 #define INIT_GETHOSTBYNAME
2948 #endif // SANITIZER_INTERCEPT_GETHOSTBYNAME
2950 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2
2951 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) {
2953 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af);
2954 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af);
2955 if (res) write_hostent(ctx, res);
2958 #define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2);
2960 #define INIT_GETHOSTBYNAME2
2961 #endif // SANITIZER_INTERCEPT_GETHOSTBYNAME2
2963 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R
2964 INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret,
2965 char *buf, SIZE_T buflen, __sanitizer_hostent **result,
2968 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result,
2970 // FIXME: under ASan the call below may write to freed memory and corrupt
2971 // its metadata. See
2972 // https://github.com/google/sanitizers/issues/321.
2973 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop);
2975 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2976 if (res == 0 && *result) write_hostent(ctx, *result);
2979 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
2982 #define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r);
2984 #define INIT_GETHOSTBYNAME_R
2987 #if SANITIZER_INTERCEPT_GETHOSTENT_R
2988 INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf,
2989 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) {
2991 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result,
2993 // FIXME: under ASan the call below may write to freed memory and corrupt
2994 // its metadata. See
2995 // https://github.com/google/sanitizers/issues/321.
2996 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop);
2998 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
2999 if (res == 0 && *result) write_hostent(ctx, *result);
3002 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
3005 #define INIT_GETHOSTENT_R \
3006 COMMON_INTERCEPT_FUNCTION(gethostent_r);
3008 #define INIT_GETHOSTENT_R
3011 #if SANITIZER_INTERCEPT_GETHOSTBYADDR_R
3012 INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type,
3013 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
3014 __sanitizer_hostent **result, int *h_errnop) {
3016 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf,
3017 buflen, result, h_errnop);
3018 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len);
3019 // FIXME: under ASan the call below may write to freed memory and corrupt
3020 // its metadata. See
3021 // https://github.com/google/sanitizers/issues/321.
3022 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result,
3025 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3026 if (res == 0 && *result) write_hostent(ctx, *result);
3029 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
3032 #define INIT_GETHOSTBYADDR_R \
3033 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r);
3035 #define INIT_GETHOSTBYADDR_R
3038 #if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R
3039 INTERCEPTOR(int, gethostbyname2_r, char *name, int af,
3040 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen,
3041 __sanitizer_hostent **result, int *h_errnop) {
3043 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen,
3045 // FIXME: under ASan the call below may write to freed memory and corrupt
3046 // its metadata. See
3047 // https://github.com/google/sanitizers/issues/321.
3049 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop);
3051 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3052 if (res == 0 && *result) write_hostent(ctx, *result);
3055 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop));
3058 #define INIT_GETHOSTBYNAME2_R \
3059 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r);
3061 #define INIT_GETHOSTBYNAME2_R
3064 #if SANITIZER_INTERCEPT_GETSOCKOPT
3065 INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval,
3068 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval,
3070 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen));
3071 // FIXME: under ASan the call below may write to freed memory and corrupt
3072 // its metadata. See
3073 // https://github.com/google/sanitizers/issues/321.
3074 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen);
3076 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen);
3079 #define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt);
3081 #define INIT_GETSOCKOPT
3084 #if SANITIZER_INTERCEPT_ACCEPT
3085 INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) {
3087 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen);
3088 unsigned addrlen0 = 0;
3090 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
3091 addrlen0 = *addrlen;
3093 int fd2 = REAL(accept)(fd, addr, addrlen);
3095 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
3096 if (addr && addrlen)
3097 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
3101 #define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept);
3106 #if SANITIZER_INTERCEPT_ACCEPT4
3107 INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) {
3109 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f);
3110 unsigned addrlen0 = 0;
3112 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
3113 addrlen0 = *addrlen;
3115 // FIXME: under ASan the call below may write to freed memory and corrupt
3116 // its metadata. See
3117 // https://github.com/google/sanitizers/issues/321.
3118 int fd2 = REAL(accept4)(fd, addr, addrlen, f);
3120 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
3121 if (addr && addrlen)
3122 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
3126 #define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4);
3128 #define INIT_ACCEPT4
3131 #if SANITIZER_INTERCEPT_PACCEPT
3132 INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen,
3133 __sanitizer_sigset_t *set, int f) {
3135 COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f);
3136 unsigned addrlen0 = 0;
3138 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
3139 addrlen0 = *addrlen;
3141 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
3142 int fd2 = REAL(paccept)(fd, addr, addrlen, set, f);
3144 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2);
3145 if (addr && addrlen)
3146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0));
3150 #define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept);
3152 #define INIT_PACCEPT
3155 #if SANITIZER_INTERCEPT_MODF
3156 INTERCEPTOR(double, modf, double x, double *iptr) {
3158 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr);
3159 // FIXME: under ASan the call below may write to freed memory and corrupt
3160 // its metadata. See
3161 // https://github.com/google/sanitizers/issues/321.
3162 double res = REAL(modf)(x, iptr);
3164 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3168 INTERCEPTOR(float, modff, float x, float *iptr) {
3170 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr);
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 float res = REAL(modff)(x, iptr);
3176 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3180 INTERCEPTOR(long double, modfl, long double x, long double *iptr) {
3182 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr);
3183 // FIXME: under ASan the call below may write to freed memory and corrupt
3184 // its metadata. See
3185 // https://github.com/google/sanitizers/issues/321.
3186 long double res = REAL(modfl)(x, iptr);
3188 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr));
3193 COMMON_INTERCEPT_FUNCTION(modf); \
3194 COMMON_INTERCEPT_FUNCTION(modff); \
3195 COMMON_INTERCEPT_FUNCTION_LDBL(modfl);
3200 #if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG
3201 static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
3203 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg));
3204 if (msg->msg_name && msg->msg_namelen)
3205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen);
3206 if (msg->msg_iov && msg->msg_iovlen)
3207 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov,
3208 sizeof(*msg->msg_iov) * msg->msg_iovlen);
3209 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
3210 if (msg->msg_control && msg->msg_controllen)
3211 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen);
3215 #if SANITIZER_INTERCEPT_RECVMSG
3216 INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg,
3219 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags);
3220 // FIXME: under ASan the call below may write to freed memory and corrupt
3221 // its metadata. See
3222 // https://github.com/google/sanitizers/issues/321.
3223 SSIZE_T res = REAL(recvmsg)(fd, msg, flags);
3225 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3227 write_msghdr(ctx, msg, res);
3228 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg);
3233 #define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg);
3235 #define INIT_RECVMSG
3238 #if SANITIZER_INTERCEPT_RECVMMSG
3239 INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
3240 unsigned int vlen, int flags, void *timeout) {
3242 COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout);
3243 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
3244 int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout);
3246 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
3247 for (int i = 0; i < res; ++i) {
3248 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
3249 sizeof(msgvec[i].msg_len));
3250 write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
3251 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr);
3256 #define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg);
3258 #define INIT_RECVMMSG
3261 #if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG
3262 static void read_msghdr_control(void *ctx, void *control, uptr controllen) {
3263 const unsigned kCmsgDataOffset =
3264 RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr));
3266 char *p = (char *)control;
3267 char *const control_end = p + controllen;
3269 if (p + sizeof(__sanitizer_cmsghdr) > control_end) break;
3270 __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p;
3271 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len));
3273 if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break;
3275 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level,
3276 sizeof(cmsg->cmsg_level));
3277 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type,
3278 sizeof(cmsg->cmsg_type));
3280 if (cmsg->cmsg_len > kCmsgDataOffset) {
3281 char *data = p + kCmsgDataOffset;
3282 unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset;
3283 if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len);
3286 p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr));
3290 static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg,
3293 COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f))
3302 if (msg->msg_name && msg->msg_namelen)
3303 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen);
3304 if (msg->msg_iov && msg->msg_iovlen)
3305 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov,
3306 sizeof(*msg->msg_iov) * msg->msg_iovlen);
3307 read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen);
3308 if (msg->msg_control && msg->msg_controllen)
3309 read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen);
3313 #if SANITIZER_INTERCEPT_SENDMSG
3314 INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg,
3317 COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags);
3319 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3320 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3322 SSIZE_T res = REAL(sendmsg)(fd, msg, flags);
3323 if (common_flags()->intercept_send && res >= 0 && msg)
3324 read_msghdr(ctx, msg, res);
3327 #define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg);
3329 #define INIT_SENDMSG
3332 #if SANITIZER_INTERCEPT_SENDMMSG
3333 INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec,
3334 unsigned vlen, int flags) {
3336 COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags);
3338 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
3339 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
3341 int res = REAL(sendmmsg)(fd, msgvec, vlen, flags);
3342 if (res >= 0 && msgvec) {
3343 for (int i = 0; i < res; ++i) {
3344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len,
3345 sizeof(msgvec[i].msg_len));
3346 if (common_flags()->intercept_send)
3347 read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len);
3352 #define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg);
3354 #define INIT_SENDMMSG
3357 #if SANITIZER_INTERCEPT_SYSMSG
3358 INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz,
3361 COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg);
3363 COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz);
3364 int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg);
3368 INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz,
3369 long msgtyp, int msgflg) {
3371 COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg);
3372 SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg);
3374 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len);
3378 #define INIT_SYSMSG \
3379 COMMON_INTERCEPT_FUNCTION(msgsnd); \
3380 COMMON_INTERCEPT_FUNCTION(msgrcv);
3385 #if SANITIZER_INTERCEPT_GETPEERNAME
3386 INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) {
3388 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen);
3391 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen));
3394 // FIXME: under ASan the call below may write to freed memory and corrupt
3395 // its metadata. See
3396 // https://github.com/google/sanitizers/issues/321.
3397 int res = REAL(getpeername)(sockfd, addr, addrlen);
3398 if (!res && addr && addrlen) {
3399 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen));
3403 #define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername);
3405 #define INIT_GETPEERNAME
3408 #if SANITIZER_INTERCEPT_SYSINFO
3409 INTERCEPTOR(int, sysinfo, void *info) {
3411 // FIXME: under ASan the call below may write to freed memory and corrupt
3412 // its metadata. See
3413 // https://github.com/google/sanitizers/issues/321.
3414 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info);
3415 int res = REAL(sysinfo)(info);
3417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz);
3420 #define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo);
3422 #define INIT_SYSINFO
3425 #if SANITIZER_INTERCEPT_READDIR
3426 INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) {
3428 COMMON_INTERCEPTOR_ENTER(ctx, opendir, path);
3429 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3430 __sanitizer_dirent *res = REAL(opendir)(path);
3432 COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path);
3436 INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) {
3438 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp);
3439 // FIXME: under ASan the call below may write to freed memory and corrupt
3440 // its metadata. See
3441 // https://github.com/google/sanitizers/issues/321.
3442 __sanitizer_dirent *res = REAL(readdir)(dirp);
3443 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3447 INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry,
3448 __sanitizer_dirent **result) {
3450 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result);
3451 // FIXME: under ASan the call below may write to freed memory and corrupt
3452 // its metadata. See
3453 // https://github.com/google/sanitizers/issues/321.
3454 int res = REAL(readdir_r)(dirp, entry, result);
3456 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3458 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3463 #define INIT_READDIR \
3464 COMMON_INTERCEPT_FUNCTION(opendir); \
3465 COMMON_INTERCEPT_FUNCTION(readdir); \
3466 COMMON_INTERCEPT_FUNCTION(readdir_r);
3468 #define INIT_READDIR
3471 #if SANITIZER_INTERCEPT_READDIR64
3472 INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) {
3474 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp);
3475 // FIXME: under ASan the call below may write to freed memory and corrupt
3476 // its metadata. See
3477 // https://github.com/google/sanitizers/issues/321.
3478 __sanitizer_dirent64 *res = REAL(readdir64)(dirp);
3479 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen);
3483 INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry,
3484 __sanitizer_dirent64 **result) {
3486 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result);
3487 // FIXME: under ASan the call below may write to freed memory and corrupt
3488 // its metadata. See
3489 // https://github.com/google/sanitizers/issues/321.
3490 int res = REAL(readdir64_r)(dirp, entry, result);
3492 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
3494 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen);
3498 #define INIT_READDIR64 \
3499 COMMON_INTERCEPT_FUNCTION(readdir64); \
3500 COMMON_INTERCEPT_FUNCTION(readdir64_r);
3502 #define INIT_READDIR64
3505 #if SANITIZER_INTERCEPT_PTRACE
3506 INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) {
3508 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data);
3509 __sanitizer_iovec local_iovec;
3512 if (request == ptrace_setregs) {
3513 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz);
3514 } else if (request == ptrace_setfpregs) {
3515 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3516 } else if (request == ptrace_setfpxregs) {
3517 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3518 } else if (request == ptrace_setvfpregs) {
3519 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3520 } else if (request == ptrace_setsiginfo) {
3521 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz);
3523 // Some kernel might zero the iovec::iov_base in case of invalid
3524 // write access. In this case copy the invalid address for further
3526 } else if (request == ptrace_setregset || request == ptrace_getregset) {
3527 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3528 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec));
3529 local_iovec = *iovec;
3530 if (request == ptrace_setregset)
3531 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len);
3535 // FIXME: under ASan the call below may write to freed memory and corrupt
3536 // its metadata. See
3537 // https://github.com/google/sanitizers/issues/321.
3538 uptr res = REAL(ptrace)(request, pid, addr, data);
3541 // Note that PEEK* requests assign different meaning to the return value.
3542 // This function does not handle them (nor does it need to).
3543 if (request == ptrace_getregs) {
3544 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz);
3545 } else if (request == ptrace_getfpregs) {
3546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz);
3547 } else if (request == ptrace_getfpxregs) {
3548 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz);
3549 } else if (request == ptrace_getvfpregs) {
3550 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz);
3551 } else if (request == ptrace_getsiginfo) {
3552 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz);
3553 } else if (request == ptrace_geteventmsg) {
3554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long));
3555 } else if (request == ptrace_getregset) {
3556 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data;
3557 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec));
3558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base,
3559 local_iovec.iov_len);
3565 #define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace);
3570 #if SANITIZER_INTERCEPT_SETLOCALE
3571 static void unpoison_ctype_arrays(void *ctx) {
3572 #if SANITIZER_NETBSD
3573 // These arrays contain 256 regular elements in unsigned char range + 1 EOF
3574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short));
3575 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short));
3576 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short));
3580 INTERCEPTOR(char *, setlocale, int category, char *locale) {
3582 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale);
3584 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, internal_strlen(locale) + 1);
3585 char *res = REAL(setlocale)(category, locale);
3587 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
3588 unpoison_ctype_arrays(ctx);
3593 #define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale);
3595 #define INIT_SETLOCALE
3598 #if SANITIZER_INTERCEPT_GETCWD
3599 INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) {
3601 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size);
3602 // FIXME: under ASan the call below may write to freed memory and corrupt
3603 // its metadata. See
3604 // https://github.com/google/sanitizers/issues/321.
3605 char *res = REAL(getcwd)(buf, size);
3606 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3609 #define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd);
3614 #if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME
3615 INTERCEPTOR(char *, get_current_dir_name, int fake) {
3617 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake);
3618 // FIXME: under ASan the call below may write to freed memory and corrupt
3619 // its metadata. See
3620 // https://github.com/google/sanitizers/issues/321.
3621 char *res = REAL(get_current_dir_name)(fake);
3622 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3626 #define INIT_GET_CURRENT_DIR_NAME \
3627 COMMON_INTERCEPT_FUNCTION(get_current_dir_name);
3629 #define INIT_GET_CURRENT_DIR_NAME
3632 UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) {
3634 if (nptr == *endptr) {
3635 // No digits were found at strtol call, we need to find out the last
3636 // symbol accessed by strtoll on our own.
3637 // We get this symbol by skipping leading blanks and optional +/- sign.
3638 while (IsSpace(*nptr)) nptr++;
3639 if (*nptr == '+' || *nptr == '-') nptr++;
3640 *endptr = const_cast<char *>(nptr);
3642 CHECK(*endptr >= nptr);
3645 UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr,
3646 char **endptr, char *real_endptr, int base) {
3648 *endptr = real_endptr;
3649 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr));
3651 // If base has unsupported value, strtol can exit with EINVAL
3652 // without reading any characters. So do additional checks only
3653 // if base is valid.
3654 bool is_valid_base = (base == 0) || (2 <= base && base <= 36);
3655 if (is_valid_base) {
3656 FixRealStrtolEndptr(nptr, &real_endptr);
3658 COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ?
3659 (real_endptr - nptr) + 1 : 0);
3663 #if SANITIZER_INTERCEPT_STRTOIMAX
3664 INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) {
3666 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base);
3667 // FIXME: under ASan the call below may write to freed memory and corrupt
3668 // its metadata. See
3669 // https://github.com/google/sanitizers/issues/321.
3671 INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base);
3672 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3676 INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) {
3678 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base);
3679 // FIXME: under ASan the call below may write to freed memory and corrupt
3680 // its metadata. See
3681 // https://github.com/google/sanitizers/issues/321.
3683 UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base);
3684 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
3688 #define INIT_STRTOIMAX \
3689 COMMON_INTERCEPT_FUNCTION(strtoimax); \
3690 COMMON_INTERCEPT_FUNCTION(strtoumax);
3692 #define INIT_STRTOIMAX
3695 #if SANITIZER_INTERCEPT_MBSTOWCS
3696 INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) {
3698 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len);
3699 // FIXME: under ASan the call below may write to freed memory and corrupt
3700 // its metadata. See
3701 // https://github.com/google/sanitizers/issues/321.
3702 SIZE_T res = REAL(mbstowcs)(dest, src, len);
3703 if (res != (SIZE_T) - 1 && dest) {
3704 SIZE_T write_cnt = res + (res < len);
3705 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3710 INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len,
3713 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps);
3714 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3715 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3716 // FIXME: under ASan the call below may write to freed memory and corrupt
3717 // its metadata. See
3718 // https://github.com/google/sanitizers/issues/321.
3719 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps);
3720 if (res != (SIZE_T)(-1) && dest && src) {
3721 // This function, and several others, may or may not write the terminating
3722 // \0 character. They write it iff they clear *src.
3723 SIZE_T write_cnt = res + !*src;
3724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3729 #define INIT_MBSTOWCS \
3730 COMMON_INTERCEPT_FUNCTION(mbstowcs); \
3731 COMMON_INTERCEPT_FUNCTION(mbsrtowcs);
3733 #define INIT_MBSTOWCS
3736 #if SANITIZER_INTERCEPT_MBSNRTOWCS
3737 INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms,
3738 SIZE_T len, void *ps) {
3740 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps);
3742 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3743 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3745 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3746 // FIXME: under ASan the call below may write to freed memory and corrupt
3747 // its metadata. See
3748 // https://github.com/google/sanitizers/issues/321.
3749 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps);
3750 if (res != (SIZE_T)(-1) && dest && src) {
3751 SIZE_T write_cnt = res + !*src;
3752 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t));
3757 #define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs);
3759 #define INIT_MBSNRTOWCS
3762 #if SANITIZER_INTERCEPT_WCSTOMBS
3763 INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) {
3765 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len);
3766 // FIXME: under ASan the call below may write to freed memory and corrupt
3767 // its metadata. See
3768 // https://github.com/google/sanitizers/issues/321.
3769 SIZE_T res = REAL(wcstombs)(dest, src, len);
3770 if (res != (SIZE_T) - 1 && dest) {
3771 SIZE_T write_cnt = res + (res < len);
3772 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3777 INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len,
3780 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps);
3781 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3782 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3783 // FIXME: under ASan the call below may write to freed memory and corrupt
3784 // its metadata. See
3785 // https://github.com/google/sanitizers/issues/321.
3786 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps);
3787 if (res != (SIZE_T) - 1 && dest && src) {
3788 SIZE_T write_cnt = res + !*src;
3789 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3794 #define INIT_WCSTOMBS \
3795 COMMON_INTERCEPT_FUNCTION(wcstombs); \
3796 COMMON_INTERCEPT_FUNCTION(wcsrtombs);
3798 #define INIT_WCSTOMBS
3801 #if SANITIZER_INTERCEPT_WCSNRTOMBS
3802 INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms,
3803 SIZE_T len, void *ps) {
3805 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps);
3807 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
3808 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms);
3810 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3811 // FIXME: under ASan the call below may write to freed memory and corrupt
3812 // its metadata. See
3813 // https://github.com/google/sanitizers/issues/321.
3814 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps);
3815 if (res != ((SIZE_T)-1) && dest && src) {
3816 SIZE_T write_cnt = res + !*src;
3817 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt);
3822 #define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs);
3824 #define INIT_WCSNRTOMBS
3828 #if SANITIZER_INTERCEPT_WCRTOMB
3829 INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) {
3831 COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps);
3832 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz);
3835 return REAL(wcrtomb)(dest, src, ps);
3837 char local_dest[32];
3838 SIZE_T res = REAL(wcrtomb)(local_dest, src, ps);
3839 if (res != ((SIZE_T)-1)) {
3840 CHECK_LE(res, sizeof(local_dest));
3841 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3842 REAL(memcpy)(dest, local_dest, res);
3847 #define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb);
3849 #define INIT_WCRTOMB
3852 #if SANITIZER_INTERCEPT_WCTOMB
3853 INTERCEPTOR(int, wctomb, char *dest, wchar_t src) {
3855 COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src);
3857 return REAL(wctomb)(dest, src);
3859 char local_dest[32];
3860 int res = REAL(wctomb)(local_dest, src);
3862 CHECK_LE(res, sizeof(local_dest));
3863 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res);
3864 REAL(memcpy)(dest, local_dest, res);
3869 #define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb);
3874 #if SANITIZER_INTERCEPT_TCGETATTR
3875 INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) {
3877 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p);
3878 // FIXME: under ASan the call below may write to freed memory and corrupt
3879 // its metadata. See
3880 // https://github.com/google/sanitizers/issues/321.
3881 int res = REAL(tcgetattr)(fd, termios_p);
3882 if (!res && termios_p)
3883 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz);
3887 #define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr);
3889 #define INIT_TCGETATTR
3892 #if SANITIZER_INTERCEPT_REALPATH
3893 INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) {
3895 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path);
3896 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3898 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest
3899 // version of a versioned symbol. For realpath(), this gives us something
3900 // (called __old_realpath) that does not handle NULL in the second argument.
3901 // Handle it as part of the interceptor.
3902 char *allocated_path = nullptr;
3904 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1);
3906 char *res = REAL(realpath)(path, resolved_path);
3907 if (allocated_path && !res)
3908 WRAP(free)(allocated_path);
3909 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3912 # define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath);
3914 #define INIT_REALPATH
3917 #if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME
3918 INTERCEPTOR(char *, canonicalize_file_name, const char *path) {
3920 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path);
3921 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
3922 char *res = REAL(canonicalize_file_name)(path);
3923 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
3926 #define INIT_CANONICALIZE_FILE_NAME \
3927 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name);
3929 #define INIT_CANONICALIZE_FILE_NAME
3932 #if SANITIZER_INTERCEPT_CONFSTR
3933 INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) {
3935 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len);
3936 // FIXME: under ASan the call below may write to freed memory and corrupt
3937 // its metadata. See
3938 // https://github.com/google/sanitizers/issues/321.
3939 SIZE_T res = REAL(confstr)(name, buf, len);
3941 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len);
3944 #define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr);
3946 #define INIT_CONFSTR
3949 #if SANITIZER_INTERCEPT_SCHED_GETAFFINITY
3950 INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) {
3952 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask);
3953 // FIXME: under ASan the call below may write to freed memory and corrupt
3954 // its metadata. See
3955 // https://github.com/google/sanitizers/issues/321.
3956 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask);
3957 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize);
3960 #define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity);
3962 #define INIT_SCHED_GETAFFINITY
3965 #if SANITIZER_INTERCEPT_SCHED_GETPARAM
3966 INTERCEPTOR(int, sched_getparam, int pid, void *param) {
3968 COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param);
3969 int res = REAL(sched_getparam)(pid, param);
3970 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz);
3973 #define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam);
3975 #define INIT_SCHED_GETPARAM
3978 #if SANITIZER_INTERCEPT_STRERROR
3979 INTERCEPTOR(char *, strerror, int errnum) {
3981 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum);
3982 COMMON_INTERCEPTOR_STRERROR();
3983 char *res = REAL(strerror)(errnum);
3984 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
3987 #define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror);
3989 #define INIT_STRERROR
3992 #if SANITIZER_INTERCEPT_STRERROR_R
3993 // There are 2 versions of strerror_r:
3994 // * POSIX version returns 0 on success, negative error code on failure,
3995 // writes message to buf.
3996 // * GNU version returns message pointer, which points to either buf or some
3998 #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \
3999 SANITIZER_APPLE || SANITIZER_ANDROID || SANITIZER_NETBSD || \
4001 // POSIX version. Spec is not clear on whether buf is NULL-terminated.
4002 // At least on OSX, buf contents are valid even when the call fails.
4003 INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) {
4005 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
4006 // FIXME: under ASan the call below may write to freed memory and corrupt
4007 // its metadata. See
4008 // https://github.com/google/sanitizers/issues/321.
4009 int res = REAL(strerror_r)(errnum, buf, buflen);
4011 SIZE_T sz = internal_strnlen(buf, buflen);
4012 if (sz < buflen) ++sz;
4013 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
4018 INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) {
4020 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen);
4021 // FIXME: under ASan the call below may write to freed memory and corrupt
4022 // its metadata. See
4023 // https://github.com/google/sanitizers/issues/321.
4024 char *res = REAL(strerror_r)(errnum, buf, buflen);
4026 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
4028 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
4031 #endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE ||
4033 #define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r);
4035 #define INIT_STRERROR_R
4038 #if SANITIZER_INTERCEPT_XPG_STRERROR_R
4039 INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) {
4041 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen);
4042 // FIXME: under ASan the call below may write to freed memory and corrupt
4043 // its metadata. See
4044 // https://github.com/google/sanitizers/issues/321.
4045 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen);
4046 // This version always returns a null-terminated string.
4048 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
4051 #define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r);
4053 #define INIT_XPG_STRERROR_R
4056 #if SANITIZER_INTERCEPT_SCANDIR
4057 typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *);
4058 typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **,
4059 const struct __sanitizer_dirent **);
4061 static THREADLOCAL scandir_filter_f scandir_filter;
4062 static THREADLOCAL scandir_compar_f scandir_compar;
4064 static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) {
4065 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
4066 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
4067 return scandir_filter(dir);
4070 static int wrapped_scandir_compar(const struct __sanitizer_dirent **a,
4071 const struct __sanitizer_dirent **b) {
4072 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
4073 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
4074 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
4075 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
4076 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
4077 return scandir_compar(a, b);
4080 INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist,
4081 scandir_filter_f filter, scandir_compar_f compar) {
4083 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar);
4084 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
4085 scandir_filter = filter;
4086 scandir_compar = compar;
4087 // FIXME: under ASan the call below may write to freed memory and corrupt
4088 // its metadata. See
4089 // https://github.com/google/sanitizers/issues/321.
4090 int res = REAL(scandir)(dirp, namelist,
4091 filter ? wrapped_scandir_filter : nullptr,
4092 compar ? wrapped_scandir_compar : nullptr);
4093 scandir_filter = nullptr;
4094 scandir_compar = nullptr;
4095 if (namelist && res > 0) {
4096 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
4097 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
4098 for (int i = 0; i < res; ++i)
4099 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
4100 (*namelist)[i]->d_reclen);
4104 #define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir);
4106 #define INIT_SCANDIR
4109 #if SANITIZER_INTERCEPT_SCANDIR64
4110 typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *);
4111 typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **,
4112 const struct __sanitizer_dirent64 **);
4114 static THREADLOCAL scandir64_filter_f scandir64_filter;
4115 static THREADLOCAL scandir64_compar_f scandir64_compar;
4117 static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) {
4118 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
4119 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen);
4120 return scandir64_filter(dir);
4123 static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a,
4124 const struct __sanitizer_dirent64 **b) {
4125 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
4126 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a));
4127 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen);
4128 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b));
4129 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen);
4130 return scandir64_compar(a, b);
4133 INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist,
4134 scandir64_filter_f filter, scandir64_compar_f compar) {
4136 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar);
4137 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, internal_strlen(dirp) + 1);
4138 scandir64_filter = filter;
4139 scandir64_compar = compar;
4140 // FIXME: under ASan the call below may write to freed memory and corrupt
4141 // its metadata. See
4142 // https://github.com/google/sanitizers/issues/321.
4144 REAL(scandir64)(dirp, namelist,
4145 filter ? wrapped_scandir64_filter : nullptr,
4146 compar ? wrapped_scandir64_compar : nullptr);
4147 scandir64_filter = nullptr;
4148 scandir64_compar = nullptr;
4149 if (namelist && res > 0) {
4150 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist));
4151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res);
4152 for (int i = 0; i < res; ++i)
4153 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i],
4154 (*namelist)[i]->d_reclen);
4158 #define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64);
4160 #define INIT_SCANDIR64
4163 #if SANITIZER_INTERCEPT_GETGROUPS
4164 INTERCEPTOR(int, getgroups, int size, u32 *lst) {
4166 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst);
4167 // FIXME: under ASan the call below may write to freed memory and corrupt
4168 // its metadata. See
4169 // https://github.com/google/sanitizers/issues/321.
4170 int res = REAL(getgroups)(size, lst);
4171 if (res >= 0 && lst && size > 0)
4172 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst));
4175 #define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups);
4177 #define INIT_GETGROUPS
4180 #if SANITIZER_INTERCEPT_POLL
4181 static void read_pollfd(void *ctx, __sanitizer_pollfd *fds,
4182 __sanitizer_nfds_t nfds) {
4183 for (unsigned i = 0; i < nfds; ++i) {
4184 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd));
4185 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events));
4189 static void write_pollfd(void *ctx, __sanitizer_pollfd *fds,
4190 __sanitizer_nfds_t nfds) {
4191 for (unsigned i = 0; i < nfds; ++i)
4192 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents,
4193 sizeof(fds[i].revents));
4196 INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
4199 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout);
4200 if (fds && nfds) read_pollfd(ctx, fds, nfds);
4201 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout);
4202 if (fds && nfds) write_pollfd(ctx, fds, nfds);
4205 #define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll);
4210 #if SANITIZER_INTERCEPT_PPOLL
4211 INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds,
4212 void *timeout_ts, __sanitizer_sigset_t *sigmask) {
4214 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask);
4215 if (fds && nfds) read_pollfd(ctx, fds, nfds);
4217 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz);
4218 if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask));
4220 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask);
4221 if (fds && nfds) write_pollfd(ctx, fds, nfds);
4224 #define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll);
4229 #if SANITIZER_INTERCEPT_WORDEXP
4230 INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) {
4232 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags);
4233 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, internal_strlen(s) + 1);
4234 // FIXME: under ASan the call below may write to freed memory and corrupt
4235 // its metadata. See
4236 // https://github.com/google/sanitizers/issues/321.
4237 int res = REAL(wordexp)(s, p, flags);
4239 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
4241 ((flags & wordexp_wrde_dooffs) ? p->we_offs : 0) + p->we_wordc;
4242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv,
4243 sizeof(*p->we_wordv) * (we_wordc + 1));
4244 for (uptr i = 0; i < we_wordc; ++i) {
4245 char *w = p->we_wordv[i];
4246 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, internal_strlen(w) + 1);
4251 #define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp);
4253 #define INIT_WORDEXP
4256 #if SANITIZER_INTERCEPT_SIGWAIT
4257 INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) {
4259 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig);
4260 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4261 // FIXME: under ASan the call below may write to freed memory and corrupt
4262 // its metadata. See
4263 // https://github.com/google/sanitizers/issues/321.
4264 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwait)(set, sig);
4265 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig));
4268 #define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait);
4270 #define INIT_SIGWAIT
4273 #if SANITIZER_INTERCEPT_SIGWAITINFO
4274 INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) {
4276 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info);
4277 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4278 // FIXME: under ASan the call below may write to freed memory and corrupt
4279 // its metadata. See
4280 // https://github.com/google/sanitizers/issues/321.
4281 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigwaitinfo)(set, info);
4282 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
4285 #define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo);
4287 #define INIT_SIGWAITINFO
4290 #if SANITIZER_INTERCEPT_SIGTIMEDWAIT
4291 INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info,
4294 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout);
4295 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz);
4296 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4297 // FIXME: under ASan the call below may write to freed memory and corrupt
4298 // its metadata. See
4299 // https://github.com/google/sanitizers/issues/321.
4300 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sigtimedwait)(set, info, timeout);
4301 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz);
4304 #define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait);
4306 #define INIT_SIGTIMEDWAIT
4309 #if SANITIZER_INTERCEPT_SIGSETOPS
4310 INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) {
4312 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set);
4313 // FIXME: under ASan the call below may write to freed memory and corrupt
4314 // its metadata. See
4315 // https://github.com/google/sanitizers/issues/321.
4316 int res = REAL(sigemptyset)(set);
4317 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4321 INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) {
4323 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set);
4324 // FIXME: under ASan the call below may write to freed memory and corrupt
4325 // its metadata. See
4326 // https://github.com/google/sanitizers/issues/321.
4327 int res = REAL(sigfillset)(set);
4328 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4331 #define INIT_SIGSETOPS \
4332 COMMON_INTERCEPT_FUNCTION(sigemptyset); \
4333 COMMON_INTERCEPT_FUNCTION(sigfillset);
4335 #define INIT_SIGSETOPS
4338 #if SANITIZER_INTERCEPT_SIGSET_LOGICOPS
4339 INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst,
4340 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4342 COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2);
4344 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4346 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4347 int res = REAL(sigandset)(dst, src1, src2);
4349 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4353 INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst,
4354 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) {
4356 COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2);
4358 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1));
4360 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2));
4361 int res = REAL(sigorset)(dst, src1, src2);
4363 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
4366 #define INIT_SIGSET_LOGICOPS \
4367 COMMON_INTERCEPT_FUNCTION(sigandset); \
4368 COMMON_INTERCEPT_FUNCTION(sigorset);
4370 #define INIT_SIGSET_LOGICOPS
4373 #if SANITIZER_INTERCEPT_SIGPENDING
4374 INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) {
4376 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set);
4377 // FIXME: under ASan the call below may write to freed memory and corrupt
4378 // its metadata. See
4379 // https://github.com/google/sanitizers/issues/321.
4380 int res = REAL(sigpending)(set);
4381 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set));
4384 #define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending);
4386 #define INIT_SIGPENDING
4389 #if SANITIZER_INTERCEPT_SIGPROCMASK
4390 INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set,
4391 __sanitizer_sigset_t *oldset) {
4393 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset);
4394 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*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(sigprocmask)(how, set, oldset);
4400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4403 #define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask);
4405 #define INIT_SIGPROCMASK
4408 #if SANITIZER_INTERCEPT_PTHREAD_SIGMASK
4409 INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set,
4410 __sanitizer_sigset_t *oldset) {
4412 COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset);
4413 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set));
4414 // FIXME: under ASan the call below may write to freed memory and corrupt
4415 // its metadata. See
4416 // https://github.com/google/sanitizers/issues/321.
4417 int res = REAL(pthread_sigmask)(how, set, oldset);
4419 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset));
4422 #define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask);
4424 #define INIT_PTHREAD_SIGMASK
4427 #if SANITIZER_INTERCEPT_BACKTRACE
4428 INTERCEPTOR(int, backtrace, void **buffer, int size) {
4430 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size);
4431 // FIXME: under ASan the call below may write to freed memory and corrupt
4432 // its metadata. See
4433 // https://github.com/google/sanitizers/issues/321.
4434 int res = REAL(backtrace)(buffer, size);
4436 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer));
4440 INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) {
4442 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size);
4444 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer));
4445 // FIXME: under ASan the call below may write to freed memory and corrupt
4446 // its metadata. See
4447 // https://github.com/google/sanitizers/issues/321.
4448 char **res = REAL(backtrace_symbols)(buffer, size);
4450 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res));
4451 for (int i = 0; i < size; ++i)
4452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], internal_strlen(res[i]) + 1);
4456 #define INIT_BACKTRACE \
4457 COMMON_INTERCEPT_FUNCTION(backtrace); \
4458 COMMON_INTERCEPT_FUNCTION(backtrace_symbols);
4460 #define INIT_BACKTRACE
4463 #if SANITIZER_INTERCEPT__EXIT
4464 INTERCEPTOR(void, _exit, int status) {
4466 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status);
4467 COMMON_INTERCEPTOR_USER_CALLBACK_START();
4468 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx);
4469 COMMON_INTERCEPTOR_USER_CALLBACK_END();
4470 if (status == 0) status = status1;
4471 REAL(_exit)(status);
4473 #define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit);
4478 #if SANITIZER_INTERCEPT_PTHREAD_MUTEX
4479 INTERCEPTOR(int, pthread_mutex_lock, void *m) {
4481 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m);
4482 COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4483 int res = REAL(pthread_mutex_lock)(m);
4484 if (res == errno_EOWNERDEAD)
4485 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4486 if (res == 0 || res == errno_EOWNERDEAD)
4487 COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4488 if (res == errno_EINVAL)
4489 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4493 INTERCEPTOR(int, pthread_mutex_unlock, void *m) {
4495 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m);
4496 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4497 int res = REAL(pthread_mutex_unlock)(m);
4498 if (res == errno_EINVAL)
4499 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4503 #define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock)
4504 #define INIT_PTHREAD_MUTEX_UNLOCK \
4505 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock)
4507 #define INIT_PTHREAD_MUTEX_LOCK
4508 #define INIT_PTHREAD_MUTEX_UNLOCK
4511 #if SANITIZER_INTERCEPT___PTHREAD_MUTEX
4512 INTERCEPTOR(int, __pthread_mutex_lock, void *m) {
4514 COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m);
4515 COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m);
4516 int res = REAL(__pthread_mutex_lock)(m);
4517 if (res == errno_EOWNERDEAD)
4518 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m);
4519 if (res == 0 || res == errno_EOWNERDEAD)
4520 COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m);
4521 if (res == errno_EINVAL)
4522 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4526 INTERCEPTOR(int, __pthread_mutex_unlock, void *m) {
4528 COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m);
4529 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m);
4530 int res = REAL(__pthread_mutex_unlock)(m);
4531 if (res == errno_EINVAL)
4532 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m);
4536 #define INIT___PTHREAD_MUTEX_LOCK \
4537 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock)
4538 #define INIT___PTHREAD_MUTEX_UNLOCK \
4539 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock)
4541 #define INIT___PTHREAD_MUTEX_LOCK
4542 #define INIT___PTHREAD_MUTEX_UNLOCK
4545 #if SANITIZER_INTERCEPT___LIBC_MUTEX
4546 INTERCEPTOR(int, __libc_mutex_lock, void *m)
4547 ALIAS(WRAPPER_NAME(pthread_mutex_lock));
4549 INTERCEPTOR(int, __libc_mutex_unlock, void *m)
4550 ALIAS(WRAPPER_NAME(pthread_mutex_unlock));
4552 INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate)
4553 ALIAS(WRAPPER_NAME(pthread_setcancelstate));
4555 #define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock)
4556 #define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock)
4557 #define INIT___LIBC_THR_SETCANCELSTATE \
4558 COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate)
4560 #define INIT___LIBC_MUTEX_LOCK
4561 #define INIT___LIBC_MUTEX_UNLOCK
4562 #define INIT___LIBC_THR_SETCANCELSTATE
4565 #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R
4566 static void write_mntent(void *ctx, __sanitizer_mntent *mnt) {
4567 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt));
4568 if (mnt->mnt_fsname)
4569 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname,
4570 internal_strlen(mnt->mnt_fsname) + 1);
4572 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir,
4573 internal_strlen(mnt->mnt_dir) + 1);
4575 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type,
4576 internal_strlen(mnt->mnt_type) + 1);
4578 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts,
4579 internal_strlen(mnt->mnt_opts) + 1);
4583 #if SANITIZER_INTERCEPT_GETMNTENT
4584 INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) {
4586 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp);
4587 __sanitizer_mntent *res = REAL(getmntent)(fp);
4588 if (res) write_mntent(ctx, res);
4591 #define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent);
4593 #define INIT_GETMNTENT
4596 #if SANITIZER_INTERCEPT_GETMNTENT_R
4597 INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp,
4598 __sanitizer_mntent *mntbuf, char *buf, int buflen) {
4600 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen);
4601 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen);
4602 if (res) write_mntent(ctx, res);
4605 #define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r);
4607 #define INIT_GETMNTENT_R
4610 #if SANITIZER_INTERCEPT_STATFS
4611 INTERCEPTOR(int, statfs, char *path, void *buf) {
4613 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf);
4614 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4615 // FIXME: under ASan the call below may write to freed memory and corrupt
4616 // its metadata. See
4617 // https://github.com/google/sanitizers/issues/321.
4618 int res = REAL(statfs)(path, buf);
4619 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4622 INTERCEPTOR(int, fstatfs, int fd, void *buf) {
4624 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf);
4625 // FIXME: under ASan the call below may write to freed memory and corrupt
4626 // its metadata. See
4627 // https://github.com/google/sanitizers/issues/321.
4628 int res = REAL(fstatfs)(fd, buf);
4629 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz);
4632 #define INIT_STATFS \
4633 COMMON_INTERCEPT_FUNCTION(statfs); \
4634 COMMON_INTERCEPT_FUNCTION(fstatfs);
4639 #if SANITIZER_INTERCEPT_STATFS64
4640 INTERCEPTOR(int, statfs64, char *path, void *buf) {
4642 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf);
4643 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4644 // FIXME: under ASan the call below may write to freed memory and corrupt
4645 // its metadata. See
4646 // https://github.com/google/sanitizers/issues/321.
4647 int res = REAL(statfs64)(path, buf);
4648 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4651 INTERCEPTOR(int, fstatfs64, int fd, void *buf) {
4653 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf);
4654 // FIXME: under ASan the call below may write to freed memory and corrupt
4655 // its metadata. See
4656 // https://github.com/google/sanitizers/issues/321.
4657 int res = REAL(fstatfs64)(fd, buf);
4658 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz);
4661 #define INIT_STATFS64 \
4662 COMMON_INTERCEPT_FUNCTION(statfs64); \
4663 COMMON_INTERCEPT_FUNCTION(fstatfs64);
4665 #define INIT_STATFS64
4668 #if SANITIZER_INTERCEPT_STATVFS
4669 INTERCEPTOR(int, statvfs, char *path, void *buf) {
4671 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf);
4672 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4673 // FIXME: under ASan the call below may write to freed memory and corrupt
4674 // its metadata. See
4675 // https://github.com/google/sanitizers/issues/321.
4676 int res = REAL(statvfs)(path, buf);
4677 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4680 INTERCEPTOR(int, fstatvfs, int fd, void *buf) {
4682 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf);
4683 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
4684 // FIXME: under ASan the call below may write to freed memory and corrupt
4685 // its metadata. See
4686 // https://github.com/google/sanitizers/issues/321.
4687 int res = REAL(fstatvfs)(fd, buf);
4689 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
4691 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
4695 #define INIT_STATVFS \
4696 COMMON_INTERCEPT_FUNCTION(statvfs); \
4697 COMMON_INTERCEPT_FUNCTION(fstatvfs);
4699 #define INIT_STATVFS
4702 #if SANITIZER_INTERCEPT_STATVFS64
4703 INTERCEPTOR(int, statvfs64, char *path, void *buf) {
4705 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf);
4706 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
4707 // FIXME: under ASan the call below may write to freed memory and corrupt
4708 // its metadata. See
4709 // https://github.com/google/sanitizers/issues/321.
4710 int res = REAL(statvfs64)(path, buf);
4711 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4714 INTERCEPTOR(int, fstatvfs64, int fd, void *buf) {
4716 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf);
4717 // FIXME: under ASan the call below may write to freed memory and corrupt
4718 // its metadata. See
4719 // https://github.com/google/sanitizers/issues/321.
4720 int res = REAL(fstatvfs64)(fd, buf);
4721 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz);
4724 #define INIT_STATVFS64 \
4725 COMMON_INTERCEPT_FUNCTION(statvfs64); \
4726 COMMON_INTERCEPT_FUNCTION(fstatvfs64);
4728 #define INIT_STATVFS64
4731 #if SANITIZER_INTERCEPT_INITGROUPS
4732 INTERCEPTOR(int, initgroups, char *user, u32 group) {
4734 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group);
4735 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, internal_strlen(user) + 1);
4736 int res = REAL(initgroups)(user, group);
4739 #define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups);
4741 #define INIT_INITGROUPS
4744 #if SANITIZER_INTERCEPT_ETHER_NTOA_ATON
4745 INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) {
4747 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr);
4748 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4749 char *res = REAL(ether_ntoa)(addr);
4750 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
4753 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) {
4755 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf);
4756 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
4757 __sanitizer_ether_addr *res = REAL(ether_aton)(buf);
4758 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res));
4761 #define INIT_ETHER_NTOA_ATON \
4762 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \
4763 COMMON_INTERCEPT_FUNCTION(ether_aton);
4765 #define INIT_ETHER_NTOA_ATON
4768 #if SANITIZER_INTERCEPT_ETHER_HOST
4769 INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) {
4771 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr);
4772 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4773 // FIXME: under ASan the call below may write to freed memory and corrupt
4774 // its metadata. See
4775 // https://github.com/google/sanitizers/issues/321.
4776 int res = REAL(ether_ntohost)(hostname, addr);
4777 if (!res && hostname)
4778 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4781 INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) {
4783 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr);
4785 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4786 // FIXME: under ASan the call below may write to freed memory and corrupt
4787 // its metadata. See
4788 // https://github.com/google/sanitizers/issues/321.
4789 int res = REAL(ether_hostton)(hostname, addr);
4790 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4793 INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr,
4796 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname);
4797 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, internal_strlen(line) + 1);
4798 // FIXME: under ASan the call below may write to freed memory and corrupt
4799 // its metadata. See
4800 // https://github.com/google/sanitizers/issues/321.
4801 int res = REAL(ether_line)(line, addr, hostname);
4803 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4805 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, internal_strlen(hostname) + 1);
4809 #define INIT_ETHER_HOST \
4810 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \
4811 COMMON_INTERCEPT_FUNCTION(ether_hostton); \
4812 COMMON_INTERCEPT_FUNCTION(ether_line);
4814 #define INIT_ETHER_HOST
4817 #if SANITIZER_INTERCEPT_ETHER_R
4818 INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) {
4820 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf);
4821 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr));
4822 // FIXME: under ASan the call below may write to freed memory and corrupt
4823 // its metadata. See
4824 // https://github.com/google/sanitizers/issues/321.
4825 char *res = REAL(ether_ntoa_r)(addr, buf);
4826 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
4829 INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf,
4830 __sanitizer_ether_addr *addr) {
4832 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr);
4833 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, internal_strlen(buf) + 1);
4834 // FIXME: under ASan the call below may write to freed memory and corrupt
4835 // its metadata. See
4836 // https://github.com/google/sanitizers/issues/321.
4837 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr);
4838 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res));
4841 #define INIT_ETHER_R \
4842 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \
4843 COMMON_INTERCEPT_FUNCTION(ether_aton_r);
4845 #define INIT_ETHER_R
4848 #if SANITIZER_INTERCEPT_SHMCTL
4849 INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) {
4851 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf);
4852 // FIXME: under ASan the call below may write to freed memory and corrupt
4853 // its metadata. See
4854 // https://github.com/google/sanitizers/issues/321.
4855 int res = REAL(shmctl)(shmid, cmd, buf);
4858 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat)
4859 sz = sizeof(__sanitizer_shmid_ds);
4860 else if (cmd == shmctl_ipc_info)
4861 sz = struct_shminfo_sz;
4862 else if (cmd == shmctl_shm_info)
4863 sz = struct_shm_info_sz;
4864 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz);
4868 #define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl);
4873 #if SANITIZER_INTERCEPT_RANDOM_R
4874 INTERCEPTOR(int, random_r, void *buf, u32 *result) {
4876 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result);
4877 // FIXME: under ASan the call below may write to freed memory and corrupt
4878 // its metadata. See
4879 // https://github.com/google/sanitizers/issues/321.
4880 int res = REAL(random_r)(buf, result);
4882 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
4885 #define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r);
4887 #define INIT_RANDOM_R
4890 // FIXME: under ASan the REAL() call below may write to freed memory and corrupt
4891 // its metadata. See
4892 // https://github.com/google/sanitizers/issues/321.
4893 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \
4894 SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \
4895 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \
4896 SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \
4897 SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \
4898 SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \
4899 SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET
4900 #define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \
4901 INTERCEPTOR(int, fn, void *attr, void *r) { \
4903 COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \
4904 int res = REAL(fn)(attr, r); \
4905 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \
4908 #define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \
4909 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz)
4910 #define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \
4911 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz)
4912 #define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \
4913 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz)
4914 #define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \
4915 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz)
4916 #define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \
4917 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz)
4920 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET
4921 INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int))
4922 INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T))
4923 INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int))
4924 INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T))
4925 INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) {
4927 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size);
4928 // FIXME: under ASan the call below may write to freed memory and corrupt
4929 // its metadata. See
4930 // https://github.com/google/sanitizers/issues/321.
4931 int res = REAL(pthread_attr_getstack)(attr, addr, size);
4933 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr));
4934 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size));
4939 // We may need to call the real pthread_attr_getstack from the run-time
4940 // in sanitizer_common, but we don't want to include the interception headers
4941 // there. So, just define this function here.
4942 namespace __sanitizer {
4944 int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) {
4945 return REAL(pthread_attr_getstack)(attr, addr, size);
4948 } // namespace __sanitizer
4950 #define INIT_PTHREAD_ATTR_GET \
4951 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \
4952 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \
4953 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \
4954 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \
4955 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack);
4957 #define INIT_PTHREAD_ATTR_GET
4960 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED
4961 INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz)
4962 INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int))
4964 #define INIT_PTHREAD_ATTR_GET_SCHED \
4965 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \
4966 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy);
4968 #define INIT_PTHREAD_ATTR_GET_SCHED
4971 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED
4972 INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int))
4974 #define INIT_PTHREAD_ATTR_GETINHERITSCHED \
4975 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched);
4977 #define INIT_PTHREAD_ATTR_GETINHERITSCHED
4980 #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP
4981 INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize,
4984 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize,
4986 // FIXME: under ASan the call below may write to freed memory and corrupt
4987 // its metadata. See
4988 // https://github.com/google/sanitizers/issues/321.
4989 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset);
4990 if (!res && cpusetsize && cpuset)
4991 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
4995 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP \
4996 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np);
4998 #define INIT_PTHREAD_ATTR_GETAFFINITY_NP
5001 #if SANITIZER_INTERCEPT_PTHREAD_GETAFFINITY_NP
5002 INTERCEPTOR(int, pthread_getaffinity_np, void *attr, SIZE_T cpusetsize,
5005 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getaffinity_np, attr, cpusetsize,
5007 // FIXME: under ASan the call below may write to freed memory and corrupt
5008 // its metadata. See
5009 // https://github.com/google/sanitizers/issues/321.
5010 int res = REAL(pthread_getaffinity_np)(attr, cpusetsize, cpuset);
5011 if (!res && cpusetsize && cpuset)
5012 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize);
5016 #define INIT_PTHREAD_GETAFFINITY_NP \
5017 COMMON_INTERCEPT_FUNCTION(pthread_getaffinity_np);
5019 #define INIT_PTHREAD_GETAFFINITY_NP
5022 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED
5023 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int))
5024 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED \
5025 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared);
5027 #define INIT_PTHREAD_MUTEXATTR_GETPSHARED
5030 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE
5031 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int))
5032 #define INIT_PTHREAD_MUTEXATTR_GETTYPE \
5033 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype);
5035 #define INIT_PTHREAD_MUTEXATTR_GETTYPE
5038 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL
5039 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int))
5040 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \
5041 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol);
5043 #define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL
5046 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING
5047 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int))
5048 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \
5049 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling);
5051 #define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING
5054 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST
5055 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int))
5056 #define INIT_PTHREAD_MUTEXATTR_GETROBUST \
5057 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust);
5059 #define INIT_PTHREAD_MUTEXATTR_GETROBUST
5062 #if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP
5063 INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int))
5064 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \
5065 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np);
5067 #define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP
5070 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED
5071 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int))
5072 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \
5073 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared);
5075 #define INIT_PTHREAD_RWLOCKATTR_GETPSHARED
5078 #if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP
5079 INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int))
5080 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \
5081 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np);
5083 #define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP
5086 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED
5087 INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int))
5088 #define INIT_PTHREAD_CONDATTR_GETPSHARED \
5089 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared);
5091 #define INIT_PTHREAD_CONDATTR_GETPSHARED
5094 #if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK
5095 INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int))
5096 #define INIT_PTHREAD_CONDATTR_GETCLOCK \
5097 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock);
5099 #define INIT_PTHREAD_CONDATTR_GETCLOCK
5102 #if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED
5103 INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android
5104 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED \
5105 COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared);
5107 #define INIT_PTHREAD_BARRIERATTR_GETPSHARED
5110 #if SANITIZER_INTERCEPT_TMPNAM
5111 INTERCEPTOR(char *, tmpnam, char *s) {
5113 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s);
5114 char *res = REAL(tmpnam)(s);
5117 // FIXME: under ASan the call below may write to freed memory and corrupt
5118 // its metadata. See
5119 // https://github.com/google/sanitizers/issues/321.
5120 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
5122 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5126 #define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam);
5131 #if SANITIZER_INTERCEPT_TMPNAM_R
5132 INTERCEPTOR(char *, tmpnam_r, char *s) {
5134 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s);
5135 // FIXME: under ASan the call below may write to freed memory and corrupt
5136 // its metadata. See
5137 // https://github.com/google/sanitizers/issues/321.
5138 char *res = REAL(tmpnam_r)(s);
5139 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, internal_strlen(s) + 1);
5142 #define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r);
5144 #define INIT_TMPNAM_R
5147 #if SANITIZER_INTERCEPT_PTSNAME
5148 INTERCEPTOR(char *, ptsname, int fd) {
5150 COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd);
5151 char *res = REAL(ptsname)(fd);
5153 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5156 #define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname);
5158 #define INIT_PTSNAME
5161 #if SANITIZER_INTERCEPT_PTSNAME_R
5162 INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) {
5164 COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize);
5165 int res = REAL(ptsname_r)(fd, name, namesize);
5167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
5170 #define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r);
5172 #define INIT_PTSNAME_R
5175 #if SANITIZER_INTERCEPT_TTYNAME
5176 INTERCEPTOR(char *, ttyname, int fd) {
5178 COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd);
5179 char *res = REAL(ttyname)(fd);
5181 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5184 #define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname);
5186 #define INIT_TTYNAME
5189 #if SANITIZER_INTERCEPT_TTYNAME_R
5190 INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) {
5192 COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize);
5193 int res = REAL(ttyname_r)(fd, name, namesize);
5195 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
5198 #define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r);
5200 #define INIT_TTYNAME_R
5203 #if SANITIZER_INTERCEPT_TEMPNAM
5204 INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
5206 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx);
5207 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, internal_strlen(dir) + 1);
5208 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, internal_strlen(pfx) + 1);
5209 char *res = REAL(tempnam)(dir, pfx);
5210 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
5213 #define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam);
5215 #define INIT_TEMPNAM
5218 #if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
5219 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
5221 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
5222 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
5223 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name);
5224 return REAL(pthread_setname_np)(thread, name);
5226 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
5227 #elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
5228 INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
5230 char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
5231 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
5232 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
5233 internal_snprintf(newname, sizeof(newname), name, arg);
5234 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
5235 return REAL(pthread_setname_np)(thread, name, arg);
5237 #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
5239 #define INIT_PTHREAD_SETNAME_NP
5242 #if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP
5243 INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) {
5245 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len);
5246 int res = REAL(pthread_getname_np)(thread, name, len);
5248 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1);
5251 #define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np);
5253 #define INIT_PTHREAD_GETNAME_NP
5256 #if SANITIZER_INTERCEPT_SINCOS
5257 INTERCEPTOR(void, sincos, double x, double *sin, double *cos) {
5259 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos);
5260 // FIXME: under ASan the call below may write to freed memory and corrupt
5261 // its metadata. See
5262 // https://github.com/google/sanitizers/issues/321.
5263 REAL(sincos)(x, sin, cos);
5264 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5265 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5267 INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) {
5269 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos);
5270 // FIXME: under ASan the call below may write to freed memory and corrupt
5271 // its metadata. See
5272 // https://github.com/google/sanitizers/issues/321.
5273 REAL(sincosf)(x, sin, cos);
5274 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5275 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5277 INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) {
5279 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos);
5280 // FIXME: under ASan the call below may write to freed memory and corrupt
5281 // its metadata. See
5282 // https://github.com/google/sanitizers/issues/321.
5283 REAL(sincosl)(x, sin, cos);
5284 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin));
5285 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos));
5287 #define INIT_SINCOS \
5288 COMMON_INTERCEPT_FUNCTION(sincos); \
5289 COMMON_INTERCEPT_FUNCTION(sincosf); \
5290 COMMON_INTERCEPT_FUNCTION_LDBL(sincosl);
5295 #if SANITIZER_INTERCEPT_REMQUO
5296 INTERCEPTOR(double, remquo, double x, double y, int *quo) {
5298 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo);
5299 // FIXME: under ASan the call below may write to freed memory and corrupt
5300 // its metadata. See
5301 // https://github.com/google/sanitizers/issues/321.
5302 double res = REAL(remquo)(x, y, quo);
5303 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5306 INTERCEPTOR(float, remquof, float x, float y, int *quo) {
5308 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo);
5309 // FIXME: under ASan the call below may write to freed memory and corrupt
5310 // its metadata. See
5311 // https://github.com/google/sanitizers/issues/321.
5312 float res = REAL(remquof)(x, y, quo);
5313 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5316 #define INIT_REMQUO \
5317 COMMON_INTERCEPT_FUNCTION(remquo); \
5318 COMMON_INTERCEPT_FUNCTION(remquof);
5323 #if SANITIZER_INTERCEPT_REMQUOL
5324 INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) {
5326 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo);
5327 // FIXME: under ASan the call below may write to freed memory and corrupt
5328 // its metadata. See
5329 // https://github.com/google/sanitizers/issues/321.
5330 long double res = REAL(remquol)(x, y, quo);
5331 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo));
5334 #define INIT_REMQUOL \
5335 COMMON_INTERCEPT_FUNCTION_LDBL(remquol);
5337 #define INIT_REMQUOL
5340 #if SANITIZER_INTERCEPT_LGAMMA
5342 INTERCEPTOR(double, lgamma, double x) {
5344 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x);
5345 double res = REAL(lgamma)(x);
5346 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5349 INTERCEPTOR(float, lgammaf, float x) {
5351 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x);
5352 float res = REAL(lgammaf)(x);
5353 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5356 #define INIT_LGAMMA \
5357 COMMON_INTERCEPT_FUNCTION(lgamma); \
5358 COMMON_INTERCEPT_FUNCTION(lgammaf);
5363 #if SANITIZER_INTERCEPT_LGAMMAL
5364 INTERCEPTOR(long double, lgammal, long double x) {
5366 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x);
5367 long double res = REAL(lgammal)(x);
5368 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam));
5371 #define INIT_LGAMMAL \
5372 COMMON_INTERCEPT_FUNCTION_LDBL(lgammal);
5374 #define INIT_LGAMMAL
5377 #if SANITIZER_INTERCEPT_LGAMMA_R
5378 INTERCEPTOR(double, lgamma_r, double x, int *signp) {
5380 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp);
5381 // FIXME: under ASan the call below may write to freed memory and corrupt
5382 // its metadata. See
5383 // https://github.com/google/sanitizers/issues/321.
5384 double res = REAL(lgamma_r)(x, signp);
5385 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5388 INTERCEPTOR(float, lgammaf_r, float x, int *signp) {
5390 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp);
5391 // FIXME: under ASan the call below may write to freed memory and corrupt
5392 // its metadata. See
5393 // https://github.com/google/sanitizers/issues/321.
5394 float res = REAL(lgammaf_r)(x, signp);
5395 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5398 #define INIT_LGAMMA_R \
5399 COMMON_INTERCEPT_FUNCTION(lgamma_r); \
5400 COMMON_INTERCEPT_FUNCTION(lgammaf_r);
5402 #define INIT_LGAMMA_R
5405 #if SANITIZER_INTERCEPT_LGAMMAL_R
5406 INTERCEPTOR(long double, lgammal_r, long double x, int *signp) {
5408 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp);
5409 // FIXME: under ASan the call below may write to freed memory and corrupt
5410 // its metadata. See
5411 // https://github.com/google/sanitizers/issues/321.
5412 long double res = REAL(lgammal_r)(x, signp);
5413 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp));
5416 #define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r);
5418 #define INIT_LGAMMAL_R
5421 #if SANITIZER_INTERCEPT_DRAND48_R
5422 INTERCEPTOR(int, drand48_r, void *buffer, double *result) {
5424 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result);
5425 // FIXME: under ASan the call below may write to freed memory and corrupt
5426 // its metadata. See
5427 // https://github.com/google/sanitizers/issues/321.
5428 int res = REAL(drand48_r)(buffer, result);
5429 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5432 INTERCEPTOR(int, lrand48_r, void *buffer, long *result) {
5434 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result);
5435 // FIXME: under ASan the call below may write to freed memory and corrupt
5436 // its metadata. See
5437 // https://github.com/google/sanitizers/issues/321.
5438 int res = REAL(lrand48_r)(buffer, result);
5439 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result));
5442 #define INIT_DRAND48_R \
5443 COMMON_INTERCEPT_FUNCTION(drand48_r); \
5444 COMMON_INTERCEPT_FUNCTION(lrand48_r);
5446 #define INIT_DRAND48_R
5449 #if SANITIZER_INTERCEPT_RAND_R
5450 INTERCEPTOR(int, rand_r, unsigned *seedp) {
5452 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp);
5453 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp));
5454 return REAL(rand_r)(seedp);
5456 #define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r);
5461 #if SANITIZER_INTERCEPT_GETLINE
5462 INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) {
5464 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream);
5465 // FIXME: under ASan the call below may write to freed memory and corrupt
5466 // its metadata. See
5467 // https://github.com/google/sanitizers/issues/321.
5468 SSIZE_T res = REAL(getline)(lineptr, n, stream);
5470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr));
5471 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
5472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1);
5477 // FIXME: under ASan the call below may write to freed memory and corrupt its
5479 // https://github.com/google/sanitizers/issues/321.
5480 #define GETDELIM_INTERCEPTOR_IMPL(vname) \
5483 COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \
5484 SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \
5486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \
5487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \
5488 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \
5493 INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim,
5495 GETDELIM_INTERCEPTOR_IMPL(__getdelim)
5497 // There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor
5498 // with its own body.
5499 INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim,
5501 GETDELIM_INTERCEPTOR_IMPL(getdelim)
5503 #define INIT_GETLINE \
5504 COMMON_INTERCEPT_FUNCTION(getline); \
5505 COMMON_INTERCEPT_FUNCTION(__getdelim); \
5506 COMMON_INTERCEPT_FUNCTION(getdelim);
5508 #define INIT_GETLINE
5511 #if SANITIZER_INTERCEPT_ICONV
5512 INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft,
5513 char **outbuf, SIZE_T *outbytesleft) {
5515 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf,
5518 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft));
5519 if (inbuf && inbytesleft)
5520 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft);
5522 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft));
5523 void *outbuf_orig = outbuf ? *outbuf : nullptr;
5524 // FIXME: under ASan the call below may write to freed memory and corrupt
5525 // its metadata. See
5526 // https://github.com/google/sanitizers/issues/321.
5527 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft);
5528 if (outbuf && *outbuf > outbuf_orig) {
5529 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig;
5530 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz);
5534 #define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv);
5539 #if SANITIZER_INTERCEPT_TIMES
5540 INTERCEPTOR(__sanitizer_clock_t, times, void *tms) {
5542 COMMON_INTERCEPTOR_ENTER(ctx, times, tms);
5543 // FIXME: under ASan the call below may write to freed memory and corrupt
5544 // its metadata. See
5545 // https://github.com/google/sanitizers/issues/321.
5546 __sanitizer_clock_t res = REAL(times)(tms);
5547 if (res != (__sanitizer_clock_t)-1 && tms)
5548 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz);
5551 #define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times);
5556 #if SANITIZER_S390 && \
5557 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5558 extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg));
5559 DEFINE_REAL(uptr, __tls_get_offset, void *arg)
5562 #if SANITIZER_INTERCEPT_TLS_GET_ADDR
5564 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr)
5565 // If you see any crashes around this functions, there are 2 known issues with
5566 // it: 1. __tls_get_addr can be called with mis-aligned stack due to:
5567 // https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066
5568 // 2. It can be called recursively if sanitizer code uses __tls_get_addr
5569 // to access thread local variables (it should not happen normally,
5570 // because sanitizers use initial-exec tls model).
5571 INTERCEPTOR(void *, __tls_get_addr, void *arg) {
5573 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg);
5574 void *res = REAL(__tls_get_addr)(arg);
5575 uptr tls_begin, tls_end;
5576 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5577 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end);
5579 // New DTLS block has been allocated.
5580 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5585 // On PowerPC, we also need to intercept __tls_get_addr_opt, which has
5586 // mostly the same semantics as __tls_get_addr, but its presence enables
5587 // some optimizations in linker (which are safe to ignore here).
5588 extern "C" __attribute__((alias("__interceptor___tls_get_addr"),
5589 visibility("default")))
5590 void *__tls_get_addr_opt(void *arg);
5592 #else // SANITIZER_S390
5593 // On s390, we have to intercept two functions here:
5594 // - __tls_get_addr_internal, which is a glibc-internal function that is like
5595 // the usual __tls_get_addr, but returns a TP-relative offset instead of
5596 // a proper pointer. It is used by dlsym for TLS symbols.
5597 // - __tls_get_offset, which is like the above, but also takes a GOT-relative
5598 // descriptor offset as an argument instead of a pointer. GOT address
5599 // is passed in r12, so it's necessary to write it in assembly. This is
5600 // the function used by the compiler.
5601 #define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset)
5602 INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) {
5604 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg);
5605 uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset));
5606 uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer());
5607 void *ptr = reinterpret_cast<void *>(res + tp);
5608 uptr tls_begin, tls_end;
5609 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end);
5610 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end);
5612 // New DTLS block has been allocated.
5613 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size);
5617 #endif // SANITIZER_S390
5619 #define INIT_TLS_GET_ADDR
5622 #if SANITIZER_S390 && \
5623 (SANITIZER_INTERCEPT_TLS_GET_ADDR || SANITIZER_INTERCEPT_TLS_GET_OFFSET)
5624 extern "C" uptr __tls_get_offset(void *arg);
5625 extern "C" uptr __interceptor___tls_get_offset(void *arg);
5626 // We need a hidden symbol aliasing the above, so that we can jump
5627 // directly to it from the assembly below.
5628 extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"),
5629 visibility("hidden")))
5630 uptr __tls_get_addr_hidden(void *arg);
5631 // Now carefully intercept __tls_get_offset.
5634 // The __intercept_ version has to exist, so that gen_dynamic_list.py
5635 // exports our symbol.
5636 ".weak __tls_get_offset\n"
5637 ".type __tls_get_offset, @function\n"
5638 "__tls_get_offset:\n"
5639 ".global __interceptor___tls_get_offset\n"
5640 ".type __interceptor___tls_get_offset, @function\n"
5641 "__interceptor___tls_get_offset:\n"
5643 "la %r2, 0(%r2,%r12)\n"
5644 "jg __tls_get_addr_hidden\n"
5647 "0: la %r2,0(%r2,%r12)\n"
5648 "l %r4,1f-0b(%r3)\n"
5650 "1: .long __tls_get_addr_hidden - 0b\n"
5652 ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n"
5653 // Assembly wrapper to call REAL(__tls_get_offset)(arg)
5654 ".type __tls_get_offset_wrapper, @function\n"
5655 "__tls_get_offset_wrapper:\n"
5662 ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n"
5666 #if SANITIZER_INTERCEPT_LISTXATTR
5667 INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) {
5669 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size);
5670 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5671 // FIXME: under ASan the call below may write to freed memory and corrupt
5672 // its metadata. See
5673 // https://github.com/google/sanitizers/issues/321.
5674 SSIZE_T res = REAL(listxattr)(path, list, size);
5675 // Here and below, size == 0 is a special case where nothing is written to the
5676 // buffer, and res contains the desired buffer size.
5677 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5680 INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) {
5682 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size);
5683 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5684 // FIXME: under ASan the call below may write to freed memory and corrupt
5685 // its metadata. See
5686 // https://github.com/google/sanitizers/issues/321.
5687 SSIZE_T res = REAL(llistxattr)(path, list, size);
5688 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5691 INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) {
5693 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size);
5694 // FIXME: under ASan the call below may write to freed memory and corrupt
5695 // its metadata. See
5696 // https://github.com/google/sanitizers/issues/321.
5697 SSIZE_T res = REAL(flistxattr)(fd, list, size);
5698 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res);
5701 #define INIT_LISTXATTR \
5702 COMMON_INTERCEPT_FUNCTION(listxattr); \
5703 COMMON_INTERCEPT_FUNCTION(llistxattr); \
5704 COMMON_INTERCEPT_FUNCTION(flistxattr);
5706 #define INIT_LISTXATTR
5709 #if SANITIZER_INTERCEPT_GETXATTR
5710 INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value,
5713 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size);
5714 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5715 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5716 // FIXME: under ASan the call below may write to freed memory and corrupt
5717 // its metadata. See
5718 // https://github.com/google/sanitizers/issues/321.
5719 SSIZE_T res = REAL(getxattr)(path, name, value, size);
5720 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5723 INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value,
5726 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size);
5727 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
5728 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5729 // FIXME: under ASan the call below may write to freed memory and corrupt
5730 // its metadata. See
5731 // https://github.com/google/sanitizers/issues/321.
5732 SSIZE_T res = REAL(lgetxattr)(path, name, value, size);
5733 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5736 INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value,
5739 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size);
5740 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
5741 // FIXME: under ASan the call below may write to freed memory and corrupt
5742 // its metadata. See
5743 // https://github.com/google/sanitizers/issues/321.
5744 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size);
5745 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res);
5748 #define INIT_GETXATTR \
5749 COMMON_INTERCEPT_FUNCTION(getxattr); \
5750 COMMON_INTERCEPT_FUNCTION(lgetxattr); \
5751 COMMON_INTERCEPT_FUNCTION(fgetxattr);
5753 #define INIT_GETXATTR
5756 #if SANITIZER_INTERCEPT_GETRESID
5757 INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) {
5759 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid);
5760 // FIXME: under ASan the call below may write to freed memory and corrupt
5761 // its metadata. See
5762 // https://github.com/google/sanitizers/issues/321.
5763 int res = REAL(getresuid)(ruid, euid, suid);
5765 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz);
5766 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz);
5767 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz);
5771 INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) {
5773 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid);
5774 // FIXME: under ASan the call below may write to freed memory and corrupt
5775 // its metadata. See
5776 // https://github.com/google/sanitizers/issues/321.
5777 int res = REAL(getresgid)(rgid, egid, sgid);
5779 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz);
5780 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz);
5781 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz);
5785 #define INIT_GETRESID \
5786 COMMON_INTERCEPT_FUNCTION(getresuid); \
5787 COMMON_INTERCEPT_FUNCTION(getresgid);
5789 #define INIT_GETRESID
5792 #if SANITIZER_INTERCEPT_GETIFADDRS
5793 // As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to
5794 // intercept freeifaddrs(). If that ceases to be the case, we might need to
5795 // intercept it to poison the memory again.
5796 INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) {
5798 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap);
5799 // FIXME: under ASan the call below may write to freed memory and corrupt
5800 // its metadata. See
5801 // https://github.com/google/sanitizers/issues/321.
5802 int res = REAL(getifaddrs)(ifap);
5803 if (res == 0 && ifap) {
5804 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *));
5805 __sanitizer_ifaddrs *p = *ifap;
5807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs));
5809 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name,
5810 internal_strlen(p->ifa_name) + 1);
5812 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz);
5814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz);
5815 // On Linux this is a union, but the other member also points to a
5816 // struct sockaddr, so the following is sufficient.
5818 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz);
5819 // FIXME(smatveev): Unpoison p->ifa_data as well.
5825 #define INIT_GETIFADDRS \
5826 COMMON_INTERCEPT_FUNCTION(getifaddrs);
5828 #define INIT_GETIFADDRS
5831 #if SANITIZER_INTERCEPT_IF_INDEXTONAME
5832 INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) {
5834 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname);
5835 // FIXME: under ASan the call below may write to freed memory and corrupt
5836 // its metadata. See
5837 // https://github.com/google/sanitizers/issues/321.
5838 char *res = REAL(if_indextoname)(ifindex, ifname);
5840 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
5843 INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) {
5845 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname);
5847 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, internal_strlen(ifname) + 1);
5848 return REAL(if_nametoindex)(ifname);
5850 #define INIT_IF_INDEXTONAME \
5851 COMMON_INTERCEPT_FUNCTION(if_indextoname); \
5852 COMMON_INTERCEPT_FUNCTION(if_nametoindex);
5854 #define INIT_IF_INDEXTONAME
5857 #if SANITIZER_INTERCEPT_CAPGET
5858 INTERCEPTOR(int, capget, void *hdrp, void *datap) {
5860 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap);
5862 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5863 // FIXME: under ASan the call below may write to freed memory and corrupt
5864 // its metadata. See
5865 // https://github.com/google/sanitizers/issues/321.
5866 int res = REAL(capget)(hdrp, datap);
5867 if (res == 0 && datap)
5868 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz);
5869 // We can also return -1 and write to hdrp->version if the version passed in
5870 // hdrp->version is unsupported. But that's not a trivial condition to check,
5871 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent.
5874 INTERCEPTOR(int, capset, void *hdrp, const void *datap) {
5876 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap);
5878 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz);
5880 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz);
5881 return REAL(capset)(hdrp, datap);
5883 #define INIT_CAPGET \
5884 COMMON_INTERCEPT_FUNCTION(capget); \
5885 COMMON_INTERCEPT_FUNCTION(capset);
5890 #if SANITIZER_INTERCEPT_AEABI_MEM
5891 INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) {
5893 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5896 INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) {
5898 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5901 INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) {
5903 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size);
5906 INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) {
5908 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5911 INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) {
5913 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5916 INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) {
5918 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size);
5921 // Note the argument order.
5922 INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) {
5924 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5927 INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) {
5929 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5932 INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) {
5934 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size);
5937 INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) {
5939 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5942 INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) {
5944 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5947 INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) {
5949 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5952 #define INIT_AEABI_MEM \
5953 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \
5954 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \
5955 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \
5956 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \
5957 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \
5958 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \
5959 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \
5960 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \
5961 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \
5962 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \
5963 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \
5964 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8);
5966 #define INIT_AEABI_MEM
5967 #endif // SANITIZER_INTERCEPT_AEABI_MEM
5969 #if SANITIZER_INTERCEPT___BZERO
5970 INTERCEPTOR(void *, __bzero, void *block, uptr size) {
5972 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5974 #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero);
5976 #define INIT___BZERO
5977 #endif // SANITIZER_INTERCEPT___BZERO
5979 #if SANITIZER_INTERCEPT_BZERO
5980 INTERCEPTOR(void *, bzero, void *block, uptr size) {
5982 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size);
5984 #define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero);
5987 #endif // SANITIZER_INTERCEPT_BZERO
5989 #if SANITIZER_INTERCEPT_FTIME
5990 INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) {
5992 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp);
5993 // FIXME: under ASan the call below may write to freed memory and corrupt
5994 // its metadata. See
5995 // https://github.com/google/sanitizers/issues/321.
5996 int res = REAL(ftime)(tp);
5998 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp));
6001 #define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime);
6004 #endif // SANITIZER_INTERCEPT_FTIME
6006 #if SANITIZER_INTERCEPT_XDR
6007 INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr,
6008 unsigned size, int op) {
6010 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op);
6011 // FIXME: under ASan the call below may write to freed memory and corrupt
6012 // its metadata. See
6013 // https://github.com/google/sanitizers/issues/321.
6014 REAL(xdrmem_create)(xdrs, addr, size, op);
6015 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
6016 if (op == __sanitizer_XDR_ENCODE) {
6017 // It's not obvious how much data individual xdr_ routines write.
6018 // Simply unpoison the entire target buffer in advance.
6019 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size);
6023 INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) {
6025 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op);
6026 // FIXME: under ASan the call below may write to freed memory and corrupt
6027 // its metadata. See
6028 // https://github.com/google/sanitizers/issues/321.
6029 REAL(xdrstdio_create)(xdrs, file, op);
6030 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs));
6033 // FIXME: under ASan the call below may write to freed memory and corrupt
6034 // its metadata. See
6035 // https://github.com/google/sanitizers/issues/321.
6036 #define XDR_INTERCEPTOR(F, T) \
6037 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \
6039 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \
6040 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \
6041 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \
6042 int res = REAL(F)(xdrs, p); \
6043 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \
6044 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \
6048 XDR_INTERCEPTOR(xdr_short, short)
6049 XDR_INTERCEPTOR(xdr_u_short, unsigned short)
6050 XDR_INTERCEPTOR(xdr_int, int)
6051 XDR_INTERCEPTOR(xdr_u_int, unsigned)
6052 XDR_INTERCEPTOR(xdr_long, long)
6053 XDR_INTERCEPTOR(xdr_u_long, unsigned long)
6054 XDR_INTERCEPTOR(xdr_hyper, long long)
6055 XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long)
6056 XDR_INTERCEPTOR(xdr_longlong_t, long long)
6057 XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long)
6058 XDR_INTERCEPTOR(xdr_int8_t, u8)
6059 XDR_INTERCEPTOR(xdr_uint8_t, u8)
6060 XDR_INTERCEPTOR(xdr_int16_t, u16)
6061 XDR_INTERCEPTOR(xdr_uint16_t, u16)
6062 XDR_INTERCEPTOR(xdr_int32_t, u32)
6063 XDR_INTERCEPTOR(xdr_uint32_t, u32)
6064 XDR_INTERCEPTOR(xdr_int64_t, u64)
6065 XDR_INTERCEPTOR(xdr_uint64_t, u64)
6066 XDR_INTERCEPTOR(xdr_quad_t, long long)
6067 XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long)
6068 XDR_INTERCEPTOR(xdr_bool, bool)
6069 XDR_INTERCEPTOR(xdr_enum, int)
6070 XDR_INTERCEPTOR(xdr_char, char)
6071 XDR_INTERCEPTOR(xdr_u_char, unsigned char)
6072 XDR_INTERCEPTOR(xdr_float, float)
6073 XDR_INTERCEPTOR(xdr_double, double)
6075 // FIXME: intercept xdr_array, opaque, union, vector, reference, pointer,
6076 // wrapstring, sizeof
6078 INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep,
6081 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize);
6082 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) {
6083 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
6084 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep));
6085 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep);
6087 // FIXME: under ASan the call below may write to freed memory and corrupt
6088 // its metadata. See
6089 // https://github.com/google/sanitizers/issues/321.
6090 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize);
6091 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) {
6092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
6093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep));
6094 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep);
6099 INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p,
6102 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize);
6103 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) {
6104 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p));
6105 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, internal_strlen(*p) + 1);
6107 // FIXME: under ASan the call below may write to freed memory and corrupt
6108 // its metadata. See
6109 // https://github.com/google/sanitizers/issues/321.
6110 int res = REAL(xdr_string)(xdrs, p, maxsize);
6111 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) {
6112 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
6114 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, internal_strlen(*p) + 1);
6120 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \
6121 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \
6122 COMMON_INTERCEPT_FUNCTION(xdr_short); \
6123 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \
6124 COMMON_INTERCEPT_FUNCTION(xdr_int); \
6125 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \
6126 COMMON_INTERCEPT_FUNCTION(xdr_long); \
6127 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \
6128 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \
6129 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \
6130 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \
6131 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \
6132 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \
6133 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \
6134 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \
6135 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \
6136 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \
6137 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \
6138 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \
6139 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \
6140 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \
6141 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \
6142 COMMON_INTERCEPT_FUNCTION(xdr_bool); \
6143 COMMON_INTERCEPT_FUNCTION(xdr_enum); \
6144 COMMON_INTERCEPT_FUNCTION(xdr_char); \
6145 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \
6146 COMMON_INTERCEPT_FUNCTION(xdr_float); \
6147 COMMON_INTERCEPT_FUNCTION(xdr_double); \
6148 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \
6149 COMMON_INTERCEPT_FUNCTION(xdr_string);
6152 #endif // SANITIZER_INTERCEPT_XDR
6154 #if SANITIZER_INTERCEPT_XDRREC
6155 typedef int (*xdrrec_cb)(char*, char*, int);
6156 struct XdrRecWrapper {
6160 typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap;
6161 static XdrRecWrapMap *xdrrec_wrap_map;
6163 static int xdrrec_wr_wrap(char *handle, char *buf, int count) {
6164 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6165 COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count);
6166 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
6167 return wrap->wr(wrap->handle, buf, count);
6170 static int xdrrec_rd_wrap(char *handle, char *buf, int count) {
6171 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6172 XdrRecWrapper *wrap = (XdrRecWrapper *)handle;
6173 return wrap->rd(wrap->handle, buf, count);
6176 // This doesn't apply to the solaris version as it has a different function
6178 INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize,
6179 unsigned rcvsize, char *handle, int (*rd)(char*, char*, int),
6180 int (*wr)(char*, char*, int)) {
6182 COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize,
6184 COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op);
6186 // We can't allocate a wrapper on the stack, as the handle is used outside
6187 // this stack frame. So we put it on the heap, and keep track of it with
6188 // the HashMap (keyed by x_private). When we later need to xdr_destroy,
6189 // we can index the map, free the wrapper, and then clean the map entry.
6190 XdrRecWrapper *wrap_data =
6191 (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper));
6192 wrap_data->handle = handle;
6196 wr = xdrrec_wr_wrap;
6198 rd = xdrrec_rd_wrap;
6199 handle = (char *)wrap_data;
6201 REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr);
6202 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr);
6204 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true);
6208 // We have to intercept this to be able to free wrapper memory;
6209 // otherwise it's not necessary.
6210 INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) {
6212 COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr);
6214 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true);
6215 InternalFree(*wrap);
6216 REAL(xdr_destroy)(xdr);
6218 #define INIT_XDRREC_LINUX \
6219 static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \
6220 xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \
6221 COMMON_INTERCEPT_FUNCTION(xdrrec_create); \
6222 COMMON_INTERCEPT_FUNCTION(xdr_destroy);
6224 #define INIT_XDRREC_LINUX
6227 #if SANITIZER_INTERCEPT_TSEARCH
6228 INTERCEPTOR(void *, tsearch, void *key, void **rootp,
6229 int (*compar)(const void *, const void *)) {
6231 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar);
6232 // FIXME: under ASan the call below may write to freed memory and corrupt
6233 // its metadata. See
6234 // https://github.com/google/sanitizers/issues/321.
6235 void *res = REAL(tsearch)(key, rootp, compar);
6236 if (res && *(void **)res == key)
6237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *));
6240 #define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch);
6242 #define INIT_TSEARCH
6245 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \
6246 SANITIZER_INTERCEPT_OPEN_MEMSTREAM
6247 void unpoison_file(__sanitizer_FILE *fp) {
6248 #if SANITIZER_HAS_STRUCT_FILE
6249 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
6250 #if SANITIZER_NETBSD
6251 if (fp->_bf._base && fp->_bf._size > 0)
6252 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
6255 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
6256 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
6257 fp->_IO_read_end - fp->_IO_read_base);
6258 if (fp->_IO_write_base && fp->_IO_write_base < fp->_IO_write_end)
6259 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_write_base,
6260 fp->_IO_write_end - fp->_IO_write_base);
6262 #endif // SANITIZER_HAS_STRUCT_FILE
6266 #if SANITIZER_INTERCEPT_LIBIO_INTERNALS
6267 // These guys are called when a .c source is built with -O2.
6268 INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) {
6270 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp);
6271 int res = REAL(__uflow)(fp);
6275 INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) {
6277 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp);
6278 int res = REAL(__underflow)(fp);
6282 INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) {
6284 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch);
6285 int res = REAL(__overflow)(fp, ch);
6289 INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) {
6291 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp);
6292 int res = REAL(__wuflow)(fp);
6296 INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) {
6298 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp);
6299 int res = REAL(__wunderflow)(fp);
6303 INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) {
6305 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch);
6306 int res = REAL(__woverflow)(fp, ch);
6310 #define INIT_LIBIO_INTERNALS \
6311 COMMON_INTERCEPT_FUNCTION(__uflow); \
6312 COMMON_INTERCEPT_FUNCTION(__underflow); \
6313 COMMON_INTERCEPT_FUNCTION(__overflow); \
6314 COMMON_INTERCEPT_FUNCTION(__wuflow); \
6315 COMMON_INTERCEPT_FUNCTION(__wunderflow); \
6316 COMMON_INTERCEPT_FUNCTION(__woverflow);
6318 #define INIT_LIBIO_INTERNALS
6321 #if SANITIZER_INTERCEPT_FOPEN
6322 INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) {
6324 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode);
6325 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6326 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6327 __sanitizer_FILE *res = REAL(fopen)(path, mode);
6328 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6329 if (res) unpoison_file(res);
6332 INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) {
6334 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode);
6335 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6336 __sanitizer_FILE *res = REAL(fdopen)(fd, mode);
6337 if (res) unpoison_file(res);
6340 INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode,
6341 __sanitizer_FILE *fp) {
6343 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp);
6344 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6345 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6346 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6347 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp);
6348 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6349 if (res) unpoison_file(res);
6352 #define INIT_FOPEN \
6353 COMMON_INTERCEPT_FUNCTION(fopen); \
6354 COMMON_INTERCEPT_FUNCTION(fdopen); \
6355 COMMON_INTERCEPT_FUNCTION(freopen);
6360 #if SANITIZER_INTERCEPT_FLOPEN
6361 INTERCEPTOR(int, flopen, const char *path, int flags, ...) {
6364 va_start(ap, flags);
6365 u16 mode = static_cast<u16>(va_arg(ap, u32));
6367 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6369 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6371 return REAL(flopen)(path, flags, mode);
6374 INTERCEPTOR(int, flopenat, int dirfd, const char *path, int flags, ...) {
6377 va_start(ap, flags);
6378 u16 mode = static_cast<u16>(va_arg(ap, u32));
6380 COMMON_INTERCEPTOR_ENTER(ctx, flopen, path, flags, mode);
6382 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6384 return REAL(flopenat)(dirfd, path, flags, mode);
6387 #define INIT_FLOPEN \
6388 COMMON_INTERCEPT_FUNCTION(flopen); \
6389 COMMON_INTERCEPT_FUNCTION(flopenat);
6394 #if SANITIZER_INTERCEPT_FOPEN64
6395 INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) {
6397 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode);
6398 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6399 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6400 __sanitizer_FILE *res = REAL(fopen64)(path, mode);
6401 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6402 if (res) unpoison_file(res);
6405 INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode,
6406 __sanitizer_FILE *fp) {
6408 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp);
6409 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
6410 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, internal_strlen(mode) + 1);
6411 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6412 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp);
6413 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path);
6414 if (res) unpoison_file(res);
6417 #define INIT_FOPEN64 \
6418 COMMON_INTERCEPT_FUNCTION(fopen64); \
6419 COMMON_INTERCEPT_FUNCTION(freopen64);
6421 #define INIT_FOPEN64
6424 #if SANITIZER_INTERCEPT_OPEN_MEMSTREAM
6425 INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) {
6427 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc);
6428 // FIXME: under ASan the call below may write to freed memory and corrupt
6429 // its metadata. See
6430 // https://github.com/google/sanitizers/issues/321.
6431 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc);
6433 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
6434 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
6436 FileMetadata file = {ptr, sizeloc};
6437 SetInterceptorMetadata(res, file);
6441 INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr,
6444 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc);
6445 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc);
6447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr));
6448 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc));
6450 FileMetadata file = {(char **)ptr, sizeloc};
6451 SetInterceptorMetadata(res, file);
6455 INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size,
6458 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode);
6459 // FIXME: under ASan the call below may write to freed memory and corrupt
6460 // its metadata. See
6461 // https://github.com/google/sanitizers/issues/321.
6462 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode);
6463 if (res) unpoison_file(res);
6466 #define INIT_OPEN_MEMSTREAM \
6467 COMMON_INTERCEPT_FUNCTION(open_memstream); \
6468 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \
6469 COMMON_INTERCEPT_FUNCTION(fmemopen);
6471 #define INIT_OPEN_MEMSTREAM
6474 #if SANITIZER_INTERCEPT_OBSTACK
6475 static void initialize_obstack(__sanitizer_obstack *obstack) {
6476 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack));
6478 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk,
6479 sizeof(*obstack->chunk));
6482 INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz,
6483 int align, void *(*alloc_fn)(uptr arg, uptr sz),
6484 void (*free_fn)(uptr arg, void *p)) {
6486 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn,
6488 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn);
6489 if (res) initialize_obstack(obstack);
6492 INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz,
6493 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) {
6495 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn,
6497 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn);
6498 if (res) initialize_obstack(obstack);
6501 INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) {
6503 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length);
6504 REAL(_obstack_newchunk)(obstack, length);
6506 COMMON_INTERCEPTOR_INITIALIZE_RANGE(
6507 obstack->chunk, obstack->next_free - (char *)obstack->chunk);
6509 #define INIT_OBSTACK \
6510 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \
6511 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \
6512 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk);
6514 #define INIT_OBSTACK
6517 #if SANITIZER_INTERCEPT_FFLUSH
6518 INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) {
6520 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp);
6523 int res = REAL(fflush)(fp);
6524 // FIXME: handle fp == NULL
6526 const FileMetadata *m = GetInterceptorMetadata(fp);
6527 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6531 #define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush);
6536 #if SANITIZER_INTERCEPT_FCLOSE
6537 INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) {
6539 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp);
6540 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
6541 const FileMetadata *m = GetInterceptorMetadata(fp);
6544 int res = REAL(fclose)(fp);
6546 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
6547 DeleteInterceptorMetadata(fp);
6551 #define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose);
6556 #if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE
6557 INTERCEPTOR(void*, dlopen, const char *filename, int flag) {
6559 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag);
6560 if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0);
6561 void *res = COMMON_INTERCEPTOR_DLOPEN(filename, flag);
6562 Symbolizer::GetOrInit()->InvalidateModuleList();
6563 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res);
6567 INTERCEPTOR(int, dlclose, void *handle) {
6569 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle);
6570 int res = REAL(dlclose)(handle);
6571 Symbolizer::GetOrInit()->InvalidateModuleList();
6572 COMMON_INTERCEPTOR_LIBRARY_UNLOADED();
6575 #define INIT_DLOPEN_DLCLOSE \
6576 COMMON_INTERCEPT_FUNCTION(dlopen); \
6577 COMMON_INTERCEPT_FUNCTION(dlclose);
6579 #define INIT_DLOPEN_DLCLOSE
6582 #if SANITIZER_INTERCEPT_GETPASS
6583 INTERCEPTOR(char *, getpass, const char *prompt) {
6585 COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt);
6587 COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, internal_strlen(prompt)+1);
6588 char *res = REAL(getpass)(prompt);
6589 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res)+1);
6593 #define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass);
6595 #define INIT_GETPASS
6598 #if SANITIZER_INTERCEPT_TIMERFD
6599 INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value,
6602 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value,
6604 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz);
6605 int res = REAL(timerfd_settime)(fd, flags, new_value, old_value);
6606 if (res != -1 && old_value)
6607 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz);
6611 INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) {
6613 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value);
6614 int res = REAL(timerfd_gettime)(fd, curr_value);
6615 if (res != -1 && curr_value)
6616 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz);
6619 #define INIT_TIMERFD \
6620 COMMON_INTERCEPT_FUNCTION(timerfd_settime); \
6621 COMMON_INTERCEPT_FUNCTION(timerfd_gettime);
6623 #define INIT_TIMERFD
6626 #if SANITIZER_INTERCEPT_MLOCKX
6627 // Linux kernel has a bug that leads to kernel deadlock if a process
6628 // maps TBs of memory and then calls mlock().
6629 static void MlockIsUnsupported() {
6630 static atomic_uint8_t printed;
6631 if (atomic_exchange(&printed, 1, memory_order_relaxed))
6633 VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n",
6637 INTERCEPTOR(int, mlock, const void *addr, uptr len) {
6638 MlockIsUnsupported();
6642 INTERCEPTOR(int, munlock, const void *addr, uptr len) {
6643 MlockIsUnsupported();
6647 INTERCEPTOR(int, mlockall, int flags) {
6648 MlockIsUnsupported();
6652 INTERCEPTOR(int, munlockall, void) {
6653 MlockIsUnsupported();
6657 #define INIT_MLOCKX \
6658 COMMON_INTERCEPT_FUNCTION(mlock); \
6659 COMMON_INTERCEPT_FUNCTION(munlock); \
6660 COMMON_INTERCEPT_FUNCTION(mlockall); \
6661 COMMON_INTERCEPT_FUNCTION(munlockall);
6665 #endif // SANITIZER_INTERCEPT_MLOCKX
6667 #if SANITIZER_INTERCEPT_FOPENCOOKIE
6668 struct WrappedCookie {
6670 __sanitizer_cookie_io_functions_t real_io_funcs;
6673 static uptr wrapped_read(void *cookie, char *buf, uptr size) {
6674 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6675 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6676 __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read;
6677 return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0;
6680 static uptr wrapped_write(void *cookie, const char *buf, uptr size) {
6681 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6682 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6683 __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write;
6684 return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size;
6687 static int wrapped_seek(void *cookie, u64 *offset, int whence) {
6688 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
6689 COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset));
6690 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6691 __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek;
6692 return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence)
6696 static int wrapped_close(void *cookie) {
6697 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
6698 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie;
6699 __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close;
6700 int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0;
6701 InternalFree(wrapped_cookie);
6705 INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode,
6706 __sanitizer_cookie_io_functions_t io_funcs) {
6708 COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs);
6709 WrappedCookie *wrapped_cookie =
6710 (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie));
6711 wrapped_cookie->real_cookie = cookie;
6712 wrapped_cookie->real_io_funcs = io_funcs;
6713 __sanitizer_FILE *res =
6714 REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write,
6715 wrapped_seek, wrapped_close});
6719 #define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie);
6721 #define INIT_FOPENCOOKIE
6722 #endif // SANITIZER_INTERCEPT_FOPENCOOKIE
6724 #if SANITIZER_INTERCEPT_SEM
6725 INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) {
6727 COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value);
6728 // Workaround a bug in glibc's "old" semaphore implementation by
6729 // zero-initializing the sem_t contents. This has to be done here because
6730 // interceptors bind to the lowest version before glibc 2.36, hitting the
6731 // buggy code path while the non-sanitized build of the same code works fine.
6732 REAL(memset)(s, 0, sizeof(*s));
6733 int res = REAL(sem_init)(s, pshared, value);
6737 INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) {
6739 COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s);
6740 int res = REAL(sem_destroy)(s);
6744 INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) {
6746 COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s);
6747 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s);
6749 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6754 INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) {
6756 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s);
6757 int res = REAL(sem_trywait)(s);
6759 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6764 INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) {
6766 COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime);
6767 COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz);
6768 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime);
6770 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6775 INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) {
6777 COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s);
6778 COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s);
6779 int res = REAL(sem_post)(s);
6783 INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) {
6785 COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval);
6786 int res = REAL(sem_getvalue)(s, sval);
6788 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s);
6789 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval));
6794 INTERCEPTOR(__sanitizer_sem_t *, sem_open, const char *name, int oflag, ...) {
6797 va_start(ap, oflag);
6798 u32 mode = va_arg(ap, u32);
6799 u32 value = va_arg(ap, u32);
6800 COMMON_INTERCEPTOR_ENTER(ctx, sem_open, name, oflag, mode, value);
6801 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
6802 __sanitizer_sem_t *s = REAL(sem_open)(name, oflag, mode, value);
6804 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, sizeof(*s));
6809 INTERCEPTOR(int, sem_unlink, const char *name) {
6811 COMMON_INTERCEPTOR_ENTER(ctx, sem_unlink, name);
6812 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
6813 return REAL(sem_unlink)(name);
6817 COMMON_INTERCEPT_FUNCTION(sem_init); \
6818 COMMON_INTERCEPT_FUNCTION(sem_destroy); \
6819 COMMON_INTERCEPT_FUNCTION(sem_wait); \
6820 COMMON_INTERCEPT_FUNCTION(sem_trywait); \
6821 COMMON_INTERCEPT_FUNCTION(sem_timedwait); \
6822 COMMON_INTERCEPT_FUNCTION(sem_post); \
6823 COMMON_INTERCEPT_FUNCTION(sem_getvalue); \
6824 COMMON_INTERCEPT_FUNCTION(sem_open); \
6825 COMMON_INTERCEPT_FUNCTION(sem_unlink);
6828 #endif // SANITIZER_INTERCEPT_SEM
6830 #if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL
6831 INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) {
6833 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate);
6834 int res = REAL(pthread_setcancelstate)(state, oldstate);
6835 if (res == 0 && oldstate != nullptr)
6836 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate));
6840 INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) {
6842 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype);
6843 int res = REAL(pthread_setcanceltype)(type, oldtype);
6844 if (res == 0 && oldtype != nullptr)
6845 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype));
6848 #define INIT_PTHREAD_SETCANCEL \
6849 COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \
6850 COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype);
6852 #define INIT_PTHREAD_SETCANCEL
6855 #if SANITIZER_INTERCEPT_MINCORE
6856 INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) {
6858 COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec);
6859 int res = REAL(mincore)(addr, length, vec);
6861 uptr page_size = GetPageSizeCached();
6862 uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size;
6863 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size);
6867 #define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore);
6869 #define INIT_MINCORE
6872 #if SANITIZER_INTERCEPT_PROCESS_VM_READV
6873 INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov,
6874 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6877 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt,
6878 remote_iov, riovcnt, flags);
6879 SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov,
6882 write_iovec(ctx, local_iov, liovcnt, res);
6886 INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov,
6887 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt,
6890 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt,
6891 remote_iov, riovcnt, flags);
6892 SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov,
6895 read_iovec(ctx, local_iov, liovcnt, res);
6898 #define INIT_PROCESS_VM_READV \
6899 COMMON_INTERCEPT_FUNCTION(process_vm_readv); \
6900 COMMON_INTERCEPT_FUNCTION(process_vm_writev);
6902 #define INIT_PROCESS_VM_READV
6905 #if SANITIZER_INTERCEPT_CTERMID
6906 INTERCEPTOR(char *, ctermid, char *s) {
6908 COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s);
6909 char *res = REAL(ctermid)(s);
6911 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
6915 #define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid);
6917 #define INIT_CTERMID
6920 #if SANITIZER_INTERCEPT_CTERMID_R
6921 INTERCEPTOR(char *, ctermid_r, char *s) {
6923 COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s);
6924 char *res = REAL(ctermid_r)(s);
6926 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
6930 #define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r);
6932 #define INIT_CTERMID_R
6935 #if SANITIZER_INTERCEPT_RECV_RECVFROM
6936 INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) {
6938 COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags);
6939 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6940 SSIZE_T res = REAL(recv)(fd, buf, len, flags);
6942 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6944 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
6948 INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags,
6949 void *srcaddr, int *addrlen) {
6951 COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr,
6953 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6955 if (srcaddr) srcaddr_sz = *addrlen;
6956 (void)srcaddr_sz; // prevent "set but not used" warning
6957 SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen);
6959 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len));
6960 if (res >= 0 && srcaddr)
6961 COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr,
6962 Min((SIZE_T)*addrlen, srcaddr_sz));
6965 #define INIT_RECV_RECVFROM \
6966 COMMON_INTERCEPT_FUNCTION(recv); \
6967 COMMON_INTERCEPT_FUNCTION(recvfrom);
6969 #define INIT_RECV_RECVFROM
6972 #if SANITIZER_INTERCEPT_SEND_SENDTO
6973 INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) {
6975 COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags);
6977 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6978 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6980 SSIZE_T res = REAL(send)(fd, buf, len, flags);
6981 if (common_flags()->intercept_send && res > 0)
6982 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
6986 INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags,
6987 void *dstaddr, int addrlen) {
6989 COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen);
6991 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
6992 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
6994 // Can't check dstaddr as it may have uninitialized padding at the end.
6995 SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen);
6996 if (common_flags()->intercept_send && res > 0)
6997 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len));
7000 #define INIT_SEND_SENDTO \
7001 COMMON_INTERCEPT_FUNCTION(send); \
7002 COMMON_INTERCEPT_FUNCTION(sendto);
7004 #define INIT_SEND_SENDTO
7007 #if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE
7008 INTERCEPTOR(int, eventfd_read, int fd, u64 *value) {
7010 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value);
7011 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7012 int res = REAL(eventfd_read)(fd, value);
7014 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value));
7015 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
7019 INTERCEPTOR(int, eventfd_write, int fd, u64 value) {
7021 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value);
7023 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
7024 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd);
7026 int res = REAL(eventfd_write)(fd, value);
7029 #define INIT_EVENTFD_READ_WRITE \
7030 COMMON_INTERCEPT_FUNCTION(eventfd_read); \
7031 COMMON_INTERCEPT_FUNCTION(eventfd_write)
7033 #define INIT_EVENTFD_READ_WRITE
7036 #if SANITIZER_INTERCEPT_STAT
7037 INTERCEPTOR(int, stat, const char *path, void *buf) {
7039 COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf);
7040 if (common_flags()->intercept_stat)
7041 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7042 int res = REAL(stat)(path, buf);
7044 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
7047 #define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat)
7052 #if SANITIZER_INTERCEPT_STAT64
7053 INTERCEPTOR(int, stat64, const char *path, void *buf) {
7055 COMMON_INTERCEPTOR_ENTER(ctx, stat64, path, buf);
7056 if (common_flags()->intercept_stat)
7057 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7058 int res = REAL(stat64)(path, buf);
7060 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
7063 #define INIT_STAT64 COMMON_INTERCEPT_FUNCTION(stat64)
7069 #if SANITIZER_INTERCEPT_LSTAT
7070 INTERCEPTOR(int, lstat, const char *path, void *buf) {
7072 COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf);
7073 if (common_flags()->intercept_stat)
7074 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7075 int res = REAL(lstat)(path, buf);
7077 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
7080 #define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat)
7085 #if SANITIZER_INTERCEPT_STAT64
7086 INTERCEPTOR(int, lstat64, const char *path, void *buf) {
7088 COMMON_INTERCEPTOR_ENTER(ctx, lstat64, path, buf);
7089 if (common_flags()->intercept_stat)
7090 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7091 int res = REAL(lstat64)(path, buf);
7093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
7096 #define INIT_LSTAT64 COMMON_INTERCEPT_FUNCTION(lstat64)
7098 #define INIT_LSTAT64
7101 #if SANITIZER_INTERCEPT___XSTAT
7102 INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) {
7104 COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf);
7105 if (common_flags()->intercept_stat)
7106 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7107 int res = REAL(__xstat)(version, path, buf);
7109 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
7112 #define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat)
7114 #define INIT___XSTAT
7117 #if SANITIZER_INTERCEPT___XSTAT64
7118 INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) {
7120 COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf);
7121 if (common_flags()->intercept_stat)
7122 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7123 int res = REAL(__xstat64)(version, path, buf);
7125 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
7128 #define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64)
7130 #define INIT___XSTAT64
7133 #if SANITIZER_INTERCEPT___LXSTAT
7134 INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) {
7136 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf);
7137 if (common_flags()->intercept_stat)
7138 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7139 int res = REAL(__lxstat)(version, path, buf);
7141 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz);
7144 #define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat)
7146 #define INIT___LXSTAT
7149 #if SANITIZER_INTERCEPT___LXSTAT64
7150 INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) {
7152 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf);
7153 if (common_flags()->intercept_stat)
7154 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0);
7155 int res = REAL(__lxstat64)(version, path, buf);
7157 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz);
7160 #define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64)
7162 #define INIT___LXSTAT64
7165 // FIXME: add other *stat interceptor
7167 #if SANITIZER_INTERCEPT_UTMP
7168 INTERCEPTOR(void *, getutent, int dummy) {
7170 COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy);
7171 void *res = REAL(getutent)(dummy);
7173 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
7176 INTERCEPTOR(void *, getutid, void *ut) {
7178 COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut);
7179 void *res = REAL(getutid)(ut);
7181 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
7184 INTERCEPTOR(void *, getutline, void *ut) {
7186 COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut);
7187 void *res = REAL(getutline)(ut);
7189 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz);
7193 COMMON_INTERCEPT_FUNCTION(getutent); \
7194 COMMON_INTERCEPT_FUNCTION(getutid); \
7195 COMMON_INTERCEPT_FUNCTION(getutline);
7200 #if SANITIZER_INTERCEPT_UTMPX
7201 INTERCEPTOR(void *, getutxent, int dummy) {
7203 COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy);
7204 void *res = REAL(getutxent)(dummy);
7206 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
7209 INTERCEPTOR(void *, getutxid, void *ut) {
7211 COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut);
7212 void *res = REAL(getutxid)(ut);
7214 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
7217 INTERCEPTOR(void *, getutxline, void *ut) {
7219 COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut);
7220 void *res = REAL(getutxline)(ut);
7222 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
7225 INTERCEPTOR(void *, pututxline, const void *ut) {
7227 COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
7229 COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
7230 void *res = REAL(pututxline)(ut);
7232 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
7235 #define INIT_UTMPX \
7236 COMMON_INTERCEPT_FUNCTION(getutxent); \
7237 COMMON_INTERCEPT_FUNCTION(getutxid); \
7238 COMMON_INTERCEPT_FUNCTION(getutxline); \
7239 COMMON_INTERCEPT_FUNCTION(pututxline);
7244 #if SANITIZER_INTERCEPT_GETLOADAVG
7245 INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) {
7247 COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem);
7248 int res = REAL(getloadavg)(loadavg, nelem);
7250 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg));
7253 #define INIT_GETLOADAVG \
7254 COMMON_INTERCEPT_FUNCTION(getloadavg);
7256 #define INIT_GETLOADAVG
7259 #if SANITIZER_INTERCEPT_MCHECK_MPROBE
7260 INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) {
7264 INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) {
7268 INTERCEPTOR(int, mprobe, void *ptr) {
7273 INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) {
7275 COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s);
7276 SIZE_T res = REAL(wcslen)(s);
7277 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1));
7281 INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) {
7283 COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n);
7284 SIZE_T res = REAL(wcsnlen)(s, n);
7285 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n));
7288 #define INIT_WCSLEN \
7289 COMMON_INTERCEPT_FUNCTION(wcslen); \
7290 COMMON_INTERCEPT_FUNCTION(wcsnlen);
7292 #if SANITIZER_INTERCEPT_WCSCAT
7293 INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) {
7295 COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src);
7296 SIZE_T src_size = internal_wcslen(src);
7297 SIZE_T dst_size = internal_wcslen(dst);
7298 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t));
7299 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
7300 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
7301 (src_size + 1) * sizeof(wchar_t));
7302 return REAL(wcscat)(dst, src);
7305 INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) {
7307 COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n);
7308 SIZE_T src_size = internal_wcsnlen(src, n);
7309 SIZE_T dst_size = internal_wcslen(dst);
7310 COMMON_INTERCEPTOR_READ_RANGE(ctx, src,
7311 Min(src_size + 1, n) * sizeof(wchar_t));
7312 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t));
7313 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size,
7314 (src_size + 1) * sizeof(wchar_t));
7315 return REAL(wcsncat)(dst, src, n);
7317 #define INIT_WCSCAT \
7318 COMMON_INTERCEPT_FUNCTION(wcscat); \
7319 COMMON_INTERCEPT_FUNCTION(wcsncat);
7324 #if SANITIZER_INTERCEPT_WCSDUP
7325 INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) {
7327 COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s);
7328 SIZE_T len = internal_wcslen(s);
7329 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1));
7330 wchar_t *result = REAL(wcsdup)(s);
7332 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1));
7336 #define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup);
7341 #if SANITIZER_INTERCEPT_STRXFRM
7342 static SIZE_T RealStrLen(const char *str) { return internal_strlen(str); }
7344 static SIZE_T RealStrLen(const wchar_t *str) { return internal_wcslen(str); }
7346 #define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \
7349 COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \
7350 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \
7351 sizeof(*src) * (RealStrLen(src) + 1)); \
7352 SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \
7354 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \
7358 INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) {
7359 STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len);
7362 INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len,
7364 STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale);
7367 #define INIT_STRXFRM \
7368 COMMON_INTERCEPT_FUNCTION(strxfrm); \
7369 COMMON_INTERCEPT_FUNCTION(strxfrm_l);
7371 #define INIT_STRXFRM
7374 #if SANITIZER_INTERCEPT___STRXFRM_L
7375 INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len,
7377 STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale);
7380 #define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l);
7382 #define INIT___STRXFRM_L
7385 #if SANITIZER_INTERCEPT_WCSXFRM
7386 INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) {
7387 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len);
7390 INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
7392 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale);
7395 #define INIT_WCSXFRM \
7396 COMMON_INTERCEPT_FUNCTION(wcsxfrm); \
7397 COMMON_INTERCEPT_FUNCTION(wcsxfrm_l);
7399 #define INIT_WCSXFRM
7402 #if SANITIZER_INTERCEPT___WCSXFRM_L
7403 INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len,
7405 STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale);
7408 #define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l);
7410 #define INIT___WCSXFRM_L
7413 #if SANITIZER_INTERCEPT_ACCT
7414 INTERCEPTOR(int, acct, const char *file) {
7416 COMMON_INTERCEPTOR_ENTER(ctx, acct, file);
7418 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
7419 return REAL(acct)(file);
7421 #define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct)
7426 #if SANITIZER_INTERCEPT_USER_FROM_UID
7427 INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) {
7430 COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser);
7431 user = REAL(user_from_uid)(uid, nouser);
7433 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, internal_strlen(user) + 1);
7436 #define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid)
7438 #define INIT_USER_FROM_UID
7441 #if SANITIZER_INTERCEPT_UID_FROM_USER
7442 INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) {
7445 COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid);
7447 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7448 res = REAL(uid_from_user)(name, uid);
7450 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid));
7453 #define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user)
7455 #define INIT_UID_FROM_USER
7458 #if SANITIZER_INTERCEPT_GROUP_FROM_GID
7459 INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) {
7462 COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup);
7463 group = REAL(group_from_gid)(gid, nogroup);
7465 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, internal_strlen(group) + 1);
7468 #define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid)
7470 #define INIT_GROUP_FROM_GID
7473 #if SANITIZER_INTERCEPT_GID_FROM_GROUP
7474 INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) {
7477 COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid);
7479 COMMON_INTERCEPTOR_READ_RANGE(ctx, group, internal_strlen(group) + 1);
7480 res = REAL(gid_from_group)(group, gid);
7482 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid));
7485 #define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group)
7487 #define INIT_GID_FROM_GROUP
7490 #if SANITIZER_INTERCEPT_ACCESS
7491 INTERCEPTOR(int, access, const char *path, int mode) {
7493 COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode);
7495 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7496 return REAL(access)(path, mode);
7498 #define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access)
7503 #if SANITIZER_INTERCEPT_FACCESSAT
7504 INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) {
7506 COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags);
7508 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7509 return REAL(faccessat)(fd, path, mode, flags);
7511 #define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat)
7513 #define INIT_FACCESSAT
7516 #if SANITIZER_INTERCEPT_GETGROUPLIST
7517 INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups,
7521 COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups);
7523 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7525 COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups));
7526 res = REAL(getgrouplist)(name, basegid, groups, ngroups);
7527 if (!res && groups && ngroups) {
7528 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
7529 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
7534 #define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist);
7536 #define INIT_GETGROUPLIST
7539 #if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP
7540 INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups,
7541 int maxgrp, int *ngroups) {
7544 COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups,
7547 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7548 res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups);
7549 if (!res && groups && ngroups) {
7550 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups));
7551 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups));
7556 #define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership);
7558 #define INIT_GETGROUPMEMBERSHIP
7561 #if SANITIZER_INTERCEPT_READLINK
7562 INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) {
7564 COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz);
7565 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7566 SSIZE_T res = REAL(readlink)(path, buf, bufsiz);
7568 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7572 #define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink)
7574 #define INIT_READLINK
7577 #if SANITIZER_INTERCEPT_READLINKAT
7578 INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf,
7581 COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz);
7582 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7583 SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz);
7585 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res);
7589 #define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat)
7591 #define INIT_READLINKAT
7594 #if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT
7595 INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname,
7596 struct file_handle *handle, int *mount_id, int flags) {
7598 COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle,
7600 COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, internal_strlen(pathname) + 1);
7602 __sanitizer_file_handle *sanitizer_handle =
7603 reinterpret_cast<__sanitizer_file_handle*>(handle);
7604 COMMON_INTERCEPTOR_READ_RANGE(
7605 ctx, &sanitizer_handle->handle_bytes,
7606 sizeof(sanitizer_handle->handle_bytes));
7608 int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags);
7610 COMMON_INTERCEPTOR_WRITE_RANGE(
7611 ctx, &sanitizer_handle->handle_bytes,
7612 sizeof(sanitizer_handle->handle_bytes));
7613 COMMON_INTERCEPTOR_WRITE_RANGE(
7614 ctx, &sanitizer_handle->handle_type,
7615 sizeof(sanitizer_handle->handle_type));
7616 COMMON_INTERCEPTOR_WRITE_RANGE(
7617 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7618 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id));
7623 #define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at)
7625 #define INIT_NAME_TO_HANDLE_AT
7628 #if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT
7629 INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle,
7632 COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags);
7634 __sanitizer_file_handle *sanitizer_handle =
7635 reinterpret_cast<__sanitizer_file_handle*>(handle);
7636 COMMON_INTERCEPTOR_READ_RANGE(
7637 ctx, &sanitizer_handle->handle_bytes,
7638 sizeof(sanitizer_handle->handle_bytes));
7639 COMMON_INTERCEPTOR_READ_RANGE(
7640 ctx, &sanitizer_handle->handle_type,
7641 sizeof(sanitizer_handle->handle_type));
7642 COMMON_INTERCEPTOR_READ_RANGE(
7643 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes);
7645 return REAL(open_by_handle_at)(mount_fd, handle, flags);
7648 #define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at)
7650 #define INIT_OPEN_BY_HANDLE_AT
7653 #if SANITIZER_INTERCEPT_STRLCPY
7654 INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) {
7657 COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size);
7659 // Keep strnlen as macro argument, as macro may ignore it.
7660 COMMON_INTERCEPTOR_READ_STRING(
7661 ctx, src, Min(internal_strnlen(src, size), size - 1) + 1);
7663 res = REAL(strlcpy)(dst, src, size);
7664 COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, internal_strlen(dst) + 1);
7668 INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) {
7671 COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size);
7672 // src is checked in the strlcpy() interceptor
7674 len = internal_strnlen(dst, size);
7675 COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1);
7677 // Reuse the rest of the code in the strlcpy() interceptor
7678 return WRAP(strlcpy)(dst + len, src, size - len) + len;
7680 #define INIT_STRLCPY \
7681 COMMON_INTERCEPT_FUNCTION(strlcpy); \
7682 COMMON_INTERCEPT_FUNCTION(strlcat);
7684 #define INIT_STRLCPY
7687 #if SANITIZER_INTERCEPT_MMAP
7688 INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd,
7691 if (common_flags()->detect_write_exec)
7692 ReportMmapWriteExec(prot, flags);
7693 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7694 return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7695 COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off);
7696 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off);
7699 INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) {
7701 if (common_flags()->detect_write_exec)
7702 ReportMmapWriteExec(prot, 0);
7703 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7704 return (int)internal_mprotect(addr, sz, prot);
7705 COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot);
7706 MprotectMallocZones(addr, prot);
7707 return REAL(mprotect)(addr, sz, prot);
7710 COMMON_INTERCEPT_FUNCTION(mmap); \
7711 COMMON_INTERCEPT_FUNCTION(mprotect);
7716 #if SANITIZER_INTERCEPT_MMAP64
7717 INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd,
7720 if (common_flags()->detect_write_exec)
7721 ReportMmapWriteExec(prot, flags);
7722 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
7723 return (void *)internal_mmap(addr, sz, prot, flags, fd, off);
7724 COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off);
7725 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off);
7727 #define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64);
7732 #if SANITIZER_INTERCEPT_DEVNAME
7733 INTERCEPTOR(char *, devname, u64 dev, u32 type) {
7736 COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type);
7737 name = REAL(devname)(dev, type);
7739 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
7742 #define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname);
7744 #define INIT_DEVNAME
7747 #if SANITIZER_INTERCEPT_DEVNAME_R
7748 #if SANITIZER_NETBSD
7749 #define DEVNAME_R_RETTYPE int
7750 #define DEVNAME_R_SUCCESS(x) (!(x))
7752 #define DEVNAME_R_RETTYPE char*
7753 #define DEVNAME_R_SUCCESS(x) (x)
7755 INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
7758 COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
7759 DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
7760 if (DEVNAME_R_SUCCESS(res))
7761 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, internal_strlen(path) + 1);
7764 #define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r);
7766 #define INIT_DEVNAME_R
7769 #if SANITIZER_INTERCEPT_FGETLN
7770 INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) {
7772 COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len);
7773 char *str = REAL(fgetln)(stream, len);
7775 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
7776 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len);
7780 #define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln)
7785 #if SANITIZER_INTERCEPT_STRMODE
7786 INTERCEPTOR(void, strmode, u32 mode, char *bp) {
7788 COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp);
7789 REAL(strmode)(mode, bp);
7791 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, internal_strlen(bp) + 1);
7793 #define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode)
7795 #define INIT_STRMODE
7798 #if SANITIZER_INTERCEPT_TTYENT
7799 INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) {
7801 COMMON_INTERCEPTOR_ENTER(ctx, getttyent);
7802 struct __sanitizer_ttyent *ttyent = REAL(getttyent)();
7804 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7807 INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) {
7809 COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name);
7811 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7812 struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name);
7814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz);
7817 #define INIT_TTYENT \
7818 COMMON_INTERCEPT_FUNCTION(getttyent); \
7819 COMMON_INTERCEPT_FUNCTION(getttynam);
7824 #if SANITIZER_INTERCEPT_TTYENTPATH
7825 INTERCEPTOR(int, setttyentpath, char *path) {
7827 COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path);
7829 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
7830 return REAL(setttyentpath)(path);
7832 #define INIT_TTYENTPATH COMMON_INTERCEPT_FUNCTION(setttyentpath);
7834 #define INIT_TTYENTPATH
7837 #if SANITIZER_INTERCEPT_PROTOENT
7838 static void write_protoent(void *ctx, struct __sanitizer_protoent *p) {
7839 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p));
7841 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, internal_strlen(p->p_name) + 1);
7843 SIZE_T pp_size = 1; // One handles the trailing \0
7845 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size)
7846 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, internal_strlen(*pp) + 1);
7848 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases,
7849 pp_size * sizeof(char **));
7852 INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) {
7854 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent);
7855 struct __sanitizer_protoent *p = REAL(getprotoent)();
7857 write_protoent(ctx, p);
7861 INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) {
7863 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name);
7865 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7866 struct __sanitizer_protoent *p = REAL(getprotobyname)(name);
7868 write_protoent(ctx, p);
7872 INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) {
7874 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto);
7875 struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto);
7877 write_protoent(ctx, p);
7880 #define INIT_PROTOENT \
7881 COMMON_INTERCEPT_FUNCTION(getprotoent); \
7882 COMMON_INTERCEPT_FUNCTION(getprotobyname); \
7883 COMMON_INTERCEPT_FUNCTION(getprotobynumber)
7885 #define INIT_PROTOENT
7888 #if SANITIZER_INTERCEPT_PROTOENT_R
7889 INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf,
7890 char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) {
7892 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen,
7894 int res = REAL(getprotoent_r)(result_buf, buf, buflen, result);
7896 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7897 if (!res && *result)
7898 write_protoent(ctx, *result);
7902 INTERCEPTOR(int, getprotobyname_r, const char *name,
7903 struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen,
7904 struct __sanitizer_protoent **result) {
7906 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf,
7909 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7910 int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result);
7912 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7913 if (!res && *result)
7914 write_protoent(ctx, *result);
7918 INTERCEPTOR(int, getprotobynumber_r, int num,
7919 struct __sanitizer_protoent *result_buf, char *buf,
7920 SIZE_T buflen, struct __sanitizer_protoent **result) {
7922 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf,
7924 int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result);
7926 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result);
7927 if (!res && *result)
7928 write_protoent(ctx, *result);
7932 #define INIT_PROTOENT_R \
7933 COMMON_INTERCEPT_FUNCTION(getprotoent_r); \
7934 COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \
7935 COMMON_INTERCEPT_FUNCTION(getprotobynumber_r);
7937 #define INIT_PROTOENT_R
7940 #if SANITIZER_INTERCEPT_NETENT
7941 INTERCEPTOR(struct __sanitizer_netent *, getnetent) {
7943 COMMON_INTERCEPTOR_ENTER(ctx, getnetent);
7944 struct __sanitizer_netent *n = REAL(getnetent)();
7946 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7948 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7950 SIZE_T nn_size = 1; // One handles the trailing \0
7952 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7953 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7956 nn_size * sizeof(char **));
7961 INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) {
7963 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name);
7965 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
7966 struct __sanitizer_netent *n = REAL(getnetbyname)(name);
7968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7970 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7972 SIZE_T nn_size = 1; // One handles the trailing \0
7974 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7975 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7977 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7978 nn_size * sizeof(char **));
7983 INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) {
7985 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type);
7986 struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type);
7988 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n));
7990 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, internal_strlen(n->n_name) + 1);
7992 SIZE_T nn_size = 1; // One handles the trailing \0
7994 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size)
7995 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, internal_strlen(*nn) + 1);
7997 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases,
7998 nn_size * sizeof(char **));
8002 #define INIT_NETENT \
8003 COMMON_INTERCEPT_FUNCTION(getnetent); \
8004 COMMON_INTERCEPT_FUNCTION(getnetbyname); \
8005 COMMON_INTERCEPT_FUNCTION(getnetbyaddr)
8010 #if SANITIZER_INTERCEPT_GETMNTINFO
8011 INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) {
8013 COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags);
8014 int cnt = REAL(getmntinfo)(mntbufp, flags);
8015 if (cnt > 0 && mntbufp) {
8016 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *));
8018 #if SANITIZER_NETBSD
8019 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz);
8021 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz);
8026 #define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo)
8028 #define INIT_GETMNTINFO
8031 #if SANITIZER_INTERCEPT_MI_VECTOR_HASH
8032 INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed,
8035 COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes);
8037 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len);
8038 REAL(mi_vector_hash)(key, len, seed, hashes);
8040 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3);
8042 #define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash)
8044 #define INIT_MI_VECTOR_HASH
8047 #if SANITIZER_INTERCEPT_SETVBUF
8048 INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode,
8051 COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size);
8052 int ret = REAL(setvbuf)(stream, buf, mode, size);
8054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
8056 unpoison_file(stream);
8060 INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) {
8062 COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf);
8063 REAL(setbuf)(stream, buf);
8065 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz);
8068 unpoison_file(stream);
8071 INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, SIZE_T size) {
8073 COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, size);
8074 REAL(setbuffer)(stream, buf, size);
8076 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size);
8079 unpoison_file(stream);
8082 INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) {
8084 COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream);
8085 REAL(setlinebuf)(stream);
8087 unpoison_file(stream);
8089 #define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \
8090 COMMON_INTERCEPT_FUNCTION(setbuf); \
8091 COMMON_INTERCEPT_FUNCTION(setbuffer); \
8092 COMMON_INTERCEPT_FUNCTION(setlinebuf)
8094 #define INIT_SETVBUF
8097 #if SANITIZER_INTERCEPT_GETVFSSTAT
8098 INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) {
8100 COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags);
8101 int ret = REAL(getvfsstat)(buf, bufsize, flags);
8103 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz);
8106 #define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat)
8108 #define INIT_GETVFSSTAT
8111 #if SANITIZER_INTERCEPT_REGEX
8112 INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) {
8114 COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags);
8116 COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, internal_strlen(pattern) + 1);
8117 int res = REAL(regcomp)(preg, pattern, cflags);
8119 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz);
8122 INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch,
8123 struct __sanitizer_regmatch *pmatch[], int eflags) {
8125 COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags);
8127 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
8129 COMMON_INTERCEPTOR_READ_RANGE(ctx, string, internal_strlen(string) + 1);
8130 int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags);
8132 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz);
8135 INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf,
8136 SIZE_T errbuf_size) {
8138 COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size);
8140 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
8141 SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size);
8143 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, internal_strlen(errbuf) + 1);
8146 INTERCEPTOR(void, regfree, const void *preg) {
8148 COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg);
8150 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
8151 REAL(regfree)(preg);
8153 #define INIT_REGEX \
8154 COMMON_INTERCEPT_FUNCTION(regcomp); \
8155 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4"); \
8156 COMMON_INTERCEPT_FUNCTION(regerror); \
8157 COMMON_INTERCEPT_FUNCTION(regfree);
8162 #if SANITIZER_INTERCEPT_REGEXSUB
8163 INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
8164 const struct __sanitizer_regmatch *rm, const char *str) {
8166 COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str);
8168 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
8169 // The implementation demands and hardcodes 10 elements
8171 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
8173 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, internal_strlen(str) + 1);
8174 SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str);
8176 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
8179 INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
8180 const struct __sanitizer_regmatch *rm, const char *sstr) {
8182 COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr);
8184 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, internal_strlen(sub) + 1);
8185 // Hardcode 10 elements as this is hardcoded size
8187 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz);
8189 COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, internal_strlen(sstr) + 1);
8190 SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr);
8191 if (res > 0 && buf) {
8192 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *));
8193 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, internal_strlen(*buf) + 1);
8198 #define INIT_REGEXSUB \
8199 COMMON_INTERCEPT_FUNCTION(regnsub); \
8200 COMMON_INTERCEPT_FUNCTION(regasub);
8202 #define INIT_REGEXSUB
8205 #if SANITIZER_INTERCEPT_FTS
8206 INTERCEPTOR(void *, fts_open, char *const *path_argv, int options,
8207 int (*compar)(void **, void **)) {
8209 COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar);
8211 for (char *const *pa = path_argv; ; ++pa) {
8212 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
8215 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
8218 // TODO(kamil): handle compar callback
8219 void *fts = REAL(fts_open)(path_argv, options, compar);
8221 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz);
8225 INTERCEPTOR(void *, fts_read, void *ftsp) {
8227 COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp);
8229 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8230 void *ftsent = REAL(fts_read)(ftsp);
8232 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
8236 INTERCEPTOR(void *, fts_children, void *ftsp, int options) {
8238 COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options);
8240 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8241 void *ftsent = REAL(fts_children)(ftsp, options);
8243 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz);
8247 INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) {
8249 COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options);
8251 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8253 COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz);
8254 return REAL(fts_set)(ftsp, f, options);
8257 INTERCEPTOR(int, fts_close, void *ftsp) {
8259 COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp);
8261 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz);
8262 return REAL(fts_close)(ftsp);
8265 COMMON_INTERCEPT_FUNCTION(fts_open); \
8266 COMMON_INTERCEPT_FUNCTION(fts_read); \
8267 COMMON_INTERCEPT_FUNCTION(fts_children); \
8268 COMMON_INTERCEPT_FUNCTION(fts_set); \
8269 COMMON_INTERCEPT_FUNCTION(fts_close);
8274 #if SANITIZER_INTERCEPT_SYSCTL
8275 INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
8276 SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
8278 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
8279 return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
8280 COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
8283 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name));
8285 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8287 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
8288 int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen);
8291 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
8299 INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
8300 void *newp, SIZE_T newlen) {
8302 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
8303 return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
8304 COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
8307 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8309 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8311 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen);
8312 int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen);
8315 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp));
8317 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp);
8323 INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name,
8326 COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp);
8328 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8330 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
8331 int res = REAL(sysctlnametomib)(sname, name, namelenp);
8334 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
8336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
8342 #define INIT_SYSCTL \
8343 COMMON_INTERCEPT_FUNCTION(sysctl); \
8344 COMMON_INTERCEPT_FUNCTION(sysctlbyname); \
8345 COMMON_INTERCEPT_FUNCTION(sysctlnametomib);
8350 #if SANITIZER_INTERCEPT_ASYSCTL
8351 INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) {
8353 COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len);
8355 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen);
8356 void *res = REAL(asysctl)(name, namelen, len);
8358 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8359 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
8364 INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) {
8366 COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len);
8368 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8369 void *res = REAL(asysctlbyname)(sname, len);
8371 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8372 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len);
8376 #define INIT_ASYSCTL \
8377 COMMON_INTERCEPT_FUNCTION(asysctl); \
8378 COMMON_INTERCEPT_FUNCTION(asysctlbyname);
8380 #define INIT_ASYSCTL
8383 #if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO
8384 INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name,
8385 unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode,
8388 COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname,
8391 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, internal_strlen(sname) + 1);
8393 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp));
8395 COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz));
8396 // Skip rnode, it's rarely used and not trivial to sanitize
8397 // It's also used mostly internally
8398 int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v);
8401 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp));
8403 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name));
8406 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz));
8408 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz);
8413 #define INIT_SYSCTLGETMIBINFO \
8414 COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo);
8416 #define INIT_SYSCTLGETMIBINFO
8419 #if SANITIZER_INTERCEPT_NL_LANGINFO
8420 INTERCEPTOR(char *, nl_langinfo, long item) {
8422 COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item);
8423 char *ret = REAL(nl_langinfo)(item);
8425 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
8428 #define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo)
8430 #define INIT_NL_LANGINFO
8433 #if SANITIZER_INTERCEPT_MODCTL
8434 INTERCEPTOR(int, modctl, int operation, void *argp) {
8437 COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp);
8439 if (operation == modctl_load) {
8441 __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp;
8442 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml));
8443 if (ml->ml_filename)
8444 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename,
8445 internal_strlen(ml->ml_filename) + 1);
8447 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen);
8449 ret = REAL(modctl)(operation, argp);
8450 } else if (operation == modctl_unload) {
8452 const char *name = (const char *)argp;
8453 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, internal_strlen(name) + 1);
8455 ret = REAL(modctl)(operation, argp);
8456 } else if (operation == modctl_stat) {
8458 struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp;
8460 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov));
8461 iov_len = iov->iov_len;
8463 ret = REAL(modctl)(operation, argp);
8465 COMMON_INTERCEPTOR_WRITE_RANGE(
8466 ctx, iov->iov_base, Min(iov_len, iov->iov_len));
8467 } else if (operation == modctl_exists) {
8468 ret = REAL(modctl)(operation, argp);
8470 ret = REAL(modctl)(operation, argp);
8475 #define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl)
8480 #if SANITIZER_INTERCEPT_STRTONUM
8481 INTERCEPTOR(long long, strtonum, const char *nptr, long long minval,
8482 long long maxval, const char **errstr) {
8484 COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr);
8486 // TODO(kamil): Implement strtoll as a common inteceptor
8488 long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10);
8489 StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10);
8491 ret = REAL(strtonum)(nptr, minval, maxval, errstr);
8493 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *));
8495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, internal_strlen(*errstr) + 1);
8499 #define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum)
8501 #define INIT_STRTONUM
8504 #if SANITIZER_INTERCEPT_FPARSELN
8505 INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len,
8506 SIZE_T *lineno, const char delim[3], int flags) {
8508 COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags);
8510 COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno));
8512 COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3);
8513 char *ret = REAL(fparseln)(stream, len, lineno, delim, flags);
8515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, internal_strlen(ret) + 1);
8517 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len));
8519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno));
8523 #define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln)
8525 #define INIT_FPARSELN
8528 #if SANITIZER_INTERCEPT_STATVFS1
8529 INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) {
8531 COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags);
8532 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
8533 int res = REAL(statvfs1)(path, buf, flags);
8534 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
8537 INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) {
8539 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags);
8540 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
8541 int res = REAL(fstatvfs1)(fd, buf, flags);
8543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz);
8545 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
8549 #define INIT_STATVFS1 \
8550 COMMON_INTERCEPT_FUNCTION(statvfs1); \
8551 COMMON_INTERCEPT_FUNCTION(fstatvfs1);
8553 #define INIT_STATVFS1
8556 #if SANITIZER_INTERCEPT_STRTOI
8557 INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base,
8558 INTMAX_T low, INTMAX_T high, int *rstatus) {
8560 COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus);
8562 INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus);
8563 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
8565 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
8569 INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
8570 UINTMAX_T low, UINTMAX_T high, int *rstatus) {
8572 COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus);
8574 UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus);
8575 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
8577 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus));
8580 #define INIT_STRTOI \
8581 COMMON_INTERCEPT_FUNCTION(strtoi); \
8582 COMMON_INTERCEPT_FUNCTION(strtou)
8587 #if SANITIZER_INTERCEPT_CAPSICUM
8588 #define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \
8591 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
8593 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
8594 __sanitizer_cap_rights_t *ret = \
8595 REAL(cap_rights_init)(rights, ##__VA_ARGS__); \
8597 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
8601 #define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \
8604 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
8606 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
8607 __sanitizer_cap_rights_t *ret = \
8608 REAL(cap_rights_set)(rights, ##__VA_ARGS__); \
8610 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
8614 #define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \
8617 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
8619 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
8620 __sanitizer_cap_rights_t *ret = \
8621 REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \
8623 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
8627 #define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \
8630 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
8632 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
8633 return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \
8636 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
8637 __sanitizer_cap_rights_t *rights) {
8638 CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
8641 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
8642 __sanitizer_cap_rights_t *rights) {
8643 CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
8646 INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
8647 __sanitizer_cap_rights_t *rights) {
8648 CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
8651 INTERCEPTOR(bool, cap_rights_is_set,
8652 __sanitizer_cap_rights_t *rights) {
8653 CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
8656 INTERCEPTOR(int, cap_rights_limit, int fd,
8657 const __sanitizer_cap_rights_t *rights) {
8659 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights);
8661 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8663 return REAL(cap_rights_limit)(fd, rights);
8666 INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) {
8668 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights);
8669 int ret = REAL(cap_rights_get)(fd, rights);
8671 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights));
8676 INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) {
8678 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights);
8680 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights));
8682 return REAL(cap_rights_is_valid(rights));
8685 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge,
8686 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8688 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src);
8690 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8692 __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src);
8694 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8699 INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove,
8700 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) {
8702 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src);
8704 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src));
8706 __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src);
8708 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst));
8713 INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big,
8714 const __sanitizer_cap_rights *little) {
8716 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little);
8718 COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little));
8720 COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big));
8722 return REAL(cap_rights_contains)(big, little);
8725 INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) {
8727 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds);
8729 COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds);
8731 return REAL(cap_ioctls_limit)(fd, cmds, ncmds);
8734 INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
8736 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds);
8737 int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds);
8739 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds);
8743 #define INIT_CAPSICUM \
8744 COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
8745 COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
8746 COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
8747 COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
8748 COMMON_INTERCEPT_FUNCTION(cap_rights_get); \
8749 COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
8750 COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
8751 COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \
8752 COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \
8753 COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \
8754 COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \
8755 COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit)
8757 #define INIT_CAPSICUM
8760 #if SANITIZER_INTERCEPT_SHA1
8761 INTERCEPTOR(void, SHA1Init, void *context) {
8763 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context);
8764 REAL(SHA1Init)(context);
8766 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8768 INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) {
8770 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len);
8771 if (data && len > 0)
8772 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8774 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8775 REAL(SHA1Update)(context, data, len);
8777 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz);
8779 INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) {
8781 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context);
8783 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8784 REAL(SHA1Final)(digest, context);
8786 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8788 INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) {
8790 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer);
8792 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8794 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64);
8795 REAL(SHA1Transform)(state, buffer);
8797 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8799 INTERCEPTOR(char *, SHA1End, void *context, char *buf) {
8801 COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf);
8803 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz);
8804 char *ret = REAL(SHA1End)(context, buf);
8806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8809 INTERCEPTOR(char *, SHA1File, char *filename, char *buf) {
8811 COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf);
8813 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8814 char *ret = REAL(SHA1File)(filename, buf);
8816 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8819 INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset,
8822 COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length);
8824 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8825 char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length);
8827 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8830 INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) {
8832 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf);
8834 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8835 char *ret = REAL(SHA1Data)(data, len, buf);
8837 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length);
8841 COMMON_INTERCEPT_FUNCTION(SHA1Init); \
8842 COMMON_INTERCEPT_FUNCTION(SHA1Update); \
8843 COMMON_INTERCEPT_FUNCTION(SHA1Final); \
8844 COMMON_INTERCEPT_FUNCTION(SHA1Transform); \
8845 COMMON_INTERCEPT_FUNCTION(SHA1End); \
8846 COMMON_INTERCEPT_FUNCTION(SHA1File); \
8847 COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \
8848 COMMON_INTERCEPT_FUNCTION(SHA1Data)
8853 #if SANITIZER_INTERCEPT_MD4
8854 INTERCEPTOR(void, MD4Init, void *context) {
8856 COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context);
8857 REAL(MD4Init)(context);
8859 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8862 INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data,
8865 COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len);
8866 if (data && len > 0)
8867 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8869 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8870 REAL(MD4Update)(context, data, len);
8872 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz);
8875 INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) {
8877 COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context);
8879 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8880 REAL(MD4Final)(digest, context);
8882 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
8885 INTERCEPTOR(char *, MD4End, void *context, char *buf) {
8887 COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf);
8889 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz);
8890 char *ret = REAL(MD4End)(context, buf);
8892 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8896 INTERCEPTOR(char *, MD4File, const char *filename, char *buf) {
8898 COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf);
8900 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8901 char *ret = REAL(MD4File)(filename, buf);
8903 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8907 INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len,
8910 COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf);
8911 if (data && len > 0)
8912 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8913 char *ret = REAL(MD4Data)(data, len, buf);
8915 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length);
8920 COMMON_INTERCEPT_FUNCTION(MD4Init); \
8921 COMMON_INTERCEPT_FUNCTION(MD4Update); \
8922 COMMON_INTERCEPT_FUNCTION(MD4Final); \
8923 COMMON_INTERCEPT_FUNCTION(MD4End); \
8924 COMMON_INTERCEPT_FUNCTION(MD4File); \
8925 COMMON_INTERCEPT_FUNCTION(MD4Data)
8930 #if SANITIZER_INTERCEPT_RMD160
8931 INTERCEPTOR(void, RMD160Init, void *context) {
8933 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context);
8934 REAL(RMD160Init)(context);
8936 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8938 INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) {
8940 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len);
8941 if (data && len > 0)
8942 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
8944 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8945 REAL(RMD160Update)(context, data, len);
8947 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz);
8949 INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) {
8951 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context);
8953 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8954 REAL(RMD160Final)(digest, context);
8956 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20);
8958 INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) {
8960 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer);
8962 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5);
8964 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16);
8965 REAL(RMD160Transform)(state, buffer);
8967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5);
8969 INTERCEPTOR(char *, RMD160End, void *context, char *buf) {
8971 COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf);
8973 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz);
8974 char *ret = REAL(RMD160End)(context, buf);
8976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8979 INTERCEPTOR(char *, RMD160File, char *filename, char *buf) {
8981 COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf);
8983 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8984 char *ret = REAL(RMD160File)(filename, buf);
8986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
8989 INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset,
8992 COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length);
8994 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
8995 char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length);
8997 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
9000 INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) {
9002 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf);
9003 if (data && len > 0)
9004 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9005 char *ret = REAL(RMD160Data)(data, len, buf);
9007 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length);
9010 #define INIT_RMD160 \
9011 COMMON_INTERCEPT_FUNCTION(RMD160Init); \
9012 COMMON_INTERCEPT_FUNCTION(RMD160Update); \
9013 COMMON_INTERCEPT_FUNCTION(RMD160Final); \
9014 COMMON_INTERCEPT_FUNCTION(RMD160Transform); \
9015 COMMON_INTERCEPT_FUNCTION(RMD160End); \
9016 COMMON_INTERCEPT_FUNCTION(RMD160File); \
9017 COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \
9018 COMMON_INTERCEPT_FUNCTION(RMD160Data)
9023 #if SANITIZER_INTERCEPT_MD5
9024 INTERCEPTOR(void, MD5Init, void *context) {
9026 COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context);
9027 REAL(MD5Init)(context);
9029 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
9032 INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data,
9035 COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len);
9036 if (data && len > 0)
9037 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9039 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
9040 REAL(MD5Update)(context, data, len);
9042 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz);
9045 INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) {
9047 COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context);
9049 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
9050 REAL(MD5Final)(digest, context);
9052 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
9055 INTERCEPTOR(char *, MD5End, void *context, char *buf) {
9057 COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf);
9059 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz);
9060 char *ret = REAL(MD5End)(context, buf);
9062 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
9066 INTERCEPTOR(char *, MD5File, const char *filename, char *buf) {
9068 COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf);
9070 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
9071 char *ret = REAL(MD5File)(filename, buf);
9073 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
9077 INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len,
9080 COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf);
9081 if (data && len > 0)
9082 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9083 char *ret = REAL(MD5Data)(data, len, buf);
9085 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length);
9090 COMMON_INTERCEPT_FUNCTION(MD5Init); \
9091 COMMON_INTERCEPT_FUNCTION(MD5Update); \
9092 COMMON_INTERCEPT_FUNCTION(MD5Final); \
9093 COMMON_INTERCEPT_FUNCTION(MD5End); \
9094 COMMON_INTERCEPT_FUNCTION(MD5File); \
9095 COMMON_INTERCEPT_FUNCTION(MD5Data)
9100 #if SANITIZER_INTERCEPT_FSEEK
9101 INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) {
9103 COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence);
9104 return REAL(fseek)(stream, offset, whence);
9106 INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) {
9108 COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence);
9109 return REAL(fseeko)(stream, offset, whence);
9111 INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) {
9113 COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream);
9114 return REAL(ftell)(stream);
9116 INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) {
9118 COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream);
9119 return REAL(ftello)(stream);
9121 INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) {
9123 COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream);
9124 return REAL(rewind)(stream);
9126 INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) {
9128 COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos);
9129 int ret = REAL(fgetpos)(stream, pos);
9131 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz);
9134 INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) {
9136 COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos);
9138 COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz);
9139 return REAL(fsetpos)(stream, pos);
9141 #define INIT_FSEEK \
9142 COMMON_INTERCEPT_FUNCTION(fseek); \
9143 COMMON_INTERCEPT_FUNCTION(fseeko); \
9144 COMMON_INTERCEPT_FUNCTION(ftell); \
9145 COMMON_INTERCEPT_FUNCTION(ftello); \
9146 COMMON_INTERCEPT_FUNCTION(rewind); \
9147 COMMON_INTERCEPT_FUNCTION(fgetpos); \
9148 COMMON_INTERCEPT_FUNCTION(fsetpos)
9153 #if SANITIZER_INTERCEPT_MD2
9154 INTERCEPTOR(void, MD2Init, void *context) {
9156 COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context);
9157 REAL(MD2Init)(context);
9159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
9162 INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data,
9165 COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len);
9166 if (data && len > 0)
9167 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9169 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
9170 REAL(MD2Update)(context, data, len);
9172 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz);
9175 INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) {
9177 COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context);
9179 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
9180 REAL(MD2Final)(digest, context);
9182 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16);
9185 INTERCEPTOR(char *, MD2End, void *context, char *buf) {
9187 COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf);
9189 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz);
9190 char *ret = REAL(MD2End)(context, buf);
9192 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
9196 INTERCEPTOR(char *, MD2File, const char *filename, char *buf) {
9198 COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf);
9200 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);
9201 char *ret = REAL(MD2File)(filename, buf);
9203 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
9207 INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
9210 COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf);
9211 if (data && len > 0)
9212 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len);
9213 char *ret = REAL(MD2Data)(data, len, buf);
9215 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length);
9220 COMMON_INTERCEPT_FUNCTION(MD2Init); \
9221 COMMON_INTERCEPT_FUNCTION(MD2Update); \
9222 COMMON_INTERCEPT_FUNCTION(MD2Final); \
9223 COMMON_INTERCEPT_FUNCTION(MD2End); \
9224 COMMON_INTERCEPT_FUNCTION(MD2File); \
9225 COMMON_INTERCEPT_FUNCTION(MD2Data)
9230 #if SANITIZER_INTERCEPT_SHA2
9231 #define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \
9232 INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \
9234 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \
9235 REAL(SHA##LEN##_Init)(context); \
9237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9239 INTERCEPTOR(void, SHA##LEN##_Update, void *context, \
9240 const u8 *data, SIZE_T len) { \
9242 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \
9243 if (data && len > 0) \
9244 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
9246 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9247 REAL(SHA##LEN##_Update)(context, data, len); \
9249 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9251 INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
9254 CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
9255 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
9257 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9258 REAL(SHA##LEN##_Final)(digest, context); \
9260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \
9261 sizeof(digest[0]) * \
9262 SHA##LEN##_digest_length); \
9264 INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \
9266 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \
9268 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
9269 char *ret = REAL(SHA##LEN##_End)(context, buf); \
9271 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9274 INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \
9276 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \
9278 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\
9279 char *ret = REAL(SHA##LEN##_File)(filename, buf); \
9281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9284 INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \
9285 OFF_T offset, OFF_T length) { \
9287 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \
9290 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, internal_strlen(filename) + 1);\
9291 char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \
9293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9296 INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \
9298 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \
9299 if (data && len > 0) \
9300 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \
9301 char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \
9303 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \
9307 SHA2_INTERCEPTORS(224, u32)
9308 SHA2_INTERCEPTORS(256, u32)
9309 SHA2_INTERCEPTORS(384, u64)
9310 SHA2_INTERCEPTORS(512, u64)
9312 #define INIT_SHA2_INTECEPTORS(LEN) \
9313 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \
9314 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \
9315 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \
9316 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \
9317 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \
9318 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \
9319 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data)
9322 INIT_SHA2_INTECEPTORS(224); \
9323 INIT_SHA2_INTECEPTORS(256); \
9324 INIT_SHA2_INTECEPTORS(384); \
9325 INIT_SHA2_INTECEPTORS(512)
9326 #undef SHA2_INTERCEPTORS
9331 #if SANITIZER_INTERCEPT_VIS
9332 INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) {
9334 COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc);
9335 char *end = REAL(vis)(dst, c, flag, nextc);
9336 // dst is NULL terminated and end points to the NULL char
9338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9341 INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) {
9343 COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc);
9344 char *end = REAL(nvis)(dst, dlen, c, flag, nextc);
9345 // nvis cannot make sure the dst is NULL terminated
9347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9350 INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) {
9352 COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag);
9354 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9355 int len = REAL(strvis)(dst, src, flag);
9357 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9360 INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) {
9362 COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag);
9364 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9365 int len = REAL(stravis)(dst, src, flag);
9367 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *));
9369 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1);
9373 INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) {
9375 COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag);
9377 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9378 int len = REAL(strnvis)(dst, dlen, src, flag);
9379 // The interface will be valid even if there is no space for NULL char
9381 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9384 INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) {
9386 COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag);
9388 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9389 int ret = REAL(strvisx)(dst, src, len, flag);
9391 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9394 INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9397 COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag);
9399 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9400 int ret = REAL(strnvisx)(dst, dlen, src, len, flag);
9401 if (dst && ret >= 0)
9402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9405 INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9406 int flag, int *cerr_ptr) {
9408 COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr);
9410 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9411 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
9412 // according to the implementation
9414 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
9415 int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr);
9416 if (dst && ret >= 0)
9417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9419 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
9422 INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc,
9423 const char *extra) {
9425 COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra);
9427 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9428 char *end = REAL(svis)(dst, c, flag, nextc, extra);
9430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1);
9433 INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc,
9434 const char *extra) {
9436 COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra);
9438 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9439 char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra);
9441 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst,
9442 Min((SIZE_T)(end - dst + 1), dlen));
9445 INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag,
9446 const char *extra) {
9448 COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra);
9450 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9452 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9453 int len = REAL(strsvis)(dst, src, flag, extra);
9455 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9458 INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag,
9459 const char *extra) {
9461 COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra);
9463 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9465 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9466 int len = REAL(strsnvis)(dst, dlen, src, flag, extra);
9467 // The interface will be valid even if there is no space for NULL char
9468 if (dst && len >= 0)
9469 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1);
9472 INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag,
9473 const char *extra) {
9475 COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra);
9477 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9479 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9480 int ret = REAL(strsvisx)(dst, src, len, flag, extra);
9482 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9485 INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len,
9486 int flag, const char *extra) {
9488 COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra);
9490 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9492 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9493 int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra);
9494 if (dst && ret >= 0)
9495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9498 INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src,
9499 SIZE_T len, int flag, const char *extra, int *cerr_ptr) {
9501 COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra,
9504 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len);
9506 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, internal_strlen(extra) + 1);
9507 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold
9508 // according to the implementation
9510 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int));
9511 int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr);
9512 if (dst && ret >= 0)
9513 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int));
9518 INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) {
9520 COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag);
9522 COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate));
9523 int ret = REAL(unvis)(cp, c, astate, flag);
9524 if (ret == unvis_valid || ret == unvis_validpush) {
9525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp));
9529 INTERCEPTOR(int, strunvis, char *dst, const char *src) {
9531 COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src);
9533 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9534 int ret = REAL(strunvis)(dst, src);
9536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9539 INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) {
9541 COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src);
9543 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9544 int ret = REAL(strnunvis)(dst, dlen, src);
9546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9549 INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) {
9551 COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag);
9553 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9554 int ret = REAL(strunvisx)(dst, src, flag);
9556 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9559 INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src,
9562 COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag);
9564 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, internal_strlen(src) + 1);
9565 int ret = REAL(strnunvisx)(dst, dlen, src, flag);
9567 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1);
9571 COMMON_INTERCEPT_FUNCTION(vis); \
9572 COMMON_INTERCEPT_FUNCTION(nvis); \
9573 COMMON_INTERCEPT_FUNCTION(strvis); \
9574 COMMON_INTERCEPT_FUNCTION(stravis); \
9575 COMMON_INTERCEPT_FUNCTION(strnvis); \
9576 COMMON_INTERCEPT_FUNCTION(strvisx); \
9577 COMMON_INTERCEPT_FUNCTION(strnvisx); \
9578 COMMON_INTERCEPT_FUNCTION(strenvisx); \
9579 COMMON_INTERCEPT_FUNCTION(svis); \
9580 COMMON_INTERCEPT_FUNCTION(snvis); \
9581 COMMON_INTERCEPT_FUNCTION(strsvis); \
9582 COMMON_INTERCEPT_FUNCTION(strsnvis); \
9583 COMMON_INTERCEPT_FUNCTION(strsvisx); \
9584 COMMON_INTERCEPT_FUNCTION(strsnvisx); \
9585 COMMON_INTERCEPT_FUNCTION(strsenvisx); \
9586 COMMON_INTERCEPT_FUNCTION(unvis); \
9587 COMMON_INTERCEPT_FUNCTION(strunvis); \
9588 COMMON_INTERCEPT_FUNCTION(strnunvis); \
9589 COMMON_INTERCEPT_FUNCTION(strunvisx); \
9590 COMMON_INTERCEPT_FUNCTION(strnunvisx)
9595 #if SANITIZER_INTERCEPT_CDB
9596 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) {
9598 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags);
9600 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
9601 struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags);
9603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9607 INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size,
9608 int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) {
9610 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap,
9613 COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size);
9614 struct __sanitizer_cdbr *cdbr =
9615 REAL(cdbr_open_mem)(base, size, flags, unmap, cookie);
9617 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr));
9621 INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) {
9623 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr);
9625 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9626 return REAL(cdbr_entries)(cdbr);
9629 INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index,
9630 const void **data, SIZE_T *datalen) {
9632 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen);
9634 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9635 int ret = REAL(cdbr_get)(cdbr, index, data, datalen);
9638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9640 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9641 if (data && datalen)
9642 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9647 INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key,
9648 SIZE_T keylen, const void **data, SIZE_T *datalen) {
9650 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen);
9652 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9654 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9655 int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen);
9658 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data));
9660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen));
9661 if (data && datalen)
9662 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen);
9667 INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) {
9669 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr);
9671 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr));
9672 REAL(cdbr_close)(cdbr);
9675 INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) {
9677 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open);
9678 struct __sanitizer_cdbw *ret = REAL(cdbw_open)();
9680 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret));
9684 INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key,
9685 SIZE_T keylen, const void *data, SIZE_T datalen) {
9687 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen);
9689 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9690 if (data && datalen)
9691 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9693 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9694 int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen);
9696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9700 INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data,
9701 SIZE_T datalen, u32 *index) {
9703 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index);
9705 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9706 if (data && datalen)
9707 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen);
9708 int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index);
9711 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index));
9713 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9718 INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key,
9719 SIZE_T keylen, u32 index) {
9721 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index);
9723 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9725 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen);
9726 int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index);
9728 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9732 INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output,
9733 const char descr[16], u32 (*seedgen)(void)) {
9735 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen);
9736 COMMON_INTERCEPTOR_FD_ACCESS(ctx, output);
9738 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9740 COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16));
9742 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen));
9743 int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen);
9746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw));
9748 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output);
9753 INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
9755 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw);
9757 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw));
9758 REAL(cdbw_close)(cdbw);
9762 COMMON_INTERCEPT_FUNCTION(cdbr_open); \
9763 COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \
9764 COMMON_INTERCEPT_FUNCTION(cdbr_entries); \
9765 COMMON_INTERCEPT_FUNCTION(cdbr_get); \
9766 COMMON_INTERCEPT_FUNCTION(cdbr_find); \
9767 COMMON_INTERCEPT_FUNCTION(cdbr_close); \
9768 COMMON_INTERCEPT_FUNCTION(cdbw_open); \
9769 COMMON_INTERCEPT_FUNCTION(cdbw_put); \
9770 COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \
9771 COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \
9772 COMMON_INTERCEPT_FUNCTION(cdbw_output); \
9773 COMMON_INTERCEPT_FUNCTION(cdbw_close)
9778 #if SANITIZER_INTERCEPT_GETFSENT
9779 INTERCEPTOR(void *, getfsent) {
9781 COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
9782 void *ret = REAL(getfsent)();
9784 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9788 INTERCEPTOR(void *, getfsspec, const char *spec) {
9790 COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
9792 COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, internal_strlen(spec) + 1);
9793 void *ret = REAL(getfsspec)(spec);
9795 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9799 INTERCEPTOR(void *, getfsfile, const char *file) {
9801 COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
9803 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, internal_strlen(file) + 1);
9804 void *ret = REAL(getfsfile)(file);
9806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
9810 #define INIT_GETFSENT \
9811 COMMON_INTERCEPT_FUNCTION(getfsent); \
9812 COMMON_INTERCEPT_FUNCTION(getfsspec); \
9813 COMMON_INTERCEPT_FUNCTION(getfsfile);
9815 #define INIT_GETFSENT
9818 #if SANITIZER_INTERCEPT_ARC4RANDOM
9819 INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
9821 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
9822 REAL(arc4random_buf)(buf, len);
9824 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
9827 INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
9829 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
9831 COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
9832 REAL(arc4random_addrandom)(dat, datlen);
9835 #define INIT_ARC4RANDOM \
9836 COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
9837 COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
9839 #define INIT_ARC4RANDOM
9842 #if SANITIZER_INTERCEPT_POPEN
9843 INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
9845 COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
9847 COMMON_INTERCEPTOR_READ_RANGE(ctx, command, internal_strlen(command) + 1);
9849 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
9850 __sanitizer_FILE *res = REAL(popen)(command, type);
9851 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9852 if (res) unpoison_file(res);
9855 #define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
9860 #if SANITIZER_INTERCEPT_POPENVE
9861 INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
9862 char *const *argv, char *const *envp, const char *type) {
9864 COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
9866 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, internal_strlen(path) + 1);
9868 for (char *const *pa = argv; ; ++pa) {
9869 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9872 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
9876 for (char *const *pa = envp; ; ++pa) {
9877 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
9880 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, internal_strlen(*pa) + 1);
9884 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, internal_strlen(type) + 1);
9885 __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
9886 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
9887 if (res) unpoison_file(res);
9890 #define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
9892 #define INIT_POPENVE
9895 #if SANITIZER_INTERCEPT_PCLOSE
9896 INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
9898 COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
9899 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
9900 const FileMetadata *m = GetInterceptorMetadata(fp);
9901 int res = REAL(pclose)(fp);
9903 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
9904 DeleteInterceptorMetadata(fp);
9908 #define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
9913 #if SANITIZER_INTERCEPT_FUNOPEN
9914 typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
9915 typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
9916 typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
9917 typedef int (*funopen_closefn)(void *cookie);
9919 struct WrappedFunopenCookie {
9921 funopen_readfn real_read;
9922 funopen_writefn real_write;
9923 funopen_seekfn real_seek;
9924 funopen_closefn real_close;
9927 static int wrapped_funopen_read(void *cookie, char *buf, int len) {
9928 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9929 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9930 funopen_readfn real_read = wrapped_cookie->real_read;
9931 return real_read(wrapped_cookie->real_cookie, buf, len);
9934 static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
9935 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9936 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9937 funopen_writefn real_write = wrapped_cookie->real_write;
9938 return real_write(wrapped_cookie->real_cookie, buf, len);
9941 static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
9942 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
9943 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9944 funopen_seekfn real_seek = wrapped_cookie->real_seek;
9945 return real_seek(wrapped_cookie->real_cookie, offset, whence);
9948 static int wrapped_funopen_close(void *cookie) {
9949 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
9950 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
9951 funopen_closefn real_close = wrapped_cookie->real_close;
9952 int res = real_close(wrapped_cookie->real_cookie);
9953 InternalFree(wrapped_cookie);
9957 INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
9958 funopen_writefn writefn, funopen_seekfn seekfn,
9959 funopen_closefn closefn) {
9961 COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
9964 WrappedFunopenCookie *wrapped_cookie =
9965 (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
9966 wrapped_cookie->real_cookie = cookie;
9967 wrapped_cookie->real_read = readfn;
9968 wrapped_cookie->real_write = writefn;
9969 wrapped_cookie->real_seek = seekfn;
9970 wrapped_cookie->real_close = closefn;
9972 __sanitizer_FILE *res =
9973 REAL(funopen)(wrapped_cookie,
9974 readfn ? wrapped_funopen_read : nullptr,
9975 writefn ? wrapped_funopen_write : nullptr,
9976 seekfn ? wrapped_funopen_seek : nullptr,
9977 closefn ? wrapped_funopen_close : nullptr);
9982 #define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
9984 #define INIT_FUNOPEN
9987 #if SANITIZER_INTERCEPT_FUNOPEN2
9988 typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
9989 typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
9990 typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
9991 typedef int (*funopen2_flushfn)(void *cookie);
9992 typedef int (*funopen2_closefn)(void *cookie);
9994 struct WrappedFunopen2Cookie {
9996 funopen2_readfn real_read;
9997 funopen2_writefn real_write;
9998 funopen2_seekfn real_seek;
9999 funopen2_flushfn real_flush;
10000 funopen2_closefn real_close;
10003 static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
10004 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10005 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
10006 funopen2_readfn real_read = wrapped_cookie->real_read;
10007 return real_read(wrapped_cookie->real_cookie, buf, len);
10010 static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
10012 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10013 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
10014 funopen2_writefn real_write = wrapped_cookie->real_write;
10015 return real_write(wrapped_cookie->real_cookie, buf, len);
10018 static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
10019 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10020 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
10021 funopen2_seekfn real_seek = wrapped_cookie->real_seek;
10022 return real_seek(wrapped_cookie->real_cookie, offset, whence);
10025 static int wrapped_funopen2_flush(void *cookie) {
10026 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
10027 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
10028 funopen2_flushfn real_flush = wrapped_cookie->real_flush;
10029 return real_flush(wrapped_cookie->real_cookie);
10032 static int wrapped_funopen2_close(void *cookie) {
10033 COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
10034 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
10035 funopen2_closefn real_close = wrapped_cookie->real_close;
10036 int res = real_close(wrapped_cookie->real_cookie);
10037 InternalFree(wrapped_cookie);
10041 INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
10042 funopen2_writefn writefn, funopen2_seekfn seekfn,
10043 funopen2_flushfn flushfn, funopen2_closefn closefn) {
10045 COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
10048 WrappedFunopen2Cookie *wrapped_cookie =
10049 (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
10050 wrapped_cookie->real_cookie = cookie;
10051 wrapped_cookie->real_read = readfn;
10052 wrapped_cookie->real_write = writefn;
10053 wrapped_cookie->real_seek = seekfn;
10054 wrapped_cookie->real_flush = flushfn;
10055 wrapped_cookie->real_close = closefn;
10057 __sanitizer_FILE *res =
10058 REAL(funopen2)(wrapped_cookie,
10059 readfn ? wrapped_funopen2_read : nullptr,
10060 writefn ? wrapped_funopen2_write : nullptr,
10061 seekfn ? wrapped_funopen2_seek : nullptr,
10062 flushfn ? wrapped_funopen2_flush : nullptr,
10063 closefn ? wrapped_funopen2_close : nullptr);
10065 unpoison_file(res);
10068 #define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
10070 #define INIT_FUNOPEN2
10073 #if SANITIZER_INTERCEPT_FDEVNAME
10074 INTERCEPTOR(char *, fdevname, int fd) {
10076 COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
10077 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10078 char *name = REAL(fdevname)(fd);
10080 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strlen(name) + 1);
10082 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
10087 INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) {
10089 COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
10090 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
10091 char *name = REAL(fdevname_r)(fd, buf, len);
10092 if (name && buf && len > 0) {
10093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, internal_strlen(buf) + 1);
10095 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
10100 #define INIT_FDEVNAME \
10101 COMMON_INTERCEPT_FUNCTION(fdevname); \
10102 COMMON_INTERCEPT_FUNCTION(fdevname_r);
10104 #define INIT_FDEVNAME
10107 #if SANITIZER_INTERCEPT_GETUSERSHELL
10108 INTERCEPTOR(char *, getusershell) {
10110 COMMON_INTERCEPTOR_ENTER(ctx, getusershell);
10111 char *res = REAL(getusershell)();
10113 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
10117 #define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
10119 #define INIT_GETUSERSHELL
10122 #if SANITIZER_INTERCEPT_SL_INIT
10123 INTERCEPTOR(void *, sl_init) {
10125 COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
10126 void *res = REAL(sl_init)();
10128 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
10132 INTERCEPTOR(int, sl_add, void *sl, char *item) {
10134 COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
10136 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
10138 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
10139 int res = REAL(sl_add)(sl, item);
10141 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
10145 INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
10147 COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
10149 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
10151 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, internal_strlen(item) + 1);
10152 char *res = REAL(sl_find)(sl, item);
10154 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, internal_strlen(res) + 1);
10158 INTERCEPTOR(void, sl_free, void *sl, int freeall) {
10160 COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
10162 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
10163 REAL(sl_free)(sl, freeall);
10166 #define INIT_SL_INIT \
10167 COMMON_INTERCEPT_FUNCTION(sl_init); \
10168 COMMON_INTERCEPT_FUNCTION(sl_add); \
10169 COMMON_INTERCEPT_FUNCTION(sl_find); \
10170 COMMON_INTERCEPT_FUNCTION(sl_free);
10172 #define INIT_SL_INIT
10175 #if SANITIZER_INTERCEPT_GETRANDOM
10176 INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) {
10178 COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags);
10179 SSIZE_T n = REAL(getrandom)(buf, buflen, flags);
10181 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n);
10185 #define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom)
10187 #define INIT_GETRANDOM
10190 #if SANITIZER_INTERCEPT_CRYPT
10191 INTERCEPTOR(char *, crypt, char *key, char *salt) {
10193 COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt);
10194 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
10195 COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
10196 char *res = REAL(crypt)(key, salt);
10197 if (res != nullptr)
10198 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
10201 #define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt);
10206 #if SANITIZER_INTERCEPT_CRYPT_R
10207 INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) {
10209 COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data);
10210 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1);
10211 COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1);
10212 char *res = REAL(crypt_r)(key, salt, data);
10213 if (res != nullptr) {
10214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data,
10215 __sanitizer::struct_crypt_data_sz);
10216 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1);
10220 #define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r);
10222 #define INIT_CRYPT_R
10225 #if SANITIZER_INTERCEPT_GETENTROPY
10226 INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) {
10228 COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen);
10229 int r = REAL(getentropy)(buf, buflen);
10231 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen);
10235 #define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy)
10237 #define INIT_GETENTROPY
10240 #if SANITIZER_INTERCEPT_QSORT_R
10241 typedef int (*qsort_r_compar_f)(const void *, const void *, void *);
10242 struct qsort_r_compar_params {
10244 qsort_r_compar_f compar;
10247 static int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) {
10248 qsort_r_compar_params *params = (qsort_r_compar_params *)arg;
10249 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10250 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, params->size);
10251 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, params->size);
10252 return params->compar(a, b, params->arg);
10255 INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size,
10256 qsort_r_compar_f compar, void *arg) {
10258 COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg);
10259 // Run the comparator over all array elements to detect any memory issues.
10261 for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10262 void *p = (void *)((char *)base + i * size);
10263 void *q = (void *)((char *)base + (i + 1) * size);
10264 COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
10268 qsort_r_compar_params params = {size, compar, arg};
10269 REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, ¶ms);
10270 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10272 # define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r)
10274 # define INIT_QSORT_R
10277 #if SANITIZER_INTERCEPT_QSORT && SANITIZER_INTERCEPT_QSORT_R
10278 INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10279 qsort_r_compar_f compar) {
10281 COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10282 WRAP(qsort_r)(base, nmemb, size, compar, nullptr);
10284 # define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10285 #elif SANITIZER_INTERCEPT_QSORT && !SANITIZER_INTERCEPT_QSORT_R
10286 // Glibc qsort uses a temporary buffer allocated either on stack or on heap.
10287 // Poisoned memory from there may get copied into the comparator arguments,
10288 // where it needs to be dealt with. But even that is not enough - the results of
10289 // the sort may be copied into the input/output array based on the results of
10290 // the comparator calls, but directly from the temp memory, bypassing the
10291 // unpoisoning done in wrapped_qsort_compar. We deal with this by, again,
10292 // unpoisoning the entire array after the sort is done.
10294 // We can not check that the entire array is initialized at the beginning. IMHO,
10295 // it's fine for parts of the sorted objects to contain uninitialized memory,
10296 // ex. as padding in structs.
10297 typedef int (*qsort_compar_f)(const void *, const void *);
10298 static THREADLOCAL qsort_compar_f qsort_compar;
10299 static THREADLOCAL SIZE_T qsort_size;
10300 static int wrapped_qsort_compar(const void *a, const void *b) {
10301 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10302 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size);
10303 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size);
10304 return qsort_compar(a, b);
10307 INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size,
10308 qsort_compar_f compar) {
10310 COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar);
10311 // Run the comparator over all array elements to detect any memory issues.
10313 for (SIZE_T i = 0; i < nmemb - 1; ++i) {
10314 void *p = (void *)((char *)base + i * size);
10315 void *q = (void *)((char *)base + (i + 1) * size);
10316 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10320 qsort_compar_f old_compar = qsort_compar;
10321 SIZE_T old_size = qsort_size;
10322 // Handle qsort() implementations that recurse using an
10323 // interposable function call:
10324 bool already_wrapped = compar == wrapped_qsort_compar;
10325 if (already_wrapped) {
10326 // This case should only happen if the qsort() implementation calls itself
10327 // using a preemptible function call (e.g. the FreeBSD libc version).
10328 // Check that the size and comparator arguments are as expected.
10329 CHECK_NE(compar, qsort_compar);
10330 CHECK_EQ(qsort_size, size);
10332 qsort_compar = compar;
10335 REAL(qsort)(base, nmemb, size, wrapped_qsort_compar);
10336 if (!already_wrapped) {
10337 qsort_compar = old_compar;
10338 qsort_size = old_size;
10340 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size);
10342 # define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort)
10344 # define INIT_QSORT
10347 #if SANITIZER_INTERCEPT_BSEARCH
10348 typedef int (*bsearch_compar_f)(const void *, const void *);
10349 struct bsearch_compar_params {
10351 bsearch_compar_f compar;
10354 static int wrapped_bsearch_compar(const void *key, const void *b) {
10355 const bsearch_compar_params *params = (const bsearch_compar_params *)key;
10356 COMMON_INTERCEPTOR_UNPOISON_PARAM(2);
10357 return params->compar(params->key, b);
10360 INTERCEPTOR(void *, bsearch, const void *key, const void *base, SIZE_T nmemb,
10361 SIZE_T size, bsearch_compar_f compar) {
10363 COMMON_INTERCEPTOR_ENTER(ctx, bsearch, key, base, nmemb, size, compar);
10364 bsearch_compar_params params = {key, compar};
10365 return REAL(bsearch)(¶ms, base, nmemb, size, wrapped_bsearch_compar);
10367 # define INIT_BSEARCH COMMON_INTERCEPT_FUNCTION(bsearch)
10369 # define INIT_BSEARCH
10372 #if SANITIZER_INTERCEPT_SIGALTSTACK
10373 INTERCEPTOR(int, sigaltstack, void *ss, void *oss) {
10375 COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss);
10376 int r = REAL(sigaltstack)(ss, oss);
10377 if (r == 0 && oss != nullptr) {
10378 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz);
10382 #define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack)
10384 #define INIT_SIGALTSTACK
10387 #if SANITIZER_INTERCEPT_PROCCTL
10388 INTERCEPTOR(int, procctl, int idtype, u64 id, int cmd, uptr data) {
10390 COMMON_INTERCEPTOR_ENTER(ctx, procctl, idtype, id, cmd, data);
10391 static const int PROC_REAP_ACQUIRE = 2;
10392 static const int PROC_REAP_RELEASE = 3;
10393 static const int PROC_REAP_STATUS = 4;
10394 static const int PROC_REAP_GETPIDS = 5;
10395 static const int PROC_REAP_KILL = 6;
10396 if (cmd < PROC_REAP_ACQUIRE || cmd > PROC_REAP_KILL) {
10397 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, sizeof(int));
10399 // reap_acquire/reap_release bears no arguments.
10400 if (cmd > PROC_REAP_RELEASE) {
10401 unsigned int reapsz;
10403 case PROC_REAP_STATUS:
10404 reapsz = struct_procctl_reaper_status_sz;
10406 case PROC_REAP_GETPIDS:
10407 reapsz = struct_procctl_reaper_pids_sz;
10409 case PROC_REAP_KILL:
10410 reapsz = struct_procctl_reaper_kill_sz;
10413 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)data, reapsz);
10416 return REAL(procctl)(idtype, id, cmd, data);
10418 #define INIT_PROCCTL COMMON_INTERCEPT_FUNCTION(procctl)
10420 #define INIT_PROCCTL
10423 #if SANITIZER_INTERCEPT_UNAME
10424 INTERCEPTOR(int, uname, struct utsname *utsname) {
10425 #if SANITIZER_LINUX
10426 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
10427 return internal_uname(utsname);
10430 COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname);
10431 int res = REAL(uname)(utsname);
10433 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10434 __sanitizer::struct_utsname_sz);
10437 #define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname)
10442 #if SANITIZER_INTERCEPT___XUNAME
10443 // FreeBSD's <sys/utsname.h> define uname() as
10444 // static __inline int uname(struct utsname *name) {
10445 // return __xuname(SYS_NMLN, (void*)name);
10447 INTERCEPTOR(int, __xuname, int size, void *utsname) {
10449 COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname);
10450 int res = REAL(__xuname)(size, utsname);
10452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname,
10453 __sanitizer::struct_utsname_sz);
10456 #define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname)
10458 #define INIT___XUNAME
10461 #include "sanitizer_common_interceptors_netbsd_compat.inc"
10463 static void InitializeCommonInterceptors() {
10465 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
10466 interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap();
10516 INIT_LOCALTIME_AND_FRIENDS;
10522 INIT_ISOC99_PRINTF;
10524 INIT_FREXPF_FREXPL;
10525 INIT_GETPWNAM_AND_FRIENDS;
10526 INIT_GETPWNAM_R_AND_FRIENDS;
10533 INIT_CLOCK_GETTIME;
10534 INIT_CLOCK_GETCPUCLOCKID;
10540 INIT_DN_COMP_EXPAND;
10545 INIT_PTHREAD_GETSCHEDPARAM;
10549 INIT_GETHOSTBYNAME;
10550 INIT_GETHOSTBYNAME2;
10551 INIT_GETHOSTBYNAME_R;
10552 INIT_GETHOSTBYNAME2_R;
10553 INIT_GETHOSTBYADDR_R;
10574 INIT_GET_CURRENT_DIR_NAME;
10584 INIT_CANONICALIZE_FILE_NAME;
10586 INIT_SCHED_GETAFFINITY;
10587 INIT_SCHED_GETPARAM;
10590 INIT_XPG_STRERROR_R;
10601 INIT_SIGSET_LOGICOPS;
10604 INIT_PTHREAD_SIGMASK;
10607 INIT_PTHREAD_MUTEX_LOCK;
10608 INIT_PTHREAD_MUTEX_UNLOCK;
10609 INIT___PTHREAD_MUTEX_LOCK;
10610 INIT___PTHREAD_MUTEX_UNLOCK;
10611 INIT___LIBC_MUTEX_LOCK;
10612 INIT___LIBC_MUTEX_UNLOCK;
10613 INIT___LIBC_THR_SETCANCELSTATE;
10621 INIT_ETHER_NTOA_ATON;
10626 INIT_PTHREAD_ATTR_GET;
10627 INIT_PTHREAD_ATTR_GET_SCHED;
10628 INIT_PTHREAD_ATTR_GETINHERITSCHED;
10629 INIT_PTHREAD_ATTR_GETAFFINITY_NP;
10630 INIT_PTHREAD_GETAFFINITY_NP;
10631 INIT_PTHREAD_MUTEXATTR_GETPSHARED;
10632 INIT_PTHREAD_MUTEXATTR_GETTYPE;
10633 INIT_PTHREAD_MUTEXATTR_GETPROTOCOL;
10634 INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING;
10635 INIT_PTHREAD_MUTEXATTR_GETROBUST;
10636 INIT_PTHREAD_MUTEXATTR_GETROBUST_NP;
10637 INIT_PTHREAD_RWLOCKATTR_GETPSHARED;
10638 INIT_PTHREAD_RWLOCKATTR_GETKIND_NP;
10639 INIT_PTHREAD_CONDATTR_GETPSHARED;
10640 INIT_PTHREAD_CONDATTR_GETCLOCK;
10641 INIT_PTHREAD_BARRIERATTR_GETPSHARED;
10649 INIT_PTHREAD_SETNAME_NP;
10650 INIT_PTHREAD_GETNAME_NP;
10668 INIT_IF_INDEXTONAME;
10677 INIT_LIBIO_INTERNALS;
10681 INIT_OPEN_MEMSTREAM;
10685 INIT_DLOPEN_DLCLOSE;
10691 INIT_PTHREAD_SETCANCEL;
10693 INIT_PROCESS_VM_READV;
10696 INIT_RECV_RECVFROM;
10700 INIT_EVENTFD_READ_WRITE;
10707 // FIXME: add other *stat interceptors.
10717 INIT_USER_FROM_UID;
10718 INIT_UID_FROM_USER;
10719 INIT_GROUP_FROM_GID;
10720 INIT_GID_FROM_GROUP;
10724 INIT_GETGROUPMEMBERSHIP;
10727 INIT_NAME_TO_HANDLE_AT;
10728 INIT_OPEN_BY_HANDLE_AT;
10739 INIT_MI_VECTOR_HASH;
10747 INIT_SYSCTLGETMIBINFO;