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