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