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