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