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