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