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