sanitizer_common_interceptors.inc revision 1.10
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// This file is distributed under the University of Illinois Open Source 4// License. See LICENSE.TXT for details. 5// 6//===----------------------------------------------------------------------===// 7// 8// Common function interceptors for tools like AddressSanitizer, 9// ThreadSanitizer, MemorySanitizer, etc. 10// 11// This file should be included into the tool's interceptor file, 12// which has to define its own macros: 13// COMMON_INTERCEPTOR_ENTER 14// COMMON_INTERCEPTOR_ENTER_NOIGNORE 15// COMMON_INTERCEPTOR_READ_RANGE 16// COMMON_INTERCEPTOR_WRITE_RANGE 17// COMMON_INTERCEPTOR_INITIALIZE_RANGE 18// COMMON_INTERCEPTOR_DIR_ACQUIRE 19// COMMON_INTERCEPTOR_FD_ACQUIRE 20// COMMON_INTERCEPTOR_FD_RELEASE 21// COMMON_INTERCEPTOR_FD_ACCESS 22// COMMON_INTERCEPTOR_SET_THREAD_NAME 23// COMMON_INTERCEPTOR_ON_DLOPEN 24// COMMON_INTERCEPTOR_ON_EXIT 25// COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 26// COMMON_INTERCEPTOR_MUTEX_POST_LOCK 27// COMMON_INTERCEPTOR_MUTEX_UNLOCK 28// COMMON_INTERCEPTOR_MUTEX_REPAIR 29// COMMON_INTERCEPTOR_SET_PTHREAD_NAME 30// COMMON_INTERCEPTOR_HANDLE_RECVMSG 31// COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED 32// COMMON_INTERCEPTOR_MEMSET_IMPL 33// COMMON_INTERCEPTOR_MEMMOVE_IMPL 34// COMMON_INTERCEPTOR_MEMCPY_IMPL 35// COMMON_INTERCEPTOR_MMAP_IMPL 36// COMMON_INTERCEPTOR_COPY_STRING 37// COMMON_INTERCEPTOR_STRNDUP_IMPL 38// COMMON_INTERCEPTOR_STRERROR 39//===----------------------------------------------------------------------===// 40 41#include "interception/interception.h" 42#include "sanitizer_addrhashmap.h" 43#include "sanitizer_errno.h" 44#include "sanitizer_placement_new.h" 45#include "sanitizer_platform_interceptors.h" 46#include "sanitizer_symbolizer.h" 47#include "sanitizer_tls_get_addr.h" 48 49#include <stdarg.h> 50 51#if SANITIZER_INTERCEPTOR_HOOKS 52#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__); 53#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \ 54 SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {} 55#else 56#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) 57#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) 58 59#endif // SANITIZER_INTERCEPTOR_HOOKS 60 61#if SANITIZER_WINDOWS && !defined(va_copy) 62#define va_copy(dst, src) ((dst) = (src)) 63#endif // _WIN32 64 65#if SANITIZER_BSD 66#define pthread_setname_np pthread_set_name_np 67#define inet_aton __inet_aton 68#define inet_pton __inet_pton 69#define iconv __bsd_iconv 70#endif 71 72#if SANITIZER_NETBSD 73#define clock_getres __clock_getres50 74#define clock_gettime __clock_gettime50 75#define clock_settime __clock_settime50 76#define ctime __ctime50 77#define ctime_r __ctime_r50 78#define devname __devname50 79#define getitimer __getitimer50 80#define getpwent __getpwent50 81#define getpwnam __getpwnam50 82#define getpwnam_r __getpwnam_r50 83#define getpwuid __getpwuid50 84#define getpwuid_r __getpwuid_r50 85#define getutent __getutent50 86#define getutxent __getutxent50 87#define getutxid __getutxid50 88#define getutxline __getutxline50 89#define glob __glob30 90#define gmtime __gmtime50 91#define gmtime_r __gmtime_r50 92#define localtime __locatime50 93#define localtime_r __localtime_r50 94#define mktime __mktime50 95#define lstat __lstat50 96#define opendir __opendir30 97#define readdir __readdir30 98#define readdir_r __readdir_r30 99#define scandir __scandir30 100#define setitimer __setitimer50 101#define setlocale __setlocale50 102#define shmctl __shmctl50 103#define sigemptyset __sigemptyset14 104#define sigfillset __sigfillset14 105#define sigpending __sigpending14 106#define sigprocmask __sigprocmask14 107#define sigtimedwait __sigtimedwait50 108#define stat __stat50 109#define time __time50 110#define times __times13 111#define wait3 __wait350 112#define wait4 __wait450 113extern const unsigned short *_ctype_tab_; 114extern const short *_toupper_tab_; 115extern const short *_tolower_tab_; 116#endif 117 118// Platform-specific options. 119#if SANITIZER_MAC 120namespace __sanitizer { 121bool PlatformHasDifferentMemcpyAndMemmove(); 122} 123#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE \ 124 (__sanitizer::PlatformHasDifferentMemcpyAndMemmove()) 125#elif SANITIZER_WINDOWS64 126#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false 127#else 128#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true 129#endif // SANITIZER_MAC 130 131#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 132#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} 133#endif 134 135#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM 136#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {} 137#endif 138 139#ifndef COMMON_INTERCEPTOR_FD_ACCESS 140#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 141#endif 142 143#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 144#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {} 145#endif 146 147#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK 148#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {} 149#endif 150 151#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 152#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 153#endif 154 155#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR 156#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} 157#endif 158 159#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID 160#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {} 161#endif 162 163#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG 164#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) 165#endif 166 167#ifndef COMMON_INTERCEPTOR_FILE_OPEN 168#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {} 169#endif 170 171#ifndef COMMON_INTERCEPTOR_FILE_CLOSE 172#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {} 173#endif 174 175#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED 176#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {} 177#endif 178 179#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED 180#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {} 181#endif 182 183#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE 184#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \ 185 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__) 186#endif 187 188#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED 189#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0) 190#endif 191 192#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \ 193 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \ 194 common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) ) 195 196#ifndef COMMON_INTERCEPTOR_ON_DLOPEN 197#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ 198 CheckNoDeepBind(filename, flag); 199#endif 200 201#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE 202#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0; 203#endif 204 205#ifndef COMMON_INTERCEPTOR_ACQUIRE 206#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {} 207#endif 208 209#ifndef COMMON_INTERCEPTOR_RELEASE 210#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {} 211#endif 212 213#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START 214#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {} 215#endif 216 217#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END 218#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {} 219#endif 220 221#ifdef SANITIZER_NLDBL_VERSION 222#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 223 COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION) 224#else 225#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 226 COMMON_INTERCEPT_FUNCTION(fn) 227#endif 228 229#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL 230#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \ 231 { \ 232 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 233 return internal_memset(dst, v, size); \ 234 COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \ 235 if (common_flags()->intercept_intrin) \ 236 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 237 return REAL(memset)(dst, v, size); \ 238 } 239#endif 240 241#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL 242#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \ 243 { \ 244 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 245 return internal_memmove(dst, src, size); \ 246 COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \ 247 if (common_flags()->intercept_intrin) { \ 248 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 249 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 250 } \ 251 return REAL(memmove)(dst, src, size); \ 252 } 253#endif 254 255#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL 256#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \ 257 { \ 258 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \ 259 return internal_memmove(dst, src, size); \ 260 } \ 261 COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \ 262 if (common_flags()->intercept_intrin) { \ 263 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 264 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 265 } \ 266 return REAL(memcpy)(dst, src, size); \ 267 } 268#endif 269 270#ifndef COMMON_INTERCEPTOR_MMAP_IMPL 271#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ 272 off) \ 273 { return REAL(mmap)(addr, sz, prot, flags, fd, off); } 274#endif 275 276#ifndef COMMON_INTERCEPTOR_COPY_STRING 277#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {} 278#endif 279 280#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL 281#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \ 282 COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \ 283 uptr copy_length = internal_strnlen(s, size); \ 284 char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \ 285 if (common_flags()->intercept_strndup) { \ 286 COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ 287 } \ 288 COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ 289 internal_memcpy(new_mem, s, copy_length); \ 290 new_mem[copy_length] = '\0'; \ 291 return new_mem; 292#endif 293 294#ifndef COMMON_INTERCEPTOR_STRERROR 295#define COMMON_INTERCEPTOR_STRERROR() {} 296#endif 297 298struct FileMetadata { 299 // For open_memstream(). 300 char **addr; 301 SIZE_T *size; 302}; 303 304struct CommonInterceptorMetadata { 305 enum { 306 CIMT_INVALID = 0, 307 CIMT_FILE 308 } type; 309 union { 310 FileMetadata file; 311 }; 312}; 313 314typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; 315 316static MetadataHashMap *interceptor_metadata_map; 317 318#if SI_POSIX 319UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, 320 const FileMetadata &file) { 321 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); 322 CHECK(h.created()); 323 h->type = CommonInterceptorMetadata::CIMT_FILE; 324 h->file = file; 325} 326 327UNUSED static const FileMetadata *GetInterceptorMetadata( 328 __sanitizer_FILE *addr) { 329 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, 330 /* remove */ false, 331 /* create */ false); 332 if (addr && h.exists()) { 333 CHECK(!h.created()); 334 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE); 335 return &h->file; 336 } else { 337 return 0; 338 } 339} 340 341UNUSED static void DeleteInterceptorMetadata(void *addr) { 342 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true); 343 CHECK(h.exists()); 344} 345#endif // SI_POSIX 346 347#if SANITIZER_INTERCEPT_STRLEN 348INTERCEPTOR(SIZE_T, strlen, const char *s) { 349 // Sometimes strlen is called prior to InitializeCommonInterceptors, 350 // in which case the REAL(strlen) typically used in 351 // COMMON_INTERCEPTOR_ENTER will fail. We use internal_strlen here 352 // to handle that. 353 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 354 return internal_strlen(s); 355 void *ctx; 356 COMMON_INTERCEPTOR_ENTER(ctx, strlen, s); 357 SIZE_T result = REAL(strlen)(s); 358 if (common_flags()->intercept_strlen) 359 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1); 360 return result; 361} 362#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen) 363#else 364#define INIT_STRLEN 365#endif 366 367#if SANITIZER_INTERCEPT_STRNLEN 368INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) { 369 void *ctx; 370 COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen); 371 SIZE_T length = REAL(strnlen)(s, maxlen); 372 if (common_flags()->intercept_strlen) 373 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen)); 374 return length; 375} 376#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen) 377#else 378#define INIT_STRNLEN 379#endif 380 381#if SANITIZER_INTERCEPT_STRNDUP 382INTERCEPTOR(char*, strndup, const char *s, uptr size) { 383 void *ctx; 384 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 385} 386#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup) 387#else 388#define INIT_STRNDUP 389#endif // SANITIZER_INTERCEPT_STRNDUP 390 391#if SANITIZER_INTERCEPT___STRNDUP 392INTERCEPTOR(char*, __strndup, const char *s, uptr size) { 393 void *ctx; 394 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 395} 396#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup) 397#else 398#define INIT___STRNDUP 399#endif // SANITIZER_INTERCEPT___STRNDUP 400 401#if SANITIZER_INTERCEPT_TEXTDOMAIN 402INTERCEPTOR(char*, textdomain, const char *domainname) { 403 void *ctx; 404 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname); 405 if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0); 406 char *domain = REAL(textdomain)(domainname); 407 if (domain) { 408 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1); 409 } 410 return domain; 411} 412#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain) 413#else 414#define INIT_TEXTDOMAIN 415#endif 416 417#if SANITIZER_INTERCEPT_STRCMP 418static inline int CharCmpX(unsigned char c1, unsigned char c2) { 419 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 420} 421 422DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc, 423 const char *s1, const char *s2, int result) 424 425INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 426 void *ctx; 427 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 428 unsigned char c1, c2; 429 uptr i; 430 for (i = 0;; i++) { 431 c1 = (unsigned char)s1[i]; 432 c2 = (unsigned char)s2[i]; 433 if (c1 != c2 || c1 == '\0') break; 434 } 435 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 436 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 437 int result = CharCmpX(c1, c2); 438 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1, 439 s2, result); 440 return result; 441} 442 443DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc, 444 const char *s1, const char *s2, uptr n, 445 int result) 446 447INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 448 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 449 return internal_strncmp(s1, s2, size); 450 void *ctx; 451 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 452 unsigned char c1 = 0, c2 = 0; 453 uptr i; 454 for (i = 0; i < size; i++) { 455 c1 = (unsigned char)s1[i]; 456 c2 = (unsigned char)s2[i]; 457 if (c1 != c2 || c1 == '\0') break; 458 } 459 uptr i1 = i; 460 uptr i2 = i; 461 if (common_flags()->strict_string_checks) { 462 for (; i1 < size && s1[i1]; i1++) {} 463 for (; i2 < size && s2[i2]; i2++) {} 464 } 465 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 466 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 467 int result = CharCmpX(c1, c2); 468 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1, 469 s2, size, result); 470 return result; 471} 472 473#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) 474#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp) 475#else 476#define INIT_STRCMP 477#define INIT_STRNCMP 478#endif 479 480#if SANITIZER_INTERCEPT_STRCASECMP 481static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 482 int c1_low = ToLower(c1); 483 int c2_low = ToLower(c2); 484 return c1_low - c2_low; 485} 486 487DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc, 488 const char *s1, const char *s2, int result) 489 490INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 491 void *ctx; 492 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 493 unsigned char c1 = 0, c2 = 0; 494 uptr i; 495 for (i = 0;; i++) { 496 c1 = (unsigned char)s1[i]; 497 c2 = (unsigned char)s2[i]; 498 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 499 } 500 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 501 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 502 int result = CharCaseCmp(c1, c2); 503 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(), 504 s1, s2, result); 505 return result; 506} 507 508DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc, 509 const char *s1, const char *s2, uptr size, 510 int result) 511 512INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) { 513 void *ctx; 514 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size); 515 unsigned char c1 = 0, c2 = 0; 516 uptr i; 517 for (i = 0; i < size; i++) { 518 c1 = (unsigned char)s1[i]; 519 c2 = (unsigned char)s2[i]; 520 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 521 } 522 uptr i1 = i; 523 uptr i2 = i; 524 if (common_flags()->strict_string_checks) { 525 for (; i1 < size && s1[i1]; i1++) {} 526 for (; i2 < size && s2[i2]; i2++) {} 527 } 528 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 529 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 530 int result = CharCaseCmp(c1, c2); 531 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(), 532 s1, s2, size, result); 533 return result; 534} 535 536#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp) 537#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp) 538#else 539#define INIT_STRCASECMP 540#define INIT_STRNCASECMP 541#endif 542 543#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR 544static inline void StrstrCheck(void *ctx, char *r, const char *s1, 545 const char *s2) { 546 uptr len1 = REAL(strlen)(s1); 547 uptr len2 = REAL(strlen)(s2); 548 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1); 549 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1); 550} 551#endif 552 553#if SANITIZER_INTERCEPT_STRSTR 554 555DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc, 556 const char *s1, const char *s2, char *result) 557 558INTERCEPTOR(char*, strstr, const char *s1, const char *s2) { 559 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 560 return internal_strstr(s1, s2); 561 void *ctx; 562 COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2); 563 char *r = REAL(strstr)(s1, s2); 564 if (common_flags()->intercept_strstr) 565 StrstrCheck(ctx, r, s1, s2); 566 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1, 567 s2, r); 568 return r; 569} 570 571#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr); 572#else 573#define INIT_STRSTR 574#endif 575 576#if SANITIZER_INTERCEPT_STRCASESTR 577 578DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc, 579 const char *s1, const char *s2, char *result) 580 581INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) { 582 void *ctx; 583 COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2); 584 char *r = REAL(strcasestr)(s1, s2); 585 if (common_flags()->intercept_strstr) 586 StrstrCheck(ctx, r, s1, s2); 587 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(), 588 s1, s2, r); 589 return r; 590} 591 592#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr); 593#else 594#define INIT_STRCASESTR 595#endif 596 597#if SANITIZER_INTERCEPT_STRTOK 598 599INTERCEPTOR(char*, strtok, char *str, const char *delimiters) { 600 void *ctx; 601 COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters); 602 if (!common_flags()->intercept_strtok) { 603 return REAL(strtok)(str, delimiters); 604 } 605 if (common_flags()->strict_string_checks) { 606 // If strict_string_checks is enabled, we check the whole first argument 607 // string on the first call (strtok saves this string in a static buffer 608 // for subsequent calls). We do not need to check strtok's result. 609 // As the delimiters can change, we check them every call. 610 if (str != nullptr) { 611 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 612 } 613 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 614 REAL(strlen)(delimiters) + 1); 615 return REAL(strtok)(str, delimiters); 616 } else { 617 // However, when strict_string_checks is disabled we cannot check the 618 // whole string on the first call. Instead, we check the result string 619 // which is guaranteed to be a NULL-terminated substring of the first 620 // argument. We also conservatively check one character of str and the 621 // delimiters. 622 if (str != nullptr) { 623 COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1); 624 } 625 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1); 626 char *result = REAL(strtok)(str, delimiters); 627 if (result != nullptr) { 628 COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1); 629 } else if (str != nullptr) { 630 // No delimiter were found, it's safe to assume that the entire str was 631 // scanned. 632 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 633 } 634 return result; 635 } 636} 637 638#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok) 639#else 640#define INIT_STRTOK 641#endif 642 643#if SANITIZER_INTERCEPT_MEMMEM 644DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc, 645 const void *s1, SIZE_T len1, const void *s2, 646 SIZE_T len2, void *result) 647 648INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2, 649 SIZE_T len2) { 650 void *ctx; 651 COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2); 652 void *r = REAL(memmem)(s1, len1, s2, len2); 653 if (common_flags()->intercept_memmem) { 654 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1); 655 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2); 656 } 657 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(), 658 s1, len1, s2, len2, r); 659 return r; 660} 661 662#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem); 663#else 664#define INIT_MEMMEM 665#endif // SANITIZER_INTERCEPT_MEMMEM 666 667#if SANITIZER_INTERCEPT_STRCHR 668INTERCEPTOR(char*, strchr, const char *s, int c) { 669 void *ctx; 670 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 671 return internal_strchr(s, c); 672 COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c); 673 char *result = REAL(strchr)(s, c); 674 if (common_flags()->intercept_strchr) { 675 // Keep strlen as macro argument, as macro may ignore it. 676 COMMON_INTERCEPTOR_READ_STRING(ctx, s, 677 (result ? result - s : REAL(strlen)(s)) + 1); 678 } 679 return result; 680} 681#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr) 682#else 683#define INIT_STRCHR 684#endif 685 686#if SANITIZER_INTERCEPT_STRCHRNUL 687INTERCEPTOR(char*, strchrnul, const char *s, int c) { 688 void *ctx; 689 COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c); 690 char *result = REAL(strchrnul)(s, c); 691 uptr len = result - s + 1; 692 if (common_flags()->intercept_strchr) 693 COMMON_INTERCEPTOR_READ_STRING(ctx, s, len); 694 return result; 695} 696#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul) 697#else 698#define INIT_STRCHRNUL 699#endif 700 701#if SANITIZER_INTERCEPT_STRRCHR 702INTERCEPTOR(char*, strrchr, const char *s, int c) { 703 void *ctx; 704 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 705 return internal_strrchr(s, c); 706 COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c); 707 if (common_flags()->intercept_strchr) 708 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 709 return REAL(strrchr)(s, c); 710} 711#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr) 712#else 713#define INIT_STRRCHR 714#endif 715 716#if SANITIZER_INTERCEPT_STRSPN 717INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) { 718 void *ctx; 719 COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2); 720 SIZE_T r = REAL(strspn)(s1, s2); 721 if (common_flags()->intercept_strspn) { 722 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 723 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 724 } 725 return r; 726} 727 728INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) { 729 void *ctx; 730 COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2); 731 SIZE_T r = REAL(strcspn)(s1, s2); 732 if (common_flags()->intercept_strspn) { 733 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 734 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 735 } 736 return r; 737} 738 739#define INIT_STRSPN \ 740 COMMON_INTERCEPT_FUNCTION(strspn); \ 741 COMMON_INTERCEPT_FUNCTION(strcspn); 742#else 743#define INIT_STRSPN 744#endif 745 746#if SANITIZER_INTERCEPT_STRPBRK 747INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { 748 void *ctx; 749 COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2); 750 char *r = REAL(strpbrk)(s1, s2); 751 if (common_flags()->intercept_strpbrk) { 752 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 753 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, 754 r ? r - s1 + 1 : REAL(strlen)(s1) + 1); 755 } 756 return r; 757} 758 759#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk); 760#else 761#define INIT_STRPBRK 762#endif 763 764#if SANITIZER_INTERCEPT_MEMSET 765INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { 766 void *ctx; 767 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size); 768} 769 770#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset) 771#else 772#define INIT_MEMSET 773#endif 774 775#if SANITIZER_INTERCEPT_MEMMOVE 776INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { 777 void *ctx; 778 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 779} 780 781#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove) 782#else 783#define INIT_MEMMOVE 784#endif 785 786#if SANITIZER_INTERCEPT_MEMCPY 787INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { 788 // On OS X, calling internal_memcpy here will cause memory corruptions, 789 // because memcpy and memmove are actually aliases of the same 790 // implementation. We need to use internal_memmove here. 791 // N.B.: If we switch this to internal_ we'll have to use internal_memmove 792 // due to memcpy being an alias of memmove on OS X. 793 void *ctx; 794 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 795 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); 796 } else { 797 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 798 } 799} 800 801#define INIT_MEMCPY \ 802 do { \ 803 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ 804 COMMON_INTERCEPT_FUNCTION(memcpy); \ 805 } else { \ 806 ASSIGN_REAL(memcpy, memmove); \ 807 } \ 808 CHECK(REAL(memcpy)); \ 809 } while (false) 810 811#else 812#define INIT_MEMCPY 813#endif 814 815#if SANITIZER_INTERCEPT_MEMCMP 816 817DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, 818 const void *s1, const void *s2, uptr n, 819 int result) 820 821INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 822 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 823 return internal_memcmp(a1, a2, size); 824 void *ctx; 825 COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); 826 if (common_flags()->intercept_memcmp) { 827 if (common_flags()->strict_memcmp) { 828 // Check the entire regions even if the first bytes of the buffers are 829 // different. 830 COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size); 831 COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size); 832 // Fallthrough to REAL(memcmp) below. 833 } else { 834 unsigned char c1 = 0, c2 = 0; 835 const unsigned char *s1 = (const unsigned char*)a1; 836 const unsigned char *s2 = (const unsigned char*)a2; 837 uptr i; 838 for (i = 0; i < size; i++) { 839 c1 = s1[i]; 840 c2 = s2[i]; 841 if (c1 != c2) break; 842 } 843 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 844 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 845 int r = CharCmpX(c1, c2); 846 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), 847 a1, a2, size, r); 848 return r; 849 } 850 } 851 int result = REAL(memcmp(a1, a2, size)); 852 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, 853 a2, size, result); 854 return result; 855} 856 857#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp) 858#else 859#define INIT_MEMCMP 860#endif 861 862#if SANITIZER_INTERCEPT_MEMCHR 863INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) { 864 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 865 return internal_memchr(s, c, n); 866 void *ctx; 867 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n); 868#if SANITIZER_WINDOWS 869 void *res; 870 if (REAL(memchr)) { 871 res = REAL(memchr)(s, c, n); 872 } else { 873 res = internal_memchr(s, c, n); 874 } 875#else 876 void *res = REAL(memchr)(s, c, n); 877#endif 878 uptr len = res ? (char *)res - (const char *)s + 1 : n; 879 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len); 880 return res; 881} 882 883#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr) 884#else 885#define INIT_MEMCHR 886#endif 887 888#if SANITIZER_INTERCEPT_MEMRCHR 889INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) { 890 void *ctx; 891 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n); 892 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n); 893 return REAL(memrchr)(s, c, n); 894} 895 896#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr) 897#else 898#define INIT_MEMRCHR 899#endif 900 901#if SANITIZER_INTERCEPT_FREXP 902INTERCEPTOR(double, frexp, double x, int *exp) { 903 void *ctx; 904 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 905 // Assuming frexp() always writes to |exp|. 906 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 907 double res = REAL(frexp)(x, exp); 908 return res; 909} 910 911#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp); 912#else 913#define INIT_FREXP 914#endif // SANITIZER_INTERCEPT_FREXP 915 916#if SANITIZER_INTERCEPT_FREXPF_FREXPL 917INTERCEPTOR(float, frexpf, float x, int *exp) { 918 void *ctx; 919 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 920 // FIXME: under ASan the call below may write to freed memory and corrupt 921 // its metadata. See 922 // https://github.com/google/sanitizers/issues/321. 923 float res = REAL(frexpf)(x, exp); 924 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 925 return res; 926} 927 928INTERCEPTOR(long double, frexpl, long double x, int *exp) { 929 void *ctx; 930 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 931 // FIXME: under ASan the call below may write to freed memory and corrupt 932 // its metadata. See 933 // https://github.com/google/sanitizers/issues/321. 934 long double res = REAL(frexpl)(x, exp); 935 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 936 return res; 937} 938 939#define INIT_FREXPF_FREXPL \ 940 COMMON_INTERCEPT_FUNCTION(frexpf); \ 941 COMMON_INTERCEPT_FUNCTION_LDBL(frexpl) 942#else 943#define INIT_FREXPF_FREXPL 944#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 945 946#if SI_POSIX 947static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 948 SIZE_T iovlen, SIZE_T maxlen) { 949 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 950 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 951 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 952 maxlen -= sz; 953 } 954} 955 956static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 957 SIZE_T iovlen, SIZE_T maxlen) { 958 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 959 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 960 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 961 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 962 maxlen -= sz; 963 } 964} 965#endif 966 967#if SANITIZER_INTERCEPT_READ 968INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 969 void *ctx; 970 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 971 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 972 // FIXME: under ASan the call below may write to freed memory and corrupt 973 // its metadata. See 974 // https://github.com/google/sanitizers/issues/321. 975 SSIZE_T res = REAL(read)(fd, ptr, count); 976 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 977 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 978 return res; 979} 980#define INIT_READ COMMON_INTERCEPT_FUNCTION(read) 981#else 982#define INIT_READ 983#endif 984 985#if SANITIZER_INTERCEPT_FREAD 986INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) { 987 // libc file streams can call user-supplied functions, see fopencookie. 988 void *ctx; 989 COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file); 990 // FIXME: under ASan the call below may write to freed memory and corrupt 991 // its metadata. See 992 // https://github.com/google/sanitizers/issues/321. 993 SIZE_T res = REAL(fread)(ptr, size, nmemb, file); 994 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size); 995 return res; 996} 997#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread) 998#else 999#define INIT_FREAD 1000#endif 1001 1002#if SANITIZER_INTERCEPT_PREAD 1003INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1004 void *ctx; 1005 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 1006 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1007 // FIXME: under ASan the call below may write to freed memory and corrupt 1008 // its metadata. See 1009 // https://github.com/google/sanitizers/issues/321. 1010 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 1011 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1012 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1013 return res; 1014} 1015#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread) 1016#else 1017#define INIT_PREAD 1018#endif 1019 1020#if SANITIZER_INTERCEPT_PREAD64 1021INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 1022 void *ctx; 1023 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 1024 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1025 // FIXME: under ASan the call below may write to freed memory and corrupt 1026 // its metadata. See 1027 // https://github.com/google/sanitizers/issues/321. 1028 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 1029 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1030 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1031 return res; 1032} 1033#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64) 1034#else 1035#define INIT_PREAD64 1036#endif 1037 1038#if SANITIZER_INTERCEPT_READV 1039INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 1040 int iovcnt) { 1041 void *ctx; 1042 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 1043 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1044 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 1045 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1046 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1047 return res; 1048} 1049#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv) 1050#else 1051#define INIT_READV 1052#endif 1053 1054#if SANITIZER_INTERCEPT_PREADV 1055INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 1056 OFF_T offset) { 1057 void *ctx; 1058 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 1059 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1060 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 1061 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1062 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1063 return res; 1064} 1065#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv) 1066#else 1067#define INIT_PREADV 1068#endif 1069 1070#if SANITIZER_INTERCEPT_PREADV64 1071INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 1072 OFF64_T offset) { 1073 void *ctx; 1074 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 1075 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1076 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 1077 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1078 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1079 return res; 1080} 1081#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64) 1082#else 1083#define INIT_PREADV64 1084#endif 1085 1086#if SANITIZER_INTERCEPT_WRITE 1087INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 1088 void *ctx; 1089 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 1090 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1091 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1092 SSIZE_T res = REAL(write)(fd, ptr, count); 1093 // FIXME: this check should be _before_ the call to REAL(write), not after 1094 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1095 return res; 1096} 1097#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write) 1098#else 1099#define INIT_WRITE 1100#endif 1101 1102#if SANITIZER_INTERCEPT_FWRITE 1103INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) { 1104 // libc file streams can call user-supplied functions, see fopencookie. 1105 void *ctx; 1106 COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file); 1107 SIZE_T res = REAL(fwrite)(p, size, nmemb, file); 1108 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size); 1109 return res; 1110} 1111#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite) 1112#else 1113#define INIT_FWRITE 1114#endif 1115 1116#if SANITIZER_INTERCEPT_PWRITE 1117INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1118 void *ctx; 1119 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 1120 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1121 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1122 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 1123 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1124 return res; 1125} 1126#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite) 1127#else 1128#define INIT_PWRITE 1129#endif 1130 1131#if SANITIZER_INTERCEPT_PWRITE64 1132INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 1133 OFF64_T offset) { 1134 void *ctx; 1135 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 1136 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1137 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1138 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 1139 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1140 return res; 1141} 1142#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64) 1143#else 1144#define INIT_PWRITE64 1145#endif 1146 1147#if SANITIZER_INTERCEPT_WRITEV 1148INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 1149 int iovcnt) { 1150 void *ctx; 1151 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 1152 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1153 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1154 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 1155 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1156 return res; 1157} 1158#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev) 1159#else 1160#define INIT_WRITEV 1161#endif 1162 1163#if SANITIZER_INTERCEPT_PWRITEV 1164INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 1165 OFF_T offset) { 1166 void *ctx; 1167 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 1168 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1169 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1170 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 1171 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1172 return res; 1173} 1174#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev) 1175#else 1176#define INIT_PWRITEV 1177#endif 1178 1179#if SANITIZER_INTERCEPT_PWRITEV64 1180INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 1181 OFF64_T offset) { 1182 void *ctx; 1183 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 1184 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1185 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1186 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 1187 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1188 return res; 1189} 1190#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64) 1191#else 1192#define INIT_PWRITEV64 1193#endif 1194 1195#if SANITIZER_INTERCEPT_FGETS 1196INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) { 1197 // libc file streams can call user-supplied functions, see fopencookie. 1198 void *ctx; 1199 COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file); 1200 // FIXME: under ASan the call below may write to freed memory and corrupt 1201 // its metadata. See 1202 // https://github.com/google/sanitizers/issues/321. 1203 char *res = REAL(fgets)(s, size, file); 1204 if (res) 1205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 1206 return res; 1207} 1208#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets) 1209#else 1210#define INIT_FGETS 1211#endif 1212 1213#if SANITIZER_INTERCEPT_FPUTS 1214INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { 1215 // libc file streams can call user-supplied functions, see fopencookie. 1216 void *ctx; 1217 COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); 1218 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1219 return REAL(fputs)(s, file); 1220} 1221#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) 1222#else 1223#define INIT_FPUTS 1224#endif 1225 1226#if SANITIZER_INTERCEPT_PUTS 1227INTERCEPTOR(int, puts, char *s) { 1228 // libc file streams can call user-supplied functions, see fopencookie. 1229 void *ctx; 1230 COMMON_INTERCEPTOR_ENTER(ctx, puts, s); 1231 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1232 return REAL(puts)(s); 1233} 1234#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) 1235#else 1236#define INIT_PUTS 1237#endif 1238 1239#if SANITIZER_INTERCEPT_PRCTL 1240INTERCEPTOR(int, prctl, int option, unsigned long arg2, 1241 unsigned long arg3, // NOLINT 1242 unsigned long arg4, unsigned long arg5) { // NOLINT 1243 void *ctx; 1244 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 1245 static const int PR_SET_NAME = 15; 1246 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 1247 if (option == PR_SET_NAME) { 1248 char buff[16]; 1249 internal_strncpy(buff, (char *)arg2, 15); 1250 buff[15] = 0; 1251 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 1252 } 1253 return res; 1254} 1255#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) 1256#else 1257#define INIT_PRCTL 1258#endif // SANITIZER_INTERCEPT_PRCTL 1259 1260#if SANITIZER_INTERCEPT_TIME 1261INTERCEPTOR(unsigned long, time, unsigned long *t) { 1262 void *ctx; 1263 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 1264 unsigned long local_t; 1265 unsigned long res = REAL(time)(&local_t); 1266 if (t && res != (unsigned long)-1) { 1267 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 1268 *t = local_t; 1269 } 1270 return res; 1271} 1272#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time); 1273#else 1274#define INIT_TIME 1275#endif // SANITIZER_INTERCEPT_TIME 1276 1277#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1278static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 1279 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1280#if !SANITIZER_SOLARIS 1281 if (tm->tm_zone) { 1282 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 1283 // can point to shared memory and tsan would report a data race. 1284 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, 1285 REAL(strlen(tm->tm_zone)) + 1); 1286 } 1287#endif 1288} 1289INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 1290 void *ctx; 1291 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 1292 __sanitizer_tm *res = REAL(localtime)(timep); 1293 if (res) { 1294 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1295 unpoison_tm(ctx, res); 1296 } 1297 return res; 1298} 1299INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 1300 void *ctx; 1301 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 1302 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 1303 if (res) { 1304 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1305 unpoison_tm(ctx, res); 1306 } 1307 return res; 1308} 1309INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 1310 void *ctx; 1311 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 1312 __sanitizer_tm *res = REAL(gmtime)(timep); 1313 if (res) { 1314 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1315 unpoison_tm(ctx, res); 1316 } 1317 return res; 1318} 1319INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 1320 void *ctx; 1321 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 1322 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 1323 if (res) { 1324 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1325 unpoison_tm(ctx, res); 1326 } 1327 return res; 1328} 1329INTERCEPTOR(char *, ctime, unsigned long *timep) { 1330 void *ctx; 1331 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 1332 // FIXME: under ASan the call below may write to freed memory and corrupt 1333 // its metadata. See 1334 // https://github.com/google/sanitizers/issues/321. 1335 char *res = REAL(ctime)(timep); 1336 if (res) { 1337 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1339 } 1340 return res; 1341} 1342INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 1343 void *ctx; 1344 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 1345 // FIXME: under ASan the call below may write to freed memory and corrupt 1346 // its metadata. See 1347 // https://github.com/google/sanitizers/issues/321. 1348 char *res = REAL(ctime_r)(timep, result); 1349 if (res) { 1350 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1351 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1352 } 1353 return res; 1354} 1355INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 1356 void *ctx; 1357 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 1358 // FIXME: under ASan the call below may write to freed memory and corrupt 1359 // its metadata. See 1360 // https://github.com/google/sanitizers/issues/321. 1361 char *res = REAL(asctime)(tm); 1362 if (res) { 1363 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1364 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1365 } 1366 return res; 1367} 1368INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 1369 void *ctx; 1370 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 1371 // FIXME: under ASan the call below may write to freed memory and corrupt 1372 // its metadata. See 1373 // https://github.com/google/sanitizers/issues/321. 1374 char *res = REAL(asctime_r)(tm, result); 1375 if (res) { 1376 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1377 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1378 } 1379 return res; 1380} 1381INTERCEPTOR(long, mktime, __sanitizer_tm *tm) { 1382 void *ctx; 1383 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm); 1384 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec)); 1385 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min)); 1386 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour)); 1387 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday)); 1388 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon)); 1389 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year)); 1390 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst)); 1391 long res = REAL(mktime)(tm); 1392 if (res != -1) unpoison_tm(ctx, tm); 1393 return res; 1394} 1395#define INIT_LOCALTIME_AND_FRIENDS \ 1396 COMMON_INTERCEPT_FUNCTION(localtime); \ 1397 COMMON_INTERCEPT_FUNCTION(localtime_r); \ 1398 COMMON_INTERCEPT_FUNCTION(gmtime); \ 1399 COMMON_INTERCEPT_FUNCTION(gmtime_r); \ 1400 COMMON_INTERCEPT_FUNCTION(ctime); \ 1401 COMMON_INTERCEPT_FUNCTION(ctime_r); \ 1402 COMMON_INTERCEPT_FUNCTION(asctime); \ 1403 COMMON_INTERCEPT_FUNCTION(asctime_r); \ 1404 COMMON_INTERCEPT_FUNCTION(mktime); 1405#else 1406#define INIT_LOCALTIME_AND_FRIENDS 1407#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1408 1409#if SANITIZER_INTERCEPT_STRPTIME 1410INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { 1411 void *ctx; 1412 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); 1413 if (format) 1414 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); 1415 // FIXME: under ASan the call below may write to freed memory and corrupt 1416 // its metadata. See 1417 // https://github.com/google/sanitizers/issues/321. 1418 char *res = REAL(strptime)(s, format, tm); 1419 COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0); 1420 if (res && tm) { 1421 // Do not call unpoison_tm here, because strptime does not, in fact, 1422 // initialize the entire struct tm. For example, tm_zone pointer is left 1423 // uninitialized. 1424 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1425 } 1426 return res; 1427} 1428#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime); 1429#else 1430#define INIT_STRPTIME 1431#endif 1432 1433#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF 1434#include "sanitizer_common_interceptors_format.inc" 1435 1436#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \ 1437 { \ 1438 void *ctx; \ 1439 va_list ap; \ 1440 va_start(ap, format); \ 1441 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 1442 int res = WRAP(vname)(__VA_ARGS__, ap); \ 1443 va_end(ap); \ 1444 return res; \ 1445 } 1446 1447#endif 1448 1449#if SANITIZER_INTERCEPT_SCANF 1450 1451#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 1452 { \ 1453 void *ctx; \ 1454 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1455 va_list aq; \ 1456 va_copy(aq, ap); \ 1457 int res = REAL(vname)(__VA_ARGS__); \ 1458 if (res > 0) \ 1459 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 1460 va_end(aq); \ 1461 return res; \ 1462 } 1463 1464INTERCEPTOR(int, vscanf, const char *format, va_list ap) 1465VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 1466 1467INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 1468VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 1469 1470INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 1471VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 1472 1473#if SANITIZER_INTERCEPT_ISOC99_SCANF 1474INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 1475VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 1476 1477INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 1478 va_list ap) 1479VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 1480 1481INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 1482VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 1483#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 1484 1485INTERCEPTOR(int, scanf, const char *format, ...) 1486FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format) 1487 1488INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 1489FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 1490 1491INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 1492FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 1493 1494#define INIT_SCANF_NORMAL \ 1495 INTERCEPT_FUNCTION(scanf); \ 1496 INTERCEPT_FUNCTION(sscanf); \ 1497 INTERCEPT_FUNCTION(fscanf); \ 1498 INTERCEPT_FUNCTION(vscanf); \ 1499 INTERCEPT_FUNCTION(vsscanf); \ 1500 INTERCEPT_FUNCTION(vfscanf); \ 1501 1502#if SANITIZER_INTERCEPT_ISOC99_SCANF 1503INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 1504FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 1505 1506INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 1507FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 1508 1509INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 1510FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 1511#endif 1512 1513#endif 1514 1515#if SANITIZER_INTERCEPT_SCANF 1516#define INIT_SCANF \ 1517 COMMON_INTERCEPT_FUNCTION_LDBL(scanf); \ 1518 COMMON_INTERCEPT_FUNCTION_LDBL(sscanf); \ 1519 COMMON_INTERCEPT_FUNCTION_LDBL(fscanf); \ 1520 COMMON_INTERCEPT_FUNCTION_LDBL(vscanf); \ 1521 COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \ 1522 COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf); 1523#else 1524#define INIT_SCANF 1525#endif 1526 1527#if SANITIZER_INTERCEPT_ISOC99_SCANF 1528#define INIT_ISOC99_SCANF \ 1529 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \ 1530 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \ 1531 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ 1532 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ 1533 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 1534 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); 1535#else 1536#define INIT_ISOC99_SCANF 1537#endif 1538 1539#if SANITIZER_INTERCEPT_PRINTF 1540 1541#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \ 1542 void *ctx; \ 1543 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1544 va_list aq; \ 1545 va_copy(aq, ap); 1546 1547#define VPRINTF_INTERCEPTOR_RETURN() \ 1548 va_end(aq); 1549 1550#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \ 1551 { \ 1552 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \ 1553 if (common_flags()->check_printf) \ 1554 printf_common(ctx, format, aq); \ 1555 int res = REAL(vname)(__VA_ARGS__); \ 1556 VPRINTF_INTERCEPTOR_RETURN(); \ 1557 return res; \ 1558 } 1559 1560// FIXME: under ASan the REAL() call below may write to freed memory and 1561// corrupt its metadata. See 1562// https://github.com/google/sanitizers/issues/321. 1563#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \ 1564 { \ 1565 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \ 1566 if (common_flags()->check_printf) { \ 1567 printf_common(ctx, format, aq); \ 1568 } \ 1569 int res = REAL(vname)(str, __VA_ARGS__); \ 1570 if (res >= 0) { \ 1571 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \ 1572 } \ 1573 VPRINTF_INTERCEPTOR_RETURN(); \ 1574 return res; \ 1575 } 1576 1577// FIXME: under ASan the REAL() call below may write to freed memory and 1578// corrupt its metadata. See 1579// https://github.com/google/sanitizers/issues/321. 1580#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \ 1581 { \ 1582 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \ 1583 if (common_flags()->check_printf) { \ 1584 printf_common(ctx, format, aq); \ 1585 } \ 1586 int res = REAL(vname)(str, size, __VA_ARGS__); \ 1587 if (res >= 0) { \ 1588 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \ 1589 } \ 1590 VPRINTF_INTERCEPTOR_RETURN(); \ 1591 return res; \ 1592 } 1593 1594// FIXME: under ASan the REAL() call below may write to freed memory and 1595// corrupt its metadata. See 1596// https://github.com/google/sanitizers/issues/321. 1597#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \ 1598 { \ 1599 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \ 1600 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \ 1601 if (common_flags()->check_printf) { \ 1602 printf_common(ctx, format, aq); \ 1603 } \ 1604 int res = REAL(vname)(strp, __VA_ARGS__); \ 1605 if (res >= 0) { \ 1606 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \ 1607 } \ 1608 VPRINTF_INTERCEPTOR_RETURN(); \ 1609 return res; \ 1610 } 1611 1612INTERCEPTOR(int, vprintf, const char *format, va_list ap) 1613VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap) 1614 1615INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format, 1616 va_list ap) 1617VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap) 1618 1619INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format, 1620 va_list ap) 1621VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1622 1623#if SANITIZER_INTERCEPT___PRINTF_CHK 1624INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag, 1625 SIZE_T size_to, const char *format, va_list ap) 1626VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1627#endif 1628 1629#if SANITIZER_INTERCEPT_PRINTF_L 1630INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc, 1631 const char *format, va_list ap) 1632VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap) 1633 1634INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc, 1635 const char *format, ...) 1636FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format) 1637#endif // SANITIZER_INTERCEPT_PRINTF_L 1638 1639INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) 1640VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1641 1642#if SANITIZER_INTERCEPT___PRINTF_CHK 1643INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to, 1644 const char *format, va_list ap) 1645VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1646#endif 1647 1648INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) 1649VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) 1650 1651#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1652INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap) 1653VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap) 1654 1655INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream, 1656 const char *format, va_list ap) 1657VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap) 1658 1659INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format, 1660 va_list ap) 1661VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap) 1662 1663INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format, 1664 va_list ap) 1665VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format, 1666 ap) 1667 1668#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1669 1670INTERCEPTOR(int, printf, const char *format, ...) 1671FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format) 1672 1673INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...) 1674FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format) 1675 1676#if SANITIZER_INTERCEPT___PRINTF_CHK 1677INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, 1678 const char *format, ...) 1679FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) 1680#endif 1681 1682INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT 1683FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT 1684 1685#if SANITIZER_INTERCEPT___PRINTF_CHK 1686INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, 1687 const char *format, ...) // NOLINT 1688FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT 1689#endif 1690 1691INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) 1692FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) 1693 1694#if SANITIZER_INTERCEPT___PRINTF_CHK 1695INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, 1696 SIZE_T size_to, const char *format, ...) // NOLINT 1697FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT 1698#endif 1699 1700INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) 1701FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) 1702 1703#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1704INTERCEPTOR(int, __isoc99_printf, const char *format, ...) 1705FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format) 1706 1707INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format, 1708 ...) 1709FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format) 1710 1711INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...) 1712FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format) 1713 1714INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size, 1715 const char *format, ...) 1716FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, 1717 format) 1718 1719#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1720 1721#endif // SANITIZER_INTERCEPT_PRINTF 1722 1723#if SANITIZER_INTERCEPT_PRINTF 1724#define INIT_PRINTF \ 1725 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \ 1726 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \ 1727 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \ 1728 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \ 1729 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \ 1730 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \ 1731 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \ 1732 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \ 1733 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \ 1734 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf); 1735#else 1736#define INIT_PRINTF 1737#endif 1738 1739#if SANITIZER_INTERCEPT___PRINTF_CHK 1740#define INIT___PRINTF_CHK \ 1741 COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \ 1742 COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \ 1743 COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \ 1744 COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \ 1745 COMMON_INTERCEPT_FUNCTION(__fprintf_chk); 1746#else 1747#define INIT___PRINTF_CHK 1748#endif 1749 1750#if SANITIZER_INTERCEPT_PRINTF_L 1751#define INIT_PRINTF_L \ 1752 COMMON_INTERCEPT_FUNCTION(snprintf_l); \ 1753 COMMON_INTERCEPT_FUNCTION(vsnprintf_l); 1754#else 1755#define INIT_PRINTF_L 1756#endif 1757 1758#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1759#define INIT_ISOC99_PRINTF \ 1760 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \ 1761 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \ 1762 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \ 1763 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \ 1764 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \ 1765 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \ 1766 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \ 1767 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf); 1768#else 1769#define INIT_ISOC99_PRINTF 1770#endif 1771 1772#if SANITIZER_INTERCEPT_IOCTL 1773#include "sanitizer_common_interceptors_ioctl.inc" 1774#include "sanitizer_interceptors_ioctl_netbsd.inc" 1775INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { 1776 // We need a frame pointer, because we call into ioctl_common_[pre|post] which 1777 // can trigger a report and we need to be able to unwind through this 1778 // function. On Mac in debug mode we might not have a frame pointer, because 1779 // ioctl_common_[pre|post] doesn't get inlined here. 1780 ENABLE_FRAME_POINTER; 1781 1782 void *ctx; 1783 va_list ap; 1784 va_start(ap, request); 1785 void *arg = va_arg(ap, void *); 1786 va_end(ap); 1787 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 1788 1789 CHECK(ioctl_initialized); 1790 1791 // Note: TSan does not use common flags, and they are zero-initialized. 1792 // This effectively disables ioctl handling in TSan. 1793 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg); 1794 1795 // Although request is unsigned long, the rest of the interceptor uses it 1796 // as just "unsigned" to save space, because we know that all values fit in 1797 // "unsigned" - they are compile-time constants. 1798 1799 const ioctl_desc *desc = ioctl_lookup(request); 1800 ioctl_desc decoded_desc; 1801 if (!desc) { 1802 VPrintf(2, "Decoding unknown ioctl 0x%x\n", request); 1803 if (!ioctl_decode(request, &decoded_desc)) 1804 Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request); 1805 else 1806 desc = &decoded_desc; 1807 } 1808 1809 if (desc) ioctl_common_pre(ctx, desc, d, request, arg); 1810 int res = REAL(ioctl)(d, request, arg); 1811 // FIXME: some ioctls have different return values for success and failure. 1812 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg); 1813 return res; 1814} 1815#define INIT_IOCTL \ 1816 ioctl_init(); \ 1817 COMMON_INTERCEPT_FUNCTION(ioctl); 1818#else 1819#define INIT_IOCTL 1820#endif 1821 1822#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \ 1823 SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \ 1824 SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1825static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { 1826 if (pwd) { 1827 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); 1828 if (pwd->pw_name) 1829 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name, 1830 REAL(strlen)(pwd->pw_name) + 1); 1831 if (pwd->pw_passwd) 1832 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd, 1833 REAL(strlen)(pwd->pw_passwd) + 1); 1834#if !SANITIZER_ANDROID 1835 if (pwd->pw_gecos) 1836 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos, 1837 REAL(strlen)(pwd->pw_gecos) + 1); 1838#endif 1839#if SANITIZER_MAC 1840 if (pwd->pw_class) 1841 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class, 1842 REAL(strlen)(pwd->pw_class) + 1); 1843#endif 1844 if (pwd->pw_dir) 1845 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir, 1846 REAL(strlen)(pwd->pw_dir) + 1); 1847 if (pwd->pw_shell) 1848 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell, 1849 REAL(strlen)(pwd->pw_shell) + 1); 1850 } 1851} 1852 1853static void unpoison_group(void *ctx, __sanitizer_group *grp) { 1854 if (grp) { 1855 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); 1856 if (grp->gr_name) 1857 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name, 1858 REAL(strlen)(grp->gr_name) + 1); 1859 if (grp->gr_passwd) 1860 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd, 1861 REAL(strlen)(grp->gr_passwd) + 1); 1862 char **p = grp->gr_mem; 1863 for (; *p; ++p) { 1864 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1); 1865 } 1866 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem, 1867 (p - grp->gr_mem + 1) * sizeof(*p)); 1868 } 1869} 1870#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || 1871 // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || 1872 // SANITIZER_INTERCEPT_GETPWENT_R || 1873 // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1874 1875#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 1876INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { 1877 void *ctx; 1878 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 1879 if (name) 1880 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1881 __sanitizer_passwd *res = REAL(getpwnam)(name); 1882 if (res) unpoison_passwd(ctx, res); 1883 return res; 1884} 1885INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { 1886 void *ctx; 1887 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 1888 __sanitizer_passwd *res = REAL(getpwuid)(uid); 1889 if (res) unpoison_passwd(ctx, res); 1890 return res; 1891} 1892INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { 1893 void *ctx; 1894 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 1895 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1896 __sanitizer_group *res = REAL(getgrnam)(name); 1897 if (res) unpoison_group(ctx, res); 1898 return res; 1899} 1900INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) { 1901 void *ctx; 1902 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 1903 __sanitizer_group *res = REAL(getgrgid)(gid); 1904 if (res) unpoison_group(ctx, res); 1905 return res; 1906} 1907#define INIT_GETPWNAM_AND_FRIENDS \ 1908 COMMON_INTERCEPT_FUNCTION(getpwnam); \ 1909 COMMON_INTERCEPT_FUNCTION(getpwuid); \ 1910 COMMON_INTERCEPT_FUNCTION(getgrnam); \ 1911 COMMON_INTERCEPT_FUNCTION(getgrgid); 1912#else 1913#define INIT_GETPWNAM_AND_FRIENDS 1914#endif 1915 1916#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1917INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, 1918 char *buf, SIZE_T buflen, __sanitizer_passwd **result) { 1919 void *ctx; 1920 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 1921 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1922 // FIXME: under ASan the call below may write to freed memory and corrupt 1923 // its metadata. See 1924 // https://github.com/google/sanitizers/issues/321. 1925 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 1926 if (!res) { 1927 if (result && *result) unpoison_passwd(ctx, *result); 1928 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1929 } 1930 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1931 return res; 1932} 1933INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf, 1934 SIZE_T buflen, __sanitizer_passwd **result) { 1935 void *ctx; 1936 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 1937 // FIXME: under ASan the call below may write to freed memory and corrupt 1938 // its metadata. See 1939 // https://github.com/google/sanitizers/issues/321. 1940 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 1941 if (!res) { 1942 if (result && *result) unpoison_passwd(ctx, *result); 1943 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1944 } 1945 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1946 return res; 1947} 1948INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, 1949 char *buf, SIZE_T buflen, __sanitizer_group **result) { 1950 void *ctx; 1951 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 1952 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1953 // FIXME: under ASan the call below may write to freed memory and corrupt 1954 // its metadata. See 1955 // https://github.com/google/sanitizers/issues/321. 1956 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 1957 if (!res) { 1958 if (result && *result) unpoison_group(ctx, *result); 1959 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1960 } 1961 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1962 return res; 1963} 1964INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf, 1965 SIZE_T buflen, __sanitizer_group **result) { 1966 void *ctx; 1967 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 1968 // FIXME: under ASan the call below may write to freed memory and corrupt 1969 // its metadata. See 1970 // https://github.com/google/sanitizers/issues/321. 1971 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 1972 if (!res) { 1973 if (result && *result) unpoison_group(ctx, *result); 1974 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1975 } 1976 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1977 return res; 1978} 1979#define INIT_GETPWNAM_R_AND_FRIENDS \ 1980 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \ 1981 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \ 1982 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \ 1983 COMMON_INTERCEPT_FUNCTION(getgrgid_r); 1984#else 1985#define INIT_GETPWNAM_R_AND_FRIENDS 1986#endif 1987 1988#if SANITIZER_INTERCEPT_GETPWENT 1989INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) { 1990 void *ctx; 1991 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy); 1992 __sanitizer_passwd *res = REAL(getpwent)(dummy); 1993 if (res) unpoison_passwd(ctx, res); 1994 return res; 1995} 1996INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) { 1997 void *ctx; 1998 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy); 1999 __sanitizer_group *res = REAL(getgrent)(dummy); 2000 if (res) unpoison_group(ctx, res);; 2001 return res; 2002} 2003#define INIT_GETPWENT \ 2004 COMMON_INTERCEPT_FUNCTION(getpwent); \ 2005 COMMON_INTERCEPT_FUNCTION(getgrent); 2006#else 2007#define INIT_GETPWENT 2008#endif 2009 2010#if SANITIZER_INTERCEPT_FGETPWENT 2011INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) { 2012 void *ctx; 2013 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp); 2014 __sanitizer_passwd *res = REAL(fgetpwent)(fp); 2015 if (res) unpoison_passwd(ctx, res); 2016 return res; 2017} 2018INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) { 2019 void *ctx; 2020 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp); 2021 __sanitizer_group *res = REAL(fgetgrent)(fp); 2022 if (res) unpoison_group(ctx, res); 2023 return res; 2024} 2025#define INIT_FGETPWENT \ 2026 COMMON_INTERCEPT_FUNCTION(fgetpwent); \ 2027 COMMON_INTERCEPT_FUNCTION(fgetgrent); 2028#else 2029#define INIT_FGETPWENT 2030#endif 2031 2032#if SANITIZER_INTERCEPT_GETPWENT_R 2033INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf, 2034 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2035 void *ctx; 2036 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp); 2037 // FIXME: under ASan the call below may write to freed memory and corrupt 2038 // its metadata. See 2039 // https://github.com/google/sanitizers/issues/321. 2040 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp); 2041 if (!res) { 2042 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 2043 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2044 } 2045 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2046 return res; 2047} 2048INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, 2049 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2050 void *ctx; 2051 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); 2052 // FIXME: under ASan the call below may write to freed memory and corrupt 2053 // its metadata. See 2054 // https://github.com/google/sanitizers/issues/321. 2055 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); 2056 if (!res) { 2057 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 2058 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2059 } 2060 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2061 return res; 2062} 2063INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, 2064 __sanitizer_group **pwbufp) { 2065 void *ctx; 2066 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); 2067 // FIXME: under ASan the call below may write to freed memory and corrupt 2068 // its metadata. See 2069 // https://github.com/google/sanitizers/issues/321. 2070 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); 2071 if (!res) { 2072 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 2073 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2074 } 2075 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2076 return res; 2077} 2078INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, 2079 SIZE_T buflen, __sanitizer_group **pwbufp) { 2080 void *ctx; 2081 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp); 2082 // FIXME: under ASan the call below may write to freed memory and corrupt 2083 // its metadata. See 2084 // https://github.com/google/sanitizers/issues/321. 2085 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp); 2086 if (!res) { 2087 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 2088 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 2089 } 2090 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2091 return res; 2092} 2093#define INIT_GETPWENT_R \ 2094 COMMON_INTERCEPT_FUNCTION(getpwent_r); \ 2095 COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \ 2096 COMMON_INTERCEPT_FUNCTION(getgrent_r); \ 2097 COMMON_INTERCEPT_FUNCTION(fgetgrent_r); 2098#else 2099#define INIT_GETPWENT_R 2100#endif 2101 2102#if SANITIZER_INTERCEPT_SETPWENT 2103// The only thing these interceptors do is disable any nested interceptors. 2104// These functions may open nss modules and call uninstrumented functions from 2105// them, and we don't want things like strlen() to trigger. 2106INTERCEPTOR(void, setpwent, int dummy) { 2107 void *ctx; 2108 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy); 2109 REAL(setpwent)(dummy); 2110} 2111INTERCEPTOR(void, endpwent, int dummy) { 2112 void *ctx; 2113 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy); 2114 REAL(endpwent)(dummy); 2115} 2116INTERCEPTOR(void, setgrent, int dummy) { 2117 void *ctx; 2118 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy); 2119 REAL(setgrent)(dummy); 2120} 2121INTERCEPTOR(void, endgrent, int dummy) { 2122 void *ctx; 2123 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy); 2124 REAL(endgrent)(dummy); 2125} 2126#define INIT_SETPWENT \ 2127 COMMON_INTERCEPT_FUNCTION(setpwent); \ 2128 COMMON_INTERCEPT_FUNCTION(endpwent); \ 2129 COMMON_INTERCEPT_FUNCTION(setgrent); \ 2130 COMMON_INTERCEPT_FUNCTION(endgrent); 2131#else 2132#define INIT_SETPWENT 2133#endif 2134 2135#if SANITIZER_INTERCEPT_CLOCK_GETTIME 2136INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 2137 void *ctx; 2138 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 2139 // FIXME: under ASan the call below may write to freed memory and corrupt 2140 // its metadata. See 2141 // https://github.com/google/sanitizers/issues/321. 2142 int res = REAL(clock_getres)(clk_id, tp); 2143 if (!res && tp) { 2144 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2145 } 2146 return res; 2147} 2148INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 2149 void *ctx; 2150 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 2151 // FIXME: under ASan the call below may write to freed memory and corrupt 2152 // its metadata. See 2153 // https://github.com/google/sanitizers/issues/321. 2154 int res = REAL(clock_gettime)(clk_id, tp); 2155 if (!res) { 2156 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2157 } 2158 return res; 2159} 2160namespace __sanitizer { 2161extern "C" { 2162int real_clock_gettime(u32 clk_id, void *tp) { 2163 return REAL(clock_gettime)(clk_id, tp); 2164} 2165} // extern "C" 2166} // namespace __sanitizer 2167INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 2168 void *ctx; 2169 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 2170 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 2171 return REAL(clock_settime)(clk_id, tp); 2172} 2173#define INIT_CLOCK_GETTIME \ 2174 COMMON_INTERCEPT_FUNCTION(clock_getres); \ 2175 COMMON_INTERCEPT_FUNCTION(clock_gettime); \ 2176 COMMON_INTERCEPT_FUNCTION(clock_settime); 2177#else 2178#define INIT_CLOCK_GETTIME 2179#endif 2180 2181#if SANITIZER_INTERCEPT_GETITIMER 2182INTERCEPTOR(int, getitimer, int which, void *curr_value) { 2183 void *ctx; 2184 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 2185 // FIXME: under ASan the call below may write to freed memory and corrupt 2186 // its metadata. See 2187 // https://github.com/google/sanitizers/issues/321. 2188 int res = REAL(getitimer)(which, curr_value); 2189 if (!res && curr_value) { 2190 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 2191 } 2192 return res; 2193} 2194INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 2195 void *ctx; 2196 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 2197 if (new_value) { 2198 // itimerval can contain padding that may be legitimately uninitialized 2199 const struct __sanitizer_itimerval *nv = 2200 (const struct __sanitizer_itimerval *)new_value; 2201 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec, 2202 sizeof(__sanitizer_time_t)); 2203 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec, 2204 sizeof(__sanitizer_suseconds_t)); 2205 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec, 2206 sizeof(__sanitizer_time_t)); 2207 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec, 2208 sizeof(__sanitizer_suseconds_t)); 2209 } 2210 // FIXME: under ASan the call below may write to freed memory and corrupt 2211 // its metadata. See 2212 // https://github.com/google/sanitizers/issues/321. 2213 int res = REAL(setitimer)(which, new_value, old_value); 2214 if (!res && old_value) { 2215 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 2216 } 2217 return res; 2218} 2219#define INIT_GETITIMER \ 2220 COMMON_INTERCEPT_FUNCTION(getitimer); \ 2221 COMMON_INTERCEPT_FUNCTION(setitimer); 2222#else 2223#define INIT_GETITIMER 2224#endif 2225 2226#if SANITIZER_INTERCEPT_GLOB 2227static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 2228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 2229 // +1 for NULL pointer at the end. 2230 if (pglob->gl_pathv) 2231 COMMON_INTERCEPTOR_WRITE_RANGE( 2232 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 2233 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 2234 char *p = pglob->gl_pathv[i]; 2235 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 2236 } 2237} 2238 2239#if SANITIZER_SOLARIS 2240INTERCEPTOR(int, glob, const char *pattern, int flags, 2241 int (*errfunc)(const char *epath, int eerrno), 2242 __sanitizer_glob_t *pglob) { 2243 void *ctx; 2244 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2245 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2246 int res = REAL(glob)(pattern, flags, errfunc, pglob); 2247 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2248 return res; 2249} 2250#else 2251static THREADLOCAL __sanitizer_glob_t *pglob_copy; 2252 2253static void wrapped_gl_closedir(void *dir) { 2254 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2255 pglob_copy->gl_closedir(dir); 2256} 2257 2258static void *wrapped_gl_readdir(void *dir) { 2259 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2260 return pglob_copy->gl_readdir(dir); 2261} 2262 2263static void *wrapped_gl_opendir(const char *s) { 2264 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2265 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2266 return pglob_copy->gl_opendir(s); 2267} 2268 2269static int wrapped_gl_lstat(const char *s, void *st) { 2270 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2271 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2272 return pglob_copy->gl_lstat(s, st); 2273} 2274 2275static int wrapped_gl_stat(const char *s, void *st) { 2276 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2277 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2278 return pglob_copy->gl_stat(s, st); 2279} 2280 2281static const __sanitizer_glob_t kGlobCopy = { 2282 0, 0, 0, 2283 0, wrapped_gl_closedir, wrapped_gl_readdir, 2284 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 2285 2286INTERCEPTOR(int, glob, const char *pattern, int flags, 2287 int (*errfunc)(const char *epath, int eerrno), 2288 __sanitizer_glob_t *pglob) { 2289 void *ctx; 2290 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2291 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2292 __sanitizer_glob_t glob_copy; 2293 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2294 if (flags & glob_altdirfunc) { 2295 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2296 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2297 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2298 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2299 Swap(pglob->gl_stat, glob_copy.gl_stat); 2300 pglob_copy = &glob_copy; 2301 } 2302 int res = REAL(glob)(pattern, flags, errfunc, pglob); 2303 if (flags & glob_altdirfunc) { 2304 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2305 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2306 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2307 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2308 Swap(pglob->gl_stat, glob_copy.gl_stat); 2309 } 2310 pglob_copy = 0; 2311 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2312 return res; 2313} 2314#endif // SANITIZER_SOLARIS 2315#define INIT_GLOB \ 2316 COMMON_INTERCEPT_FUNCTION(glob); 2317#else // SANITIZER_INTERCEPT_GLOB 2318#define INIT_GLOB 2319#endif // SANITIZER_INTERCEPT_GLOB 2320 2321#if SANITIZER_INTERCEPT_GLOB64 2322INTERCEPTOR(int, glob64, const char *pattern, int flags, 2323 int (*errfunc)(const char *epath, int eerrno), 2324 __sanitizer_glob_t *pglob) { 2325 void *ctx; 2326 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 2327 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2328 __sanitizer_glob_t glob_copy; 2329 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2330 if (flags & glob_altdirfunc) { 2331 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2332 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2333 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2334 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2335 Swap(pglob->gl_stat, glob_copy.gl_stat); 2336 pglob_copy = &glob_copy; 2337 } 2338 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 2339 if (flags & glob_altdirfunc) { 2340 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2341 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2342 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2343 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2344 Swap(pglob->gl_stat, glob_copy.gl_stat); 2345 } 2346 pglob_copy = 0; 2347 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2348 return res; 2349} 2350#define INIT_GLOB64 \ 2351 COMMON_INTERCEPT_FUNCTION(glob64); 2352#else // SANITIZER_INTERCEPT_GLOB64 2353#define INIT_GLOB64 2354#endif // SANITIZER_INTERCEPT_GLOB64 2355 2356#if SANITIZER_INTERCEPT_WAIT 2357// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 2358// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 2359// details. 2360INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 2361 void *ctx; 2362 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 2363 // FIXME: under ASan the call below may write to freed memory and corrupt 2364 // its metadata. See 2365 // https://github.com/google/sanitizers/issues/321. 2366 int res = REAL(wait)(status); 2367 if (res != -1 && status) 2368 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2369 return res; 2370} 2371// On FreeBSD id_t is always 64-bit wide. 2372#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) 2373INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop, 2374 int options) { 2375#else 2376INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 2377 int options) { 2378#endif 2379 void *ctx; 2380 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 2381 // FIXME: under ASan the call below may write to freed memory and corrupt 2382 // its metadata. See 2383 // https://github.com/google/sanitizers/issues/321. 2384 int res = REAL(waitid)(idtype, id, infop, options); 2385 if (res != -1 && infop) 2386 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 2387 return res; 2388} 2389INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 2390 void *ctx; 2391 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 2392 // FIXME: under ASan the call below may write to freed memory and corrupt 2393 // its metadata. See 2394 // https://github.com/google/sanitizers/issues/321. 2395 int res = REAL(waitpid)(pid, status, options); 2396 if (res != -1 && status) 2397 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2398 return res; 2399} 2400INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 2401 void *ctx; 2402 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 2403 // FIXME: under ASan the call below may write to freed memory and corrupt 2404 // its metadata. See 2405 // https://github.com/google/sanitizers/issues/321. 2406 int res = REAL(wait3)(status, options, rusage); 2407 if (res != -1) { 2408 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2409 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2410 } 2411 return res; 2412} 2413#if SANITIZER_ANDROID 2414INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { 2415 void *ctx; 2416 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); 2417 // FIXME: under ASan the call below may write to freed memory and corrupt 2418 // its metadata. See 2419 // https://github.com/google/sanitizers/issues/321. 2420 int res = REAL(__wait4)(pid, status, options, rusage); 2421 if (res != -1) { 2422 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2423 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2424 } 2425 return res; 2426} 2427#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4); 2428#else 2429INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 2430 void *ctx; 2431 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 2432 // FIXME: under ASan the call below may write to freed memory and corrupt 2433 // its metadata. See 2434 // https://github.com/google/sanitizers/issues/321. 2435 int res = REAL(wait4)(pid, status, options, rusage); 2436 if (res != -1) { 2437 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2438 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2439 } 2440 return res; 2441} 2442#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4); 2443#endif // SANITIZER_ANDROID 2444#define INIT_WAIT \ 2445 COMMON_INTERCEPT_FUNCTION(wait); \ 2446 COMMON_INTERCEPT_FUNCTION(waitid); \ 2447 COMMON_INTERCEPT_FUNCTION(waitpid); \ 2448 COMMON_INTERCEPT_FUNCTION(wait3); 2449#else 2450#define INIT_WAIT 2451#define INIT_WAIT4 2452#endif 2453 2454#if SANITIZER_INTERCEPT_INET 2455INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 2456 void *ctx; 2457 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 2458 uptr sz = __sanitizer_in_addr_sz(af); 2459 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 2460 // FIXME: figure out read size based on the address family. 2461 // FIXME: under ASan the call below may write to freed memory and corrupt 2462 // its metadata. See 2463 // https://github.com/google/sanitizers/issues/321. 2464 char *res = REAL(inet_ntop)(af, src, dst, size); 2465 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2466 return res; 2467} 2468INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 2469 void *ctx; 2470 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 2471 COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0); 2472 // FIXME: figure out read size based on the address family. 2473 // FIXME: under ASan the call below may write to freed memory and corrupt 2474 // its metadata. See 2475 // https://github.com/google/sanitizers/issues/321. 2476 int res = REAL(inet_pton)(af, src, dst); 2477 if (res == 1) { 2478 uptr sz = __sanitizer_in_addr_sz(af); 2479 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2480 } 2481 return res; 2482} 2483#define INIT_INET \ 2484 COMMON_INTERCEPT_FUNCTION(inet_ntop); \ 2485 COMMON_INTERCEPT_FUNCTION(inet_pton); 2486#else 2487#define INIT_INET 2488#endif 2489 2490#if SANITIZER_INTERCEPT_INET 2491INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 2492 void *ctx; 2493 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 2494 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 2495 // FIXME: under ASan the call below may write to freed memory and corrupt 2496 // its metadata. See 2497 // https://github.com/google/sanitizers/issues/321. 2498 int res = REAL(inet_aton)(cp, dst); 2499 if (res != 0) { 2500 uptr sz = __sanitizer_in_addr_sz(af_inet); 2501 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2502 } 2503 return res; 2504} 2505#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton); 2506#else 2507#define INIT_INET_ATON 2508#endif 2509 2510#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 2511INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 2512 void *ctx; 2513 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 2514 // FIXME: under ASan the call below may write to freed memory and corrupt 2515 // its metadata. See 2516 // https://github.com/google/sanitizers/issues/321. 2517 int res = REAL(pthread_getschedparam)(thread, policy, param); 2518 if (res == 0) { 2519 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 2520 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 2521 } 2522 return res; 2523} 2524#define INIT_PTHREAD_GETSCHEDPARAM \ 2525 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam); 2526#else 2527#define INIT_PTHREAD_GETSCHEDPARAM 2528#endif 2529 2530#if SANITIZER_INTERCEPT_GETADDRINFO 2531INTERCEPTOR(int, getaddrinfo, char *node, char *service, 2532 struct __sanitizer_addrinfo *hints, 2533 struct __sanitizer_addrinfo **out) { 2534 void *ctx; 2535 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 2536 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 2537 if (service) 2538 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 2539 if (hints) 2540 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 2541 // FIXME: under ASan the call below may write to freed memory and corrupt 2542 // its metadata. See 2543 // https://github.com/google/sanitizers/issues/321. 2544 int res = REAL(getaddrinfo)(node, service, hints, out); 2545 if (res == 0 && out) { 2546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 2547 struct __sanitizer_addrinfo *p = *out; 2548 while (p) { 2549 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2550 if (p->ai_addr) 2551 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 2552 if (p->ai_canonname) 2553 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 2554 REAL(strlen)(p->ai_canonname) + 1); 2555 p = p->ai_next; 2556 } 2557 } 2558 return res; 2559} 2560#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo); 2561#else 2562#define INIT_GETADDRINFO 2563#endif 2564 2565#if SANITIZER_INTERCEPT_GETNAMEINFO 2566INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 2567 unsigned hostlen, char *serv, unsigned servlen, int flags) { 2568 void *ctx; 2569 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 2570 serv, servlen, flags); 2571 // FIXME: consider adding READ_RANGE(sockaddr, salen) 2572 // There is padding in in_addr that may make this too noisy 2573 // FIXME: under ASan the call below may write to freed memory and corrupt 2574 // its metadata. See 2575 // https://github.com/google/sanitizers/issues/321. 2576 int res = 2577 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 2578 if (res == 0) { 2579 if (host && hostlen) 2580 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 2581 if (serv && servlen) 2582 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 2583 } 2584 return res; 2585} 2586#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo); 2587#else 2588#define INIT_GETNAMEINFO 2589#endif 2590 2591#if SANITIZER_INTERCEPT_GETSOCKNAME 2592INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 2593 void *ctx; 2594 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 2595 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2596 int addrlen_in = *addrlen; 2597 // FIXME: under ASan the call below may write to freed memory and corrupt 2598 // its metadata. See 2599 // https://github.com/google/sanitizers/issues/321. 2600 int res = REAL(getsockname)(sock_fd, addr, addrlen); 2601 if (res == 0) { 2602 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 2603 } 2604 return res; 2605} 2606#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname); 2607#else 2608#define INIT_GETSOCKNAME 2609#endif 2610 2611#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2612static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 2613 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 2614 if (h->h_name) 2615 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 2616 char **p = h->h_aliases; 2617 while (*p) { 2618 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 2619 ++p; 2620 } 2621 COMMON_INTERCEPTOR_WRITE_RANGE( 2622 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 2623 p = h->h_addr_list; 2624 while (*p) { 2625 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 2626 ++p; 2627 } 2628 COMMON_INTERCEPTOR_WRITE_RANGE( 2629 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 2630} 2631#endif 2632 2633#if SANITIZER_INTERCEPT_GETHOSTBYNAME 2634INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 2635 void *ctx; 2636 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 2637 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 2638 if (res) write_hostent(ctx, res); 2639 return res; 2640} 2641 2642INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 2643 int type) { 2644 void *ctx; 2645 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 2646 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2647 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 2648 if (res) write_hostent(ctx, res); 2649 return res; 2650} 2651 2652INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 2653 void *ctx; 2654 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 2655 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 2656 if (res) write_hostent(ctx, res); 2657 return res; 2658} 2659#define INIT_GETHOSTBYNAME \ 2660 COMMON_INTERCEPT_FUNCTION(gethostent); \ 2661 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ 2662 COMMON_INTERCEPT_FUNCTION(gethostbyname); 2663#else 2664#define INIT_GETHOSTBYNAME 2665#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME 2666 2667#if SANITIZER_INTERCEPT_GETHOSTBYNAME2 2668INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 2669 void *ctx; 2670 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 2671 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 2672 if (res) write_hostent(ctx, res); 2673 return res; 2674} 2675#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2); 2676#else 2677#define INIT_GETHOSTBYNAME2 2678#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME2 2679 2680#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2681INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 2682 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 2683 int *h_errnop) { 2684 void *ctx; 2685 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 2686 h_errnop); 2687 // FIXME: under ASan the call below may write to freed memory and corrupt 2688 // its metadata. See 2689 // https://github.com/google/sanitizers/issues/321. 2690 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 2691 if (result) { 2692 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2693 if (res == 0 && *result) write_hostent(ctx, *result); 2694 } 2695 if (h_errnop) 2696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2697 return res; 2698} 2699#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r); 2700#else 2701#define INIT_GETHOSTBYNAME_R 2702#endif 2703 2704#if SANITIZER_INTERCEPT_GETHOSTENT_R 2705INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 2706 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 2707 void *ctx; 2708 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 2709 h_errnop); 2710 // FIXME: under ASan the call below may write to freed memory and corrupt 2711 // its metadata. See 2712 // https://github.com/google/sanitizers/issues/321. 2713 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 2714 if (result) { 2715 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2716 if (res == 0 && *result) write_hostent(ctx, *result); 2717 } 2718 if (h_errnop) 2719 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2720 return res; 2721} 2722#define INIT_GETHOSTENT_R \ 2723 COMMON_INTERCEPT_FUNCTION(gethostent_r); 2724#else 2725#define INIT_GETHOSTENT_R 2726#endif 2727 2728#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R 2729INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 2730 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2731 __sanitizer_hostent **result, int *h_errnop) { 2732 void *ctx; 2733 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 2734 buflen, result, h_errnop); 2735 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2736 // FIXME: under ASan the call below may write to freed memory and corrupt 2737 // its metadata. See 2738 // https://github.com/google/sanitizers/issues/321. 2739 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 2740 h_errnop); 2741 if (result) { 2742 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2743 if (res == 0 && *result) write_hostent(ctx, *result); 2744 } 2745 if (h_errnop) 2746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2747 return res; 2748} 2749#define INIT_GETHOSTBYADDR_R \ 2750 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r); 2751#else 2752#define INIT_GETHOSTBYADDR_R 2753#endif 2754 2755#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R 2756INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 2757 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2758 __sanitizer_hostent **result, int *h_errnop) { 2759 void *ctx; 2760 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 2761 result, h_errnop); 2762 // FIXME: under ASan the call below may write to freed memory and corrupt 2763 // its metadata. See 2764 // https://github.com/google/sanitizers/issues/321. 2765 int res = 2766 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 2767 if (result) { 2768 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2769 if (res == 0 && *result) write_hostent(ctx, *result); 2770 } 2771 if (h_errnop) 2772 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2773 return res; 2774} 2775#define INIT_GETHOSTBYNAME2_R \ 2776 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r); 2777#else 2778#define INIT_GETHOSTBYNAME2_R 2779#endif 2780 2781#if SANITIZER_INTERCEPT_GETSOCKOPT 2782INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 2783 int *optlen) { 2784 void *ctx; 2785 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 2786 optlen); 2787 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 2788 // FIXME: under ASan the call below may write to freed memory and corrupt 2789 // its metadata. See 2790 // https://github.com/google/sanitizers/issues/321. 2791 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 2792 if (res == 0) 2793 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 2794 return res; 2795} 2796#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt); 2797#else 2798#define INIT_GETSOCKOPT 2799#endif 2800 2801#if SANITIZER_INTERCEPT_ACCEPT 2802INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 2803 void *ctx; 2804 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 2805 unsigned addrlen0 = 0; 2806 if (addrlen) { 2807 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2808 addrlen0 = *addrlen; 2809 } 2810 int fd2 = REAL(accept)(fd, addr, addrlen); 2811 if (fd2 >= 0) { 2812 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2813 if (addr && addrlen) 2814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2815 } 2816 return fd2; 2817} 2818#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept); 2819#else 2820#define INIT_ACCEPT 2821#endif 2822 2823#if SANITIZER_INTERCEPT_ACCEPT4 2824INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 2825 void *ctx; 2826 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 2827 unsigned addrlen0 = 0; 2828 if (addrlen) { 2829 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2830 addrlen0 = *addrlen; 2831 } 2832 // FIXME: under ASan the call below may write to freed memory and corrupt 2833 // its metadata. See 2834 // https://github.com/google/sanitizers/issues/321. 2835 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 2836 if (fd2 >= 0) { 2837 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2838 if (addr && addrlen) 2839 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2840 } 2841 return fd2; 2842} 2843#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4); 2844#else 2845#define INIT_ACCEPT4 2846#endif 2847 2848#if SANITIZER_INTERCEPT_PACCEPT 2849INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, 2850 __sanitizer_sigset_t *set, int f) { 2851 void *ctx; 2852 COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f); 2853 unsigned addrlen0 = 0; 2854 if (addrlen) { 2855 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2856 addrlen0 = *addrlen; 2857 } 2858 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 2859 int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); 2860 if (fd2 >= 0) { 2861 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2862 if (addr && addrlen) 2863 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2864 } 2865 return fd2; 2866} 2867#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept); 2868#else 2869#define INIT_PACCEPT 2870#endif 2871 2872#if SANITIZER_INTERCEPT_MODF 2873INTERCEPTOR(double, modf, double x, double *iptr) { 2874 void *ctx; 2875 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 2876 // FIXME: under ASan the call below may write to freed memory and corrupt 2877 // its metadata. See 2878 // https://github.com/google/sanitizers/issues/321. 2879 double res = REAL(modf)(x, iptr); 2880 if (iptr) { 2881 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2882 } 2883 return res; 2884} 2885INTERCEPTOR(float, modff, float x, float *iptr) { 2886 void *ctx; 2887 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 2888 // FIXME: under ASan the call below may write to freed memory and corrupt 2889 // its metadata. See 2890 // https://github.com/google/sanitizers/issues/321. 2891 float res = REAL(modff)(x, iptr); 2892 if (iptr) { 2893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2894 } 2895 return res; 2896} 2897INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 2898 void *ctx; 2899 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 2900 // FIXME: under ASan the call below may write to freed memory and corrupt 2901 // its metadata. See 2902 // https://github.com/google/sanitizers/issues/321. 2903 long double res = REAL(modfl)(x, iptr); 2904 if (iptr) { 2905 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2906 } 2907 return res; 2908} 2909#define INIT_MODF \ 2910 COMMON_INTERCEPT_FUNCTION(modf); \ 2911 COMMON_INTERCEPT_FUNCTION(modff); \ 2912 COMMON_INTERCEPT_FUNCTION_LDBL(modfl); 2913#else 2914#define INIT_MODF 2915#endif 2916 2917#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG 2918static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 2919 SSIZE_T maxlen) { 2920 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 2921 if (msg->msg_name && msg->msg_namelen) 2922 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 2923 if (msg->msg_iov && msg->msg_iovlen) 2924 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 2925 sizeof(*msg->msg_iov) * msg->msg_iovlen); 2926 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 2927 if (msg->msg_control && msg->msg_controllen) 2928 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 2929} 2930#endif 2931 2932#if SANITIZER_INTERCEPT_RECVMSG 2933INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 2934 int flags) { 2935 void *ctx; 2936 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 2937 // FIXME: under ASan the call below may write to freed memory and corrupt 2938 // its metadata. See 2939 // https://github.com/google/sanitizers/issues/321. 2940 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 2941 if (res >= 0) { 2942 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 2943 if (msg) { 2944 write_msghdr(ctx, msg, res); 2945 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg); 2946 } 2947 } 2948 return res; 2949} 2950#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg); 2951#else 2952#define INIT_RECVMSG 2953#endif 2954 2955#if SANITIZER_INTERCEPT_RECVMMSG 2956INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 2957 unsigned int vlen, int flags, void *timeout) { 2958 void *ctx; 2959 COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout); 2960 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2961 int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); 2962 if (res >= 0) { 2963 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 2964 for (int i = 0; i < res; ++i) { 2965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 2966 sizeof(msgvec[i].msg_len)); 2967 write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 2968 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr); 2969 } 2970 } 2971 return res; 2972} 2973#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg); 2974#else 2975#define INIT_RECVMMSG 2976#endif 2977 2978#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG 2979static void read_msghdr_control(void *ctx, void *control, uptr controllen) { 2980 const unsigned kCmsgDataOffset = 2981 RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr)); 2982 2983 char *p = (char *)control; 2984 char *const control_end = p + controllen; 2985 while (true) { 2986 if (p + sizeof(__sanitizer_cmsghdr) > control_end) break; 2987 __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p; 2988 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len)); 2989 2990 if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break; 2991 2992 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level, 2993 sizeof(cmsg->cmsg_level)); 2994 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type, 2995 sizeof(cmsg->cmsg_type)); 2996 2997 if (cmsg->cmsg_len > kCmsgDataOffset) { 2998 char *data = p + kCmsgDataOffset; 2999 unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset; 3000 if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len); 3001 } 3002 3003 p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr)); 3004 } 3005} 3006 3007static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 3008 SSIZE_T maxlen) { 3009#define R(f) \ 3010 COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f)) 3011 R(name); 3012 R(namelen); 3013 R(iov); 3014 R(iovlen); 3015 R(control); 3016 R(controllen); 3017 R(flags); 3018#undef R 3019 if (msg->msg_name && msg->msg_namelen) 3020 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen); 3021 if (msg->msg_iov && msg->msg_iovlen) 3022 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov, 3023 sizeof(*msg->msg_iov) * msg->msg_iovlen); 3024 read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 3025 if (msg->msg_control && msg->msg_controllen) 3026 read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen); 3027} 3028#endif 3029 3030#if SANITIZER_INTERCEPT_SENDMSG 3031INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, 3032 int flags) { 3033 void *ctx; 3034 COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags); 3035 if (fd >= 0) { 3036 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3037 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3038 } 3039 SSIZE_T res = REAL(sendmsg)(fd, msg, flags); 3040 if (common_flags()->intercept_send && res >= 0 && msg) 3041 read_msghdr(ctx, msg, res); 3042 return res; 3043} 3044#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg); 3045#else 3046#define INIT_SENDMSG 3047#endif 3048 3049#if SANITIZER_INTERCEPT_SENDMMSG 3050INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 3051 unsigned vlen, int flags) { 3052 void *ctx; 3053 COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags); 3054 if (fd >= 0) { 3055 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3056 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3057 } 3058 int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); 3059 if (res >= 0 && msgvec) 3060 for (int i = 0; i < res; ++i) { 3061 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 3062 sizeof(msgvec[i].msg_len)); 3063 if (common_flags()->intercept_send) 3064 read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 3065 } 3066 return res; 3067} 3068#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); 3069#else 3070#define INIT_SENDMMSG 3071#endif 3072 3073#if SANITIZER_INTERCEPT_GETPEERNAME 3074INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 3075 void *ctx; 3076 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 3077 unsigned addr_sz; 3078 if (addrlen) addr_sz = *addrlen; 3079 // FIXME: under ASan the call below may write to freed memory and corrupt 3080 // its metadata. See 3081 // https://github.com/google/sanitizers/issues/321. 3082 int res = REAL(getpeername)(sockfd, addr, addrlen); 3083 if (!res && addr && addrlen) 3084 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 3085 return res; 3086} 3087#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername); 3088#else 3089#define INIT_GETPEERNAME 3090#endif 3091 3092#if SANITIZER_INTERCEPT_SYSINFO 3093INTERCEPTOR(int, sysinfo, void *info) { 3094 void *ctx; 3095 // FIXME: under ASan the call below may write to freed memory and corrupt 3096 // its metadata. See 3097 // https://github.com/google/sanitizers/issues/321. 3098 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 3099 int res = REAL(sysinfo)(info); 3100 if (!res && info) 3101 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 3102 return res; 3103} 3104#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo); 3105#else 3106#define INIT_SYSINFO 3107#endif 3108 3109#if SANITIZER_INTERCEPT_READDIR 3110INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) { 3111 void *ctx; 3112 COMMON_INTERCEPTOR_ENTER(ctx, opendir, path); 3113 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3114 __sanitizer_dirent *res = REAL(opendir)(path); 3115 if (res) 3116 COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path); 3117 return res; 3118} 3119 3120INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 3121 void *ctx; 3122 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 3123 // FIXME: under ASan the call below may write to freed memory and corrupt 3124 // its metadata. See 3125 // https://github.com/google/sanitizers/issues/321. 3126 __sanitizer_dirent *res = REAL(readdir)(dirp); 3127 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3128 return res; 3129} 3130 3131INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 3132 __sanitizer_dirent **result) { 3133 void *ctx; 3134 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 3135 // FIXME: under ASan the call below may write to freed memory and corrupt 3136 // its metadata. See 3137 // https://github.com/google/sanitizers/issues/321. 3138 int res = REAL(readdir_r)(dirp, entry, result); 3139 if (!res) { 3140 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3141 if (*result) 3142 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3143 } 3144 return res; 3145} 3146 3147#define INIT_READDIR \ 3148 COMMON_INTERCEPT_FUNCTION(opendir); \ 3149 COMMON_INTERCEPT_FUNCTION(readdir); \ 3150 COMMON_INTERCEPT_FUNCTION(readdir_r); 3151#else 3152#define INIT_READDIR 3153#endif 3154 3155#if SANITIZER_INTERCEPT_READDIR64 3156INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 3157 void *ctx; 3158 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 3159 // FIXME: under ASan the call below may write to freed memory and corrupt 3160 // its metadata. See 3161 // https://github.com/google/sanitizers/issues/321. 3162 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 3163 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3164 return res; 3165} 3166 3167INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 3168 __sanitizer_dirent64 **result) { 3169 void *ctx; 3170 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 3171 // FIXME: under ASan the call below may write to freed memory and corrupt 3172 // its metadata. See 3173 // https://github.com/google/sanitizers/issues/321. 3174 int res = REAL(readdir64_r)(dirp, entry, result); 3175 if (!res) { 3176 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3177 if (*result) 3178 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3179 } 3180 return res; 3181} 3182#define INIT_READDIR64 \ 3183 COMMON_INTERCEPT_FUNCTION(readdir64); \ 3184 COMMON_INTERCEPT_FUNCTION(readdir64_r); 3185#else 3186#define INIT_READDIR64 3187#endif 3188 3189#if SANITIZER_INTERCEPT_PTRACE 3190INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 3191 void *ctx; 3192 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 3193 __sanitizer_iovec local_iovec; 3194 3195 if (data) { 3196 if (request == ptrace_setregs) 3197 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 3198 else if (request == ptrace_setfpregs) 3199 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3200 else if (request == ptrace_setfpxregs) 3201 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3202 else if (request == ptrace_setvfpregs) 3203 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3204 else if (request == ptrace_setsiginfo) 3205 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 3206 // Some kernel might zero the iovec::iov_base in case of invalid 3207 // write access. In this case copy the invalid address for further 3208 // inspection. 3209 else if (request == ptrace_setregset || request == ptrace_getregset) { 3210 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3211 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec)); 3212 local_iovec = *iovec; 3213 if (request == ptrace_setregset) 3214 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len); 3215 } 3216 } 3217 3218 // FIXME: under ASan the call below may write to freed memory and corrupt 3219 // its metadata. See 3220 // https://github.com/google/sanitizers/issues/321. 3221 uptr res = REAL(ptrace)(request, pid, addr, data); 3222 3223 if (!res && data) { 3224 // Note that PEEK* requests assign different meaning to the return value. 3225 // This function does not handle them (nor does it need to). 3226 if (request == ptrace_getregs) 3227 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 3228 else if (request == ptrace_getfpregs) 3229 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3230 else if (request == ptrace_getfpxregs) 3231 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3232 else if (request == ptrace_getvfpregs) 3233 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3234 else if (request == ptrace_getsiginfo) 3235 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 3236 else if (request == ptrace_geteventmsg) 3237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long)); 3238 else if (request == ptrace_getregset) { 3239 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec)); 3241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base, 3242 local_iovec.iov_len); 3243 } 3244 } 3245 return res; 3246} 3247 3248#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace); 3249#else 3250#define INIT_PTRACE 3251#endif 3252 3253#if SANITIZER_INTERCEPT_SETLOCALE 3254static void unpoison_ctype_arrays(void *ctx) { 3255#if SANITIZER_NETBSD 3256 // These arrays contain 256 regular elements in unsigned char range + 1 EOF 3257 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short)); 3258 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short)); 3259 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short)); 3260#endif 3261} 3262 3263INTERCEPTOR(char *, setlocale, int category, char *locale) { 3264 void *ctx; 3265 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 3266 if (locale) 3267 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 3268 char *res = REAL(setlocale)(category, locale); 3269 if (res) { 3270 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3271 unpoison_ctype_arrays(ctx); 3272 } 3273 return res; 3274} 3275 3276#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale); 3277#else 3278#define INIT_SETLOCALE 3279#endif 3280 3281#if SANITIZER_INTERCEPT_GETCWD 3282INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 3283 void *ctx; 3284 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 3285 // FIXME: under ASan the call below may write to freed memory and corrupt 3286 // its metadata. See 3287 // https://github.com/google/sanitizers/issues/321. 3288 char *res = REAL(getcwd)(buf, size); 3289 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3290 return res; 3291} 3292#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); 3293#else 3294#define INIT_GETCWD 3295#endif 3296 3297#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 3298INTERCEPTOR(char *, get_current_dir_name, int fake) { 3299 void *ctx; 3300 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 3301 // FIXME: under ASan the call below may write to freed memory and corrupt 3302 // its metadata. See 3303 // https://github.com/google/sanitizers/issues/321. 3304 char *res = REAL(get_current_dir_name)(fake); 3305 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3306 return res; 3307} 3308 3309#define INIT_GET_CURRENT_DIR_NAME \ 3310 COMMON_INTERCEPT_FUNCTION(get_current_dir_name); 3311#else 3312#define INIT_GET_CURRENT_DIR_NAME 3313#endif 3314 3315UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 3316 CHECK(endptr); 3317 if (nptr == *endptr) { 3318 // No digits were found at strtol call, we need to find out the last 3319 // symbol accessed by strtoll on our own. 3320 // We get this symbol by skipping leading blanks and optional +/- sign. 3321 while (IsSpace(*nptr)) nptr++; 3322 if (*nptr == '+' || *nptr == '-') nptr++; 3323 *endptr = const_cast<char *>(nptr); 3324 } 3325 CHECK(*endptr >= nptr); 3326} 3327 3328UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr, 3329 char **endptr, char *real_endptr, int base) { 3330 if (endptr) { 3331 *endptr = real_endptr; 3332 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 3333 } 3334 // If base has unsupported value, strtol can exit with EINVAL 3335 // without reading any characters. So do additional checks only 3336 // if base is valid. 3337 bool is_valid_base = (base == 0) || (2 <= base && base <= 36); 3338 if (is_valid_base) { 3339 FixRealStrtolEndptr(nptr, &real_endptr); 3340 } 3341 COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ? 3342 (real_endptr - nptr) + 1 : 0); 3343} 3344 3345 3346#if SANITIZER_INTERCEPT_STRTOIMAX 3347INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 3348 void *ctx; 3349 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 3350 // FIXME: under ASan the call below may write to freed memory and corrupt 3351 // its metadata. See 3352 // https://github.com/google/sanitizers/issues/321. 3353 char *real_endptr; 3354 INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base); 3355 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3356 return res; 3357} 3358 3359INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 3360 void *ctx; 3361 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 3362 // FIXME: under ASan the call below may write to freed memory and corrupt 3363 // its metadata. See 3364 // https://github.com/google/sanitizers/issues/321. 3365 char *real_endptr; 3366 UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); 3367 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3368 return res; 3369} 3370 3371#define INIT_STRTOIMAX \ 3372 COMMON_INTERCEPT_FUNCTION(strtoimax); \ 3373 COMMON_INTERCEPT_FUNCTION(strtoumax); 3374#else 3375#define INIT_STRTOIMAX 3376#endif 3377 3378#if SANITIZER_INTERCEPT_MBSTOWCS 3379INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 3380 void *ctx; 3381 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 3382 // FIXME: under ASan the call below may write to freed memory and corrupt 3383 // its metadata. See 3384 // https://github.com/google/sanitizers/issues/321. 3385 SIZE_T res = REAL(mbstowcs)(dest, src, len); 3386 if (res != (SIZE_T) - 1 && dest) { 3387 SIZE_T write_cnt = res + (res < len); 3388 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3389 } 3390 return res; 3391} 3392 3393INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 3394 void *ps) { 3395 void *ctx; 3396 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 3397 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3398 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3399 // FIXME: under ASan the call below may write to freed memory and corrupt 3400 // its metadata. See 3401 // https://github.com/google/sanitizers/issues/321. 3402 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 3403 if (res != (SIZE_T)(-1) && dest && src) { 3404 // This function, and several others, may or may not write the terminating 3405 // \0 character. They write it iff they clear *src. 3406 SIZE_T write_cnt = res + !*src; 3407 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3408 } 3409 return res; 3410} 3411 3412#define INIT_MBSTOWCS \ 3413 COMMON_INTERCEPT_FUNCTION(mbstowcs); \ 3414 COMMON_INTERCEPT_FUNCTION(mbsrtowcs); 3415#else 3416#define INIT_MBSTOWCS 3417#endif 3418 3419#if SANITIZER_INTERCEPT_MBSNRTOWCS 3420INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 3421 SIZE_T len, void *ps) { 3422 void *ctx; 3423 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 3424 if (src) { 3425 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3426 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3427 } 3428 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3429 // FIXME: under ASan the call below may write to freed memory and corrupt 3430 // its metadata. See 3431 // https://github.com/google/sanitizers/issues/321. 3432 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 3433 if (res != (SIZE_T)(-1) && dest && src) { 3434 SIZE_T write_cnt = res + !*src; 3435 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3436 } 3437 return res; 3438} 3439 3440#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs); 3441#else 3442#define INIT_MBSNRTOWCS 3443#endif 3444 3445#if SANITIZER_INTERCEPT_WCSTOMBS 3446INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 3447 void *ctx; 3448 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 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 SIZE_T res = REAL(wcstombs)(dest, src, len); 3453 if (res != (SIZE_T) - 1 && dest) { 3454 SIZE_T write_cnt = res + (res < len); 3455 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3456 } 3457 return res; 3458} 3459 3460INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 3461 void *ps) { 3462 void *ctx; 3463 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 3464 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3465 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3466 // FIXME: under ASan the call below may write to freed memory and corrupt 3467 // its metadata. See 3468 // https://github.com/google/sanitizers/issues/321. 3469 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 3470 if (res != (SIZE_T) - 1 && dest && src) { 3471 SIZE_T write_cnt = res + !*src; 3472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3473 } 3474 return res; 3475} 3476 3477#define INIT_WCSTOMBS \ 3478 COMMON_INTERCEPT_FUNCTION(wcstombs); \ 3479 COMMON_INTERCEPT_FUNCTION(wcsrtombs); 3480#else 3481#define INIT_WCSTOMBS 3482#endif 3483 3484#if SANITIZER_INTERCEPT_WCSNRTOMBS 3485INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 3486 SIZE_T len, void *ps) { 3487 void *ctx; 3488 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 3489 if (src) { 3490 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3491 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3492 } 3493 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3494 // FIXME: under ASan the call below may write to freed memory and corrupt 3495 // its metadata. See 3496 // https://github.com/google/sanitizers/issues/321. 3497 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 3498 if (res != ((SIZE_T)-1) && dest && src) { 3499 SIZE_T write_cnt = res + !*src; 3500 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3501 } 3502 return res; 3503} 3504 3505#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs); 3506#else 3507#define INIT_WCSNRTOMBS 3508#endif 3509 3510 3511#if SANITIZER_INTERCEPT_WCRTOMB 3512INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { 3513 void *ctx; 3514 COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps); 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(wcrtomb)(dest, src, ps); 3520 if (res != ((SIZE_T)-1) && dest) { 3521 SIZE_T write_cnt = res; 3522 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3523 } 3524 return res; 3525} 3526 3527#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb); 3528#else 3529#define INIT_WCRTOMB 3530#endif 3531 3532#if SANITIZER_INTERCEPT_TCGETATTR 3533INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 3534 void *ctx; 3535 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 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 int res = REAL(tcgetattr)(fd, termios_p); 3540 if (!res && termios_p) 3541 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 3542 return res; 3543} 3544 3545#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr); 3546#else 3547#define INIT_TCGETATTR 3548#endif 3549 3550#if SANITIZER_INTERCEPT_REALPATH 3551INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 3552 void *ctx; 3553 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 3554 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3555 3556 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 3557 // version of a versioned symbol. For realpath(), this gives us something 3558 // (called __old_realpath) that does not handle NULL in the second argument. 3559 // Handle it as part of the interceptor. 3560 char *allocated_path = nullptr; 3561 if (!resolved_path) 3562 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 3563 3564 char *res = REAL(realpath)(path, resolved_path); 3565 if (allocated_path && !res) WRAP(free)(allocated_path); 3566 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3567 return res; 3568} 3569#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); 3570#else 3571#define INIT_REALPATH 3572#endif 3573 3574#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 3575INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 3576 void *ctx; 3577 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 3578 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3579 char *res = REAL(canonicalize_file_name)(path); 3580 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3581 return res; 3582} 3583#define INIT_CANONICALIZE_FILE_NAME \ 3584 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name); 3585#else 3586#define INIT_CANONICALIZE_FILE_NAME 3587#endif 3588 3589#if SANITIZER_INTERCEPT_CONFSTR 3590INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 3591 void *ctx; 3592 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 3593 // FIXME: under ASan the call below may write to freed memory and corrupt 3594 // its metadata. See 3595 // https://github.com/google/sanitizers/issues/321. 3596 SIZE_T res = REAL(confstr)(name, buf, len); 3597 if (buf && res) 3598 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 3599 return res; 3600} 3601#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr); 3602#else 3603#define INIT_CONFSTR 3604#endif 3605 3606#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 3607INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 3608 void *ctx; 3609 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 3610 // FIXME: under ASan the call below may write to freed memory and corrupt 3611 // its metadata. See 3612 // https://github.com/google/sanitizers/issues/321. 3613 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 3614 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 3615 return res; 3616} 3617#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity); 3618#else 3619#define INIT_SCHED_GETAFFINITY 3620#endif 3621 3622#if SANITIZER_INTERCEPT_SCHED_GETPARAM 3623INTERCEPTOR(int, sched_getparam, int pid, void *param) { 3624 void *ctx; 3625 COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param); 3626 int res = REAL(sched_getparam)(pid, param); 3627 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz); 3628 return res; 3629} 3630#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam); 3631#else 3632#define INIT_SCHED_GETPARAM 3633#endif 3634 3635#if SANITIZER_INTERCEPT_STRERROR 3636INTERCEPTOR(char *, strerror, int errnum) { 3637 void *ctx; 3638 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 3639 COMMON_INTERCEPTOR_STRERROR(); 3640 char *res = REAL(strerror)(errnum); 3641 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3642 return res; 3643} 3644#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); 3645#else 3646#define INIT_STRERROR 3647#endif 3648 3649#if SANITIZER_INTERCEPT_STRERROR_R 3650// There are 2 versions of strerror_r: 3651// * POSIX version returns 0 on success, negative error code on failure, 3652// writes message to buf. 3653// * GNU version returns message pointer, which points to either buf or some 3654// static storage. 3655#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ 3656 SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ 3657 SANITIZER_FREEBSD || SANITIZER_OPENBSD 3658// POSIX version. Spec is not clear on whether buf is NULL-terminated. 3659// At least on OSX, buf contents are valid even when the call fails. 3660INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3661 void *ctx; 3662 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3663 // FIXME: under ASan the call below may write to freed memory and corrupt 3664 // its metadata. See 3665 // https://github.com/google/sanitizers/issues/321. 3666 int res = REAL(strerror_r)(errnum, buf, buflen); 3667 3668 SIZE_T sz = internal_strnlen(buf, buflen); 3669 if (sz < buflen) ++sz; 3670 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 3671 return res; 3672} 3673#else 3674// GNU version. 3675INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3676 void *ctx; 3677 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3678 // FIXME: under ASan the call below may write to freed memory and corrupt 3679 // its metadata. See 3680 // https://github.com/google/sanitizers/issues/321. 3681 char *res = REAL(strerror_r)(errnum, buf, buflen); 3682 if (res == buf) 3683 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3684 else 3685 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3686 return res; 3687} 3688#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE || 3689 //SANITIZER_MAC 3690#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); 3691#else 3692#define INIT_STRERROR_R 3693#endif 3694 3695#if SANITIZER_INTERCEPT_XPG_STRERROR_R 3696INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) { 3697 void *ctx; 3698 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen); 3699 // FIXME: under ASan the call below may write to freed memory and corrupt 3700 // its metadata. See 3701 // https://github.com/google/sanitizers/issues/321. 3702 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen); 3703 // This version always returns a null-terminated string. 3704 if (buf && buflen) 3705 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 3706 return res; 3707} 3708#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r); 3709#else 3710#define INIT_XPG_STRERROR_R 3711#endif 3712 3713#if SANITIZER_INTERCEPT_SCANDIR 3714typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 3715typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 3716 const struct __sanitizer_dirent **); 3717 3718static THREADLOCAL scandir_filter_f scandir_filter; 3719static THREADLOCAL scandir_compar_f scandir_compar; 3720 3721static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 3722 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3723 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3724 return scandir_filter(dir); 3725} 3726 3727static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 3728 const struct __sanitizer_dirent **b) { 3729 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3730 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3731 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3732 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3733 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3734 return scandir_compar(a, b); 3735} 3736 3737INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 3738 scandir_filter_f filter, scandir_compar_f compar) { 3739 void *ctx; 3740 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 3741 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3742 scandir_filter = filter; 3743 scandir_compar = compar; 3744 // FIXME: under ASan the call below may write to freed memory and corrupt 3745 // its metadata. See 3746 // https://github.com/google/sanitizers/issues/321. 3747 int res = REAL(scandir)(dirp, namelist, 3748 filter ? wrapped_scandir_filter : nullptr, 3749 compar ? wrapped_scandir_compar : nullptr); 3750 scandir_filter = nullptr; 3751 scandir_compar = nullptr; 3752 if (namelist && res > 0) { 3753 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3754 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3755 for (int i = 0; i < res; ++i) 3756 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3757 (*namelist)[i]->d_reclen); 3758 } 3759 return res; 3760} 3761#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir); 3762#else 3763#define INIT_SCANDIR 3764#endif 3765 3766#if SANITIZER_INTERCEPT_SCANDIR64 3767typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 3768typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 3769 const struct __sanitizer_dirent64 **); 3770 3771static THREADLOCAL scandir64_filter_f scandir64_filter; 3772static THREADLOCAL scandir64_compar_f scandir64_compar; 3773 3774static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 3775 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3776 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3777 return scandir64_filter(dir); 3778} 3779 3780static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 3781 const struct __sanitizer_dirent64 **b) { 3782 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3783 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3784 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3785 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3786 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3787 return scandir64_compar(a, b); 3788} 3789 3790INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 3791 scandir64_filter_f filter, scandir64_compar_f compar) { 3792 void *ctx; 3793 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 3794 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3795 scandir64_filter = filter; 3796 scandir64_compar = compar; 3797 // FIXME: under ASan the call below may write to freed memory and corrupt 3798 // its metadata. See 3799 // https://github.com/google/sanitizers/issues/321. 3800 int res = 3801 REAL(scandir64)(dirp, namelist, 3802 filter ? wrapped_scandir64_filter : nullptr, 3803 compar ? wrapped_scandir64_compar : nullptr); 3804 scandir64_filter = nullptr; 3805 scandir64_compar = nullptr; 3806 if (namelist && res > 0) { 3807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3808 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3809 for (int i = 0; i < res; ++i) 3810 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3811 (*namelist)[i]->d_reclen); 3812 } 3813 return res; 3814} 3815#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64); 3816#else 3817#define INIT_SCANDIR64 3818#endif 3819 3820#if SANITIZER_INTERCEPT_GETGROUPS 3821INTERCEPTOR(int, getgroups, int size, u32 *lst) { 3822 void *ctx; 3823 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 3824 // FIXME: under ASan the call below may write to freed memory and corrupt 3825 // its metadata. See 3826 // https://github.com/google/sanitizers/issues/321. 3827 int res = REAL(getgroups)(size, lst); 3828 if (res >= 0 && lst && size > 0) 3829 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 3830 return res; 3831} 3832#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups); 3833#else 3834#define INIT_GETGROUPS 3835#endif 3836 3837#if SANITIZER_INTERCEPT_POLL 3838static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 3839 __sanitizer_nfds_t nfds) { 3840 for (unsigned i = 0; i < nfds; ++i) { 3841 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 3842 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 3843 } 3844} 3845 3846static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 3847 __sanitizer_nfds_t nfds) { 3848 for (unsigned i = 0; i < nfds; ++i) 3849 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 3850 sizeof(fds[i].revents)); 3851} 3852 3853INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3854 int timeout) { 3855 void *ctx; 3856 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 3857 if (fds && nfds) read_pollfd(ctx, fds, nfds); 3858 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 3859 if (fds && nfds) write_pollfd(ctx, fds, nfds); 3860 return res; 3861} 3862#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll); 3863#else 3864#define INIT_POLL 3865#endif 3866 3867#if SANITIZER_INTERCEPT_PPOLL 3868INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3869 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 3870 void *ctx; 3871 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 3872 if (fds && nfds) read_pollfd(ctx, fds, nfds); 3873 if (timeout_ts) 3874 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 3875 if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask)); 3876 int res = 3877 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 3878 if (fds && nfds) write_pollfd(ctx, fds, nfds); 3879 return res; 3880} 3881#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll); 3882#else 3883#define INIT_PPOLL 3884#endif 3885 3886#if SANITIZER_INTERCEPT_WORDEXP 3887INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 3888 void *ctx; 3889 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 3890 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 3891 // FIXME: under ASan the call below may write to freed memory and corrupt 3892 // its metadata. See 3893 // https://github.com/google/sanitizers/issues/321. 3894 int res = REAL(wordexp)(s, p, flags); 3895 if (!res && p) { 3896 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 3897 if (p->we_wordc) 3898 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 3899 sizeof(*p->we_wordv) * p->we_wordc); 3900 for (uptr i = 0; i < p->we_wordc; ++i) { 3901 char *w = p->we_wordv[i]; 3902 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 3903 } 3904 } 3905 return res; 3906} 3907#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp); 3908#else 3909#define INIT_WORDEXP 3910#endif 3911 3912#if SANITIZER_INTERCEPT_SIGWAIT 3913INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 3914 void *ctx; 3915 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 3916 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3917 // FIXME: under ASan the call below may write to freed memory and corrupt 3918 // its metadata. See 3919 // https://github.com/google/sanitizers/issues/321. 3920 int res = REAL(sigwait)(set, sig); 3921 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 3922 return res; 3923} 3924#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait); 3925#else 3926#define INIT_SIGWAIT 3927#endif 3928 3929#if SANITIZER_INTERCEPT_SIGWAITINFO 3930INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 3931 void *ctx; 3932 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 3933 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3934 // FIXME: under ASan the call below may write to freed memory and corrupt 3935 // its metadata. See 3936 // https://github.com/google/sanitizers/issues/321. 3937 int res = REAL(sigwaitinfo)(set, info); 3938 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 3939 return res; 3940} 3941#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo); 3942#else 3943#define INIT_SIGWAITINFO 3944#endif 3945 3946#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 3947INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 3948 void *timeout) { 3949 void *ctx; 3950 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 3951 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 3952 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 3953 // FIXME: under ASan the call below may write to freed memory and corrupt 3954 // its metadata. See 3955 // https://github.com/google/sanitizers/issues/321. 3956 int res = REAL(sigtimedwait)(set, info, timeout); 3957 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 3958 return res; 3959} 3960#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait); 3961#else 3962#define INIT_SIGTIMEDWAIT 3963#endif 3964 3965#if SANITIZER_INTERCEPT_SIGSETOPS 3966INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 3967 void *ctx; 3968 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 3969 // FIXME: under ASan the call below may write to freed memory and corrupt 3970 // its metadata. See 3971 // https://github.com/google/sanitizers/issues/321. 3972 int res = REAL(sigemptyset)(set); 3973 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 3974 return res; 3975} 3976 3977INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 3978 void *ctx; 3979 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 3980 // FIXME: under ASan the call below may write to freed memory and corrupt 3981 // its metadata. See 3982 // https://github.com/google/sanitizers/issues/321. 3983 int res = REAL(sigfillset)(set); 3984 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 3985 return res; 3986} 3987#define INIT_SIGSETOPS \ 3988 COMMON_INTERCEPT_FUNCTION(sigemptyset); \ 3989 COMMON_INTERCEPT_FUNCTION(sigfillset); 3990#else 3991#define INIT_SIGSETOPS 3992#endif 3993 3994#if SANITIZER_INTERCEPT_SIGPENDING 3995INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 3996 void *ctx; 3997 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 3998 // FIXME: under ASan the call below may write to freed memory and corrupt 3999 // its metadata. See 4000 // https://github.com/google/sanitizers/issues/321. 4001 int res = REAL(sigpending)(set); 4002 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 4003 return res; 4004} 4005#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending); 4006#else 4007#define INIT_SIGPENDING 4008#endif 4009 4010#if SANITIZER_INTERCEPT_SIGPROCMASK 4011INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 4012 __sanitizer_sigset_t *oldset) { 4013 void *ctx; 4014 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 4015 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4016 // FIXME: under ASan the call below may write to freed memory and corrupt 4017 // its metadata. See 4018 // https://github.com/google/sanitizers/issues/321. 4019 int res = REAL(sigprocmask)(how, set, oldset); 4020 if (!res && oldset) 4021 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 4022 return res; 4023} 4024#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask); 4025#else 4026#define INIT_SIGPROCMASK 4027#endif 4028 4029#if SANITIZER_INTERCEPT_BACKTRACE 4030INTERCEPTOR(int, backtrace, void **buffer, int size) { 4031 void *ctx; 4032 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 4033 // FIXME: under ASan the call below may write to freed memory and corrupt 4034 // its metadata. See 4035 // https://github.com/google/sanitizers/issues/321. 4036 int res = REAL(backtrace)(buffer, size); 4037 if (res && buffer) 4038 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 4039 return res; 4040} 4041 4042INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 4043 void *ctx; 4044 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 4045 if (buffer && size) 4046 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 4047 // FIXME: under ASan the call below may write to freed memory and corrupt 4048 // its metadata. See 4049 // https://github.com/google/sanitizers/issues/321. 4050 char **res = REAL(backtrace_symbols)(buffer, size); 4051 if (res && size) { 4052 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 4053 for (int i = 0; i < size; ++i) 4054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 4055 } 4056 return res; 4057} 4058#define INIT_BACKTRACE \ 4059 COMMON_INTERCEPT_FUNCTION(backtrace); \ 4060 COMMON_INTERCEPT_FUNCTION(backtrace_symbols); 4061#else 4062#define INIT_BACKTRACE 4063#endif 4064 4065#if SANITIZER_INTERCEPT__EXIT 4066INTERCEPTOR(void, _exit, int status) { 4067 void *ctx; 4068 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 4069 COMMON_INTERCEPTOR_USER_CALLBACK_START(); 4070 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 4071 COMMON_INTERCEPTOR_USER_CALLBACK_END(); 4072 if (status == 0) status = status1; 4073 REAL(_exit)(status); 4074} 4075#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit); 4076#else 4077#define INIT__EXIT 4078#endif 4079 4080#if SANITIZER_INTERCEPT_PTHREAD_MUTEX 4081INTERCEPTOR(int, pthread_mutex_lock, void *m) { 4082 void *ctx; 4083 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 4084 COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); 4085 int res = REAL(pthread_mutex_lock)(m); 4086 if (res == errno_EOWNERDEAD) 4087 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 4088 if (res == 0 || res == errno_EOWNERDEAD) 4089 COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); 4090 if (res == errno_EINVAL) 4091 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4092 return res; 4093} 4094 4095INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 4096 void *ctx; 4097 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 4098 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 4099 int res = REAL(pthread_mutex_unlock)(m); 4100 if (res == errno_EINVAL) 4101 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4102 return res; 4103} 4104 4105#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) 4106#define INIT_PTHREAD_MUTEX_UNLOCK \ 4107 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) 4108#else 4109#define INIT_PTHREAD_MUTEX_LOCK 4110#define INIT_PTHREAD_MUTEX_UNLOCK 4111#endif 4112 4113#if SANITIZER_INTERCEPT___PTHREAD_MUTEX 4114INTERCEPTOR(int, __pthread_mutex_lock, void *m) { 4115 return WRAP(pthread_mutex_lock)(m); 4116} 4117 4118INTERCEPTOR(int, __pthread_mutex_unlock, void *m) { 4119 return WRAP(pthread_mutex_unlock)(m); 4120} 4121 4122#define INIT___PTHREAD_MUTEX_LOCK \ 4123 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock) 4124#define INIT___PTHREAD_MUTEX_UNLOCK \ 4125 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock) 4126#else 4127#define INIT___PTHREAD_MUTEX_LOCK 4128#define INIT___PTHREAD_MUTEX_UNLOCK 4129#endif 4130 4131#if SANITIZER_INTERCEPT___LIBC_MUTEX 4132INTERCEPTOR(int, __libc_mutex_lock, void *m) 4133ALIAS(WRAPPER_NAME(pthread_mutex_lock)); 4134 4135INTERCEPTOR(int, __libc_mutex_unlock, void *m) 4136ALIAS(WRAPPER_NAME(pthread_mutex_unlock)); 4137 4138INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate) 4139ALIAS(WRAPPER_NAME(pthread_setcancelstate)); 4140 4141#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock) 4142#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock) 4143#define INIT___LIBC_THR_SETCANCELSTATE \ 4144 COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate) 4145#else 4146#define INIT___LIBC_MUTEX_LOCK 4147#define INIT___LIBC_MUTEX_UNLOCK 4148#define INIT___LIBC_THR_SETCANCELSTATE 4149#endif 4150 4151#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 4152static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 4153 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 4154 if (mnt->mnt_fsname) 4155 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 4156 REAL(strlen)(mnt->mnt_fsname) + 1); 4157 if (mnt->mnt_dir) 4158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 4159 REAL(strlen)(mnt->mnt_dir) + 1); 4160 if (mnt->mnt_type) 4161 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 4162 REAL(strlen)(mnt->mnt_type) + 1); 4163 if (mnt->mnt_opts) 4164 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 4165 REAL(strlen)(mnt->mnt_opts) + 1); 4166} 4167#endif 4168 4169#if SANITIZER_INTERCEPT_GETMNTENT 4170INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 4171 void *ctx; 4172 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 4173 __sanitizer_mntent *res = REAL(getmntent)(fp); 4174 if (res) write_mntent(ctx, res); 4175 return res; 4176} 4177#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent); 4178#else 4179#define INIT_GETMNTENT 4180#endif 4181 4182#if SANITIZER_INTERCEPT_GETMNTENT_R 4183INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 4184 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 4185 void *ctx; 4186 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 4187 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 4188 if (res) write_mntent(ctx, res); 4189 return res; 4190} 4191#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r); 4192#else 4193#define INIT_GETMNTENT_R 4194#endif 4195 4196#if SANITIZER_INTERCEPT_STATFS 4197INTERCEPTOR(int, statfs, char *path, void *buf) { 4198 void *ctx; 4199 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 4200 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4201 // FIXME: under ASan the call below may write to freed memory and corrupt 4202 // its metadata. See 4203 // https://github.com/google/sanitizers/issues/321. 4204 int res = REAL(statfs)(path, buf); 4205 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4206 return res; 4207} 4208INTERCEPTOR(int, fstatfs, int fd, void *buf) { 4209 void *ctx; 4210 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 4211 // FIXME: under ASan the call below may write to freed memory and corrupt 4212 // its metadata. See 4213 // https://github.com/google/sanitizers/issues/321. 4214 int res = REAL(fstatfs)(fd, buf); 4215 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4216 return res; 4217} 4218#define INIT_STATFS \ 4219 COMMON_INTERCEPT_FUNCTION(statfs); \ 4220 COMMON_INTERCEPT_FUNCTION(fstatfs); 4221#else 4222#define INIT_STATFS 4223#endif 4224 4225#if SANITIZER_INTERCEPT_STATFS64 4226INTERCEPTOR(int, statfs64, char *path, void *buf) { 4227 void *ctx; 4228 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 4229 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4230 // FIXME: under ASan the call below may write to freed memory and corrupt 4231 // its metadata. See 4232 // https://github.com/google/sanitizers/issues/321. 4233 int res = REAL(statfs64)(path, buf); 4234 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4235 return res; 4236} 4237INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 4238 void *ctx; 4239 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 4240 // FIXME: under ASan the call below may write to freed memory and corrupt 4241 // its metadata. See 4242 // https://github.com/google/sanitizers/issues/321. 4243 int res = REAL(fstatfs64)(fd, buf); 4244 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4245 return res; 4246} 4247#define INIT_STATFS64 \ 4248 COMMON_INTERCEPT_FUNCTION(statfs64); \ 4249 COMMON_INTERCEPT_FUNCTION(fstatfs64); 4250#else 4251#define INIT_STATFS64 4252#endif 4253 4254#if SANITIZER_INTERCEPT_STATVFS 4255INTERCEPTOR(int, statvfs, char *path, void *buf) { 4256 void *ctx; 4257 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 4258 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4259 // FIXME: under ASan the call below may write to freed memory and corrupt 4260 // its metadata. See 4261 // https://github.com/google/sanitizers/issues/321. 4262 int res = REAL(statvfs)(path, buf); 4263 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4264 return res; 4265} 4266INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 4267 void *ctx; 4268 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 4269 // FIXME: under ASan the call below may write to freed memory and corrupt 4270 // its metadata. See 4271 // https://github.com/google/sanitizers/issues/321. 4272 int res = REAL(fstatvfs)(fd, buf); 4273 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4274 return res; 4275} 4276#define INIT_STATVFS \ 4277 COMMON_INTERCEPT_FUNCTION(statvfs); \ 4278 COMMON_INTERCEPT_FUNCTION(fstatvfs); 4279#else 4280#define INIT_STATVFS 4281#endif 4282 4283#if SANITIZER_INTERCEPT_STATVFS64 4284INTERCEPTOR(int, statvfs64, char *path, void *buf) { 4285 void *ctx; 4286 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 4287 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4288 // FIXME: under ASan the call below may write to freed memory and corrupt 4289 // its metadata. See 4290 // https://github.com/google/sanitizers/issues/321. 4291 int res = REAL(statvfs64)(path, buf); 4292 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4293 return res; 4294} 4295INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 4296 void *ctx; 4297 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 4298 // FIXME: under ASan the call below may write to freed memory and corrupt 4299 // its metadata. See 4300 // https://github.com/google/sanitizers/issues/321. 4301 int res = REAL(fstatvfs64)(fd, buf); 4302 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4303 return res; 4304} 4305#define INIT_STATVFS64 \ 4306 COMMON_INTERCEPT_FUNCTION(statvfs64); \ 4307 COMMON_INTERCEPT_FUNCTION(fstatvfs64); 4308#else 4309#define INIT_STATVFS64 4310#endif 4311 4312#if SANITIZER_INTERCEPT_INITGROUPS 4313INTERCEPTOR(int, initgroups, char *user, u32 group) { 4314 void *ctx; 4315 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 4316 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 4317 int res = REAL(initgroups)(user, group); 4318 return res; 4319} 4320#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups); 4321#else 4322#define INIT_INITGROUPS 4323#endif 4324 4325#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON 4326INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 4327 void *ctx; 4328 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 4329 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4330 char *res = REAL(ether_ntoa)(addr); 4331 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4332 return res; 4333} 4334INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 4335 void *ctx; 4336 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 4337 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4338 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 4339 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res)); 4340 return res; 4341} 4342#define INIT_ETHER_NTOA_ATON \ 4343 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \ 4344 COMMON_INTERCEPT_FUNCTION(ether_aton); 4345#else 4346#define INIT_ETHER_NTOA_ATON 4347#endif 4348 4349#if SANITIZER_INTERCEPT_ETHER_HOST 4350INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 4351 void *ctx; 4352 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 4353 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4354 // FIXME: under ASan the call below may write to freed memory and corrupt 4355 // its metadata. See 4356 // https://github.com/google/sanitizers/issues/321. 4357 int res = REAL(ether_ntohost)(hostname, addr); 4358 if (!res && hostname) 4359 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4360 return res; 4361} 4362INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 4363 void *ctx; 4364 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 4365 if (hostname) 4366 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4367 // FIXME: under ASan the call below may write to freed memory and corrupt 4368 // its metadata. See 4369 // https://github.com/google/sanitizers/issues/321. 4370 int res = REAL(ether_hostton)(hostname, addr); 4371 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4372 return res; 4373} 4374INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 4375 char *hostname) { 4376 void *ctx; 4377 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 4378 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 4379 // FIXME: under ASan the call below may write to freed memory and corrupt 4380 // its metadata. See 4381 // https://github.com/google/sanitizers/issues/321. 4382 int res = REAL(ether_line)(line, addr, hostname); 4383 if (!res) { 4384 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4385 if (hostname) 4386 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4387 } 4388 return res; 4389} 4390#define INIT_ETHER_HOST \ 4391 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \ 4392 COMMON_INTERCEPT_FUNCTION(ether_hostton); \ 4393 COMMON_INTERCEPT_FUNCTION(ether_line); 4394#else 4395#define INIT_ETHER_HOST 4396#endif 4397 4398#if SANITIZER_INTERCEPT_ETHER_R 4399INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 4400 void *ctx; 4401 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 4402 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4403 // FIXME: under ASan the call below may write to freed memory and corrupt 4404 // its metadata. See 4405 // https://github.com/google/sanitizers/issues/321. 4406 char *res = REAL(ether_ntoa_r)(addr, buf); 4407 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 4408 return res; 4409} 4410INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 4411 __sanitizer_ether_addr *addr) { 4412 void *ctx; 4413 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 4414 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4415 // FIXME: under ASan the call below may write to freed memory and corrupt 4416 // its metadata. See 4417 // https://github.com/google/sanitizers/issues/321. 4418 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 4419 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 4420 return res; 4421} 4422#define INIT_ETHER_R \ 4423 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \ 4424 COMMON_INTERCEPT_FUNCTION(ether_aton_r); 4425#else 4426#define INIT_ETHER_R 4427#endif 4428 4429#if SANITIZER_INTERCEPT_SHMCTL 4430INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 4431 void *ctx; 4432 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 4433 // FIXME: under ASan the call below may write to freed memory and corrupt 4434 // its metadata. See 4435 // https://github.com/google/sanitizers/issues/321. 4436 int res = REAL(shmctl)(shmid, cmd, buf); 4437 if (res >= 0) { 4438 unsigned sz = 0; 4439 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 4440 sz = sizeof(__sanitizer_shmid_ds); 4441 else if (cmd == shmctl_ipc_info) 4442 sz = struct_shminfo_sz; 4443 else if (cmd == shmctl_shm_info) 4444 sz = struct_shm_info_sz; 4445 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 4446 } 4447 return res; 4448} 4449#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); 4450#else 4451#define INIT_SHMCTL 4452#endif 4453 4454#if SANITIZER_INTERCEPT_RANDOM_R 4455INTERCEPTOR(int, random_r, void *buf, u32 *result) { 4456 void *ctx; 4457 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 4458 // FIXME: under ASan the call below may write to freed memory and corrupt 4459 // its metadata. See 4460 // https://github.com/google/sanitizers/issues/321. 4461 int res = REAL(random_r)(buf, result); 4462 if (!res && result) 4463 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4464 return res; 4465} 4466#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r); 4467#else 4468#define INIT_RANDOM_R 4469#endif 4470 4471// FIXME: under ASan the REAL() call below may write to freed memory and corrupt 4472// its metadata. See 4473// https://github.com/google/sanitizers/issues/321. 4474#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 4475 SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \ 4476 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \ 4477 SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \ 4478 SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \ 4479 SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \ 4480 SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET 4481#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \ 4482 INTERCEPTOR(int, fn, void *attr, void *r) { \ 4483 void *ctx; \ 4484 COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \ 4485 int res = REAL(fn)(attr, r); \ 4486 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 4487 return res; \ 4488 } 4489#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 4490 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz) 4491#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \ 4492 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz) 4493#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \ 4494 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz) 4495#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \ 4496 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz) 4497#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \ 4498 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz) 4499#endif 4500 4501#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 4502INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 4503INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 4504INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 4505INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 4506INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 4507 void *ctx; 4508 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 4509 // FIXME: under ASan the call below may write to freed memory and corrupt 4510 // its metadata. See 4511 // https://github.com/google/sanitizers/issues/321. 4512 int res = REAL(pthread_attr_getstack)(attr, addr, size); 4513 if (!res) { 4514 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4515 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 4516 } 4517 return res; 4518} 4519 4520// We may need to call the real pthread_attr_getstack from the run-time 4521// in sanitizer_common, but we don't want to include the interception headers 4522// there. So, just define this function here. 4523namespace __sanitizer { 4524extern "C" { 4525int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { 4526 return REAL(pthread_attr_getstack)(attr, addr, size); 4527} 4528} // extern "C" 4529} // namespace __sanitizer 4530 4531#define INIT_PTHREAD_ATTR_GET \ 4532 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 4533 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 4534 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ 4535 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 4536 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); 4537#else 4538#define INIT_PTHREAD_ATTR_GET 4539#endif 4540 4541#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED 4542INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 4543INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 4544 4545#define INIT_PTHREAD_ATTR_GET_SCHED \ 4546 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 4547 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); 4548#else 4549#define INIT_PTHREAD_ATTR_GET_SCHED 4550#endif 4551 4552#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 4553INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 4554 4555#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 4556 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 4557#else 4558#define INIT_PTHREAD_ATTR_GETINHERITSCHED 4559#endif 4560 4561#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 4562INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 4563 void *cpuset) { 4564 void *ctx; 4565 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 4566 cpuset); 4567 // FIXME: under ASan the call below may write to freed memory and corrupt 4568 // its metadata. See 4569 // https://github.com/google/sanitizers/issues/321. 4570 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 4571 if (!res && cpusetsize && cpuset) 4572 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 4573 return res; 4574} 4575 4576#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 4577 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 4578#else 4579#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 4580#endif 4581 4582#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED 4583INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int)) 4584#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \ 4585 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared); 4586#else 4587#define INIT_PTHREAD_MUTEXATTR_GETPSHARED 4588#endif 4589 4590#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE 4591INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int)) 4592#define INIT_PTHREAD_MUTEXATTR_GETTYPE \ 4593 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype); 4594#else 4595#define INIT_PTHREAD_MUTEXATTR_GETTYPE 4596#endif 4597 4598#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL 4599INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int)) 4600#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \ 4601 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol); 4602#else 4603#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL 4604#endif 4605 4606#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4607INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int)) 4608#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ 4609 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling); 4610#else 4611#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4612#endif 4613 4614#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST 4615INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int)) 4616#define INIT_PTHREAD_MUTEXATTR_GETROBUST \ 4617 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust); 4618#else 4619#define INIT_PTHREAD_MUTEXATTR_GETROBUST 4620#endif 4621 4622#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP 4623INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int)) 4624#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \ 4625 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np); 4626#else 4627#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP 4628#endif 4629 4630#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED 4631INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int)) 4632#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \ 4633 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared); 4634#else 4635#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED 4636#endif 4637 4638#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP 4639INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int)) 4640#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \ 4641 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np); 4642#else 4643#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP 4644#endif 4645 4646#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED 4647INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int)) 4648#define INIT_PTHREAD_CONDATTR_GETPSHARED \ 4649 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared); 4650#else 4651#define INIT_PTHREAD_CONDATTR_GETPSHARED 4652#endif 4653 4654#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK 4655INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int)) 4656#define INIT_PTHREAD_CONDATTR_GETCLOCK \ 4657 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock); 4658#else 4659#define INIT_PTHREAD_CONDATTR_GETCLOCK 4660#endif 4661 4662#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED 4663INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android 4664#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \ 4665 COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared); 4666#else 4667#define INIT_PTHREAD_BARRIERATTR_GETPSHARED 4668#endif 4669 4670#if SANITIZER_INTERCEPT_TMPNAM 4671INTERCEPTOR(char *, tmpnam, char *s) { 4672 void *ctx; 4673 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 4674 char *res = REAL(tmpnam)(s); 4675 if (res) { 4676 if (s) 4677 // FIXME: under ASan the call below may write to freed memory and corrupt 4678 // its metadata. See 4679 // https://github.com/google/sanitizers/issues/321. 4680 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4681 else 4682 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4683 } 4684 return res; 4685} 4686#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam); 4687#else 4688#define INIT_TMPNAM 4689#endif 4690 4691#if SANITIZER_INTERCEPT_TMPNAM_R 4692INTERCEPTOR(char *, tmpnam_r, char *s) { 4693 void *ctx; 4694 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 4695 // FIXME: under ASan the call below may write to freed memory and corrupt 4696 // its metadata. See 4697 // https://github.com/google/sanitizers/issues/321. 4698 char *res = REAL(tmpnam_r)(s); 4699 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4700 return res; 4701} 4702#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); 4703#else 4704#define INIT_TMPNAM_R 4705#endif 4706 4707#if SANITIZER_INTERCEPT_TTYNAME_R 4708INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { 4709 void *ctx; 4710 COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize); 4711 int res = REAL(ttyname_r)(fd, name, namesize); 4712 if (res == 0) 4713 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 4714 return res; 4715} 4716#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r); 4717#else 4718#define INIT_TTYNAME_R 4719#endif 4720 4721#if SANITIZER_INTERCEPT_TEMPNAM 4722INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 4723 void *ctx; 4724 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 4725 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 4726 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 4727 char *res = REAL(tempnam)(dir, pfx); 4728 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4729 return res; 4730} 4731#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); 4732#else 4733#define INIT_TEMPNAM 4734#endif 4735 4736#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD 4737INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 4738 void *ctx; 4739 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 4740 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4741 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 4742 return REAL(pthread_setname_np)(thread, name); 4743} 4744#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4745#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD 4746INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) { 4747 void *ctx; 4748 char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32 4749 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg); 4750 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4751 internal_snprintf(newname, sizeof(newname), name, arg); 4752 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname); 4753 return REAL(pthread_setname_np)(thread, name, arg); 4754} 4755#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4756#else 4757#define INIT_PTHREAD_SETNAME_NP 4758#endif 4759 4760#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP 4761INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) { 4762 void *ctx; 4763 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len); 4764 int res = REAL(pthread_getname_np)(thread, name, len); 4765 if (!res) 4766 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1); 4767 return res; 4768} 4769#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np); 4770#else 4771#define INIT_PTHREAD_GETNAME_NP 4772#endif 4773 4774#if SANITIZER_INTERCEPT_SINCOS 4775INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 4776 void *ctx; 4777 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 4778 // FIXME: under ASan the call below may write to freed memory and corrupt 4779 // its metadata. See 4780 // https://github.com/google/sanitizers/issues/321. 4781 REAL(sincos)(x, sin, cos); 4782 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4783 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4784} 4785INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 4786 void *ctx; 4787 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 4788 // FIXME: under ASan the call below may write to freed memory and corrupt 4789 // its metadata. See 4790 // https://github.com/google/sanitizers/issues/321. 4791 REAL(sincosf)(x, sin, cos); 4792 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4793 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4794} 4795INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 4796 void *ctx; 4797 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 4798 // FIXME: under ASan the call below may write to freed memory and corrupt 4799 // its metadata. See 4800 // https://github.com/google/sanitizers/issues/321. 4801 REAL(sincosl)(x, sin, cos); 4802 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 4803 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 4804} 4805#define INIT_SINCOS \ 4806 COMMON_INTERCEPT_FUNCTION(sincos); \ 4807 COMMON_INTERCEPT_FUNCTION(sincosf); \ 4808 COMMON_INTERCEPT_FUNCTION_LDBL(sincosl); 4809#else 4810#define INIT_SINCOS 4811#endif 4812 4813#if SANITIZER_INTERCEPT_REMQUO 4814INTERCEPTOR(double, remquo, double x, double y, int *quo) { 4815 void *ctx; 4816 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 4817 // FIXME: under ASan the call below may write to freed memory and corrupt 4818 // its metadata. See 4819 // https://github.com/google/sanitizers/issues/321. 4820 double res = REAL(remquo)(x, y, quo); 4821 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4822 return res; 4823} 4824INTERCEPTOR(float, remquof, float x, float y, int *quo) { 4825 void *ctx; 4826 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 4827 // FIXME: under ASan the call below may write to freed memory and corrupt 4828 // its metadata. See 4829 // https://github.com/google/sanitizers/issues/321. 4830 float res = REAL(remquof)(x, y, quo); 4831 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4832 return res; 4833} 4834INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 4835 void *ctx; 4836 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 4837 // FIXME: under ASan the call below may write to freed memory and corrupt 4838 // its metadata. See 4839 // https://github.com/google/sanitizers/issues/321. 4840 long double res = REAL(remquol)(x, y, quo); 4841 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 4842 return res; 4843} 4844#define INIT_REMQUO \ 4845 COMMON_INTERCEPT_FUNCTION(remquo); \ 4846 COMMON_INTERCEPT_FUNCTION(remquof); \ 4847 COMMON_INTERCEPT_FUNCTION_LDBL(remquol); 4848#else 4849#define INIT_REMQUO 4850#endif 4851 4852#if SANITIZER_INTERCEPT_LGAMMA 4853extern int signgam; 4854INTERCEPTOR(double, lgamma, double x) { 4855 void *ctx; 4856 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 4857 double res = REAL(lgamma)(x); 4858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4859 return res; 4860} 4861INTERCEPTOR(float, lgammaf, float x) { 4862 void *ctx; 4863 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 4864 float res = REAL(lgammaf)(x); 4865 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4866 return res; 4867} 4868INTERCEPTOR(long double, lgammal, long double x) { 4869 void *ctx; 4870 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 4871 long double res = REAL(lgammal)(x); 4872 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 4873 return res; 4874} 4875#define INIT_LGAMMA \ 4876 COMMON_INTERCEPT_FUNCTION(lgamma); \ 4877 COMMON_INTERCEPT_FUNCTION(lgammaf); \ 4878 COMMON_INTERCEPT_FUNCTION_LDBL(lgammal); 4879#else 4880#define INIT_LGAMMA 4881#endif 4882 4883#if SANITIZER_INTERCEPT_LGAMMA_R 4884INTERCEPTOR(double, lgamma_r, double x, int *signp) { 4885 void *ctx; 4886 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 4887 // FIXME: under ASan the call below may write to freed memory and corrupt 4888 // its metadata. See 4889 // https://github.com/google/sanitizers/issues/321. 4890 double res = REAL(lgamma_r)(x, signp); 4891 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4892 return res; 4893} 4894INTERCEPTOR(float, lgammaf_r, float x, int *signp) { 4895 void *ctx; 4896 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 4897 // FIXME: under ASan the call below may write to freed memory and corrupt 4898 // its metadata. See 4899 // https://github.com/google/sanitizers/issues/321. 4900 float res = REAL(lgammaf_r)(x, signp); 4901 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4902 return res; 4903} 4904#define INIT_LGAMMA_R \ 4905 COMMON_INTERCEPT_FUNCTION(lgamma_r); \ 4906 COMMON_INTERCEPT_FUNCTION(lgammaf_r); 4907#else 4908#define INIT_LGAMMA_R 4909#endif 4910 4911#if SANITIZER_INTERCEPT_LGAMMAL_R 4912INTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 4913 void *ctx; 4914 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 4915 // FIXME: under ASan the call below may write to freed memory and corrupt 4916 // its metadata. See 4917 // https://github.com/google/sanitizers/issues/321. 4918 long double res = REAL(lgammal_r)(x, signp); 4919 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 4920 return res; 4921} 4922#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r); 4923#else 4924#define INIT_LGAMMAL_R 4925#endif 4926 4927#if SANITIZER_INTERCEPT_DRAND48_R 4928INTERCEPTOR(int, drand48_r, void *buffer, double *result) { 4929 void *ctx; 4930 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 4931 // FIXME: under ASan the call below may write to freed memory and corrupt 4932 // its metadata. See 4933 // https://github.com/google/sanitizers/issues/321. 4934 int res = REAL(drand48_r)(buffer, result); 4935 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4936 return res; 4937} 4938INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 4939 void *ctx; 4940 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 4941 // FIXME: under ASan the call below may write to freed memory and corrupt 4942 // its metadata. See 4943 // https://github.com/google/sanitizers/issues/321. 4944 int res = REAL(lrand48_r)(buffer, result); 4945 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4946 return res; 4947} 4948#define INIT_DRAND48_R \ 4949 COMMON_INTERCEPT_FUNCTION(drand48_r); \ 4950 COMMON_INTERCEPT_FUNCTION(lrand48_r); 4951#else 4952#define INIT_DRAND48_R 4953#endif 4954 4955#if SANITIZER_INTERCEPT_RAND_R 4956INTERCEPTOR(int, rand_r, unsigned *seedp) { 4957 void *ctx; 4958 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp); 4959 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp)); 4960 return REAL(rand_r)(seedp); 4961} 4962#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r); 4963#else 4964#define INIT_RAND_R 4965#endif 4966 4967#if SANITIZER_INTERCEPT_GETLINE 4968INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { 4969 void *ctx; 4970 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); 4971 // FIXME: under ASan the call below may write to freed memory and corrupt 4972 // its metadata. See 4973 // https://github.com/google/sanitizers/issues/321. 4974 SSIZE_T res = REAL(getline)(lineptr, n, stream); 4975 if (res > 0) { 4976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 4977 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 4978 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 4979 } 4980 return res; 4981} 4982 4983// FIXME: under ASan the call below may write to freed memory and corrupt its 4984// metadata. See 4985// https://github.com/google/sanitizers/issues/321. 4986#define GETDELIM_INTERCEPTOR_IMPL(vname) \ 4987 { \ 4988 void *ctx; \ 4989 COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \ 4990 SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \ 4991 if (res > 0) { \ 4992 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \ 4993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \ 4994 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \ 4995 } \ 4996 return res; \ 4997 } 4998 4999INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim, 5000 void *stream) 5001GETDELIM_INTERCEPTOR_IMPL(__getdelim) 5002 5003// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor 5004// with its own body. 5005INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, 5006 void *stream) 5007GETDELIM_INTERCEPTOR_IMPL(getdelim) 5008 5009#define INIT_GETLINE \ 5010 COMMON_INTERCEPT_FUNCTION(getline); \ 5011 COMMON_INTERCEPT_FUNCTION(__getdelim); \ 5012 COMMON_INTERCEPT_FUNCTION(getdelim); 5013#else 5014#define INIT_GETLINE 5015#endif 5016 5017#if SANITIZER_INTERCEPT_ICONV 5018INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft, 5019 char **outbuf, SIZE_T *outbytesleft) { 5020 void *ctx; 5021 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf, 5022 outbytesleft); 5023 if (inbytesleft) 5024 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft)); 5025 if (inbuf && inbytesleft) 5026 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft); 5027 if (outbytesleft) 5028 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft)); 5029 void *outbuf_orig = outbuf ? *outbuf : nullptr; 5030 // FIXME: under ASan the call below may write to freed memory and corrupt 5031 // its metadata. See 5032 // https://github.com/google/sanitizers/issues/321. 5033 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft); 5034 if (outbuf && *outbuf > outbuf_orig) { 5035 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig; 5036 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz); 5037 } 5038 return res; 5039} 5040#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv); 5041#else 5042#define INIT_ICONV 5043#endif 5044 5045#if SANITIZER_INTERCEPT_TIMES 5046INTERCEPTOR(__sanitizer_clock_t, times, void *tms) { 5047 void *ctx; 5048 COMMON_INTERCEPTOR_ENTER(ctx, times, tms); 5049 // FIXME: under ASan the call below may write to freed memory and corrupt 5050 // its metadata. See 5051 // https://github.com/google/sanitizers/issues/321. 5052 __sanitizer_clock_t res = REAL(times)(tms); 5053 if (res != (__sanitizer_clock_t)-1 && tms) 5054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz); 5055 return res; 5056} 5057#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times); 5058#else 5059#define INIT_TIMES 5060#endif 5061 5062#if SANITIZER_INTERCEPT_TLS_GET_ADDR 5063#if !SANITIZER_S390 5064#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr) 5065// If you see any crashes around this functions, there are 2 known issues with 5066// it: 1. __tls_get_addr can be called with mis-aligned stack due to: 5067// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 5068// 2. It can be called recursively if sanitizer code uses __tls_get_addr 5069// to access thread local variables (it should not happen normally, 5070// because sanitizers use initial-exec tls model). 5071INTERCEPTOR(void *, __tls_get_addr, void *arg) { 5072 void *ctx; 5073 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg); 5074 void *res = REAL(__tls_get_addr)(arg); 5075 uptr tls_begin, tls_end; 5076 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5077 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end); 5078 if (dtv) { 5079 // New DTLS block has been allocated. 5080 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5081 } 5082 return res; 5083} 5084#if SANITIZER_PPC 5085// On PowerPC, we also need to intercept __tls_get_addr_opt, which has 5086// mostly the same semantics as __tls_get_addr, but its presence enables 5087// some optimizations in linker (which are safe to ignore here). 5088extern "C" __attribute__((alias("__interceptor___tls_get_addr"), 5089 visibility("default"))) 5090void *__tls_get_addr_opt(void *arg); 5091#endif 5092#else // SANITIZER_S390 5093// On s390, we have to intercept two functions here: 5094// - __tls_get_addr_internal, which is a glibc-internal function that is like 5095// the usual __tls_get_addr, but returns a TP-relative offset instead of 5096// a proper pointer. It is used by dlsym for TLS symbols. 5097// - __tls_get_offset, which is like the above, but also takes a GOT-relative 5098// descriptor offset as an argument instead of a pointer. GOT address 5099// is passed in r12, so it's necessary to write it in assembly. This is 5100// the function used by the compiler. 5101extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg)); 5102#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset) 5103DEFINE_REAL(uptr, __tls_get_offset, void *arg) 5104extern "C" uptr __tls_get_offset(void *arg); 5105extern "C" uptr __interceptor___tls_get_offset(void *arg); 5106INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) { 5107 void *ctx; 5108 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg); 5109 uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset)); 5110 uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer()); 5111 void *ptr = reinterpret_cast<void *>(res + tp); 5112 uptr tls_begin, tls_end; 5113 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5114 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end); 5115 if (dtv) { 5116 // New DTLS block has been allocated. 5117 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5118 } 5119 return res; 5120} 5121// We need a hidden symbol aliasing the above, so that we can jump 5122// directly to it from the assembly below. 5123extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"), 5124 visibility("hidden"))) 5125uptr __tls_get_addr_hidden(void *arg); 5126// Now carefully intercept __tls_get_offset. 5127asm( 5128 ".text\n" 5129// The __intercept_ version has to exist, so that gen_dynamic_list.py 5130// exports our symbol. 5131 ".weak __tls_get_offset\n" 5132 ".type __tls_get_offset, @function\n" 5133 "__tls_get_offset:\n" 5134 ".global __interceptor___tls_get_offset\n" 5135 ".type __interceptor___tls_get_offset, @function\n" 5136 "__interceptor___tls_get_offset:\n" 5137#ifdef __s390x__ 5138 "la %r2, 0(%r2,%r12)\n" 5139 "jg __tls_get_addr_hidden\n" 5140#else 5141 "basr %r3,0\n" 5142 "0: la %r2,0(%r2,%r12)\n" 5143 "l %r4,1f-0b(%r3)\n" 5144 "b 0(%r4,%r3)\n" 5145 "1: .long __tls_get_addr_hidden - 0b\n" 5146#endif 5147 ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n" 5148// Assembly wrapper to call REAL(__tls_get_offset)(arg) 5149 ".type __tls_get_offset_wrapper, @function\n" 5150 "__tls_get_offset_wrapper:\n" 5151#ifdef __s390x__ 5152 "sgr %r2,%r12\n" 5153#else 5154 "sr %r2,%r12\n" 5155#endif 5156 "br %r3\n" 5157 ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n" 5158); 5159#endif // SANITIZER_S390 5160#else 5161#define INIT_TLS_GET_ADDR 5162#endif 5163 5164#if SANITIZER_INTERCEPT_LISTXATTR 5165INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { 5166 void *ctx; 5167 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size); 5168 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5169 // FIXME: under ASan the call below may write to freed memory and corrupt 5170 // its metadata. See 5171 // https://github.com/google/sanitizers/issues/321. 5172 SSIZE_T res = REAL(listxattr)(path, list, size); 5173 // Here and below, size == 0 is a special case where nothing is written to the 5174 // buffer, and res contains the desired buffer size. 5175 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5176 return res; 5177} 5178INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) { 5179 void *ctx; 5180 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size); 5181 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 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 SSIZE_T res = REAL(llistxattr)(path, list, size); 5186 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5187 return res; 5188} 5189INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) { 5190 void *ctx; 5191 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size); 5192 // FIXME: under ASan the call below may write to freed memory and corrupt 5193 // its metadata. See 5194 // https://github.com/google/sanitizers/issues/321. 5195 SSIZE_T res = REAL(flistxattr)(fd, list, size); 5196 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5197 return res; 5198} 5199#define INIT_LISTXATTR \ 5200 COMMON_INTERCEPT_FUNCTION(listxattr); \ 5201 COMMON_INTERCEPT_FUNCTION(llistxattr); \ 5202 COMMON_INTERCEPT_FUNCTION(flistxattr); 5203#else 5204#define INIT_LISTXATTR 5205#endif 5206 5207#if SANITIZER_INTERCEPT_GETXATTR 5208INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value, 5209 SIZE_T size) { 5210 void *ctx; 5211 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size); 5212 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5213 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5214 // FIXME: under ASan the call below may write to freed memory and corrupt 5215 // its metadata. See 5216 // https://github.com/google/sanitizers/issues/321. 5217 SSIZE_T res = REAL(getxattr)(path, name, value, size); 5218 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5219 return res; 5220} 5221INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value, 5222 SIZE_T size) { 5223 void *ctx; 5224 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size); 5225 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5226 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5227 // FIXME: under ASan the call below may write to freed memory and corrupt 5228 // its metadata. See 5229 // https://github.com/google/sanitizers/issues/321. 5230 SSIZE_T res = REAL(lgetxattr)(path, name, value, size); 5231 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5232 return res; 5233} 5234INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value, 5235 SIZE_T size) { 5236 void *ctx; 5237 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size); 5238 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5239 // FIXME: under ASan the call below may write to freed memory and corrupt 5240 // its metadata. See 5241 // https://github.com/google/sanitizers/issues/321. 5242 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size); 5243 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5244 return res; 5245} 5246#define INIT_GETXATTR \ 5247 COMMON_INTERCEPT_FUNCTION(getxattr); \ 5248 COMMON_INTERCEPT_FUNCTION(lgetxattr); \ 5249 COMMON_INTERCEPT_FUNCTION(fgetxattr); 5250#else 5251#define INIT_GETXATTR 5252#endif 5253 5254#if SANITIZER_INTERCEPT_GETRESID 5255INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) { 5256 void *ctx; 5257 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid); 5258 // FIXME: under ASan the call below may write to freed memory and corrupt 5259 // its metadata. See 5260 // https://github.com/google/sanitizers/issues/321. 5261 int res = REAL(getresuid)(ruid, euid, suid); 5262 if (res >= 0) { 5263 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz); 5264 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz); 5265 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz); 5266 } 5267 return res; 5268} 5269INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) { 5270 void *ctx; 5271 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid); 5272 // FIXME: under ASan the call below may write to freed memory and corrupt 5273 // its metadata. See 5274 // https://github.com/google/sanitizers/issues/321. 5275 int res = REAL(getresgid)(rgid, egid, sgid); 5276 if (res >= 0) { 5277 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz); 5278 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz); 5279 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz); 5280 } 5281 return res; 5282} 5283#define INIT_GETRESID \ 5284 COMMON_INTERCEPT_FUNCTION(getresuid); \ 5285 COMMON_INTERCEPT_FUNCTION(getresgid); 5286#else 5287#define INIT_GETRESID 5288#endif 5289 5290#if SANITIZER_INTERCEPT_GETIFADDRS 5291// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to 5292// intercept freeifaddrs(). If that ceases to be the case, we might need to 5293// intercept it to poison the memory again. 5294INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) { 5295 void *ctx; 5296 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap); 5297 // FIXME: under ASan the call below may write to freed memory and corrupt 5298 // its metadata. See 5299 // https://github.com/google/sanitizers/issues/321. 5300 int res = REAL(getifaddrs)(ifap); 5301 if (res == 0 && ifap) { 5302 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *)); 5303 __sanitizer_ifaddrs *p = *ifap; 5304 while (p) { 5305 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs)); 5306 if (p->ifa_name) 5307 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name, 5308 REAL(strlen)(p->ifa_name) + 1); 5309 if (p->ifa_addr) 5310 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz); 5311 if (p->ifa_netmask) 5312 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz); 5313 // On Linux this is a union, but the other member also points to a 5314 // struct sockaddr, so the following is sufficient. 5315 if (p->ifa_dstaddr) 5316 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz); 5317 // FIXME(smatveev): Unpoison p->ifa_data as well. 5318 p = p->ifa_next; 5319 } 5320 } 5321 return res; 5322} 5323#define INIT_GETIFADDRS \ 5324 COMMON_INTERCEPT_FUNCTION(getifaddrs); 5325#else 5326#define INIT_GETIFADDRS 5327#endif 5328 5329#if SANITIZER_INTERCEPT_IF_INDEXTONAME 5330INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) { 5331 void *ctx; 5332 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname); 5333 // FIXME: under ASan the call below may write to freed memory and corrupt 5334 // its metadata. See 5335 // https://github.com/google/sanitizers/issues/321. 5336 char *res = REAL(if_indextoname)(ifindex, ifname); 5337 if (res && ifname) 5338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5339 return res; 5340} 5341INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) { 5342 void *ctx; 5343 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname); 5344 if (ifname) 5345 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5346 return REAL(if_nametoindex)(ifname); 5347} 5348#define INIT_IF_INDEXTONAME \ 5349 COMMON_INTERCEPT_FUNCTION(if_indextoname); \ 5350 COMMON_INTERCEPT_FUNCTION(if_nametoindex); 5351#else 5352#define INIT_IF_INDEXTONAME 5353#endif 5354 5355#if SANITIZER_INTERCEPT_CAPGET 5356INTERCEPTOR(int, capget, void *hdrp, void *datap) { 5357 void *ctx; 5358 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap); 5359 if (hdrp) 5360 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5361 // FIXME: under ASan the call below may write to freed memory and corrupt 5362 // its metadata. See 5363 // https://github.com/google/sanitizers/issues/321. 5364 int res = REAL(capget)(hdrp, datap); 5365 if (res == 0 && datap) 5366 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz); 5367 // We can also return -1 and write to hdrp->version if the version passed in 5368 // hdrp->version is unsupported. But that's not a trivial condition to check, 5369 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent. 5370 return res; 5371} 5372INTERCEPTOR(int, capset, void *hdrp, const void *datap) { 5373 void *ctx; 5374 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap); 5375 if (hdrp) 5376 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5377 if (datap) 5378 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz); 5379 return REAL(capset)(hdrp, datap); 5380} 5381#define INIT_CAPGET \ 5382 COMMON_INTERCEPT_FUNCTION(capget); \ 5383 COMMON_INTERCEPT_FUNCTION(capset); 5384#else 5385#define INIT_CAPGET 5386#endif 5387 5388#if SANITIZER_INTERCEPT_AEABI_MEM 5389INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { 5390 void *ctx; 5391 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5392} 5393 5394INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { 5395 void *ctx; 5396 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5397} 5398 5399INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { 5400 void *ctx; 5401 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5402} 5403 5404INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { 5405 void *ctx; 5406 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5407} 5408 5409INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { 5410 void *ctx; 5411 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5412} 5413 5414INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { 5415 void *ctx; 5416 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5417} 5418 5419// Note the argument order. 5420INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { 5421 void *ctx; 5422 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5423} 5424 5425INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { 5426 void *ctx; 5427 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5428} 5429 5430INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { 5431 void *ctx; 5432 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5433} 5434 5435INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { 5436 void *ctx; 5437 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5438} 5439 5440INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { 5441 void *ctx; 5442 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5443} 5444 5445INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { 5446 void *ctx; 5447 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5448} 5449 5450#define INIT_AEABI_MEM \ 5451 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \ 5452 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \ 5453 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \ 5454 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \ 5455 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \ 5456 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \ 5457 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \ 5458 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \ 5459 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \ 5460 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \ 5461 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \ 5462 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8); 5463#else 5464#define INIT_AEABI_MEM 5465#endif // SANITIZER_INTERCEPT_AEABI_MEM 5466 5467#if SANITIZER_INTERCEPT___BZERO 5468INTERCEPTOR(void *, __bzero, void *block, uptr size) { 5469 void *ctx; 5470 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5471} 5472 5473#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); 5474#else 5475#define INIT___BZERO 5476#endif // SANITIZER_INTERCEPT___BZERO 5477 5478#if SANITIZER_INTERCEPT_FTIME 5479INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { 5480 void *ctx; 5481 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp); 5482 // FIXME: under ASan the call below may write to freed memory and corrupt 5483 // its metadata. See 5484 // https://github.com/google/sanitizers/issues/321. 5485 int res = REAL(ftime)(tp); 5486 if (tp) 5487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp)); 5488 return res; 5489} 5490#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime); 5491#else 5492#define INIT_FTIME 5493#endif // SANITIZER_INTERCEPT_FTIME 5494 5495#if SANITIZER_INTERCEPT_XDR 5496INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr, 5497 unsigned size, int op) { 5498 void *ctx; 5499 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op); 5500 // FIXME: under ASan the call below may write to freed memory and corrupt 5501 // its metadata. See 5502 // https://github.com/google/sanitizers/issues/321. 5503 REAL(xdrmem_create)(xdrs, addr, size, op); 5504 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5505 if (op == __sanitizer_XDR_ENCODE) { 5506 // It's not obvious how much data individual xdr_ routines write. 5507 // Simply unpoison the entire target buffer in advance. 5508 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size); 5509 } 5510} 5511 5512INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) { 5513 void *ctx; 5514 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op); 5515 // FIXME: under ASan the call below may write to freed memory and corrupt 5516 // its metadata. See 5517 // https://github.com/google/sanitizers/issues/321. 5518 REAL(xdrstdio_create)(xdrs, file, op); 5519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5520} 5521 5522// FIXME: under ASan the call below may write to freed memory and corrupt 5523// its metadata. See 5524// https://github.com/google/sanitizers/issues/321. 5525#define XDR_INTERCEPTOR(F, T) \ 5526 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \ 5527 void *ctx; \ 5528 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \ 5529 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \ 5530 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \ 5531 int res = REAL(F)(xdrs, p); \ 5532 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \ 5533 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \ 5534 return res; \ 5535 } 5536 5537XDR_INTERCEPTOR(xdr_short, short) 5538XDR_INTERCEPTOR(xdr_u_short, unsigned short) 5539XDR_INTERCEPTOR(xdr_int, int) 5540XDR_INTERCEPTOR(xdr_u_int, unsigned) 5541XDR_INTERCEPTOR(xdr_long, long) 5542XDR_INTERCEPTOR(xdr_u_long, unsigned long) 5543XDR_INTERCEPTOR(xdr_hyper, long long) 5544XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long) 5545XDR_INTERCEPTOR(xdr_longlong_t, long long) 5546XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long) 5547XDR_INTERCEPTOR(xdr_int8_t, u8) 5548XDR_INTERCEPTOR(xdr_uint8_t, u8) 5549XDR_INTERCEPTOR(xdr_int16_t, u16) 5550XDR_INTERCEPTOR(xdr_uint16_t, u16) 5551XDR_INTERCEPTOR(xdr_int32_t, u32) 5552XDR_INTERCEPTOR(xdr_uint32_t, u32) 5553XDR_INTERCEPTOR(xdr_int64_t, u64) 5554XDR_INTERCEPTOR(xdr_uint64_t, u64) 5555XDR_INTERCEPTOR(xdr_quad_t, long long) 5556XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long) 5557XDR_INTERCEPTOR(xdr_bool, bool) 5558XDR_INTERCEPTOR(xdr_enum, int) 5559XDR_INTERCEPTOR(xdr_char, char) 5560XDR_INTERCEPTOR(xdr_u_char, unsigned char) 5561XDR_INTERCEPTOR(xdr_float, float) 5562XDR_INTERCEPTOR(xdr_double, double) 5563 5564// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer, 5565// wrapstring, sizeof 5566 5567INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep, 5568 unsigned maxsize) { 5569 void *ctx; 5570 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize); 5571 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5572 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5573 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep)); 5574 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep); 5575 } 5576 // FIXME: under ASan the call below may write to freed memory and corrupt 5577 // its metadata. See 5578 // https://github.com/google/sanitizers/issues/321. 5579 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize); 5580 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) { 5581 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5582 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep)); 5583 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep); 5584 } 5585 return res; 5586} 5587 5588INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, 5589 unsigned maxsize) { 5590 void *ctx; 5591 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize); 5592 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5593 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5594 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5595 } 5596 // FIXME: under ASan the call below may write to freed memory and corrupt 5597 // its metadata. See 5598 // https://github.com/google/sanitizers/issues/321. 5599 int res = REAL(xdr_string)(xdrs, p, maxsize); 5600 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) { 5601 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5602 if (res && *p) 5603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5604 } 5605 return res; 5606} 5607 5608#define INIT_XDR \ 5609 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \ 5610 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \ 5611 COMMON_INTERCEPT_FUNCTION(xdr_short); \ 5612 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \ 5613 COMMON_INTERCEPT_FUNCTION(xdr_int); \ 5614 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \ 5615 COMMON_INTERCEPT_FUNCTION(xdr_long); \ 5616 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \ 5617 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \ 5618 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \ 5619 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \ 5620 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \ 5621 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \ 5622 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \ 5623 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \ 5624 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \ 5625 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \ 5626 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \ 5627 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \ 5628 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \ 5629 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \ 5630 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \ 5631 COMMON_INTERCEPT_FUNCTION(xdr_bool); \ 5632 COMMON_INTERCEPT_FUNCTION(xdr_enum); \ 5633 COMMON_INTERCEPT_FUNCTION(xdr_char); \ 5634 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \ 5635 COMMON_INTERCEPT_FUNCTION(xdr_float); \ 5636 COMMON_INTERCEPT_FUNCTION(xdr_double); \ 5637 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \ 5638 COMMON_INTERCEPT_FUNCTION(xdr_string); 5639#else 5640#define INIT_XDR 5641#endif // SANITIZER_INTERCEPT_XDR 5642 5643#if SANITIZER_INTERCEPT_TSEARCH 5644INTERCEPTOR(void *, tsearch, void *key, void **rootp, 5645 int (*compar)(const void *, const void *)) { 5646 void *ctx; 5647 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar); 5648 // FIXME: under ASan the call below may write to freed memory and corrupt 5649 // its metadata. See 5650 // https://github.com/google/sanitizers/issues/321. 5651 void *res = REAL(tsearch)(key, rootp, compar); 5652 if (res && *(void **)res == key) 5653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *)); 5654 return res; 5655} 5656#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch); 5657#else 5658#define INIT_TSEARCH 5659#endif 5660 5661#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \ 5662 SANITIZER_INTERCEPT_OPEN_MEMSTREAM 5663void unpoison_file(__sanitizer_FILE *fp) { 5664#if SANITIZER_HAS_STRUCT_FILE 5665 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp)); 5666 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) 5667 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, 5668 fp->_IO_read_end - fp->_IO_read_base); 5669#endif // SANITIZER_HAS_STRUCT_FILE 5670} 5671#endif 5672 5673#if SANITIZER_INTERCEPT_LIBIO_INTERNALS 5674// These guys are called when a .c source is built with -O2. 5675INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) { 5676 void *ctx; 5677 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp); 5678 int res = REAL(__uflow)(fp); 5679 unpoison_file(fp); 5680 return res; 5681} 5682INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) { 5683 void *ctx; 5684 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp); 5685 int res = REAL(__underflow)(fp); 5686 unpoison_file(fp); 5687 return res; 5688} 5689INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) { 5690 void *ctx; 5691 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch); 5692 int res = REAL(__overflow)(fp, ch); 5693 unpoison_file(fp); 5694 return res; 5695} 5696INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) { 5697 void *ctx; 5698 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp); 5699 int res = REAL(__wuflow)(fp); 5700 unpoison_file(fp); 5701 return res; 5702} 5703INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) { 5704 void *ctx; 5705 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp); 5706 int res = REAL(__wunderflow)(fp); 5707 unpoison_file(fp); 5708 return res; 5709} 5710INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) { 5711 void *ctx; 5712 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch); 5713 int res = REAL(__woverflow)(fp, ch); 5714 unpoison_file(fp); 5715 return res; 5716} 5717#define INIT_LIBIO_INTERNALS \ 5718 COMMON_INTERCEPT_FUNCTION(__uflow); \ 5719 COMMON_INTERCEPT_FUNCTION(__underflow); \ 5720 COMMON_INTERCEPT_FUNCTION(__overflow); \ 5721 COMMON_INTERCEPT_FUNCTION(__wuflow); \ 5722 COMMON_INTERCEPT_FUNCTION(__wunderflow); \ 5723 COMMON_INTERCEPT_FUNCTION(__woverflow); 5724#else 5725#define INIT_LIBIO_INTERNALS 5726#endif 5727 5728#if SANITIZER_INTERCEPT_FOPEN 5729INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { 5730 void *ctx; 5731 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode); 5732 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5733 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5734 __sanitizer_FILE *res = REAL(fopen)(path, mode); 5735 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5736 if (res) unpoison_file(res); 5737 return res; 5738} 5739INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) { 5740 void *ctx; 5741 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode); 5742 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5743 __sanitizer_FILE *res = REAL(fdopen)(fd, mode); 5744 if (res) unpoison_file(res); 5745 return res; 5746} 5747INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode, 5748 __sanitizer_FILE *fp) { 5749 void *ctx; 5750 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp); 5751 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5752 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5753 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5754 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp); 5755 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5756 if (res) unpoison_file(res); 5757 return res; 5758} 5759#define INIT_FOPEN \ 5760 COMMON_INTERCEPT_FUNCTION(fopen); \ 5761 COMMON_INTERCEPT_FUNCTION(fdopen); \ 5762 COMMON_INTERCEPT_FUNCTION(freopen); 5763#else 5764#define INIT_FOPEN 5765#endif 5766 5767#if SANITIZER_INTERCEPT_FOPEN64 5768INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) { 5769 void *ctx; 5770 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode); 5771 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5772 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5773 __sanitizer_FILE *res = REAL(fopen64)(path, mode); 5774 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5775 if (res) unpoison_file(res); 5776 return res; 5777} 5778INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode, 5779 __sanitizer_FILE *fp) { 5780 void *ctx; 5781 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp); 5782 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5783 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 5784 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5785 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp); 5786 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 5787 if (res) unpoison_file(res); 5788 return res; 5789} 5790#define INIT_FOPEN64 \ 5791 COMMON_INTERCEPT_FUNCTION(fopen64); \ 5792 COMMON_INTERCEPT_FUNCTION(freopen64); 5793#else 5794#define INIT_FOPEN64 5795#endif 5796 5797#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM 5798INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) { 5799 void *ctx; 5800 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc); 5801 // FIXME: under ASan the call below may write to freed memory and corrupt 5802 // its metadata. See 5803 // https://github.com/google/sanitizers/issues/321. 5804 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc); 5805 if (res) { 5806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 5807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 5808 unpoison_file(res); 5809 FileMetadata file = {ptr, sizeloc}; 5810 SetInterceptorMetadata(res, file); 5811 } 5812 return res; 5813} 5814INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr, 5815 SIZE_T *sizeloc) { 5816 void *ctx; 5817 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc); 5818 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc); 5819 if (res) { 5820 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 5821 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 5822 unpoison_file(res); 5823 FileMetadata file = {(char **)ptr, sizeloc}; 5824 SetInterceptorMetadata(res, file); 5825 } 5826 return res; 5827} 5828INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size, 5829 const char *mode) { 5830 void *ctx; 5831 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode); 5832 // FIXME: under ASan the call below may write to freed memory and corrupt 5833 // its metadata. See 5834 // https://github.com/google/sanitizers/issues/321. 5835 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode); 5836 if (res) unpoison_file(res); 5837 return res; 5838} 5839#define INIT_OPEN_MEMSTREAM \ 5840 COMMON_INTERCEPT_FUNCTION(open_memstream); \ 5841 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \ 5842 COMMON_INTERCEPT_FUNCTION(fmemopen); 5843#else 5844#define INIT_OPEN_MEMSTREAM 5845#endif 5846 5847#if SANITIZER_INTERCEPT_OBSTACK 5848static void initialize_obstack(__sanitizer_obstack *obstack) { 5849 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack)); 5850 if (obstack->chunk) 5851 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk, 5852 sizeof(*obstack->chunk)); 5853} 5854 5855INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz, 5856 int align, void *(*alloc_fn)(uptr arg, uptr sz), 5857 void (*free_fn)(uptr arg, void *p)) { 5858 void *ctx; 5859 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn, 5860 free_fn); 5861 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn); 5862 if (res) initialize_obstack(obstack); 5863 return res; 5864} 5865INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz, 5866 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) { 5867 void *ctx; 5868 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn, 5869 free_fn); 5870 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn); 5871 if (res) initialize_obstack(obstack); 5872 return res; 5873} 5874INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) { 5875 void *ctx; 5876 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length); 5877 REAL(_obstack_newchunk)(obstack, length); 5878 if (obstack->chunk) 5879 COMMON_INTERCEPTOR_INITIALIZE_RANGE( 5880 obstack->chunk, obstack->next_free - (char *)obstack->chunk); 5881} 5882#define INIT_OBSTACK \ 5883 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \ 5884 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \ 5885 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk); 5886#else 5887#define INIT_OBSTACK 5888#endif 5889 5890#if SANITIZER_INTERCEPT_FFLUSH 5891INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) { 5892 void *ctx; 5893 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp); 5894 int res = REAL(fflush)(fp); 5895 // FIXME: handle fp == NULL 5896 if (fp) { 5897 const FileMetadata *m = GetInterceptorMetadata(fp); 5898 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 5899 } 5900 return res; 5901} 5902#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush); 5903#else 5904#define INIT_FFLUSH 5905#endif 5906 5907#if SANITIZER_INTERCEPT_FCLOSE 5908INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) { 5909 void *ctx; 5910 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp); 5911 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 5912 const FileMetadata *m = GetInterceptorMetadata(fp); 5913 int res = REAL(fclose)(fp); 5914 if (m) { 5915 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 5916 DeleteInterceptorMetadata(fp); 5917 } 5918 return res; 5919} 5920#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose); 5921#else 5922#define INIT_FCLOSE 5923#endif 5924 5925#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE 5926INTERCEPTOR(void*, dlopen, const char *filename, int flag) { 5927 void *ctx; 5928 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); 5929 if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); 5930 COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); 5931 void *res = REAL(dlopen)(filename, flag); 5932 Symbolizer::GetOrInit()->InvalidateModuleList(); 5933 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); 5934 return res; 5935} 5936 5937INTERCEPTOR(int, dlclose, void *handle) { 5938 void *ctx; 5939 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); 5940 int res = REAL(dlclose)(handle); 5941 Symbolizer::GetOrInit()->InvalidateModuleList(); 5942 COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); 5943 return res; 5944} 5945#define INIT_DLOPEN_DLCLOSE \ 5946 COMMON_INTERCEPT_FUNCTION(dlopen); \ 5947 COMMON_INTERCEPT_FUNCTION(dlclose); 5948#else 5949#define INIT_DLOPEN_DLCLOSE 5950#endif 5951 5952#if SANITIZER_INTERCEPT_GETPASS 5953INTERCEPTOR(char *, getpass, const char *prompt) { 5954 void *ctx; 5955 COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt); 5956 if (prompt) 5957 COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1); 5958 char *res = REAL(getpass)(prompt); 5959 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1); 5960 return res; 5961} 5962 5963#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass); 5964#else 5965#define INIT_GETPASS 5966#endif 5967 5968#if SANITIZER_INTERCEPT_TIMERFD 5969INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value, 5970 void *old_value) { 5971 void *ctx; 5972 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value, 5973 old_value); 5974 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz); 5975 int res = REAL(timerfd_settime)(fd, flags, new_value, old_value); 5976 if (res != -1 && old_value) 5977 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz); 5978 return res; 5979} 5980 5981INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) { 5982 void *ctx; 5983 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value); 5984 int res = REAL(timerfd_gettime)(fd, curr_value); 5985 if (res != -1 && curr_value) 5986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz); 5987 return res; 5988} 5989#define INIT_TIMERFD \ 5990 COMMON_INTERCEPT_FUNCTION(timerfd_settime); \ 5991 COMMON_INTERCEPT_FUNCTION(timerfd_gettime); 5992#else 5993#define INIT_TIMERFD 5994#endif 5995 5996#if SANITIZER_INTERCEPT_MLOCKX 5997// Linux kernel has a bug that leads to kernel deadlock if a process 5998// maps TBs of memory and then calls mlock(). 5999static void MlockIsUnsupported() { 6000 static atomic_uint8_t printed; 6001 if (atomic_exchange(&printed, 1, memory_order_relaxed)) 6002 return; 6003 VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n", 6004 SanitizerToolName); 6005} 6006 6007INTERCEPTOR(int, mlock, const void *addr, uptr len) { 6008 MlockIsUnsupported(); 6009 return 0; 6010} 6011 6012INTERCEPTOR(int, munlock, const void *addr, uptr len) { 6013 MlockIsUnsupported(); 6014 return 0; 6015} 6016 6017INTERCEPTOR(int, mlockall, int flags) { 6018 MlockIsUnsupported(); 6019 return 0; 6020} 6021 6022INTERCEPTOR(int, munlockall, void) { 6023 MlockIsUnsupported(); 6024 return 0; 6025} 6026 6027#define INIT_MLOCKX \ 6028 COMMON_INTERCEPT_FUNCTION(mlock); \ 6029 COMMON_INTERCEPT_FUNCTION(munlock); \ 6030 COMMON_INTERCEPT_FUNCTION(mlockall); \ 6031 COMMON_INTERCEPT_FUNCTION(munlockall); 6032 6033#else 6034#define INIT_MLOCKX 6035#endif // SANITIZER_INTERCEPT_MLOCKX 6036 6037#if SANITIZER_INTERCEPT_FOPENCOOKIE 6038struct WrappedCookie { 6039 void *real_cookie; 6040 __sanitizer_cookie_io_functions_t real_io_funcs; 6041}; 6042 6043static uptr wrapped_read(void *cookie, char *buf, uptr size) { 6044 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6045 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6046 __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read; 6047 return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0; 6048} 6049 6050static uptr wrapped_write(void *cookie, const char *buf, uptr size) { 6051 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6052 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6053 __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write; 6054 return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size; 6055} 6056 6057static int wrapped_seek(void *cookie, u64 *offset, int whence) { 6058 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6059 COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset)); 6060 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6061 __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek; 6062 return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence) 6063 : -1; 6064} 6065 6066static int wrapped_close(void *cookie) { 6067 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 6068 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6069 __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close; 6070 int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0; 6071 InternalFree(wrapped_cookie); 6072 return res; 6073} 6074 6075INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode, 6076 __sanitizer_cookie_io_functions_t io_funcs) { 6077 void *ctx; 6078 COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs); 6079 WrappedCookie *wrapped_cookie = 6080 (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie)); 6081 wrapped_cookie->real_cookie = cookie; 6082 wrapped_cookie->real_io_funcs = io_funcs; 6083 __sanitizer_FILE *res = 6084 REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write, 6085 wrapped_seek, wrapped_close}); 6086 return res; 6087} 6088 6089#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie); 6090#else 6091#define INIT_FOPENCOOKIE 6092#endif // SANITIZER_INTERCEPT_FOPENCOOKIE 6093 6094#if SANITIZER_INTERCEPT_SEM 6095INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) { 6096 void *ctx; 6097 COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value); 6098 // Workaround a bug in glibc's "old" semaphore implementation by 6099 // zero-initializing the sem_t contents. This has to be done here because 6100 // interceptors bind to the lowest symbols version by default, hitting the 6101 // buggy code path while the non-sanitized build of the same code works fine. 6102 REAL(memset)(s, 0, sizeof(*s)); 6103 int res = REAL(sem_init)(s, pshared, value); 6104 return res; 6105} 6106 6107INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) { 6108 void *ctx; 6109 COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s); 6110 int res = REAL(sem_destroy)(s); 6111 return res; 6112} 6113 6114INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) { 6115 void *ctx; 6116 COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s); 6117 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s); 6118 if (res == 0) { 6119 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6120 } 6121 return res; 6122} 6123 6124INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) { 6125 void *ctx; 6126 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s); 6127 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s); 6128 if (res == 0) { 6129 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6130 } 6131 return res; 6132} 6133 6134INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) { 6135 void *ctx; 6136 COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime); 6137 COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz); 6138 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime); 6139 if (res == 0) { 6140 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6141 } 6142 return res; 6143} 6144 6145INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) { 6146 void *ctx; 6147 COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s); 6148 COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s); 6149 int res = REAL(sem_post)(s); 6150 return res; 6151} 6152 6153INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) { 6154 void *ctx; 6155 COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval); 6156 int res = REAL(sem_getvalue)(s, sval); 6157 if (res == 0) { 6158 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval)); 6160 } 6161 return res; 6162} 6163#define INIT_SEM \ 6164 COMMON_INTERCEPT_FUNCTION(sem_init); \ 6165 COMMON_INTERCEPT_FUNCTION(sem_destroy); \ 6166 COMMON_INTERCEPT_FUNCTION(sem_wait); \ 6167 COMMON_INTERCEPT_FUNCTION(sem_trywait); \ 6168 COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ 6169 COMMON_INTERCEPT_FUNCTION(sem_post); \ 6170 COMMON_INTERCEPT_FUNCTION(sem_getvalue); 6171#else 6172#define INIT_SEM 6173#endif // SANITIZER_INTERCEPT_SEM 6174 6175#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL 6176INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { 6177 void *ctx; 6178 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); 6179 int res = REAL(pthread_setcancelstate)(state, oldstate); 6180 if (res == 0 && oldstate != nullptr) 6181 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); 6182 return res; 6183} 6184 6185INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { 6186 void *ctx; 6187 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); 6188 int res = REAL(pthread_setcanceltype)(type, oldtype); 6189 if (res == 0 && oldtype != nullptr) 6190 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); 6191 return res; 6192} 6193#define INIT_PTHREAD_SETCANCEL \ 6194 COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \ 6195 COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype); 6196#else 6197#define INIT_PTHREAD_SETCANCEL 6198#endif 6199 6200#if SANITIZER_INTERCEPT_MINCORE 6201INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) { 6202 void *ctx; 6203 COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec); 6204 int res = REAL(mincore)(addr, length, vec); 6205 if (res == 0) { 6206 uptr page_size = GetPageSizeCached(); 6207 uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size; 6208 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size); 6209 } 6210 return res; 6211} 6212#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore); 6213#else 6214#define INIT_MINCORE 6215#endif 6216 6217#if SANITIZER_INTERCEPT_PROCESS_VM_READV 6218INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov, 6219 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6220 uptr flags) { 6221 void *ctx; 6222 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt, 6223 remote_iov, riovcnt, flags); 6224 SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov, 6225 riovcnt, flags); 6226 if (res > 0) 6227 write_iovec(ctx, local_iov, liovcnt, res); 6228 return res; 6229} 6230 6231INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov, 6232 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6233 uptr flags) { 6234 void *ctx; 6235 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt, 6236 remote_iov, riovcnt, flags); 6237 SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov, 6238 riovcnt, flags); 6239 if (res > 0) 6240 read_iovec(ctx, local_iov, liovcnt, res); 6241 return res; 6242} 6243#define INIT_PROCESS_VM_READV \ 6244 COMMON_INTERCEPT_FUNCTION(process_vm_readv); \ 6245 COMMON_INTERCEPT_FUNCTION(process_vm_writev); 6246#else 6247#define INIT_PROCESS_VM_READV 6248#endif 6249 6250#if SANITIZER_INTERCEPT_CTERMID 6251INTERCEPTOR(char *, ctermid, char *s) { 6252 void *ctx; 6253 COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s); 6254 char *res = REAL(ctermid)(s); 6255 if (res) { 6256 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6257 } 6258 return res; 6259} 6260#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid); 6261#else 6262#define INIT_CTERMID 6263#endif 6264 6265#if SANITIZER_INTERCEPT_CTERMID_R 6266INTERCEPTOR(char *, ctermid_r, char *s) { 6267 void *ctx; 6268 COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s); 6269 char *res = REAL(ctermid_r)(s); 6270 if (res) { 6271 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6272 } 6273 return res; 6274} 6275#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r); 6276#else 6277#define INIT_CTERMID_R 6278#endif 6279 6280#if SANITIZER_INTERCEPT_RECV_RECVFROM 6281INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { 6282 void *ctx; 6283 COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags); 6284 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6285 SSIZE_T res = REAL(recv)(fd, buf, len, flags); 6286 if (res > 0) { 6287 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6288 } 6289 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6290 return res; 6291} 6292 6293INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, 6294 void *srcaddr, int *addrlen) { 6295 void *ctx; 6296 COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr, 6297 addrlen); 6298 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6299 SIZE_T srcaddr_sz; 6300 if (srcaddr) srcaddr_sz = *addrlen; 6301 (void)srcaddr_sz; // prevent "set but not used" warning 6302 SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); 6303 if (res > 0) { 6304 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6305 if (srcaddr) 6306 COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr, 6307 Min((SIZE_T)*addrlen, srcaddr_sz)); 6308 } 6309 return res; 6310} 6311#define INIT_RECV_RECVFROM \ 6312 COMMON_INTERCEPT_FUNCTION(recv); \ 6313 COMMON_INTERCEPT_FUNCTION(recvfrom); 6314#else 6315#define INIT_RECV_RECVFROM 6316#endif 6317 6318#if SANITIZER_INTERCEPT_SEND_SENDTO 6319INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) { 6320 void *ctx; 6321 COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags); 6322 if (fd >= 0) { 6323 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6324 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6325 } 6326 SSIZE_T res = REAL(send)(fd, buf, len, flags); 6327 if (common_flags()->intercept_send && res > 0) 6328 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6329 return res; 6330} 6331 6332INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags, 6333 void *dstaddr, int addrlen) { 6334 void *ctx; 6335 COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen); 6336 if (fd >= 0) { 6337 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6338 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6339 } 6340 // Can't check dstaddr as it may have uninitialized padding at the end. 6341 SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen); 6342 if (common_flags()->intercept_send && res > 0) 6343 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6344 return res; 6345} 6346#define INIT_SEND_SENDTO \ 6347 COMMON_INTERCEPT_FUNCTION(send); \ 6348 COMMON_INTERCEPT_FUNCTION(sendto); 6349#else 6350#define INIT_SEND_SENDTO 6351#endif 6352 6353#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE 6354INTERCEPTOR(int, eventfd_read, int fd, u64 *value) { 6355 void *ctx; 6356 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value); 6357 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6358 int res = REAL(eventfd_read)(fd, value); 6359 if (res == 0) { 6360 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value)); 6361 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6362 } 6363 return res; 6364} 6365INTERCEPTOR(int, eventfd_write, int fd, u64 value) { 6366 void *ctx; 6367 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value); 6368 if (fd >= 0) { 6369 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6370 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6371 } 6372 int res = REAL(eventfd_write)(fd, value); 6373 return res; 6374} 6375#define INIT_EVENTFD_READ_WRITE \ 6376 COMMON_INTERCEPT_FUNCTION(eventfd_read); \ 6377 COMMON_INTERCEPT_FUNCTION(eventfd_write) 6378#else 6379#define INIT_EVENTFD_READ_WRITE 6380#endif 6381 6382#if SANITIZER_INTERCEPT_STAT 6383INTERCEPTOR(int, stat, const char *path, void *buf) { 6384 void *ctx; 6385 COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf); 6386 if (common_flags()->intercept_stat) 6387 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6388 int res = REAL(stat)(path, buf); 6389 if (!res) 6390 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6391 return res; 6392} 6393#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat) 6394#else 6395#define INIT_STAT 6396#endif 6397 6398#if SANITIZER_INTERCEPT_LSTAT 6399INTERCEPTOR(int, lstat, const char *path, void *buf) { 6400 void *ctx; 6401 COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf); 6402 if (common_flags()->intercept_stat) 6403 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6404 int res = REAL(lstat)(path, buf); 6405 if (!res) 6406 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6407 return res; 6408} 6409#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat) 6410#else 6411#define INIT_LSTAT 6412#endif 6413 6414#if SANITIZER_INTERCEPT___XSTAT 6415INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { 6416 void *ctx; 6417 COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf); 6418 if (common_flags()->intercept_stat) 6419 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6420 int res = REAL(__xstat)(version, path, buf); 6421 if (!res) 6422 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6423 return res; 6424} 6425#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat) 6426#else 6427#define INIT___XSTAT 6428#endif 6429 6430#if SANITIZER_INTERCEPT___XSTAT64 6431INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) { 6432 void *ctx; 6433 COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf); 6434 if (common_flags()->intercept_stat) 6435 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6436 int res = REAL(__xstat64)(version, path, buf); 6437 if (!res) 6438 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6439 return res; 6440} 6441#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64) 6442#else 6443#define INIT___XSTAT64 6444#endif 6445 6446#if SANITIZER_INTERCEPT___LXSTAT 6447INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) { 6448 void *ctx; 6449 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf); 6450 if (common_flags()->intercept_stat) 6451 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6452 int res = REAL(__lxstat)(version, path, buf); 6453 if (!res) 6454 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6455 return res; 6456} 6457#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat) 6458#else 6459#define INIT___LXSTAT 6460#endif 6461 6462#if SANITIZER_INTERCEPT___LXSTAT64 6463INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { 6464 void *ctx; 6465 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf); 6466 if (common_flags()->intercept_stat) 6467 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6468 int res = REAL(__lxstat64)(version, path, buf); 6469 if (!res) 6470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6471 return res; 6472} 6473#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64) 6474#else 6475#define INIT___LXSTAT64 6476#endif 6477 6478// FIXME: add other *stat interceptor 6479 6480#if SANITIZER_INTERCEPT_UTMP 6481INTERCEPTOR(void *, getutent, int dummy) { 6482 void *ctx; 6483 COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy); 6484 void *res = REAL(getutent)(dummy); 6485 if (res) 6486 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6487 return res; 6488} 6489INTERCEPTOR(void *, getutid, void *ut) { 6490 void *ctx; 6491 COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut); 6492 void *res = REAL(getutid)(ut); 6493 if (res) 6494 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6495 return res; 6496} 6497INTERCEPTOR(void *, getutline, void *ut) { 6498 void *ctx; 6499 COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut); 6500 void *res = REAL(getutline)(ut); 6501 if (res) 6502 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6503 return res; 6504} 6505#define INIT_UTMP \ 6506 COMMON_INTERCEPT_FUNCTION(getutent); \ 6507 COMMON_INTERCEPT_FUNCTION(getutid); \ 6508 COMMON_INTERCEPT_FUNCTION(getutline); 6509#else 6510#define INIT_UTMP 6511#endif 6512 6513#if SANITIZER_INTERCEPT_UTMPX 6514INTERCEPTOR(void *, getutxent, int dummy) { 6515 void *ctx; 6516 COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy); 6517 void *res = REAL(getutxent)(dummy); 6518 if (res) 6519 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6520 return res; 6521} 6522INTERCEPTOR(void *, getutxid, void *ut) { 6523 void *ctx; 6524 COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut); 6525 void *res = REAL(getutxid)(ut); 6526 if (res) 6527 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6528 return res; 6529} 6530INTERCEPTOR(void *, getutxline, void *ut) { 6531 void *ctx; 6532 COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut); 6533 void *res = REAL(getutxline)(ut); 6534 if (res) 6535 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6536 return res; 6537} 6538#define INIT_UTMPX \ 6539 COMMON_INTERCEPT_FUNCTION(getutxent); \ 6540 COMMON_INTERCEPT_FUNCTION(getutxid); \ 6541 COMMON_INTERCEPT_FUNCTION(getutxline); 6542#else 6543#define INIT_UTMPX 6544#endif 6545 6546#if SANITIZER_INTERCEPT_GETLOADAVG 6547INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) { 6548 void *ctx; 6549 COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem); 6550 int res = REAL(getloadavg)(loadavg, nelem); 6551 if (res > 0) 6552 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg)); 6553 return res; 6554} 6555#define INIT_GETLOADAVG \ 6556 COMMON_INTERCEPT_FUNCTION(getloadavg); 6557#else 6558#define INIT_GETLOADAVG 6559#endif 6560 6561#if SANITIZER_INTERCEPT_MCHECK_MPROBE 6562INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { 6563 return 0; 6564} 6565 6566INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { 6567 return 0; 6568} 6569 6570INTERCEPTOR(int, mprobe, void *ptr) { 6571 return 0; 6572} 6573#endif 6574 6575INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) { 6576 void *ctx; 6577 COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s); 6578 SIZE_T res = REAL(wcslen)(s); 6579 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1)); 6580 return res; 6581} 6582 6583INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) { 6584 void *ctx; 6585 COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n); 6586 SIZE_T res = REAL(wcsnlen)(s, n); 6587 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n)); 6588 return res; 6589} 6590#define INIT_WCSLEN \ 6591 COMMON_INTERCEPT_FUNCTION(wcslen); \ 6592 COMMON_INTERCEPT_FUNCTION(wcsnlen); 6593 6594#if SANITIZER_INTERCEPT_WCSCAT 6595INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { 6596 void *ctx; 6597 COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src); 6598 SIZE_T src_size = REAL(wcslen)(src); 6599 SIZE_T dst_size = REAL(wcslen)(dst); 6600 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t)); 6601 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6602 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6603 (src_size + 1) * sizeof(wchar_t)); 6604 return REAL(wcscat)(dst, src); // NOLINT 6605} 6606 6607INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { 6608 void *ctx; 6609 COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n); 6610 SIZE_T src_size = REAL(wcsnlen)(src, n); 6611 SIZE_T dst_size = REAL(wcslen)(dst); 6612 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, 6613 Min(src_size + 1, n) * sizeof(wchar_t)); 6614 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6615 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6616 (src_size + 1) * sizeof(wchar_t)); 6617 return REAL(wcsncat)(dst, src, n); // NOLINT 6618} 6619#define INIT_WCSCAT \ 6620 COMMON_INTERCEPT_FUNCTION(wcscat); \ 6621 COMMON_INTERCEPT_FUNCTION(wcsncat); 6622#else 6623#define INIT_WCSCAT 6624#endif 6625 6626#if SANITIZER_INTERCEPT_STRXFRM 6627static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } 6628 6629static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); } 6630 6631#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \ 6632 { \ 6633 void *ctx; \ 6634 COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \ 6635 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \ 6636 sizeof(*src) * (RealStrLen(src) + 1)); \ 6637 SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \ 6638 if (res < len) \ 6639 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \ 6640 return res; \ 6641 } 6642 6643INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) { 6644 STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len); 6645} 6646 6647INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len, 6648 void *locale) { 6649 STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale); 6650} 6651 6652#define INIT_STRXFRM \ 6653 COMMON_INTERCEPT_FUNCTION(strxfrm); \ 6654 COMMON_INTERCEPT_FUNCTION(strxfrm_l); 6655#else 6656#define INIT_STRXFRM 6657#endif 6658 6659#if SANITIZER_INTERCEPT___STRXFRM_L 6660INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len, 6661 void *locale) { 6662 STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale); 6663} 6664 6665#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l); 6666#else 6667#define INIT___STRXFRM_L 6668#endif 6669 6670#if SANITIZER_INTERCEPT_WCSXFRM 6671INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) { 6672 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len); 6673} 6674 6675INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 6676 void *locale) { 6677 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale); 6678} 6679 6680#define INIT_WCSXFRM \ 6681 COMMON_INTERCEPT_FUNCTION(wcsxfrm); \ 6682 COMMON_INTERCEPT_FUNCTION(wcsxfrm_l); 6683#else 6684#define INIT_WCSXFRM 6685#endif 6686 6687#if SANITIZER_INTERCEPT___WCSXFRM_L 6688INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 6689 void *locale) { 6690 STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale); 6691} 6692 6693#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l); 6694#else 6695#define INIT___WCSXFRM_L 6696#endif 6697 6698#if SANITIZER_INTERCEPT_ACCT 6699INTERCEPTOR(int, acct, const char *file) { 6700 void *ctx; 6701 COMMON_INTERCEPTOR_ENTER(ctx, acct, file); 6702 if (file) 6703 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); 6704 return REAL(acct)(file); 6705} 6706#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct) 6707#else 6708#define INIT_ACCT 6709#endif 6710 6711#if SANITIZER_INTERCEPT_USER_FROM_UID 6712INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) { 6713 void *ctx; 6714 const char *user; 6715 COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser); 6716 user = REAL(user_from_uid)(uid, nouser); 6717 if (user) 6718 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1); 6719 return user; 6720} 6721#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid) 6722#else 6723#define INIT_USER_FROM_UID 6724#endif 6725 6726#if SANITIZER_INTERCEPT_UID_FROM_USER 6727INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) { 6728 void *ctx; 6729 int res; 6730 COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid); 6731 if (name) 6732 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6733 res = REAL(uid_from_user)(name, uid); 6734 if (uid) 6735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid)); 6736 return res; 6737} 6738#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user) 6739#else 6740#define INIT_UID_FROM_USER 6741#endif 6742 6743#if SANITIZER_INTERCEPT_GROUP_FROM_GID 6744INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) { 6745 void *ctx; 6746 const char *group; 6747 COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup); 6748 group = REAL(group_from_gid)(gid, nogroup); 6749 if (group) 6750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1); 6751 return group; 6752} 6753#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid) 6754#else 6755#define INIT_GROUP_FROM_GID 6756#endif 6757 6758#if SANITIZER_INTERCEPT_GID_FROM_GROUP 6759INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) { 6760 void *ctx; 6761 int res; 6762 COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid); 6763 if (group) 6764 COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1); 6765 res = REAL(gid_from_group)(group, gid); 6766 if (gid) 6767 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid)); 6768 return res; 6769} 6770#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group) 6771#else 6772#define INIT_GID_FROM_GROUP 6773#endif 6774 6775#if SANITIZER_INTERCEPT_ACCESS 6776INTERCEPTOR(int, access, const char *path, int mode) { 6777 void *ctx; 6778 COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode); 6779 if (path) 6780 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6781 return REAL(access)(path, mode); 6782} 6783#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access) 6784#else 6785#define INIT_ACCESS 6786#endif 6787 6788#if SANITIZER_INTERCEPT_FACCESSAT 6789INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) { 6790 void *ctx; 6791 COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags); 6792 if (path) 6793 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6794 return REAL(faccessat)(fd, path, mode, flags); 6795} 6796#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat) 6797#else 6798#define INIT_FACCESSAT 6799#endif 6800 6801#if SANITIZER_INTERCEPT_GETGROUPLIST 6802INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups, 6803 int *ngroups) { 6804 void *ctx; 6805 int res; 6806 COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups); 6807 if (name) 6808 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6809 if (ngroups) 6810 COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups)); 6811 res = REAL(getgrouplist)(name, basegid, groups, ngroups); 6812 if (!res && groups && ngroups) { 6813 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 6814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 6815 } 6816 return res; 6817} 6818 6819#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist); 6820#else 6821#define INIT_GETGROUPLIST 6822#endif 6823 6824#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP 6825INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, 6826 int maxgrp, int *ngroups) { 6827 void *ctx; 6828 int res; 6829 COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, 6830 maxgrp, ngroups); 6831 if (name) 6832 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 6833 res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups); 6834 if (!res && groups && ngroups) { 6835 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 6836 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 6837 } 6838 return res; 6839} 6840 6841#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership); 6842#else 6843#define INIT_GETGROUPMEMBERSHIP 6844#endif 6845 6846#if SANITIZER_INTERCEPT_READLINK 6847INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { 6848 void* ctx; 6849 COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz); 6850 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6851 SSIZE_T res = REAL(readlink)(path, buf, bufsiz); 6852 if (res > 0) 6853 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 6854 return res; 6855} 6856 6857#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink) 6858#else 6859#define INIT_READLINK 6860#endif 6861 6862#if SANITIZER_INTERCEPT_READLINKAT 6863INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf, 6864 SIZE_T bufsiz) { 6865 void* ctx; 6866 COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz); 6867 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6868 SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz); 6869 if (res > 0) 6870 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 6871 return res; 6872} 6873 6874#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat) 6875#else 6876#define INIT_READLINKAT 6877#endif 6878 6879#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT 6880INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname, 6881 struct file_handle *handle, int *mount_id, int flags) { 6882 void* ctx; 6883 COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle, 6884 mount_id, flags); 6885 COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1); 6886 6887 __sanitizer_file_handle *sanitizer_handle = 6888 reinterpret_cast<__sanitizer_file_handle*>(handle); 6889 COMMON_INTERCEPTOR_READ_RANGE( 6890 ctx, &sanitizer_handle->handle_bytes, 6891 sizeof(sanitizer_handle->handle_bytes)); 6892 6893 int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags); 6894 if (!res) { 6895 COMMON_INTERCEPTOR_WRITE_RANGE( 6896 ctx, &sanitizer_handle->handle_bytes, 6897 sizeof(sanitizer_handle->handle_bytes)); 6898 COMMON_INTERCEPTOR_WRITE_RANGE( 6899 ctx, &sanitizer_handle->handle_type, 6900 sizeof(sanitizer_handle->handle_type)); 6901 COMMON_INTERCEPTOR_WRITE_RANGE( 6902 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 6903 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id)); 6904 } 6905 return res; 6906} 6907 6908#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at) 6909#else 6910#define INIT_NAME_TO_HANDLE_AT 6911#endif 6912 6913#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT 6914INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle, 6915 int flags) { 6916 void* ctx; 6917 COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags); 6918 6919 __sanitizer_file_handle *sanitizer_handle = 6920 reinterpret_cast<__sanitizer_file_handle*>(handle); 6921 COMMON_INTERCEPTOR_READ_RANGE( 6922 ctx, &sanitizer_handle->handle_bytes, 6923 sizeof(sanitizer_handle->handle_bytes)); 6924 COMMON_INTERCEPTOR_READ_RANGE( 6925 ctx, &sanitizer_handle->handle_type, 6926 sizeof(sanitizer_handle->handle_type)); 6927 COMMON_INTERCEPTOR_READ_RANGE( 6928 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 6929 6930 return REAL(open_by_handle_at)(mount_fd, handle, flags); 6931} 6932 6933#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at) 6934#else 6935#define INIT_OPEN_BY_HANDLE_AT 6936#endif 6937 6938#if SANITIZER_INTERCEPT_STRLCPY 6939INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) { 6940 void *ctx; 6941 SIZE_T res; 6942 COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size); 6943 if (src) { 6944 // Keep strnlen as macro argument, as macro may ignore it. 6945 COMMON_INTERCEPTOR_READ_STRING( 6946 ctx, src, Min(internal_strnlen(src, size), size - 1) + 1); 6947 } 6948 res = REAL(strlcpy)(dst, src, size); 6949 COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1); 6950 return res; 6951} 6952 6953INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) { 6954 void *ctx; 6955 SIZE_T len = 0; 6956 COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size); 6957 // src is checked in the strlcpy() interceptor 6958 if (dst) { 6959 len = internal_strnlen(dst, size); 6960 COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1); 6961 } 6962 // Reuse the rest of the code in the strlcpy() interceptor 6963 return WRAP(strlcpy)(dst + len, src, size - len) + len; 6964} 6965#define INIT_STRLCPY \ 6966 COMMON_INTERCEPT_FUNCTION(strlcpy); \ 6967 COMMON_INTERCEPT_FUNCTION(strlcat); 6968#else 6969#define INIT_STRLCPY 6970#endif 6971 6972#if SANITIZER_INTERCEPT_MMAP 6973INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, 6974 OFF_T off) { 6975 void *ctx; 6976 if (common_flags()->detect_write_exec) 6977 ReportMmapWriteExec(prot); 6978 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 6979 return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 6980 COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); 6981 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off); 6982} 6983 6984INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) { 6985 void *ctx; 6986 if (common_flags()->detect_write_exec) 6987 ReportMmapWriteExec(prot); 6988 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 6989 return (int)internal_mprotect(addr, sz, prot); 6990 COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot); 6991 MprotectMallocZones(addr, prot); 6992 return REAL(mprotect)(addr, sz, prot); 6993} 6994#define INIT_MMAP \ 6995 COMMON_INTERCEPT_FUNCTION(mmap); \ 6996 COMMON_INTERCEPT_FUNCTION(mprotect); 6997#else 6998#define INIT_MMAP 6999#endif 7000 7001#if SANITIZER_INTERCEPT_MMAP64 7002INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, 7003 OFF64_T off) { 7004 void *ctx; 7005 if (common_flags()->detect_write_exec) 7006 ReportMmapWriteExec(prot); 7007 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7008 return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 7009 COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); 7010 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off); 7011} 7012#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64); 7013#else 7014#define INIT_MMAP64 7015#endif 7016 7017#if SANITIZER_INTERCEPT_DEVNAME 7018INTERCEPTOR(char *, devname, u64 dev, u32 type) { 7019 void *ctx; 7020 char *name; 7021 COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type); 7022 name = REAL(devname)(dev, type); 7023 if (name) 7024 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 7025 return name; 7026} 7027#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname); 7028#else 7029#define INIT_DEVNAME 7030#endif 7031 7032#if SANITIZER_INTERCEPT_DEVNAME_R 7033INTERCEPTOR(int, devname_r, u64 dev, u32 type, char *path, uptr len) { 7034 void *ctx; 7035 int res; 7036 COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len); 7037 res = REAL(devname_r)(dev, type, path, len); 7038 if (!res) 7039 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); 7040 return res; 7041} 7042#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r); 7043#else 7044#define INIT_DEVNAME_R 7045#endif 7046 7047#if SANITIZER_INTERCEPT_FGETLN 7048INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) { 7049 void *ctx; 7050 COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len); 7051 char *str = REAL(fgetln)(stream, len); 7052 if (str && len) { 7053 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len); 7055 } 7056 return str; 7057} 7058#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln) 7059#else 7060#define INIT_FGETLN 7061#endif 7062 7063#if SANITIZER_INTERCEPT_STRMODE 7064INTERCEPTOR(void, strmode, u32 mode, char *bp) { 7065 void *ctx; 7066 COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp); 7067 REAL(strmode)(mode, bp); 7068 if (bp) 7069 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1); 7070} 7071#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode) 7072#else 7073#define INIT_STRMODE 7074#endif 7075 7076#if SANITIZER_INTERCEPT_TTYENT 7077INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) { 7078 void *ctx; 7079 COMMON_INTERCEPTOR_ENTER(ctx, getttyent); 7080 struct __sanitizer_ttyent *ttyent = REAL(getttyent)(); 7081 if (ttyent) 7082 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7083 return ttyent; 7084} 7085INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) { 7086 void *ctx; 7087 COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name); 7088 if (name) 7089 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7090 struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name); 7091 if (ttyent) 7092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7093 return ttyent; 7094} 7095INTERCEPTOR(int, setttyentpath, char *path) { 7096 void *ctx; 7097 COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path); 7098 if (path) 7099 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7100 return REAL(setttyentpath)(path); 7101} 7102#define INIT_TTYENT \ 7103 COMMON_INTERCEPT_FUNCTION(getttyent); \ 7104 COMMON_INTERCEPT_FUNCTION(getttynam); \ 7105 COMMON_INTERCEPT_FUNCTION(setttyentpath) 7106#else 7107#define INIT_TTYENT 7108#endif 7109 7110#if SANITIZER_INTERCEPT_PROTOENT 7111INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { 7112 void *ctx; 7113 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); 7114 struct __sanitizer_protoent *p = REAL(getprotoent)(); 7115 if (p) { 7116 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7117 7118 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7119 7120 SIZE_T pp_size = 1; // One handles the trailing \0 7121 7122 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7123 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7124 7125 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7126 pp_size * sizeof(char **)); 7127 } 7128 return p; 7129} 7130 7131INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { 7132 void *ctx; 7133 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name); 7134 if (name) 7135 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7136 struct __sanitizer_protoent *p = REAL(getprotobyname)(name); 7137 if (p) { 7138 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7139 7140 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7141 7142 SIZE_T pp_size = 1; // One handles the trailing \0 7143 7144 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7145 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7146 7147 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7148 pp_size * sizeof(char **)); 7149 } 7150 return p; 7151} 7152 7153INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { 7154 void *ctx; 7155 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); 7156 struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); 7157 if (p) { 7158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7159 7160 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7161 7162 SIZE_T pp_size = 1; // One handles the trailing \0 7163 7164 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7165 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7166 7167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7168 pp_size * sizeof(char **)); 7169 } 7170 return p; 7171} 7172#define INIT_PROTOENT \ 7173 COMMON_INTERCEPT_FUNCTION(getprotoent); \ 7174 COMMON_INTERCEPT_FUNCTION(getprotobyname); \ 7175 COMMON_INTERCEPT_FUNCTION(getprotobynumber) 7176#else 7177#define INIT_PROTOENT 7178#endif 7179 7180#if SANITIZER_INTERCEPT_NETENT 7181INTERCEPTOR(struct __sanitizer_netent *, getnetent) { 7182 void *ctx; 7183 COMMON_INTERCEPTOR_ENTER(ctx, getnetent); 7184 struct __sanitizer_netent *n = REAL(getnetent)(); 7185 if (n) { 7186 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7187 7188 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7189 7190 SIZE_T nn_size = 1; // One handles the trailing \0 7191 7192 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7193 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7194 7195 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7196 nn_size * sizeof(char **)); 7197 } 7198 return n; 7199} 7200 7201INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { 7202 void *ctx; 7203 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); 7204 if (name) 7205 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7206 struct __sanitizer_netent *n = REAL(getnetbyname)(name); 7207 if (n) { 7208 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7209 7210 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7211 7212 SIZE_T nn_size = 1; // One handles the trailing \0 7213 7214 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7215 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7216 7217 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7218 nn_size * sizeof(char **)); 7219 } 7220 return n; 7221} 7222 7223INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { 7224 void *ctx; 7225 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type); 7226 struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type); 7227 if (n) { 7228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7229 7230 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7231 7232 SIZE_T nn_size = 1; // One handles the trailing \0 7233 7234 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7235 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7236 7237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7238 nn_size * sizeof(char **)); 7239 } 7240 return n; 7241} 7242#define INIT_NETENT \ 7243 COMMON_INTERCEPT_FUNCTION(getnetent); \ 7244 COMMON_INTERCEPT_FUNCTION(getnetbyname); \ 7245 COMMON_INTERCEPT_FUNCTION(getnetbyaddr) 7246#else 7247#define INIT_NETENT 7248#endif 7249 7250static void InitializeCommonInterceptors() { 7251 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; 7252 interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); 7253 7254 INIT_MMAP; 7255 INIT_MMAP64; 7256 INIT_TEXTDOMAIN; 7257 INIT_STRLEN; 7258 INIT_STRNLEN; 7259 INIT_STRNDUP; 7260 INIT___STRNDUP; 7261 INIT_STRCMP; 7262 INIT_STRNCMP; 7263 INIT_STRCASECMP; 7264 INIT_STRNCASECMP; 7265 INIT_STRSTR; 7266 INIT_STRCASESTR; 7267 INIT_STRCHR; 7268 INIT_STRCHRNUL; 7269 INIT_STRRCHR; 7270 INIT_STRSPN; 7271 INIT_STRTOK; 7272 INIT_STRPBRK; 7273 INIT_STRXFRM; 7274 INIT___STRXFRM_L; 7275 INIT_MEMSET; 7276 INIT_MEMMOVE; 7277 INIT_MEMCPY; 7278 INIT_MEMCHR; 7279 INIT_MEMCMP; 7280 INIT_MEMRCHR; 7281 INIT_MEMMEM; 7282 INIT_READ; 7283 INIT_FREAD; 7284 INIT_PREAD; 7285 INIT_PREAD64; 7286 INIT_READV; 7287 INIT_PREADV; 7288 INIT_PREADV64; 7289 INIT_WRITE; 7290 INIT_FWRITE; 7291 INIT_PWRITE; 7292 INIT_PWRITE64; 7293 INIT_WRITEV; 7294 INIT_PWRITEV; 7295 INIT_PWRITEV64; 7296 INIT_FGETS; 7297 INIT_FPUTS; 7298 INIT_PUTS; 7299 INIT_PRCTL; 7300 INIT_LOCALTIME_AND_FRIENDS; 7301 INIT_STRPTIME; 7302 INIT_SCANF; 7303 INIT_ISOC99_SCANF; 7304 INIT_PRINTF; 7305 INIT_PRINTF_L; 7306 INIT_ISOC99_PRINTF; 7307 INIT_FREXP; 7308 INIT_FREXPF_FREXPL; 7309 INIT_GETPWNAM_AND_FRIENDS; 7310 INIT_GETPWNAM_R_AND_FRIENDS; 7311 INIT_GETPWENT; 7312 INIT_FGETPWENT; 7313 INIT_GETPWENT_R; 7314 INIT_SETPWENT; 7315 INIT_CLOCK_GETTIME; 7316 INIT_GETITIMER; 7317 INIT_TIME; 7318 INIT_GLOB; 7319 INIT_GLOB64; 7320 INIT_WAIT; 7321 INIT_WAIT4; 7322 INIT_INET; 7323 INIT_PTHREAD_GETSCHEDPARAM; 7324 INIT_GETADDRINFO; 7325 INIT_GETNAMEINFO; 7326 INIT_GETSOCKNAME; 7327 INIT_GETHOSTBYNAME; 7328 INIT_GETHOSTBYNAME2; 7329 INIT_GETHOSTBYNAME_R; 7330 INIT_GETHOSTBYNAME2_R; 7331 INIT_GETHOSTBYADDR_R; 7332 INIT_GETHOSTENT_R; 7333 INIT_GETSOCKOPT; 7334 INIT_ACCEPT; 7335 INIT_ACCEPT4; 7336 INIT_PACCEPT; 7337 INIT_MODF; 7338 INIT_RECVMSG; 7339 INIT_SENDMSG; 7340 INIT_RECVMMSG; 7341 INIT_SENDMMSG; 7342 INIT_GETPEERNAME; 7343 INIT_IOCTL; 7344 INIT_INET_ATON; 7345 INIT_SYSINFO; 7346 INIT_READDIR; 7347 INIT_READDIR64; 7348 INIT_PTRACE; 7349 INIT_SETLOCALE; 7350 INIT_GETCWD; 7351 INIT_GET_CURRENT_DIR_NAME; 7352 INIT_STRTOIMAX; 7353 INIT_MBSTOWCS; 7354 INIT_MBSNRTOWCS; 7355 INIT_WCSTOMBS; 7356 INIT_WCSNRTOMBS; 7357 INIT_WCRTOMB; 7358 INIT_TCGETATTR; 7359 INIT_REALPATH; 7360 INIT_CANONICALIZE_FILE_NAME; 7361 INIT_CONFSTR; 7362 INIT_SCHED_GETAFFINITY; 7363 INIT_SCHED_GETPARAM; 7364 INIT_STRERROR; 7365 INIT_STRERROR_R; 7366 INIT_XPG_STRERROR_R; 7367 INIT_SCANDIR; 7368 INIT_SCANDIR64; 7369 INIT_GETGROUPS; 7370 INIT_POLL; 7371 INIT_PPOLL; 7372 INIT_WORDEXP; 7373 INIT_SIGWAIT; 7374 INIT_SIGWAITINFO; 7375 INIT_SIGTIMEDWAIT; 7376 INIT_SIGSETOPS; 7377 INIT_SIGPENDING; 7378 INIT_SIGPROCMASK; 7379 INIT_BACKTRACE; 7380 INIT__EXIT; 7381 INIT_PTHREAD_MUTEX_LOCK; 7382 INIT_PTHREAD_MUTEX_UNLOCK; 7383 INIT___PTHREAD_MUTEX_LOCK; 7384 INIT___PTHREAD_MUTEX_UNLOCK; 7385 INIT___LIBC_MUTEX_LOCK; 7386 INIT___LIBC_MUTEX_UNLOCK; 7387 INIT___LIBC_THR_SETCANCELSTATE; 7388 INIT_GETMNTENT; 7389 INIT_GETMNTENT_R; 7390 INIT_STATFS; 7391 INIT_STATFS64; 7392 INIT_STATVFS; 7393 INIT_STATVFS64; 7394 INIT_INITGROUPS; 7395 INIT_ETHER_NTOA_ATON; 7396 INIT_ETHER_HOST; 7397 INIT_ETHER_R; 7398 INIT_SHMCTL; 7399 INIT_RANDOM_R; 7400 INIT_PTHREAD_ATTR_GET; 7401 INIT_PTHREAD_ATTR_GET_SCHED; 7402 INIT_PTHREAD_ATTR_GETINHERITSCHED; 7403 INIT_PTHREAD_ATTR_GETAFFINITY_NP; 7404 INIT_PTHREAD_MUTEXATTR_GETPSHARED; 7405 INIT_PTHREAD_MUTEXATTR_GETTYPE; 7406 INIT_PTHREAD_MUTEXATTR_GETPROTOCOL; 7407 INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING; 7408 INIT_PTHREAD_MUTEXATTR_GETROBUST; 7409 INIT_PTHREAD_MUTEXATTR_GETROBUST_NP; 7410 INIT_PTHREAD_RWLOCKATTR_GETPSHARED; 7411 INIT_PTHREAD_RWLOCKATTR_GETKIND_NP; 7412 INIT_PTHREAD_CONDATTR_GETPSHARED; 7413 INIT_PTHREAD_CONDATTR_GETCLOCK; 7414 INIT_PTHREAD_BARRIERATTR_GETPSHARED; 7415 INIT_TMPNAM; 7416 INIT_TMPNAM_R; 7417 INIT_TTYNAME_R; 7418 INIT_TEMPNAM; 7419 INIT_PTHREAD_SETNAME_NP; 7420 INIT_PTHREAD_GETNAME_NP; 7421 INIT_SINCOS; 7422 INIT_REMQUO; 7423 INIT_LGAMMA; 7424 INIT_LGAMMA_R; 7425 INIT_LGAMMAL_R; 7426 INIT_DRAND48_R; 7427 INIT_RAND_R; 7428 INIT_GETLINE; 7429 INIT_ICONV; 7430 INIT_TIMES; 7431 INIT_TLS_GET_ADDR; 7432 INIT_LISTXATTR; 7433 INIT_GETXATTR; 7434 INIT_GETRESID; 7435 INIT_GETIFADDRS; 7436 INIT_IF_INDEXTONAME; 7437 INIT_CAPGET; 7438 INIT_AEABI_MEM; 7439 INIT___BZERO; 7440 INIT_FTIME; 7441 INIT_XDR; 7442 INIT_TSEARCH; 7443 INIT_LIBIO_INTERNALS; 7444 INIT_FOPEN; 7445 INIT_FOPEN64; 7446 INIT_OPEN_MEMSTREAM; 7447 INIT_OBSTACK; 7448 INIT_FFLUSH; 7449 INIT_FCLOSE; 7450 INIT_DLOPEN_DLCLOSE; 7451 INIT_GETPASS; 7452 INIT_TIMERFD; 7453 INIT_MLOCKX; 7454 INIT_FOPENCOOKIE; 7455 INIT_SEM; 7456 INIT_PTHREAD_SETCANCEL; 7457 INIT_MINCORE; 7458 INIT_PROCESS_VM_READV; 7459 INIT_CTERMID; 7460 INIT_CTERMID_R; 7461 INIT_RECV_RECVFROM; 7462 INIT_SEND_SENDTO; 7463 INIT_STAT; 7464 INIT_EVENTFD_READ_WRITE; 7465 INIT_LSTAT; 7466 INIT___XSTAT; 7467 INIT___XSTAT64; 7468 INIT___LXSTAT; 7469 INIT___LXSTAT64; 7470 // FIXME: add other *stat interceptors. 7471 INIT_UTMP; 7472 INIT_UTMPX; 7473 INIT_GETLOADAVG; 7474 INIT_WCSLEN; 7475 INIT_WCSCAT; 7476 INIT_WCSXFRM; 7477 INIT___WCSXFRM_L; 7478 INIT_ACCT; 7479 INIT_USER_FROM_UID; 7480 INIT_UID_FROM_USER; 7481 INIT_GROUP_FROM_GID; 7482 INIT_GID_FROM_GROUP; 7483 INIT_ACCESS; 7484 INIT_FACCESSAT; 7485 INIT_GETGROUPLIST; 7486 INIT_GETGROUPMEMBERSHIP; 7487 INIT_READLINK; 7488 INIT_READLINKAT; 7489 INIT_NAME_TO_HANDLE_AT; 7490 INIT_OPEN_BY_HANDLE_AT; 7491 INIT_STRLCPY; 7492 INIT_DEVNAME; 7493 INIT_DEVNAME_R; 7494 INIT_FGETLN; 7495 INIT_STRMODE; 7496 INIT_TTYENT; 7497 INIT_PROTOENT; 7498 INIT_NETENT; 7499 7500 INIT___PRINTF_CHK; 7501} 7502