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