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