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