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