1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 4// See https://llvm.org/LICENSE.txt for license information. 5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 6// 7//===----------------------------------------------------------------------===// 8// 9// Common function interceptors for tools like AddressSanitizer, 10// ThreadSanitizer, MemorySanitizer, etc. 11// 12// This file should be included into the tool's interceptor file, 13// which has to define its own macros: 14// COMMON_INTERCEPTOR_ENTER 15// COMMON_INTERCEPTOR_ENTER_NOIGNORE 16// COMMON_INTERCEPTOR_READ_RANGE 17// COMMON_INTERCEPTOR_WRITE_RANGE 18// COMMON_INTERCEPTOR_INITIALIZE_RANGE 19// COMMON_INTERCEPTOR_DIR_ACQUIRE 20// COMMON_INTERCEPTOR_FD_ACQUIRE 21// COMMON_INTERCEPTOR_FD_RELEASE 22// COMMON_INTERCEPTOR_FD_ACCESS 23// COMMON_INTERCEPTOR_SET_THREAD_NAME 24// COMMON_INTERCEPTOR_ON_DLOPEN 25// COMMON_INTERCEPTOR_ON_EXIT 26// COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 27// COMMON_INTERCEPTOR_MUTEX_POST_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// COMMON_INTERCEPTOR_MEMSET_IMPL 34// COMMON_INTERCEPTOR_MEMMOVE_IMPL 35// COMMON_INTERCEPTOR_MEMCPY_IMPL 36// COMMON_INTERCEPTOR_MMAP_IMPL 37// COMMON_INTERCEPTOR_COPY_STRING 38// COMMON_INTERCEPTOR_STRNDUP_IMPL 39// COMMON_INTERCEPTOR_STRERROR 40//===----------------------------------------------------------------------===// 41 42#include "interception/interception.h" 43#include "sanitizer_addrhashmap.h" 44#include "sanitizer_errno.h" 45#include "sanitizer_placement_new.h" 46#include "sanitizer_platform_interceptors.h" 47#include "sanitizer_symbolizer.h" 48#include "sanitizer_tls_get_addr.h" 49 50#include <stdarg.h> 51 52#if SANITIZER_INTERCEPTOR_HOOKS 53#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) f(__VA_ARGS__); 54#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) \ 55 SANITIZER_INTERFACE_WEAK_DEF(void, f, __VA_ARGS__) {} 56#else 57#define DECLARE_WEAK_INTERCEPTOR_HOOK(f, ...) 58#define CALL_WEAK_INTERCEPTOR_HOOK(f, ...) 59 60#endif // SANITIZER_INTERCEPTOR_HOOKS 61 62#if SANITIZER_WINDOWS && !defined(va_copy) 63#define va_copy(dst, src) ((dst) = (src)) 64#endif // _WIN32 65 66#if SANITIZER_FREEBSD 67#define pthread_setname_np pthread_set_name_np 68#define inet_aton __inet_aton 69#define inet_pton __inet_pton 70#define iconv __bsd_iconv 71#endif 72 73#if SANITIZER_NETBSD 74#define clock_getres __clock_getres50 75#define clock_gettime __clock_gettime50 76#define clock_settime __clock_settime50 77#define ctime __ctime50 78#define ctime_r __ctime_r50 79#define devname __devname50 80#define fgetpos __fgetpos50 81#define fsetpos __fsetpos50 82#define fstatvfs __fstatvfs90 83#define fstatvfs1 __fstatvfs190 84#define fts_children __fts_children60 85#define fts_close __fts_close60 86#define fts_open __fts_open60 87#define fts_read __fts_read60 88#define fts_set __fts_set60 89#define getitimer __getitimer50 90#define getmntinfo __getmntinfo90 91#define getpwent __getpwent50 92#define getpwnam __getpwnam50 93#define getpwnam_r __getpwnam_r50 94#define getpwuid __getpwuid50 95#define getpwuid_r __getpwuid_r50 96#define getutent __getutent50 97#define getutxent __getutxent50 98#define getutxid __getutxid50 99#define getutxline __getutxline50 100#define getvfsstat __getvfsstat90 101#define pututxline __pututxline50 102#define glob __glob30 103#define gmtime __gmtime50 104#define gmtime_r __gmtime_r50 105#define localtime __locatime50 106#define localtime_r __localtime_r50 107#define mktime __mktime50 108#define lstat __lstat50 109#define opendir __opendir30 110#define readdir __readdir30 111#define readdir_r __readdir_r30 112#define scandir __scandir30 113#define setitimer __setitimer50 114#define setlocale __setlocale50 115#define shmctl __shmctl50 116#define sigaltstack __sigaltstack14 117#define sigemptyset __sigemptyset14 118#define sigfillset __sigfillset14 119#define sigpending __sigpending14 120#define sigprocmask __sigprocmask14 121#define sigtimedwait __sigtimedwait50 122#define stat __stat50 123#define statvfs __statvfs90 124#define statvfs1 __statvfs190 125#define time __time50 126#define times __times13 127#define unvis __unvis50 128#define wait3 __wait350 129#define wait4 __wait450 130extern const unsigned short *_ctype_tab_; 131extern const short *_toupper_tab_; 132extern const short *_tolower_tab_; 133#endif 134 135// Platform-specific options. 136#if SANITIZER_MAC 137#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false 138#elif SANITIZER_WINDOWS64 139#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE false 140#else 141#define PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE true 142#endif // SANITIZER_MAC 143 144#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 145#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} 146#endif 147 148#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM 149#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {} 150#endif 151 152#ifndef COMMON_INTERCEPTOR_FD_ACCESS 153#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 154#endif 155 156#ifndef COMMON_INTERCEPTOR_MUTEX_PRE_LOCK 157#define COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m) {} 158#endif 159 160#ifndef COMMON_INTERCEPTOR_MUTEX_POST_LOCK 161#define COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m) {} 162#endif 163 164#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 165#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 166#endif 167 168#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR 169#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} 170#endif 171 172#ifndef COMMON_INTERCEPTOR_MUTEX_INVALID 173#define COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m) {} 174#endif 175 176#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG 177#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) 178#endif 179 180#ifndef COMMON_INTERCEPTOR_FILE_OPEN 181#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {} 182#endif 183 184#ifndef COMMON_INTERCEPTOR_FILE_CLOSE 185#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {} 186#endif 187 188#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED 189#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) {} 190#endif 191 192#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED 193#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {} 194#endif 195 196#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE 197#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \ 198 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__) 199#endif 200 201#ifndef COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED 202#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (0) 203#endif 204 205#define COMMON_INTERCEPTOR_READ_STRING(ctx, s, n) \ 206 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s), \ 207 common_flags()->strict_string_checks ? (REAL(strlen)(s)) + 1 : (n) ) 208 209#ifndef COMMON_INTERCEPTOR_ON_DLOPEN 210#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \ 211 CheckNoDeepBind(filename, flag); 212#endif 213 214#ifndef COMMON_INTERCEPTOR_GET_TLS_RANGE 215#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) *begin = *end = 0; 216#endif 217 218#ifndef COMMON_INTERCEPTOR_ACQUIRE 219#define COMMON_INTERCEPTOR_ACQUIRE(ctx, u) {} 220#endif 221 222#ifndef COMMON_INTERCEPTOR_RELEASE 223#define COMMON_INTERCEPTOR_RELEASE(ctx, u) {} 224#endif 225 226#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_START 227#define COMMON_INTERCEPTOR_USER_CALLBACK_START() {} 228#endif 229 230#ifndef COMMON_INTERCEPTOR_USER_CALLBACK_END 231#define COMMON_INTERCEPTOR_USER_CALLBACK_END() {} 232#endif 233 234#ifdef SANITIZER_NLDBL_VERSION 235#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 236 COMMON_INTERCEPT_FUNCTION_VER(fn, SANITIZER_NLDBL_VERSION) 237#else 238#define COMMON_INTERCEPT_FUNCTION_LDBL(fn) \ 239 COMMON_INTERCEPT_FUNCTION(fn) 240#endif 241 242#ifdef __GLIBC__ 243// If we could not find the versioned symbol, fall back to an unversioned 244// lookup. This is needed to work around a GLibc bug that causes dlsym 245// with RTLD_NEXT to return the oldest versioned symbol. 246// See https://sourceware.org/bugzilla/show_bug.cgi?id=14932. 247// For certain symbols (e.g. regexec) we have to perform a versioned lookup, 248// but that versioned symbol will only exist for architectures where the 249// oldest Glibc version pre-dates support for that architecture. 250// For example, regexec@GLIBC_2.3.4 exists on x86_64, but not RISC-V. 251// See also https://gcc.gnu.org/bugzilla/show_bug.cgi?id=98920. 252#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \ 253 COMMON_INTERCEPT_FUNCTION_VER_UNVERSIONED_FALLBACK(fn, ver) 254#else 255#define COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(fn, ver) \ 256 COMMON_INTERCEPT_FUNCTION(fn) 257#endif 258 259#ifndef COMMON_INTERCEPTOR_MEMSET_IMPL 260#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size) \ 261 { \ 262 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 263 return internal_memset(dst, v, size); \ 264 COMMON_INTERCEPTOR_ENTER(ctx, memset, dst, v, size); \ 265 if (common_flags()->intercept_intrin) \ 266 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 267 return REAL(memset)(dst, v, size); \ 268 } 269#endif 270 271#ifndef COMMON_INTERCEPTOR_MEMMOVE_IMPL 272#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size) \ 273 { \ 274 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) \ 275 return internal_memmove(dst, src, size); \ 276 COMMON_INTERCEPTOR_ENTER(ctx, memmove, dst, src, size); \ 277 if (common_flags()->intercept_intrin) { \ 278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 279 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 280 } \ 281 return REAL(memmove)(dst, src, size); \ 282 } 283#endif 284 285#ifndef COMMON_INTERCEPTOR_MEMCPY_IMPL 286#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size) \ 287 { \ 288 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) { \ 289 return internal_memmove(dst, src, size); \ 290 } \ 291 COMMON_INTERCEPTOR_ENTER(ctx, memcpy, dst, src, size); \ 292 if (common_flags()->intercept_intrin) { \ 293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, size); \ 294 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, size); \ 295 } \ 296 return REAL(memcpy)(dst, src, size); \ 297 } 298#endif 299 300#ifndef COMMON_INTERCEPTOR_MMAP_IMPL 301#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ 302 off) \ 303 { return REAL(mmap)(addr, sz, prot, flags, fd, off); } 304#endif 305 306#ifndef COMMON_INTERCEPTOR_COPY_STRING 307#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {} 308#endif 309 310#ifndef COMMON_INTERCEPTOR_STRNDUP_IMPL 311#define COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size) \ 312 COMMON_INTERCEPTOR_ENTER(ctx, strndup, s, size); \ 313 uptr copy_length = internal_strnlen(s, size); \ 314 char *new_mem = (char *)WRAP(malloc)(copy_length + 1); \ 315 if (common_flags()->intercept_strndup) { \ 316 COMMON_INTERCEPTOR_READ_STRING(ctx, s, Min(size, copy_length + 1)); \ 317 } \ 318 COMMON_INTERCEPTOR_COPY_STRING(ctx, new_mem, s, copy_length); \ 319 internal_memcpy(new_mem, s, copy_length); \ 320 new_mem[copy_length] = '\0'; \ 321 return new_mem; 322#endif 323 324#ifndef COMMON_INTERCEPTOR_STRERROR 325#define COMMON_INTERCEPTOR_STRERROR() {} 326#endif 327 328struct FileMetadata { 329 // For open_memstream(). 330 char **addr; 331 SIZE_T *size; 332}; 333 334struct CommonInterceptorMetadata { 335 enum { 336 CIMT_INVALID = 0, 337 CIMT_FILE 338 } type; 339 union { 340 FileMetadata file; 341 }; 342}; 343 344#if SI_POSIX 345typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; 346 347static MetadataHashMap *interceptor_metadata_map; 348 349UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, 350 const FileMetadata &file) { 351 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); 352 CHECK(h.created()); 353 h->type = CommonInterceptorMetadata::CIMT_FILE; 354 h->file = file; 355} 356 357UNUSED static const FileMetadata *GetInterceptorMetadata( 358 __sanitizer_FILE *addr) { 359 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, 360 /* remove */ false, 361 /* create */ false); 362 if (addr && h.exists()) { 363 CHECK(!h.created()); 364 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE); 365 return &h->file; 366 } else { 367 return 0; 368 } 369} 370 371UNUSED static void DeleteInterceptorMetadata(void *addr) { 372 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true); 373 CHECK(h.exists()); 374} 375#endif // SI_POSIX 376 377#if SANITIZER_INTERCEPT_STRLEN 378INTERCEPTOR(SIZE_T, strlen, const char *s) { 379 // Sometimes strlen is called prior to InitializeCommonInterceptors, 380 // in which case the REAL(strlen) typically used in 381 // COMMON_INTERCEPTOR_ENTER will fail. We use internal_strlen here 382 // to handle that. 383 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 384 return internal_strlen(s); 385 void *ctx; 386 COMMON_INTERCEPTOR_ENTER(ctx, strlen, s); 387 SIZE_T result = REAL(strlen)(s); 388 if (common_flags()->intercept_strlen) 389 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, result + 1); 390 return result; 391} 392#define INIT_STRLEN COMMON_INTERCEPT_FUNCTION(strlen) 393#else 394#define INIT_STRLEN 395#endif 396 397#if SANITIZER_INTERCEPT_STRNLEN 398INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T maxlen) { 399 void *ctx; 400 COMMON_INTERCEPTOR_ENTER(ctx, strnlen, s, maxlen); 401 SIZE_T length = REAL(strnlen)(s, maxlen); 402 if (common_flags()->intercept_strlen) 403 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, Min(length + 1, maxlen)); 404 return length; 405} 406#define INIT_STRNLEN COMMON_INTERCEPT_FUNCTION(strnlen) 407#else 408#define INIT_STRNLEN 409#endif 410 411#if SANITIZER_INTERCEPT_STRNDUP 412INTERCEPTOR(char*, strndup, const char *s, uptr size) { 413 void *ctx; 414 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 415} 416#define INIT_STRNDUP COMMON_INTERCEPT_FUNCTION(strndup) 417#else 418#define INIT_STRNDUP 419#endif // SANITIZER_INTERCEPT_STRNDUP 420 421#if SANITIZER_INTERCEPT___STRNDUP 422INTERCEPTOR(char*, __strndup, const char *s, uptr size) { 423 void *ctx; 424 COMMON_INTERCEPTOR_STRNDUP_IMPL(ctx, s, size); 425} 426#define INIT___STRNDUP COMMON_INTERCEPT_FUNCTION(__strndup) 427#else 428#define INIT___STRNDUP 429#endif // SANITIZER_INTERCEPT___STRNDUP 430 431#if SANITIZER_INTERCEPT_TEXTDOMAIN 432INTERCEPTOR(char*, textdomain, const char *domainname) { 433 void *ctx; 434 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname); 435 if (domainname) COMMON_INTERCEPTOR_READ_STRING(ctx, domainname, 0); 436 char *domain = REAL(textdomain)(domainname); 437 if (domain) { 438 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1); 439 } 440 return domain; 441} 442#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain) 443#else 444#define INIT_TEXTDOMAIN 445#endif 446 447#if SANITIZER_INTERCEPT_STRCMP 448static inline int CharCmpX(unsigned char c1, unsigned char c2) { 449 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 450} 451 452DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, uptr called_pc, 453 const char *s1, const char *s2, int result) 454 455INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 456 void *ctx; 457 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 458 unsigned char c1, c2; 459 uptr i; 460 for (i = 0;; i++) { 461 c1 = (unsigned char)s1[i]; 462 c2 = (unsigned char)s2[i]; 463 if (c1 != c2 || c1 == '\0') break; 464 } 465 if (common_flags()->intercept_strcmp) { 466 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 467 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 468 } 469 int result = CharCmpX(c1, c2); 470 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcmp, GET_CALLER_PC(), s1, 471 s2, result); 472 return result; 473} 474 475DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, uptr called_pc, 476 const char *s1, const char *s2, uptr n, 477 int result) 478 479INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 480 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 481 return internal_strncmp(s1, s2, size); 482 void *ctx; 483 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 484 unsigned char c1 = 0, c2 = 0; 485 uptr i; 486 for (i = 0; i < size; i++) { 487 c1 = (unsigned char)s1[i]; 488 c2 = (unsigned char)s2[i]; 489 if (c1 != c2 || c1 == '\0') break; 490 } 491 uptr i1 = i; 492 uptr i2 = i; 493 if (common_flags()->strict_string_checks) { 494 for (; i1 < size && s1[i1]; i1++) {} 495 for (; i2 < size && s2[i2]; i2++) {} 496 } 497 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 498 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 499 int result = CharCmpX(c1, c2); 500 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncmp, GET_CALLER_PC(), s1, 501 s2, size, result); 502 return result; 503} 504 505#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) 506#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp) 507#else 508#define INIT_STRCMP 509#define INIT_STRNCMP 510#endif 511 512#if SANITIZER_INTERCEPT_STRCASECMP 513static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 514 int c1_low = ToLower(c1); 515 int c2_low = ToLower(c2); 516 return c1_low - c2_low; 517} 518 519DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, uptr called_pc, 520 const char *s1, const char *s2, int result) 521 522INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 523 void *ctx; 524 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 525 unsigned char c1 = 0, c2 = 0; 526 uptr i; 527 for (i = 0;; i++) { 528 c1 = (unsigned char)s1[i]; 529 c2 = (unsigned char)s2[i]; 530 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 531 } 532 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, i + 1); 533 COMMON_INTERCEPTOR_READ_STRING(ctx, s2, i + 1); 534 int result = CharCaseCmp(c1, c2); 535 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasecmp, GET_CALLER_PC(), 536 s1, s2, result); 537 return result; 538} 539 540DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, uptr called_pc, 541 const char *s1, const char *s2, uptr size, 542 int result) 543 544INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T size) { 545 void *ctx; 546 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, size); 547 unsigned char c1 = 0, c2 = 0; 548 uptr i; 549 for (i = 0; i < size; i++) { 550 c1 = (unsigned char)s1[i]; 551 c2 = (unsigned char)s2[i]; 552 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 553 } 554 uptr i1 = i; 555 uptr i2 = i; 556 if (common_flags()->strict_string_checks) { 557 for (; i1 < size && s1[i1]; i1++) {} 558 for (; i2 < size && s2[i2]; i2++) {} 559 } 560 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s1), Min(i1 + 1, size)); 561 COMMON_INTERCEPTOR_READ_RANGE((ctx), (s2), Min(i2 + 1, size)); 562 int result = CharCaseCmp(c1, c2); 563 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strncasecmp, GET_CALLER_PC(), 564 s1, s2, size, result); 565 return result; 566} 567 568#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp) 569#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp) 570#else 571#define INIT_STRCASECMP 572#define INIT_STRNCASECMP 573#endif 574 575#if SANITIZER_INTERCEPT_STRSTR || SANITIZER_INTERCEPT_STRCASESTR 576static inline void StrstrCheck(void *ctx, char *r, const char *s1, 577 const char *s2) { 578 uptr len1 = REAL(strlen)(s1); 579 uptr len2 = REAL(strlen)(s2); 580 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r ? r - s1 + len2 : len1 + 1); 581 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2 + 1); 582} 583#endif 584 585#if SANITIZER_INTERCEPT_STRSTR 586 587DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, uptr called_pc, 588 const char *s1, const char *s2, char *result) 589 590INTERCEPTOR(char*, strstr, const char *s1, const char *s2) { 591 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 592 return internal_strstr(s1, s2); 593 void *ctx; 594 COMMON_INTERCEPTOR_ENTER(ctx, strstr, s1, s2); 595 char *r = REAL(strstr)(s1, s2); 596 if (common_flags()->intercept_strstr) 597 StrstrCheck(ctx, r, s1, s2); 598 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strstr, GET_CALLER_PC(), s1, 599 s2, r); 600 return r; 601} 602 603#define INIT_STRSTR COMMON_INTERCEPT_FUNCTION(strstr); 604#else 605#define INIT_STRSTR 606#endif 607 608#if SANITIZER_INTERCEPT_STRCASESTR 609 610DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, uptr called_pc, 611 const char *s1, const char *s2, char *result) 612 613INTERCEPTOR(char*, strcasestr, const char *s1, const char *s2) { 614 void *ctx; 615 COMMON_INTERCEPTOR_ENTER(ctx, strcasestr, s1, s2); 616 char *r = REAL(strcasestr)(s1, s2); 617 if (common_flags()->intercept_strstr) 618 StrstrCheck(ctx, r, s1, s2); 619 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_strcasestr, GET_CALLER_PC(), 620 s1, s2, r); 621 return r; 622} 623 624#define INIT_STRCASESTR COMMON_INTERCEPT_FUNCTION(strcasestr); 625#else 626#define INIT_STRCASESTR 627#endif 628 629#if SANITIZER_INTERCEPT_STRTOK 630 631INTERCEPTOR(char*, strtok, char *str, const char *delimiters) { 632 void *ctx; 633 COMMON_INTERCEPTOR_ENTER(ctx, strtok, str, delimiters); 634 if (!common_flags()->intercept_strtok) { 635 return REAL(strtok)(str, delimiters); 636 } 637 if (common_flags()->strict_string_checks) { 638 // If strict_string_checks is enabled, we check the whole first argument 639 // string on the first call (strtok saves this string in a static buffer 640 // for subsequent calls). We do not need to check strtok's result. 641 // As the delimiters can change, we check them every call. 642 if (str != nullptr) { 643 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 644 } 645 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 646 REAL(strlen)(delimiters) + 1); 647 return REAL(strtok)(str, delimiters); 648 } else { 649 // However, when strict_string_checks is disabled we cannot check the 650 // whole string on the first call. Instead, we check the result string 651 // which is guaranteed to be a NULL-terminated substring of the first 652 // argument. We also conservatively check one character of str and the 653 // delimiters. 654 if (str != nullptr) { 655 COMMON_INTERCEPTOR_READ_STRING(ctx, str, 1); 656 } 657 COMMON_INTERCEPTOR_READ_RANGE(ctx, delimiters, 1); 658 char *result = REAL(strtok)(str, delimiters); 659 if (result != nullptr) { 660 COMMON_INTERCEPTOR_READ_RANGE(ctx, result, REAL(strlen)(result) + 1); 661 } else if (str != nullptr) { 662 // No delimiter were found, it's safe to assume that the entire str was 663 // scanned. 664 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 665 } 666 return result; 667 } 668} 669 670#define INIT_STRTOK COMMON_INTERCEPT_FUNCTION(strtok) 671#else 672#define INIT_STRTOK 673#endif 674 675#if SANITIZER_INTERCEPT_MEMMEM 676DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, uptr called_pc, 677 const void *s1, SIZE_T len1, const void *s2, 678 SIZE_T len2, void *result) 679 680INTERCEPTOR(void*, memmem, const void *s1, SIZE_T len1, const void *s2, 681 SIZE_T len2) { 682 void *ctx; 683 COMMON_INTERCEPTOR_ENTER(ctx, memmem, s1, len1, s2, len2); 684 void *r = REAL(memmem)(s1, len1, s2, len2); 685 if (common_flags()->intercept_memmem) { 686 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, len1); 687 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, len2); 688 } 689 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memmem, GET_CALLER_PC(), 690 s1, len1, s2, len2, r); 691 return r; 692} 693 694#define INIT_MEMMEM COMMON_INTERCEPT_FUNCTION(memmem); 695#else 696#define INIT_MEMMEM 697#endif // SANITIZER_INTERCEPT_MEMMEM 698 699#if SANITIZER_INTERCEPT_STRCHR 700INTERCEPTOR(char*, strchr, const char *s, int c) { 701 void *ctx; 702 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 703 return internal_strchr(s, c); 704 COMMON_INTERCEPTOR_ENTER(ctx, strchr, s, c); 705 char *result = REAL(strchr)(s, c); 706 if (common_flags()->intercept_strchr) { 707 // Keep strlen as macro argument, as macro may ignore it. 708 COMMON_INTERCEPTOR_READ_STRING(ctx, s, 709 (result ? result - s : REAL(strlen)(s)) + 1); 710 } 711 return result; 712} 713#define INIT_STRCHR COMMON_INTERCEPT_FUNCTION(strchr) 714#else 715#define INIT_STRCHR 716#endif 717 718#if SANITIZER_INTERCEPT_STRCHRNUL 719INTERCEPTOR(char*, strchrnul, const char *s, int c) { 720 void *ctx; 721 COMMON_INTERCEPTOR_ENTER(ctx, strchrnul, s, c); 722 char *result = REAL(strchrnul)(s, c); 723 uptr len = result - s + 1; 724 if (common_flags()->intercept_strchr) 725 COMMON_INTERCEPTOR_READ_STRING(ctx, s, len); 726 return result; 727} 728#define INIT_STRCHRNUL COMMON_INTERCEPT_FUNCTION(strchrnul) 729#else 730#define INIT_STRCHRNUL 731#endif 732 733#if SANITIZER_INTERCEPT_STRRCHR 734INTERCEPTOR(char*, strrchr, const char *s, int c) { 735 void *ctx; 736 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 737 return internal_strrchr(s, c); 738 COMMON_INTERCEPTOR_ENTER(ctx, strrchr, s, c); 739 if (common_flags()->intercept_strchr) 740 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 741 return REAL(strrchr)(s, c); 742} 743#define INIT_STRRCHR COMMON_INTERCEPT_FUNCTION(strrchr) 744#else 745#define INIT_STRRCHR 746#endif 747 748#if SANITIZER_INTERCEPT_STRSPN 749INTERCEPTOR(SIZE_T, strspn, const char *s1, const char *s2) { 750 void *ctx; 751 COMMON_INTERCEPTOR_ENTER(ctx, strspn, s1, s2); 752 SIZE_T r = REAL(strspn)(s1, s2); 753 if (common_flags()->intercept_strspn) { 754 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 755 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 756 } 757 return r; 758} 759 760INTERCEPTOR(SIZE_T, strcspn, const char *s1, const char *s2) { 761 void *ctx; 762 COMMON_INTERCEPTOR_ENTER(ctx, strcspn, s1, s2); 763 SIZE_T r = REAL(strcspn)(s1, s2); 764 if (common_flags()->intercept_strspn) { 765 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 766 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, r + 1); 767 } 768 return r; 769} 770 771#define INIT_STRSPN \ 772 COMMON_INTERCEPT_FUNCTION(strspn); \ 773 COMMON_INTERCEPT_FUNCTION(strcspn); 774#else 775#define INIT_STRSPN 776#endif 777 778#if SANITIZER_INTERCEPT_STRPBRK 779INTERCEPTOR(char *, strpbrk, const char *s1, const char *s2) { 780 void *ctx; 781 COMMON_INTERCEPTOR_ENTER(ctx, strpbrk, s1, s2); 782 char *r = REAL(strpbrk)(s1, s2); 783 if (common_flags()->intercept_strpbrk) { 784 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, REAL(strlen)(s2) + 1); 785 COMMON_INTERCEPTOR_READ_STRING(ctx, s1, 786 r ? r - s1 + 1 : REAL(strlen)(s1) + 1); 787 } 788 return r; 789} 790 791#define INIT_STRPBRK COMMON_INTERCEPT_FUNCTION(strpbrk); 792#else 793#define INIT_STRPBRK 794#endif 795 796#if SANITIZER_INTERCEPT_MEMSET 797INTERCEPTOR(void *, memset, void *dst, int v, uptr size) { 798 void *ctx; 799 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, dst, v, size); 800} 801 802#define INIT_MEMSET COMMON_INTERCEPT_FUNCTION(memset) 803#else 804#define INIT_MEMSET 805#endif 806 807#if SANITIZER_INTERCEPT_MEMMOVE 808INTERCEPTOR(void *, memmove, void *dst, const void *src, uptr size) { 809 void *ctx; 810 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 811} 812 813#define INIT_MEMMOVE COMMON_INTERCEPT_FUNCTION(memmove) 814#else 815#define INIT_MEMMOVE 816#endif 817 818#if SANITIZER_INTERCEPT_MEMCPY 819INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { 820 // On OS X, calling internal_memcpy here will cause memory corruptions, 821 // because memcpy and memmove are actually aliases of the same 822 // implementation. We need to use internal_memmove here. 823 // N.B.: If we switch this to internal_ we'll have to use internal_memmove 824 // due to memcpy being an alias of memmove on OS X. 825 void *ctx; 826 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { 827 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, dst, src, size); 828 } else { 829 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, dst, src, size); 830 } 831} 832 833#define INIT_MEMCPY \ 834 do { \ 835 if (PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE) { \ 836 COMMON_INTERCEPT_FUNCTION(memcpy); \ 837 } else { \ 838 ASSIGN_REAL(memcpy, memmove); \ 839 } \ 840 CHECK(REAL(memcpy)); \ 841 } while (false) 842 843#else 844#define INIT_MEMCPY 845#endif 846 847#if SANITIZER_INTERCEPT_MEMCMP 848DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, 849 const void *s1, const void *s2, uptr n, 850 int result) 851 852// Common code for `memcmp` and `bcmp`. 853int MemcmpInterceptorCommon(void *ctx, 854 int (*real_fn)(const void *, const void *, uptr), 855 const void *a1, const void *a2, uptr size) { 856 if (common_flags()->intercept_memcmp) { 857 if (common_flags()->strict_memcmp) { 858 // Check the entire regions even if the first bytes of the buffers are 859 // different. 860 COMMON_INTERCEPTOR_READ_RANGE(ctx, a1, size); 861 COMMON_INTERCEPTOR_READ_RANGE(ctx, a2, size); 862 // Fallthrough to REAL(memcmp) below. 863 } else { 864 unsigned char c1 = 0, c2 = 0; 865 const unsigned char *s1 = (const unsigned char*)a1; 866 const unsigned char *s2 = (const unsigned char*)a2; 867 uptr i; 868 for (i = 0; i < size; i++) { 869 c1 = s1[i]; 870 c2 = s2[i]; 871 if (c1 != c2) break; 872 } 873 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 874 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 875 int r = CharCmpX(c1, c2); 876 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), 877 a1, a2, size, r); 878 return r; 879 } 880 } 881 int result = real_fn(a1, a2, size); 882 CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, 883 a2, size, result); 884 return result; 885} 886 887INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { 888 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 889 return internal_memcmp(a1, a2, size); 890 void *ctx; 891 COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); 892 return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size); 893} 894 895#define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp) 896#else 897#define INIT_MEMCMP 898#endif 899 900#if SANITIZER_INTERCEPT_BCMP 901INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) { 902 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 903 return internal_memcmp(a1, a2, size); 904 void *ctx; 905 COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size); 906 return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size); 907} 908 909#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp) 910#else 911#define INIT_BCMP 912#endif 913 914#if SANITIZER_INTERCEPT_MEMCHR 915INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) { 916 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 917 return internal_memchr(s, c, n); 918 void *ctx; 919 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n); 920#if SANITIZER_WINDOWS 921 void *res; 922 if (REAL(memchr)) { 923 res = REAL(memchr)(s, c, n); 924 } else { 925 res = internal_memchr(s, c, n); 926 } 927#else 928 void *res = REAL(memchr)(s, c, n); 929#endif 930 uptr len = res ? (char *)res - (const char *)s + 1 : n; 931 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len); 932 return res; 933} 934 935#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr) 936#else 937#define INIT_MEMCHR 938#endif 939 940#if SANITIZER_INTERCEPT_MEMRCHR 941INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) { 942 void *ctx; 943 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n); 944 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n); 945 return REAL(memrchr)(s, c, n); 946} 947 948#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr) 949#else 950#define INIT_MEMRCHR 951#endif 952 953#if SANITIZER_INTERCEPT_FREXP 954INTERCEPTOR(double, frexp, double x, int *exp) { 955 void *ctx; 956 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 957 // Assuming frexp() always writes to |exp|. 958 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 959 double res = REAL(frexp)(x, exp); 960 return res; 961} 962 963#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp); 964#else 965#define INIT_FREXP 966#endif // SANITIZER_INTERCEPT_FREXP 967 968#if SANITIZER_INTERCEPT_FREXPF_FREXPL 969INTERCEPTOR(float, frexpf, float x, int *exp) { 970 void *ctx; 971 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 972 // FIXME: under ASan the call below may write to freed memory and corrupt 973 // its metadata. See 974 // https://github.com/google/sanitizers/issues/321. 975 float res = REAL(frexpf)(x, exp); 976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 977 return res; 978} 979 980INTERCEPTOR(long double, frexpl, long double x, int *exp) { 981 void *ctx; 982 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 983 // FIXME: under ASan the call below may write to freed memory and corrupt 984 // its metadata. See 985 // https://github.com/google/sanitizers/issues/321. 986 long double res = REAL(frexpl)(x, exp); 987 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 988 return res; 989} 990 991#define INIT_FREXPF_FREXPL \ 992 COMMON_INTERCEPT_FUNCTION(frexpf); \ 993 COMMON_INTERCEPT_FUNCTION_LDBL(frexpl) 994#else 995#define INIT_FREXPF_FREXPL 996#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 997 998#if SI_POSIX 999static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 1000 SIZE_T iovlen, SIZE_T maxlen) { 1001 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 1002 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 1003 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 1004 maxlen -= sz; 1005 } 1006} 1007 1008static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 1009 SIZE_T iovlen, SIZE_T maxlen) { 1010 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 1011 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 1012 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 1013 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 1014 maxlen -= sz; 1015 } 1016} 1017#endif 1018 1019#if SANITIZER_INTERCEPT_READ 1020INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 1021 void *ctx; 1022 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 1023 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1024 // FIXME: under ASan the call below may write to freed memory and corrupt 1025 // its metadata. See 1026 // https://github.com/google/sanitizers/issues/321. 1027 SSIZE_T res = REAL(read)(fd, ptr, count); 1028 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1029 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1030 return res; 1031} 1032#define INIT_READ COMMON_INTERCEPT_FUNCTION(read) 1033#else 1034#define INIT_READ 1035#endif 1036 1037#if SANITIZER_INTERCEPT_FREAD 1038INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) { 1039 // libc file streams can call user-supplied functions, see fopencookie. 1040 void *ctx; 1041 COMMON_INTERCEPTOR_ENTER(ctx, fread, ptr, size, nmemb, file); 1042 // FIXME: under ASan the call below may write to freed memory and corrupt 1043 // its metadata. See 1044 // https://github.com/google/sanitizers/issues/321. 1045 SIZE_T res = REAL(fread)(ptr, size, nmemb, file); 1046 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res * size); 1047 return res; 1048} 1049#define INIT_FREAD COMMON_INTERCEPT_FUNCTION(fread) 1050#else 1051#define INIT_FREAD 1052#endif 1053 1054#if SANITIZER_INTERCEPT_PREAD 1055INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1056 void *ctx; 1057 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 1058 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1059 // FIXME: under ASan the call below may write to freed memory and corrupt 1060 // its metadata. See 1061 // https://github.com/google/sanitizers/issues/321. 1062 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 1063 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1064 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1065 return res; 1066} 1067#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread) 1068#else 1069#define INIT_PREAD 1070#endif 1071 1072#if SANITIZER_INTERCEPT_PREAD64 1073INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 1074 void *ctx; 1075 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 1076 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1077 // FIXME: under ASan the call below may write to freed memory and corrupt 1078 // its metadata. See 1079 // https://github.com/google/sanitizers/issues/321. 1080 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 1081 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 1082 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1083 return res; 1084} 1085#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64) 1086#else 1087#define INIT_PREAD64 1088#endif 1089 1090#if SANITIZER_INTERCEPT_READV 1091INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 1092 int iovcnt) { 1093 void *ctx; 1094 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 1095 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1096 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 1097 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1098 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1099 return res; 1100} 1101#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv) 1102#else 1103#define INIT_READV 1104#endif 1105 1106#if SANITIZER_INTERCEPT_PREADV 1107INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 1108 OFF_T offset) { 1109 void *ctx; 1110 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 1111 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1112 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 1113 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1114 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1115 return res; 1116} 1117#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv) 1118#else 1119#define INIT_PREADV 1120#endif 1121 1122#if SANITIZER_INTERCEPT_PREADV64 1123INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 1124 OFF64_T offset) { 1125 void *ctx; 1126 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 1127 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1128 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 1129 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 1130 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1131 return res; 1132} 1133#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64) 1134#else 1135#define INIT_PREADV64 1136#endif 1137 1138#if SANITIZER_INTERCEPT_WRITE 1139INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 1140 void *ctx; 1141 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 1142 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1143 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1144 SSIZE_T res = REAL(write)(fd, ptr, count); 1145 // FIXME: this check should be _before_ the call to REAL(write), not after 1146 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1147 return res; 1148} 1149#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write) 1150#else 1151#define INIT_WRITE 1152#endif 1153 1154#if SANITIZER_INTERCEPT_FWRITE 1155INTERCEPTOR(SIZE_T, fwrite, const void *p, uptr size, uptr nmemb, void *file) { 1156 // libc file streams can call user-supplied functions, see fopencookie. 1157 void *ctx; 1158 COMMON_INTERCEPTOR_ENTER(ctx, fwrite, p, size, nmemb, file); 1159 SIZE_T res = REAL(fwrite)(p, size, nmemb, file); 1160 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, p, res * size); 1161 return res; 1162} 1163#define INIT_FWRITE COMMON_INTERCEPT_FUNCTION(fwrite) 1164#else 1165#define INIT_FWRITE 1166#endif 1167 1168#if SANITIZER_INTERCEPT_PWRITE 1169INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 1170 void *ctx; 1171 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 1172 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1173 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1174 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 1175 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1176 return res; 1177} 1178#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite) 1179#else 1180#define INIT_PWRITE 1181#endif 1182 1183#if SANITIZER_INTERCEPT_PWRITE64 1184INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 1185 OFF64_T offset) { 1186 void *ctx; 1187 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 1188 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1189 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1190 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 1191 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 1192 return res; 1193} 1194#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64) 1195#else 1196#define INIT_PWRITE64 1197#endif 1198 1199#if SANITIZER_INTERCEPT_WRITEV 1200INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 1201 int iovcnt) { 1202 void *ctx; 1203 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 1204 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1205 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1206 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 1207 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1208 return res; 1209} 1210#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev) 1211#else 1212#define INIT_WRITEV 1213#endif 1214 1215#if SANITIZER_INTERCEPT_PWRITEV 1216INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 1217 OFF_T offset) { 1218 void *ctx; 1219 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 1220 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1221 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1222 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 1223 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1224 return res; 1225} 1226#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev) 1227#else 1228#define INIT_PWRITEV 1229#endif 1230 1231#if SANITIZER_INTERCEPT_PWRITEV64 1232INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 1233 OFF64_T offset) { 1234 void *ctx; 1235 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 1236 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 1237 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 1238 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 1239 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 1240 return res; 1241} 1242#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64) 1243#else 1244#define INIT_PWRITEV64 1245#endif 1246 1247#if SANITIZER_INTERCEPT_FGETS 1248INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) { 1249 // libc file streams can call user-supplied functions, see fopencookie. 1250 void *ctx; 1251 COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file); 1252 // FIXME: under ASan the call below may write to freed memory and corrupt 1253 // its metadata. See 1254 // https://github.com/google/sanitizers/issues/321. 1255 char *res = REAL(fgets)(s, size, file); 1256 if (res) 1257 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 1258 return res; 1259} 1260#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets) 1261#else 1262#define INIT_FGETS 1263#endif 1264 1265#if SANITIZER_INTERCEPT_FPUTS 1266INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { 1267 // libc file streams can call user-supplied functions, see fopencookie. 1268 void *ctx; 1269 COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); 1270 if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin. 1271 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1272 } 1273 return REAL(fputs)(s, file); 1274} 1275#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) 1276#else 1277#define INIT_FPUTS 1278#endif 1279 1280#if SANITIZER_INTERCEPT_PUTS 1281INTERCEPTOR(int, puts, char *s) { 1282 // libc file streams can call user-supplied functions, see fopencookie. 1283 void *ctx; 1284 COMMON_INTERCEPTOR_ENTER(ctx, puts, s); 1285 if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin. 1286 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 1287 } 1288 return REAL(puts)(s); 1289} 1290#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) 1291#else 1292#define INIT_PUTS 1293#endif 1294 1295#if SANITIZER_INTERCEPT_PRCTL 1296INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, 1297 unsigned long arg4, unsigned long arg5) { 1298 void *ctx; 1299 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 1300 static const int PR_SET_NAME = 15; 1301 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 1302 if (option == PR_SET_NAME) { 1303 char buff[16]; 1304 internal_strncpy(buff, (char *)arg2, 15); 1305 buff[15] = 0; 1306 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 1307 } 1308 return res; 1309} 1310#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) 1311#else 1312#define INIT_PRCTL 1313#endif // SANITIZER_INTERCEPT_PRCTL 1314 1315#if SANITIZER_INTERCEPT_TIME 1316INTERCEPTOR(unsigned long, time, unsigned long *t) { 1317 void *ctx; 1318 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 1319 unsigned long local_t; 1320 unsigned long res = REAL(time)(&local_t); 1321 if (t && res != (unsigned long)-1) { 1322 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 1323 *t = local_t; 1324 } 1325 return res; 1326} 1327#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time); 1328#else 1329#define INIT_TIME 1330#endif // SANITIZER_INTERCEPT_TIME 1331 1332#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1333static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 1334 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1335#if !SANITIZER_SOLARIS 1336 if (tm->tm_zone) { 1337 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 1338 // can point to shared memory and tsan would report a data race. 1339 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, 1340 REAL(strlen(tm->tm_zone)) + 1); 1341 } 1342#endif 1343} 1344INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 1345 void *ctx; 1346 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 1347 __sanitizer_tm *res = REAL(localtime)(timep); 1348 if (res) { 1349 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1350 unpoison_tm(ctx, res); 1351 } 1352 return res; 1353} 1354INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 1355 void *ctx; 1356 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 1357 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 1358 if (res) { 1359 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1360 unpoison_tm(ctx, res); 1361 } 1362 return res; 1363} 1364INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 1365 void *ctx; 1366 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 1367 __sanitizer_tm *res = REAL(gmtime)(timep); 1368 if (res) { 1369 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1370 unpoison_tm(ctx, res); 1371 } 1372 return res; 1373} 1374INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 1375 void *ctx; 1376 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 1377 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 1378 if (res) { 1379 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1380 unpoison_tm(ctx, res); 1381 } 1382 return res; 1383} 1384INTERCEPTOR(char *, ctime, unsigned long *timep) { 1385 void *ctx; 1386 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 1387 // FIXME: under ASan the call below may write to freed memory and corrupt 1388 // its metadata. See 1389 // https://github.com/google/sanitizers/issues/321. 1390 char *res = REAL(ctime)(timep); 1391 if (res) { 1392 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1393 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1394 } 1395 return res; 1396} 1397INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 1398 void *ctx; 1399 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 1400 // FIXME: under ASan the call below may write to freed memory and corrupt 1401 // its metadata. See 1402 // https://github.com/google/sanitizers/issues/321. 1403 char *res = REAL(ctime_r)(timep, result); 1404 if (res) { 1405 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 1406 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1407 } 1408 return res; 1409} 1410INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 1411 void *ctx; 1412 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 1413 // FIXME: under ASan the call below may write to freed memory and corrupt 1414 // its metadata. See 1415 // https://github.com/google/sanitizers/issues/321. 1416 char *res = REAL(asctime)(tm); 1417 if (res) { 1418 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1419 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1420 } 1421 return res; 1422} 1423INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 1424 void *ctx; 1425 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 1426 // FIXME: under ASan the call below may write to freed memory and corrupt 1427 // its metadata. See 1428 // https://github.com/google/sanitizers/issues/321. 1429 char *res = REAL(asctime_r)(tm, result); 1430 if (res) { 1431 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 1432 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1433 } 1434 return res; 1435} 1436INTERCEPTOR(long, mktime, __sanitizer_tm *tm) { 1437 void *ctx; 1438 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm); 1439 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec)); 1440 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min)); 1441 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour)); 1442 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday)); 1443 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon)); 1444 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year)); 1445 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst)); 1446 long res = REAL(mktime)(tm); 1447 if (res != -1) unpoison_tm(ctx, tm); 1448 return res; 1449} 1450#define INIT_LOCALTIME_AND_FRIENDS \ 1451 COMMON_INTERCEPT_FUNCTION(localtime); \ 1452 COMMON_INTERCEPT_FUNCTION(localtime_r); \ 1453 COMMON_INTERCEPT_FUNCTION(gmtime); \ 1454 COMMON_INTERCEPT_FUNCTION(gmtime_r); \ 1455 COMMON_INTERCEPT_FUNCTION(ctime); \ 1456 COMMON_INTERCEPT_FUNCTION(ctime_r); \ 1457 COMMON_INTERCEPT_FUNCTION(asctime); \ 1458 COMMON_INTERCEPT_FUNCTION(asctime_r); \ 1459 COMMON_INTERCEPT_FUNCTION(mktime); 1460#else 1461#define INIT_LOCALTIME_AND_FRIENDS 1462#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 1463 1464#if SANITIZER_INTERCEPT_STRPTIME 1465INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { 1466 void *ctx; 1467 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); 1468 if (format) 1469 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); 1470 // FIXME: under ASan the call below may write to freed memory and corrupt 1471 // its metadata. See 1472 // https://github.com/google/sanitizers/issues/321. 1473 char *res = REAL(strptime)(s, format, tm); 1474 COMMON_INTERCEPTOR_READ_STRING(ctx, s, res ? res - s : 0); 1475 if (res && tm) { 1476 // Do not call unpoison_tm here, because strptime does not, in fact, 1477 // initialize the entire struct tm. For example, tm_zone pointer is left 1478 // uninitialized. 1479 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 1480 } 1481 return res; 1482} 1483#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime); 1484#else 1485#define INIT_STRPTIME 1486#endif 1487 1488#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF 1489#include "sanitizer_common_interceptors_format.inc" 1490 1491#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \ 1492 { \ 1493 void *ctx; \ 1494 va_list ap; \ 1495 va_start(ap, format); \ 1496 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 1497 int res = WRAP(vname)(__VA_ARGS__, ap); \ 1498 va_end(ap); \ 1499 return res; \ 1500 } 1501 1502#endif 1503 1504#if SANITIZER_INTERCEPT_SCANF 1505 1506#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 1507 { \ 1508 void *ctx; \ 1509 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1510 va_list aq; \ 1511 va_copy(aq, ap); \ 1512 int res = REAL(vname)(__VA_ARGS__); \ 1513 if (res > 0) \ 1514 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 1515 va_end(aq); \ 1516 return res; \ 1517 } 1518 1519INTERCEPTOR(int, vscanf, const char *format, va_list ap) 1520VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 1521 1522INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 1523VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 1524 1525INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 1526VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 1527 1528#if SANITIZER_INTERCEPT_ISOC99_SCANF 1529INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 1530VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 1531 1532INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 1533 va_list ap) 1534VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 1535 1536INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 1537VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 1538#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 1539 1540INTERCEPTOR(int, scanf, const char *format, ...) 1541FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format) 1542 1543INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 1544FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 1545 1546INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 1547FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 1548 1549#if SANITIZER_INTERCEPT_ISOC99_SCANF 1550INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 1551FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 1552 1553INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 1554FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 1555 1556INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 1557FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 1558#endif 1559 1560#endif 1561 1562#if SANITIZER_INTERCEPT_SCANF 1563#define INIT_SCANF \ 1564 COMMON_INTERCEPT_FUNCTION_LDBL(scanf); \ 1565 COMMON_INTERCEPT_FUNCTION_LDBL(sscanf); \ 1566 COMMON_INTERCEPT_FUNCTION_LDBL(fscanf); \ 1567 COMMON_INTERCEPT_FUNCTION_LDBL(vscanf); \ 1568 COMMON_INTERCEPT_FUNCTION_LDBL(vsscanf); \ 1569 COMMON_INTERCEPT_FUNCTION_LDBL(vfscanf); 1570#else 1571#define INIT_SCANF 1572#endif 1573 1574#if SANITIZER_INTERCEPT_ISOC99_SCANF 1575#define INIT_ISOC99_SCANF \ 1576 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \ 1577 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \ 1578 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ 1579 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ 1580 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 1581 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); 1582#else 1583#define INIT_ISOC99_SCANF 1584#endif 1585 1586#if SANITIZER_INTERCEPT_PRINTF 1587 1588#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \ 1589 void *ctx; \ 1590 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 1591 va_list aq; \ 1592 va_copy(aq, ap); 1593 1594#define VPRINTF_INTERCEPTOR_RETURN() \ 1595 va_end(aq); 1596 1597#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \ 1598 { \ 1599 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \ 1600 if (common_flags()->check_printf) \ 1601 printf_common(ctx, format, aq); \ 1602 int res = REAL(vname)(__VA_ARGS__); \ 1603 VPRINTF_INTERCEPTOR_RETURN(); \ 1604 return res; \ 1605 } 1606 1607// FIXME: under ASan the REAL() call below may write to freed memory and 1608// corrupt its metadata. See 1609// https://github.com/google/sanitizers/issues/321. 1610#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \ 1611 { \ 1612 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \ 1613 if (common_flags()->check_printf) { \ 1614 printf_common(ctx, format, aq); \ 1615 } \ 1616 int res = REAL(vname)(str, __VA_ARGS__); \ 1617 if (res >= 0) { \ 1618 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \ 1619 } \ 1620 VPRINTF_INTERCEPTOR_RETURN(); \ 1621 return res; \ 1622 } 1623 1624// FIXME: under ASan the REAL() call below may write to freed memory and 1625// corrupt its metadata. See 1626// https://github.com/google/sanitizers/issues/321. 1627#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \ 1628 { \ 1629 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \ 1630 if (common_flags()->check_printf) { \ 1631 printf_common(ctx, format, aq); \ 1632 } \ 1633 int res = REAL(vname)(str, size, __VA_ARGS__); \ 1634 if (res >= 0) { \ 1635 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \ 1636 } \ 1637 VPRINTF_INTERCEPTOR_RETURN(); \ 1638 return res; \ 1639 } 1640 1641// FIXME: under ASan the REAL() call below may write to freed memory and 1642// corrupt its metadata. See 1643// https://github.com/google/sanitizers/issues/321. 1644#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \ 1645 { \ 1646 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \ 1647 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \ 1648 if (common_flags()->check_printf) { \ 1649 printf_common(ctx, format, aq); \ 1650 } \ 1651 int res = REAL(vname)(strp, __VA_ARGS__); \ 1652 if (res >= 0) { \ 1653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \ 1654 } \ 1655 VPRINTF_INTERCEPTOR_RETURN(); \ 1656 return res; \ 1657 } 1658 1659INTERCEPTOR(int, vprintf, const char *format, va_list ap) 1660VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap) 1661 1662INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format, 1663 va_list ap) 1664VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap) 1665 1666INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format, 1667 va_list ap) 1668VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1669 1670#if SANITIZER_INTERCEPT___PRINTF_CHK 1671INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag, 1672 SIZE_T size_to, const char *format, va_list ap) 1673VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 1674#endif 1675 1676#if SANITIZER_INTERCEPT_PRINTF_L 1677INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc, 1678 const char *format, va_list ap) 1679VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf_l, str, size, loc, format, ap) 1680 1681INTERCEPTOR(int, snprintf_l, char *str, SIZE_T size, void *loc, 1682 const char *format, ...) 1683FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format) 1684#endif // SANITIZER_INTERCEPT_PRINTF_L 1685 1686INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) 1687VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1688 1689#if SANITIZER_INTERCEPT___PRINTF_CHK 1690INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to, 1691 const char *format, va_list ap) 1692VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 1693#endif 1694 1695INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) 1696VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) 1697 1698#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1699INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap) 1700VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap) 1701 1702INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream, 1703 const char *format, va_list ap) 1704VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap) 1705 1706INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format, 1707 va_list ap) 1708VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap) 1709 1710INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format, 1711 va_list ap) 1712VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format, 1713 ap) 1714 1715#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1716 1717INTERCEPTOR(int, printf, const char *format, ...) 1718FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format) 1719 1720INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...) 1721FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format) 1722 1723#if SANITIZER_INTERCEPT___PRINTF_CHK 1724INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, 1725 const char *format, ...) 1726FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) 1727#endif 1728 1729INTERCEPTOR(int, sprintf, char *str, const char *format, ...) 1730FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) 1731 1732#if SANITIZER_INTERCEPT___PRINTF_CHK 1733INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, 1734 const char *format, ...) 1735FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) 1736#endif 1737 1738INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) 1739FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) 1740 1741#if SANITIZER_INTERCEPT___PRINTF_CHK 1742INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, 1743 SIZE_T size_to, const char *format, ...) 1744FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) 1745#endif 1746 1747INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) 1748FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) 1749 1750#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1751INTERCEPTOR(int, __isoc99_printf, const char *format, ...) 1752FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format) 1753 1754INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format, 1755 ...) 1756FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format) 1757 1758INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...) 1759FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format) 1760 1761INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size, 1762 const char *format, ...) 1763FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, 1764 format) 1765 1766#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 1767 1768#endif // SANITIZER_INTERCEPT_PRINTF 1769 1770#if SANITIZER_INTERCEPT_PRINTF 1771#define INIT_PRINTF \ 1772 COMMON_INTERCEPT_FUNCTION_LDBL(printf); \ 1773 COMMON_INTERCEPT_FUNCTION_LDBL(sprintf); \ 1774 COMMON_INTERCEPT_FUNCTION_LDBL(snprintf); \ 1775 COMMON_INTERCEPT_FUNCTION_LDBL(asprintf); \ 1776 COMMON_INTERCEPT_FUNCTION_LDBL(fprintf); \ 1777 COMMON_INTERCEPT_FUNCTION_LDBL(vprintf); \ 1778 COMMON_INTERCEPT_FUNCTION_LDBL(vsprintf); \ 1779 COMMON_INTERCEPT_FUNCTION_LDBL(vsnprintf); \ 1780 COMMON_INTERCEPT_FUNCTION_LDBL(vasprintf); \ 1781 COMMON_INTERCEPT_FUNCTION_LDBL(vfprintf); 1782#else 1783#define INIT_PRINTF 1784#endif 1785 1786#if SANITIZER_INTERCEPT___PRINTF_CHK 1787#define INIT___PRINTF_CHK \ 1788 COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \ 1789 COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \ 1790 COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \ 1791 COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \ 1792 COMMON_INTERCEPT_FUNCTION(__fprintf_chk); 1793#else 1794#define INIT___PRINTF_CHK 1795#endif 1796 1797#if SANITIZER_INTERCEPT_PRINTF_L 1798#define INIT_PRINTF_L \ 1799 COMMON_INTERCEPT_FUNCTION(snprintf_l); \ 1800 COMMON_INTERCEPT_FUNCTION(vsnprintf_l); 1801#else 1802#define INIT_PRINTF_L 1803#endif 1804 1805#if SANITIZER_INTERCEPT_ISOC99_PRINTF 1806#define INIT_ISOC99_PRINTF \ 1807 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \ 1808 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \ 1809 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \ 1810 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \ 1811 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \ 1812 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \ 1813 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \ 1814 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf); 1815#else 1816#define INIT_ISOC99_PRINTF 1817#endif 1818 1819#if SANITIZER_INTERCEPT_IOCTL 1820#include "sanitizer_common_interceptors_ioctl.inc" 1821#include "sanitizer_interceptors_ioctl_netbsd.inc" 1822INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { 1823 // We need a frame pointer, because we call into ioctl_common_[pre|post] which 1824 // can trigger a report and we need to be able to unwind through this 1825 // function. On Mac in debug mode we might not have a frame pointer, because 1826 // ioctl_common_[pre|post] doesn't get inlined here. 1827 ENABLE_FRAME_POINTER; 1828 1829 void *ctx; 1830 va_list ap; 1831 va_start(ap, request); 1832 void *arg = va_arg(ap, void *); 1833 va_end(ap); 1834 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 1835 1836 CHECK(ioctl_initialized); 1837 1838 // Note: TSan does not use common flags, and they are zero-initialized. 1839 // This effectively disables ioctl handling in TSan. 1840 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg); 1841 1842 // Although request is unsigned long, the rest of the interceptor uses it 1843 // as just "unsigned" to save space, because we know that all values fit in 1844 // "unsigned" - they are compile-time constants. 1845 1846 const ioctl_desc *desc = ioctl_lookup(request); 1847 ioctl_desc decoded_desc; 1848 if (!desc) { 1849 VPrintf(2, "Decoding unknown ioctl 0x%x\n", request); 1850 if (!ioctl_decode(request, &decoded_desc)) 1851 Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request); 1852 else 1853 desc = &decoded_desc; 1854 } 1855 1856 if (desc) ioctl_common_pre(ctx, desc, d, request, arg); 1857 int res = REAL(ioctl)(d, request, arg); 1858 // FIXME: some ioctls have different return values for success and failure. 1859 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg); 1860 return res; 1861} 1862#define INIT_IOCTL \ 1863 ioctl_init(); \ 1864 COMMON_INTERCEPT_FUNCTION(ioctl); 1865#else 1866#define INIT_IOCTL 1867#endif 1868 1869#if SANITIZER_POSIX 1870UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { 1871 if (pwd) { 1872 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); 1873 if (pwd->pw_name) 1874 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name, 1875 REAL(strlen)(pwd->pw_name) + 1); 1876 if (pwd->pw_passwd) 1877 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd, 1878 REAL(strlen)(pwd->pw_passwd) + 1); 1879#if !SANITIZER_ANDROID 1880 if (pwd->pw_gecos) 1881 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos, 1882 REAL(strlen)(pwd->pw_gecos) + 1); 1883#endif 1884#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD 1885 if (pwd->pw_class) 1886 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class, 1887 REAL(strlen)(pwd->pw_class) + 1); 1888#endif 1889 if (pwd->pw_dir) 1890 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir, 1891 REAL(strlen)(pwd->pw_dir) + 1); 1892 if (pwd->pw_shell) 1893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell, 1894 REAL(strlen)(pwd->pw_shell) + 1); 1895 } 1896} 1897 1898UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) { 1899 if (grp) { 1900 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); 1901 if (grp->gr_name) 1902 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name, 1903 REAL(strlen)(grp->gr_name) + 1); 1904 if (grp->gr_passwd) 1905 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd, 1906 REAL(strlen)(grp->gr_passwd) + 1); 1907 char **p = grp->gr_mem; 1908 for (; *p; ++p) { 1909 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1910 } 1911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem, 1912 (p - grp->gr_mem + 1) * sizeof(*p)); 1913 } 1914} 1915#endif // SANITIZER_POSIX 1916 1917#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 1918INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { 1919 void *ctx; 1920 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 1921 if (name) 1922 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1923 __sanitizer_passwd *res = REAL(getpwnam)(name); 1924 unpoison_passwd(ctx, res); 1925 return res; 1926} 1927INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { 1928 void *ctx; 1929 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 1930 __sanitizer_passwd *res = REAL(getpwuid)(uid); 1931 unpoison_passwd(ctx, res); 1932 return res; 1933} 1934INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { 1935 void *ctx; 1936 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 1937 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1938 __sanitizer_group *res = REAL(getgrnam)(name); 1939 unpoison_group(ctx, res); 1940 return res; 1941} 1942INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) { 1943 void *ctx; 1944 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 1945 __sanitizer_group *res = REAL(getgrgid)(gid); 1946 unpoison_group(ctx, res); 1947 return res; 1948} 1949#define INIT_GETPWNAM_AND_FRIENDS \ 1950 COMMON_INTERCEPT_FUNCTION(getpwnam); \ 1951 COMMON_INTERCEPT_FUNCTION(getpwuid); \ 1952 COMMON_INTERCEPT_FUNCTION(getgrnam); \ 1953 COMMON_INTERCEPT_FUNCTION(getgrgid); 1954#else 1955#define INIT_GETPWNAM_AND_FRIENDS 1956#endif 1957 1958#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1959INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, 1960 char *buf, SIZE_T buflen, __sanitizer_passwd **result) { 1961 void *ctx; 1962 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 1963 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1964 // FIXME: under ASan the call below may write to freed memory and corrupt 1965 // its metadata. See 1966 // https://github.com/google/sanitizers/issues/321. 1967 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 1968 if (!res && result) 1969 unpoison_passwd(ctx, *result); 1970 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1971 return res; 1972} 1973INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf, 1974 SIZE_T buflen, __sanitizer_passwd **result) { 1975 void *ctx; 1976 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 1977 // FIXME: under ASan the call below may write to freed memory and corrupt 1978 // its metadata. See 1979 // https://github.com/google/sanitizers/issues/321. 1980 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 1981 if (!res && result) 1982 unpoison_passwd(ctx, *result); 1983 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1984 return res; 1985} 1986INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, 1987 char *buf, SIZE_T buflen, __sanitizer_group **result) { 1988 void *ctx; 1989 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 1990 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1991 // FIXME: under ASan the call below may write to freed memory and corrupt 1992 // its metadata. See 1993 // https://github.com/google/sanitizers/issues/321. 1994 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 1995 if (!res && result) 1996 unpoison_group(ctx, *result); 1997 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1998 return res; 1999} 2000INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf, 2001 SIZE_T buflen, __sanitizer_group **result) { 2002 void *ctx; 2003 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 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(getgrgid_r)(gid, grp, buf, buflen, result); 2008 if (!res && result) 2009 unpoison_group(ctx, *result); 2010 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2011 return res; 2012} 2013#define INIT_GETPWNAM_R_AND_FRIENDS \ 2014 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \ 2015 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \ 2016 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \ 2017 COMMON_INTERCEPT_FUNCTION(getgrgid_r); 2018#else 2019#define INIT_GETPWNAM_R_AND_FRIENDS 2020#endif 2021 2022#if SANITIZER_INTERCEPT_GETPWENT 2023INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) { 2024 void *ctx; 2025 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy); 2026 __sanitizer_passwd *res = REAL(getpwent)(dummy); 2027 unpoison_passwd(ctx, res); 2028 return res; 2029} 2030INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) { 2031 void *ctx; 2032 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy); 2033 __sanitizer_group *res = REAL(getgrent)(dummy); 2034 unpoison_group(ctx, res); 2035 return res; 2036} 2037#define INIT_GETPWENT \ 2038 COMMON_INTERCEPT_FUNCTION(getpwent); \ 2039 COMMON_INTERCEPT_FUNCTION(getgrent); 2040#else 2041#define INIT_GETPWENT 2042#endif 2043 2044#if SANITIZER_INTERCEPT_FGETPWENT 2045INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) { 2046 void *ctx; 2047 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp); 2048 __sanitizer_passwd *res = REAL(fgetpwent)(fp); 2049 unpoison_passwd(ctx, res); 2050 return res; 2051} 2052INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) { 2053 void *ctx; 2054 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp); 2055 __sanitizer_group *res = REAL(fgetgrent)(fp); 2056 unpoison_group(ctx, res); 2057 return res; 2058} 2059#define INIT_FGETPWENT \ 2060 COMMON_INTERCEPT_FUNCTION(fgetpwent); \ 2061 COMMON_INTERCEPT_FUNCTION(fgetgrent); 2062#else 2063#define INIT_FGETPWENT 2064#endif 2065 2066#if SANITIZER_INTERCEPT_GETPWENT_R 2067INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf, 2068 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2069 void *ctx; 2070 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp); 2071 // FIXME: under ASan the call below may write to freed memory and corrupt 2072 // its metadata. See 2073 // https://github.com/google/sanitizers/issues/321. 2074 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp); 2075 if (!res && pwbufp) 2076 unpoison_passwd(ctx, *pwbufp); 2077 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2078 return res; 2079} 2080INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, 2081 __sanitizer_group **pwbufp) { 2082 void *ctx; 2083 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); 2084 // FIXME: under ASan the call below may write to freed memory and corrupt 2085 // its metadata. See 2086 // https://github.com/google/sanitizers/issues/321. 2087 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); 2088 if (!res && pwbufp) 2089 unpoison_group(ctx, *pwbufp); 2090 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2091 return res; 2092} 2093#define INIT_GETPWENT_R \ 2094 COMMON_INTERCEPT_FUNCTION(getpwent_r); \ 2095 COMMON_INTERCEPT_FUNCTION(getgrent_r); 2096#else 2097#define INIT_GETPWENT_R 2098#endif 2099 2100#if SANITIZER_INTERCEPT_FGETPWENT_R 2101INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, 2102 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 2103 void *ctx; 2104 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); 2105 // FIXME: under ASan the call below may write to freed memory and corrupt 2106 // its metadata. See 2107 // https://github.com/google/sanitizers/issues/321. 2108 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); 2109 if (!res && pwbufp) 2110 unpoison_passwd(ctx, *pwbufp); 2111 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2112 return res; 2113} 2114#define INIT_FGETPWENT_R \ 2115 COMMON_INTERCEPT_FUNCTION(fgetpwent_r); 2116#else 2117#define INIT_FGETPWENT_R 2118#endif 2119 2120#if SANITIZER_INTERCEPT_FGETGRENT_R 2121INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, 2122 SIZE_T buflen, __sanitizer_group **pwbufp) { 2123 void *ctx; 2124 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp); 2125 // FIXME: under ASan the call below may write to freed memory and corrupt 2126 // its metadata. See 2127 // https://github.com/google/sanitizers/issues/321. 2128 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp); 2129 if (!res && pwbufp) 2130 unpoison_group(ctx, *pwbufp); 2131 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 2132 return res; 2133} 2134#define INIT_FGETGRENT_R \ 2135 COMMON_INTERCEPT_FUNCTION(fgetgrent_r); 2136#else 2137#define INIT_FGETGRENT_R 2138#endif 2139 2140#if SANITIZER_INTERCEPT_SETPWENT 2141// The only thing these interceptors do is disable any nested interceptors. 2142// These functions may open nss modules and call uninstrumented functions from 2143// them, and we don't want things like strlen() to trigger. 2144INTERCEPTOR(void, setpwent, int dummy) { 2145 void *ctx; 2146 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy); 2147 REAL(setpwent)(dummy); 2148} 2149INTERCEPTOR(void, endpwent, int dummy) { 2150 void *ctx; 2151 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy); 2152 REAL(endpwent)(dummy); 2153} 2154INTERCEPTOR(void, setgrent, int dummy) { 2155 void *ctx; 2156 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy); 2157 REAL(setgrent)(dummy); 2158} 2159INTERCEPTOR(void, endgrent, int dummy) { 2160 void *ctx; 2161 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy); 2162 REAL(endgrent)(dummy); 2163} 2164#define INIT_SETPWENT \ 2165 COMMON_INTERCEPT_FUNCTION(setpwent); \ 2166 COMMON_INTERCEPT_FUNCTION(endpwent); \ 2167 COMMON_INTERCEPT_FUNCTION(setgrent); \ 2168 COMMON_INTERCEPT_FUNCTION(endgrent); 2169#else 2170#define INIT_SETPWENT 2171#endif 2172 2173#if SANITIZER_INTERCEPT_CLOCK_GETTIME 2174INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 2175 void *ctx; 2176 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 2177 // FIXME: under ASan the call below may write to freed memory and corrupt 2178 // its metadata. See 2179 // https://github.com/google/sanitizers/issues/321. 2180 int res = REAL(clock_getres)(clk_id, tp); 2181 if (!res && tp) { 2182 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2183 } 2184 return res; 2185} 2186INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 2187 void *ctx; 2188 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 2189 // FIXME: under ASan the call below may write to freed memory and corrupt 2190 // its metadata. See 2191 // https://github.com/google/sanitizers/issues/321. 2192 int res = REAL(clock_gettime)(clk_id, tp); 2193 if (!res) { 2194 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 2195 } 2196 return res; 2197} 2198namespace __sanitizer { 2199extern "C" { 2200int real_clock_gettime(u32 clk_id, void *tp) { 2201 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 2202 return internal_clock_gettime(clk_id, tp); 2203 return REAL(clock_gettime)(clk_id, tp); 2204} 2205} // extern "C" 2206} // namespace __sanitizer 2207INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 2208 void *ctx; 2209 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 2210 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 2211 return REAL(clock_settime)(clk_id, tp); 2212} 2213#define INIT_CLOCK_GETTIME \ 2214 COMMON_INTERCEPT_FUNCTION(clock_getres); \ 2215 COMMON_INTERCEPT_FUNCTION(clock_gettime); \ 2216 COMMON_INTERCEPT_FUNCTION(clock_settime); 2217#else 2218#define INIT_CLOCK_GETTIME 2219#endif 2220 2221#if SANITIZER_INTERCEPT_CLOCK_GETCPUCLOCKID 2222INTERCEPTOR(int, clock_getcpuclockid, pid_t pid, 2223 __sanitizer_clockid_t *clockid) { 2224 void *ctx; 2225 COMMON_INTERCEPTOR_ENTER(ctx, clock_getcpuclockid, pid, clockid); 2226 int res = REAL(clock_getcpuclockid)(pid, clockid); 2227 if (!res && clockid) { 2228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, clockid, sizeof *clockid); 2229 } 2230 return res; 2231} 2232 2233#define INIT_CLOCK_GETCPUCLOCKID \ 2234 COMMON_INTERCEPT_FUNCTION(clock_getcpuclockid); 2235#else 2236#define INIT_CLOCK_GETCPUCLOCKID 2237#endif 2238 2239#if SANITIZER_INTERCEPT_GETITIMER 2240INTERCEPTOR(int, getitimer, int which, void *curr_value) { 2241 void *ctx; 2242 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 2243 // FIXME: under ASan the call below may write to freed memory and corrupt 2244 // its metadata. See 2245 // https://github.com/google/sanitizers/issues/321. 2246 int res = REAL(getitimer)(which, curr_value); 2247 if (!res && curr_value) { 2248 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 2249 } 2250 return res; 2251} 2252INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 2253 void *ctx; 2254 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 2255 if (new_value) { 2256 // itimerval can contain padding that may be legitimately uninitialized 2257 const struct __sanitizer_itimerval *nv = 2258 (const struct __sanitizer_itimerval *)new_value; 2259 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec, 2260 sizeof(__sanitizer_time_t)); 2261 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec, 2262 sizeof(__sanitizer_suseconds_t)); 2263 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec, 2264 sizeof(__sanitizer_time_t)); 2265 COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec, 2266 sizeof(__sanitizer_suseconds_t)); 2267 } 2268 // FIXME: under ASan the call below may write to freed memory and corrupt 2269 // its metadata. See 2270 // https://github.com/google/sanitizers/issues/321. 2271 int res = REAL(setitimer)(which, new_value, old_value); 2272 if (!res && old_value) { 2273 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 2274 } 2275 return res; 2276} 2277#define INIT_GETITIMER \ 2278 COMMON_INTERCEPT_FUNCTION(getitimer); \ 2279 COMMON_INTERCEPT_FUNCTION(setitimer); 2280#else 2281#define INIT_GETITIMER 2282#endif 2283 2284#if SANITIZER_INTERCEPT_GLOB 2285static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 2286 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 2287 // +1 for NULL pointer at the end. 2288 if (pglob->gl_pathv) 2289 COMMON_INTERCEPTOR_WRITE_RANGE( 2290 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 2291 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 2292 char *p = pglob->gl_pathv[i]; 2293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 2294 } 2295} 2296 2297#if SANITIZER_SOLARIS 2298INTERCEPTOR(int, glob, const char *pattern, int flags, 2299 int (*errfunc)(const char *epath, int eerrno), 2300 __sanitizer_glob_t *pglob) { 2301 void *ctx; 2302 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2303 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2304 int res = REAL(glob)(pattern, flags, errfunc, pglob); 2305 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2306 return res; 2307} 2308#else 2309static THREADLOCAL __sanitizer_glob_t *pglob_copy; 2310 2311static void wrapped_gl_closedir(void *dir) { 2312 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2313 pglob_copy->gl_closedir(dir); 2314} 2315 2316static void *wrapped_gl_readdir(void *dir) { 2317 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2318 return pglob_copy->gl_readdir(dir); 2319} 2320 2321static void *wrapped_gl_opendir(const char *s) { 2322 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2323 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2324 return pglob_copy->gl_opendir(s); 2325} 2326 2327static int wrapped_gl_lstat(const char *s, void *st) { 2328 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2329 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2330 return pglob_copy->gl_lstat(s, st); 2331} 2332 2333static int wrapped_gl_stat(const char *s, void *st) { 2334 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2335 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 2336 return pglob_copy->gl_stat(s, st); 2337} 2338 2339static const __sanitizer_glob_t kGlobCopy = { 2340 0, 0, 0, 2341 0, wrapped_gl_closedir, wrapped_gl_readdir, 2342 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 2343 2344INTERCEPTOR(int, glob, const char *pattern, int flags, 2345 int (*errfunc)(const char *epath, int eerrno), 2346 __sanitizer_glob_t *pglob) { 2347 void *ctx; 2348 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 2349 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2350 __sanitizer_glob_t glob_copy; 2351 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2352 if (flags & glob_altdirfunc) { 2353 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2354 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2355 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2356 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2357 Swap(pglob->gl_stat, glob_copy.gl_stat); 2358 pglob_copy = &glob_copy; 2359 } 2360 int res = REAL(glob)(pattern, flags, errfunc, pglob); 2361 if (flags & glob_altdirfunc) { 2362 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2363 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2364 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2365 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2366 Swap(pglob->gl_stat, glob_copy.gl_stat); 2367 } 2368 pglob_copy = 0; 2369 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2370 return res; 2371} 2372#endif // SANITIZER_SOLARIS 2373#define INIT_GLOB \ 2374 COMMON_INTERCEPT_FUNCTION(glob); 2375#else // SANITIZER_INTERCEPT_GLOB 2376#define INIT_GLOB 2377#endif // SANITIZER_INTERCEPT_GLOB 2378 2379#if SANITIZER_INTERCEPT_GLOB64 2380INTERCEPTOR(int, glob64, const char *pattern, int flags, 2381 int (*errfunc)(const char *epath, int eerrno), 2382 __sanitizer_glob_t *pglob) { 2383 void *ctx; 2384 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 2385 COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); 2386 __sanitizer_glob_t glob_copy; 2387 internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); 2388 if (flags & glob_altdirfunc) { 2389 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2390 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2391 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2392 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2393 Swap(pglob->gl_stat, glob_copy.gl_stat); 2394 pglob_copy = &glob_copy; 2395 } 2396 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 2397 if (flags & glob_altdirfunc) { 2398 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 2399 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 2400 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 2401 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 2402 Swap(pglob->gl_stat, glob_copy.gl_stat); 2403 } 2404 pglob_copy = 0; 2405 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 2406 return res; 2407} 2408#define INIT_GLOB64 \ 2409 COMMON_INTERCEPT_FUNCTION(glob64); 2410#else // SANITIZER_INTERCEPT_GLOB64 2411#define INIT_GLOB64 2412#endif // SANITIZER_INTERCEPT_GLOB64 2413 2414#if SANITIZER_INTERCEPT_WAIT 2415// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 2416// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 2417// details. 2418INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 2419 void *ctx; 2420 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 2421 // FIXME: under ASan the call below may write to freed memory and corrupt 2422 // its metadata. See 2423 // https://github.com/google/sanitizers/issues/321. 2424 int res = REAL(wait)(status); 2425 if (res != -1 && status) 2426 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2427 return res; 2428} 2429// On FreeBSD id_t is always 64-bit wide. 2430#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) 2431INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, long long id, void *infop, 2432 int options) { 2433#else 2434INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 2435 int options) { 2436#endif 2437 void *ctx; 2438 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 2439 // FIXME: under ASan the call below may write to freed memory and corrupt 2440 // its metadata. See 2441 // https://github.com/google/sanitizers/issues/321. 2442 int res = REAL(waitid)(idtype, id, infop, options); 2443 if (res != -1 && infop) 2444 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 2445 return res; 2446} 2447INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 2448 void *ctx; 2449 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 2450 // FIXME: under ASan the call below may write to freed memory and corrupt 2451 // its metadata. See 2452 // https://github.com/google/sanitizers/issues/321. 2453 int res = REAL(waitpid)(pid, status, options); 2454 if (res != -1 && status) 2455 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2456 return res; 2457} 2458INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 2459 void *ctx; 2460 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 2461 // FIXME: under ASan the call below may write to freed memory and corrupt 2462 // its metadata. See 2463 // https://github.com/google/sanitizers/issues/321. 2464 int res = REAL(wait3)(status, options, rusage); 2465 if (res != -1) { 2466 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2467 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2468 } 2469 return res; 2470} 2471#if SANITIZER_ANDROID 2472INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { 2473 void *ctx; 2474 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); 2475 // FIXME: under ASan the call below may write to freed memory and corrupt 2476 // its metadata. See 2477 // https://github.com/google/sanitizers/issues/321. 2478 int res = REAL(__wait4)(pid, status, options, rusage); 2479 if (res != -1) { 2480 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2481 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2482 } 2483 return res; 2484} 2485#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4); 2486#else 2487INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 2488 void *ctx; 2489 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 2490 // FIXME: under ASan the call below may write to freed memory and corrupt 2491 // its metadata. See 2492 // https://github.com/google/sanitizers/issues/321. 2493 int res = REAL(wait4)(pid, status, options, rusage); 2494 if (res != -1) { 2495 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 2496 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 2497 } 2498 return res; 2499} 2500#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4); 2501#endif // SANITIZER_ANDROID 2502#define INIT_WAIT \ 2503 COMMON_INTERCEPT_FUNCTION(wait); \ 2504 COMMON_INTERCEPT_FUNCTION(waitid); \ 2505 COMMON_INTERCEPT_FUNCTION(waitpid); \ 2506 COMMON_INTERCEPT_FUNCTION(wait3); 2507#else 2508#define INIT_WAIT 2509#define INIT_WAIT4 2510#endif 2511 2512#if SANITIZER_INTERCEPT_INET 2513INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 2514 void *ctx; 2515 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 2516 uptr sz = __sanitizer_in_addr_sz(af); 2517 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 2518 // FIXME: figure out read size based on the address family. 2519 // FIXME: under ASan the call below may write to freed memory and corrupt 2520 // its metadata. See 2521 // https://github.com/google/sanitizers/issues/321. 2522 char *res = REAL(inet_ntop)(af, src, dst, size); 2523 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2524 return res; 2525} 2526INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 2527 void *ctx; 2528 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 2529 COMMON_INTERCEPTOR_READ_STRING(ctx, src, 0); 2530 // FIXME: figure out read size based on the address family. 2531 // FIXME: under ASan the call below may write to freed memory and corrupt 2532 // its metadata. See 2533 // https://github.com/google/sanitizers/issues/321. 2534 int res = REAL(inet_pton)(af, src, dst); 2535 if (res == 1) { 2536 uptr sz = __sanitizer_in_addr_sz(af); 2537 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2538 } 2539 return res; 2540} 2541#define INIT_INET \ 2542 COMMON_INTERCEPT_FUNCTION(inet_ntop); \ 2543 COMMON_INTERCEPT_FUNCTION(inet_pton); 2544#else 2545#define INIT_INET 2546#endif 2547 2548#if SANITIZER_INTERCEPT_INET 2549INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 2550 void *ctx; 2551 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 2552 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 2553 // FIXME: under ASan the call below may write to freed memory and corrupt 2554 // its metadata. See 2555 // https://github.com/google/sanitizers/issues/321. 2556 int res = REAL(inet_aton)(cp, dst); 2557 if (res != 0) { 2558 uptr sz = __sanitizer_in_addr_sz(af_inet); 2559 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 2560 } 2561 return res; 2562} 2563#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton); 2564#else 2565#define INIT_INET_ATON 2566#endif 2567 2568#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 2569INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 2570 void *ctx; 2571 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 2572 // FIXME: under ASan the call below may write to freed memory and corrupt 2573 // its metadata. See 2574 // https://github.com/google/sanitizers/issues/321. 2575 int res = REAL(pthread_getschedparam)(thread, policy, param); 2576 if (res == 0) { 2577 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 2578 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 2579 } 2580 return res; 2581} 2582#define INIT_PTHREAD_GETSCHEDPARAM \ 2583 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam); 2584#else 2585#define INIT_PTHREAD_GETSCHEDPARAM 2586#endif 2587 2588#if SANITIZER_INTERCEPT_GETADDRINFO 2589INTERCEPTOR(int, getaddrinfo, char *node, char *service, 2590 struct __sanitizer_addrinfo *hints, 2591 struct __sanitizer_addrinfo **out) { 2592 void *ctx; 2593 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 2594 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 2595 if (service) 2596 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 2597 if (hints) 2598 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 2599 // FIXME: under ASan the call below may write to freed memory and corrupt 2600 // its metadata. See 2601 // https://github.com/google/sanitizers/issues/321. 2602 int res = REAL(getaddrinfo)(node, service, hints, out); 2603 if (res == 0 && out) { 2604 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 2605 struct __sanitizer_addrinfo *p = *out; 2606 while (p) { 2607 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2608 if (p->ai_addr) 2609 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 2610 if (p->ai_canonname) 2611 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 2612 REAL(strlen)(p->ai_canonname) + 1); 2613 p = p->ai_next; 2614 } 2615 } 2616 return res; 2617} 2618#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo); 2619#else 2620#define INIT_GETADDRINFO 2621#endif 2622 2623#if SANITIZER_INTERCEPT_GETNAMEINFO 2624INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 2625 unsigned hostlen, char *serv, unsigned servlen, int flags) { 2626 void *ctx; 2627 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 2628 serv, servlen, flags); 2629 // FIXME: consider adding READ_RANGE(sockaddr, salen) 2630 // There is padding in in_addr that may make this too noisy 2631 // FIXME: under ASan the call below may write to freed memory and corrupt 2632 // its metadata. See 2633 // https://github.com/google/sanitizers/issues/321. 2634 int res = 2635 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 2636 if (res == 0) { 2637 if (host && hostlen) 2638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 2639 if (serv && servlen) 2640 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 2641 } 2642 return res; 2643} 2644#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo); 2645#else 2646#define INIT_GETNAMEINFO 2647#endif 2648 2649#if SANITIZER_INTERCEPT_GETSOCKNAME 2650INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 2651 void *ctx; 2652 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 2653 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2654 int addrlen_in = *addrlen; 2655 // FIXME: under ASan the call below may write to freed memory and corrupt 2656 // its metadata. See 2657 // https://github.com/google/sanitizers/issues/321. 2658 int res = REAL(getsockname)(sock_fd, addr, addrlen); 2659 if (res == 0) { 2660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 2661 } 2662 return res; 2663} 2664#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname); 2665#else 2666#define INIT_GETSOCKNAME 2667#endif 2668 2669#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2670static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 2671 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 2672 if (h->h_name) 2673 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 2674 char **p = h->h_aliases; 2675 while (*p) { 2676 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 2677 ++p; 2678 } 2679 COMMON_INTERCEPTOR_WRITE_RANGE( 2680 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 2681 p = h->h_addr_list; 2682 while (*p) { 2683 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 2684 ++p; 2685 } 2686 COMMON_INTERCEPTOR_WRITE_RANGE( 2687 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 2688} 2689#endif 2690 2691#if SANITIZER_INTERCEPT_GETHOSTBYNAME 2692INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 2693 void *ctx; 2694 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 2695 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 2696 if (res) write_hostent(ctx, res); 2697 return res; 2698} 2699 2700INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 2701 int type) { 2702 void *ctx; 2703 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 2704 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2705 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 2706 if (res) write_hostent(ctx, res); 2707 return res; 2708} 2709 2710INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 2711 void *ctx; 2712 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 2713 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 2714 if (res) write_hostent(ctx, res); 2715 return res; 2716} 2717#define INIT_GETHOSTBYNAME \ 2718 COMMON_INTERCEPT_FUNCTION(gethostent); \ 2719 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ 2720 COMMON_INTERCEPT_FUNCTION(gethostbyname); 2721#else 2722#define INIT_GETHOSTBYNAME 2723#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME 2724 2725#if SANITIZER_INTERCEPT_GETHOSTBYNAME2 2726INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 2727 void *ctx; 2728 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 2729 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 2730 if (res) write_hostent(ctx, res); 2731 return res; 2732} 2733#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2); 2734#else 2735#define INIT_GETHOSTBYNAME2 2736#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME2 2737 2738#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 2739INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 2740 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 2741 int *h_errnop) { 2742 void *ctx; 2743 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 2744 h_errnop); 2745 // FIXME: under ASan the call below may write to freed memory and corrupt 2746 // its metadata. See 2747 // https://github.com/google/sanitizers/issues/321. 2748 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 2749 if (result) { 2750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2751 if (res == 0 && *result) write_hostent(ctx, *result); 2752 } 2753 if (h_errnop) 2754 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2755 return res; 2756} 2757#define INIT_GETHOSTBYNAME_R COMMON_INTERCEPT_FUNCTION(gethostbyname_r); 2758#else 2759#define INIT_GETHOSTBYNAME_R 2760#endif 2761 2762#if SANITIZER_INTERCEPT_GETHOSTENT_R 2763INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 2764 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 2765 void *ctx; 2766 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 2767 h_errnop); 2768 // FIXME: under ASan the call below may write to freed memory and corrupt 2769 // its metadata. See 2770 // https://github.com/google/sanitizers/issues/321. 2771 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 2772 if (result) { 2773 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2774 if (res == 0 && *result) write_hostent(ctx, *result); 2775 } 2776 if (h_errnop) 2777 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2778 return res; 2779} 2780#define INIT_GETHOSTENT_R \ 2781 COMMON_INTERCEPT_FUNCTION(gethostent_r); 2782#else 2783#define INIT_GETHOSTENT_R 2784#endif 2785 2786#if SANITIZER_INTERCEPT_GETHOSTBYADDR_R 2787INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 2788 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2789 __sanitizer_hostent **result, int *h_errnop) { 2790 void *ctx; 2791 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 2792 buflen, result, h_errnop); 2793 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 2794 // FIXME: under ASan the call below may write to freed memory and corrupt 2795 // its metadata. See 2796 // https://github.com/google/sanitizers/issues/321. 2797 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 2798 h_errnop); 2799 if (result) { 2800 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2801 if (res == 0 && *result) write_hostent(ctx, *result); 2802 } 2803 if (h_errnop) 2804 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2805 return res; 2806} 2807#define INIT_GETHOSTBYADDR_R \ 2808 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r); 2809#else 2810#define INIT_GETHOSTBYADDR_R 2811#endif 2812 2813#if SANITIZER_INTERCEPT_GETHOSTBYNAME2_R 2814INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 2815 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 2816 __sanitizer_hostent **result, int *h_errnop) { 2817 void *ctx; 2818 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 2819 result, h_errnop); 2820 // FIXME: under ASan the call below may write to freed memory and corrupt 2821 // its metadata. See 2822 // https://github.com/google/sanitizers/issues/321. 2823 int res = 2824 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 2825 if (result) { 2826 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2827 if (res == 0 && *result) write_hostent(ctx, *result); 2828 } 2829 if (h_errnop) 2830 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 2831 return res; 2832} 2833#define INIT_GETHOSTBYNAME2_R \ 2834 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r); 2835#else 2836#define INIT_GETHOSTBYNAME2_R 2837#endif 2838 2839#if SANITIZER_INTERCEPT_GETSOCKOPT 2840INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 2841 int *optlen) { 2842 void *ctx; 2843 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 2844 optlen); 2845 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 2846 // FIXME: under ASan the call below may write to freed memory and corrupt 2847 // its metadata. See 2848 // https://github.com/google/sanitizers/issues/321. 2849 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 2850 if (res == 0) 2851 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 2852 return res; 2853} 2854#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt); 2855#else 2856#define INIT_GETSOCKOPT 2857#endif 2858 2859#if SANITIZER_INTERCEPT_ACCEPT 2860INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 2861 void *ctx; 2862 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 2863 unsigned addrlen0 = 0; 2864 if (addrlen) { 2865 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2866 addrlen0 = *addrlen; 2867 } 2868 int fd2 = REAL(accept)(fd, addr, addrlen); 2869 if (fd2 >= 0) { 2870 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2871 if (addr && addrlen) 2872 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2873 } 2874 return fd2; 2875} 2876#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept); 2877#else 2878#define INIT_ACCEPT 2879#endif 2880 2881#if SANITIZER_INTERCEPT_ACCEPT4 2882INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 2883 void *ctx; 2884 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 2885 unsigned addrlen0 = 0; 2886 if (addrlen) { 2887 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2888 addrlen0 = *addrlen; 2889 } 2890 // FIXME: under ASan the call below may write to freed memory and corrupt 2891 // its metadata. See 2892 // https://github.com/google/sanitizers/issues/321. 2893 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 2894 if (fd2 >= 0) { 2895 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2896 if (addr && addrlen) 2897 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2898 } 2899 return fd2; 2900} 2901#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4); 2902#else 2903#define INIT_ACCEPT4 2904#endif 2905 2906#if SANITIZER_INTERCEPT_PACCEPT 2907INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, 2908 __sanitizer_sigset_t *set, int f) { 2909 void *ctx; 2910 COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f); 2911 unsigned addrlen0 = 0; 2912 if (addrlen) { 2913 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 2914 addrlen0 = *addrlen; 2915 } 2916 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 2917 int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); 2918 if (fd2 >= 0) { 2919 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 2920 if (addr && addrlen) 2921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 2922 } 2923 return fd2; 2924} 2925#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept); 2926#else 2927#define INIT_PACCEPT 2928#endif 2929 2930#if SANITIZER_INTERCEPT_MODF 2931INTERCEPTOR(double, modf, double x, double *iptr) { 2932 void *ctx; 2933 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 2934 // FIXME: under ASan the call below may write to freed memory and corrupt 2935 // its metadata. See 2936 // https://github.com/google/sanitizers/issues/321. 2937 double res = REAL(modf)(x, iptr); 2938 if (iptr) { 2939 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2940 } 2941 return res; 2942} 2943INTERCEPTOR(float, modff, float x, float *iptr) { 2944 void *ctx; 2945 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 2946 // FIXME: under ASan the call below may write to freed memory and corrupt 2947 // its metadata. See 2948 // https://github.com/google/sanitizers/issues/321. 2949 float res = REAL(modff)(x, iptr); 2950 if (iptr) { 2951 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2952 } 2953 return res; 2954} 2955INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 2956 void *ctx; 2957 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 2958 // FIXME: under ASan the call below may write to freed memory and corrupt 2959 // its metadata. See 2960 // https://github.com/google/sanitizers/issues/321. 2961 long double res = REAL(modfl)(x, iptr); 2962 if (iptr) { 2963 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 2964 } 2965 return res; 2966} 2967#define INIT_MODF \ 2968 COMMON_INTERCEPT_FUNCTION(modf); \ 2969 COMMON_INTERCEPT_FUNCTION(modff); \ 2970 COMMON_INTERCEPT_FUNCTION_LDBL(modfl); 2971#else 2972#define INIT_MODF 2973#endif 2974 2975#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG 2976static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 2977 SSIZE_T maxlen) { 2978 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 2979 if (msg->msg_name && msg->msg_namelen) 2980 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 2981 if (msg->msg_iov && msg->msg_iovlen) 2982 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 2983 sizeof(*msg->msg_iov) * msg->msg_iovlen); 2984 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 2985 if (msg->msg_control && msg->msg_controllen) 2986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 2987} 2988#endif 2989 2990#if SANITIZER_INTERCEPT_RECVMSG 2991INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 2992 int flags) { 2993 void *ctx; 2994 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 2995 // FIXME: under ASan the call below may write to freed memory and corrupt 2996 // its metadata. See 2997 // https://github.com/google/sanitizers/issues/321. 2998 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 2999 if (res >= 0) { 3000 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 3001 if (msg) { 3002 write_msghdr(ctx, msg, res); 3003 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg); 3004 } 3005 } 3006 return res; 3007} 3008#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg); 3009#else 3010#define INIT_RECVMSG 3011#endif 3012 3013#if SANITIZER_INTERCEPT_RECVMMSG 3014INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 3015 unsigned int vlen, int flags, void *timeout) { 3016 void *ctx; 3017 COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout); 3018 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 3019 int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); 3020 if (res >= 0) { 3021 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 3022 for (int i = 0; i < res; ++i) { 3023 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 3024 sizeof(msgvec[i].msg_len)); 3025 write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 3026 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr); 3027 } 3028 } 3029 return res; 3030} 3031#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg); 3032#else 3033#define INIT_RECVMMSG 3034#endif 3035 3036#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG 3037static void read_msghdr_control(void *ctx, void *control, uptr controllen) { 3038 const unsigned kCmsgDataOffset = 3039 RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr)); 3040 3041 char *p = (char *)control; 3042 char *const control_end = p + controllen; 3043 while (true) { 3044 if (p + sizeof(__sanitizer_cmsghdr) > control_end) break; 3045 __sanitizer_cmsghdr *cmsg = (__sanitizer_cmsghdr *)p; 3046 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_len, sizeof(cmsg->cmsg_len)); 3047 3048 if (p + RoundUpTo(cmsg->cmsg_len, sizeof(uptr)) > control_end) break; 3049 3050 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_level, 3051 sizeof(cmsg->cmsg_level)); 3052 COMMON_INTERCEPTOR_READ_RANGE(ctx, &cmsg->cmsg_type, 3053 sizeof(cmsg->cmsg_type)); 3054 3055 if (cmsg->cmsg_len > kCmsgDataOffset) { 3056 char *data = p + kCmsgDataOffset; 3057 unsigned data_len = cmsg->cmsg_len - kCmsgDataOffset; 3058 if (data_len > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, data, data_len); 3059 } 3060 3061 p += RoundUpTo(cmsg->cmsg_len, sizeof(uptr)); 3062 } 3063} 3064 3065static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 3066 SSIZE_T maxlen) { 3067#define R(f) \ 3068 COMMON_INTERCEPTOR_READ_RANGE(ctx, &msg->msg_##f, sizeof(msg->msg_##f)) 3069 R(name); 3070 R(namelen); 3071 R(iov); 3072 R(iovlen); 3073 R(control); 3074 R(controllen); 3075 R(flags); 3076#undef R 3077 if (msg->msg_name && msg->msg_namelen) 3078 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_name, msg->msg_namelen); 3079 if (msg->msg_iov && msg->msg_iovlen) 3080 COMMON_INTERCEPTOR_READ_RANGE(ctx, msg->msg_iov, 3081 sizeof(*msg->msg_iov) * msg->msg_iovlen); 3082 read_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 3083 if (msg->msg_control && msg->msg_controllen) 3084 read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen); 3085} 3086#endif 3087 3088#if SANITIZER_INTERCEPT_SENDMSG 3089INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, 3090 int flags) { 3091 void *ctx; 3092 COMMON_INTERCEPTOR_ENTER(ctx, sendmsg, fd, msg, flags); 3093 if (fd >= 0) { 3094 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3095 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3096 } 3097 SSIZE_T res = REAL(sendmsg)(fd, msg, flags); 3098 if (common_flags()->intercept_send && res >= 0 && msg) 3099 read_msghdr(ctx, msg, res); 3100 return res; 3101} 3102#define INIT_SENDMSG COMMON_INTERCEPT_FUNCTION(sendmsg); 3103#else 3104#define INIT_SENDMSG 3105#endif 3106 3107#if SANITIZER_INTERCEPT_SENDMMSG 3108INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, 3109 unsigned vlen, int flags) { 3110 void *ctx; 3111 COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags); 3112 if (fd >= 0) { 3113 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 3114 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 3115 } 3116 int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); 3117 if (res >= 0 && msgvec) { 3118 for (int i = 0; i < res; ++i) { 3119 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, 3120 sizeof(msgvec[i].msg_len)); 3121 if (common_flags()->intercept_send) 3122 read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); 3123 } 3124 } 3125 return res; 3126} 3127#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); 3128#else 3129#define INIT_SENDMMSG 3130#endif 3131 3132#if SANITIZER_INTERCEPT_SYSMSG 3133INTERCEPTOR(int, msgsnd, int msqid, const void *msgp, SIZE_T msgsz, 3134 int msgflg) { 3135 void *ctx; 3136 COMMON_INTERCEPTOR_ENTER(ctx, msgsnd, msqid, msgp, msgsz, msgflg); 3137 if (msgp) 3138 COMMON_INTERCEPTOR_READ_RANGE(ctx, msgp, sizeof(long) + msgsz); 3139 int res = REAL(msgsnd)(msqid, msgp, msgsz, msgflg); 3140 return res; 3141} 3142 3143INTERCEPTOR(SSIZE_T, msgrcv, int msqid, void *msgp, SIZE_T msgsz, 3144 long msgtyp, int msgflg) { 3145 void *ctx; 3146 COMMON_INTERCEPTOR_ENTER(ctx, msgrcv, msqid, msgp, msgsz, msgtyp, msgflg); 3147 SSIZE_T len = REAL(msgrcv)(msqid, msgp, msgsz, msgtyp, msgflg); 3148 if (len != -1) 3149 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msgp, sizeof(long) + len); 3150 return len; 3151} 3152 3153#define INIT_SYSMSG \ 3154 COMMON_INTERCEPT_FUNCTION(msgsnd); \ 3155 COMMON_INTERCEPT_FUNCTION(msgrcv); 3156#else 3157#define INIT_SYSMSG 3158#endif 3159 3160#if SANITIZER_INTERCEPT_GETPEERNAME 3161INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 3162 void *ctx; 3163 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 3164 unsigned addr_sz; 3165 if (addrlen) addr_sz = *addrlen; 3166 // FIXME: under ASan the call below may write to freed memory and corrupt 3167 // its metadata. See 3168 // https://github.com/google/sanitizers/issues/321. 3169 int res = REAL(getpeername)(sockfd, addr, addrlen); 3170 if (!res && addr && addrlen) 3171 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 3172 return res; 3173} 3174#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername); 3175#else 3176#define INIT_GETPEERNAME 3177#endif 3178 3179#if SANITIZER_INTERCEPT_SYSINFO 3180INTERCEPTOR(int, sysinfo, void *info) { 3181 void *ctx; 3182 // FIXME: under ASan the call below may write to freed memory and corrupt 3183 // its metadata. See 3184 // https://github.com/google/sanitizers/issues/321. 3185 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 3186 int res = REAL(sysinfo)(info); 3187 if (!res && info) 3188 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 3189 return res; 3190} 3191#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo); 3192#else 3193#define INIT_SYSINFO 3194#endif 3195 3196#if SANITIZER_INTERCEPT_READDIR 3197INTERCEPTOR(__sanitizer_dirent *, opendir, const char *path) { 3198 void *ctx; 3199 COMMON_INTERCEPTOR_ENTER(ctx, opendir, path); 3200 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3201 __sanitizer_dirent *res = REAL(opendir)(path); 3202 if (res) 3203 COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path); 3204 return res; 3205} 3206 3207INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 3208 void *ctx; 3209 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 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 __sanitizer_dirent *res = REAL(readdir)(dirp); 3214 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3215 return res; 3216} 3217 3218INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 3219 __sanitizer_dirent **result) { 3220 void *ctx; 3221 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 3222 // FIXME: under ASan the call below may write to freed memory and corrupt 3223 // its metadata. See 3224 // https://github.com/google/sanitizers/issues/321. 3225 int res = REAL(readdir_r)(dirp, entry, result); 3226 if (!res) { 3227 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3228 if (*result) 3229 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3230 } 3231 return res; 3232} 3233 3234#define INIT_READDIR \ 3235 COMMON_INTERCEPT_FUNCTION(opendir); \ 3236 COMMON_INTERCEPT_FUNCTION(readdir); \ 3237 COMMON_INTERCEPT_FUNCTION(readdir_r); 3238#else 3239#define INIT_READDIR 3240#endif 3241 3242#if SANITIZER_INTERCEPT_READDIR64 3243INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 3244 void *ctx; 3245 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 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 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 3250 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 3251 return res; 3252} 3253 3254INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 3255 __sanitizer_dirent64 **result) { 3256 void *ctx; 3257 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 3258 // FIXME: under ASan the call below may write to freed memory and corrupt 3259 // its metadata. See 3260 // https://github.com/google/sanitizers/issues/321. 3261 int res = REAL(readdir64_r)(dirp, entry, result); 3262 if (!res) { 3263 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3264 if (*result) 3265 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 3266 } 3267 return res; 3268} 3269#define INIT_READDIR64 \ 3270 COMMON_INTERCEPT_FUNCTION(readdir64); \ 3271 COMMON_INTERCEPT_FUNCTION(readdir64_r); 3272#else 3273#define INIT_READDIR64 3274#endif 3275 3276#if SANITIZER_INTERCEPT_PTRACE 3277INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 3278 void *ctx; 3279 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 3280 __sanitizer_iovec local_iovec; 3281 3282 if (data) { 3283 if (request == ptrace_setregs) { 3284 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 3285 } else if (request == ptrace_setfpregs) { 3286 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3287 } else if (request == ptrace_setfpxregs) { 3288 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3289 } else if (request == ptrace_setvfpregs) { 3290 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3291 } else if (request == ptrace_setsiginfo) { 3292 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 3293 3294 // Some kernel might zero the iovec::iov_base in case of invalid 3295 // write access. In this case copy the invalid address for further 3296 // inspection. 3297 } else if (request == ptrace_setregset || request == ptrace_getregset) { 3298 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3299 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec)); 3300 local_iovec = *iovec; 3301 if (request == ptrace_setregset) 3302 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec->iov_base, iovec->iov_len); 3303 } 3304 } 3305 3306 // FIXME: under ASan the call below may write to freed memory and corrupt 3307 // its metadata. See 3308 // https://github.com/google/sanitizers/issues/321. 3309 uptr res = REAL(ptrace)(request, pid, addr, data); 3310 3311 if (!res && data) { 3312 // Note that PEEK* requests assign different meaning to the return value. 3313 // This function does not handle them (nor does it need to). 3314 if (request == ptrace_getregs) { 3315 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 3316 } else if (request == ptrace_getfpregs) { 3317 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 3318 } else if (request == ptrace_getfpxregs) { 3319 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 3320 } else if (request == ptrace_getvfpregs) { 3321 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz); 3322 } else if (request == ptrace_getsiginfo) { 3323 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 3324 } else if (request == ptrace_geteventmsg) { 3325 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long)); 3326 } else if (request == ptrace_getregset) { 3327 __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; 3328 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec)); 3329 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base, 3330 local_iovec.iov_len); 3331 } 3332 } 3333 return res; 3334} 3335 3336#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace); 3337#else 3338#define INIT_PTRACE 3339#endif 3340 3341#if SANITIZER_INTERCEPT_SETLOCALE 3342static void unpoison_ctype_arrays(void *ctx) { 3343#if SANITIZER_NETBSD 3344 // These arrays contain 256 regular elements in unsigned char range + 1 EOF 3345 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short)); 3346 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short)); 3347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short)); 3348#endif 3349} 3350 3351INTERCEPTOR(char *, setlocale, int category, char *locale) { 3352 void *ctx; 3353 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 3354 if (locale) 3355 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 3356 char *res = REAL(setlocale)(category, locale); 3357 if (res) { 3358 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3359 unpoison_ctype_arrays(ctx); 3360 } 3361 return res; 3362} 3363 3364#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale); 3365#else 3366#define INIT_SETLOCALE 3367#endif 3368 3369#if SANITIZER_INTERCEPT_GETCWD 3370INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 3371 void *ctx; 3372 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 3373 // FIXME: under ASan the call below may write to freed memory and corrupt 3374 // its metadata. See 3375 // https://github.com/google/sanitizers/issues/321. 3376 char *res = REAL(getcwd)(buf, size); 3377 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3378 return res; 3379} 3380#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); 3381#else 3382#define INIT_GETCWD 3383#endif 3384 3385#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 3386INTERCEPTOR(char *, get_current_dir_name, int fake) { 3387 void *ctx; 3388 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 3389 // FIXME: under ASan the call below may write to freed memory and corrupt 3390 // its metadata. See 3391 // https://github.com/google/sanitizers/issues/321. 3392 char *res = REAL(get_current_dir_name)(fake); 3393 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3394 return res; 3395} 3396 3397#define INIT_GET_CURRENT_DIR_NAME \ 3398 COMMON_INTERCEPT_FUNCTION(get_current_dir_name); 3399#else 3400#define INIT_GET_CURRENT_DIR_NAME 3401#endif 3402 3403UNUSED static inline void FixRealStrtolEndptr(const char *nptr, char **endptr) { 3404 CHECK(endptr); 3405 if (nptr == *endptr) { 3406 // No digits were found at strtol call, we need to find out the last 3407 // symbol accessed by strtoll on our own. 3408 // We get this symbol by skipping leading blanks and optional +/- sign. 3409 while (IsSpace(*nptr)) nptr++; 3410 if (*nptr == '+' || *nptr == '-') nptr++; 3411 *endptr = const_cast<char *>(nptr); 3412 } 3413 CHECK(*endptr >= nptr); 3414} 3415 3416UNUSED static inline void StrtolFixAndCheck(void *ctx, const char *nptr, 3417 char **endptr, char *real_endptr, int base) { 3418 if (endptr) { 3419 *endptr = real_endptr; 3420 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 3421 } 3422 // If base has unsupported value, strtol can exit with EINVAL 3423 // without reading any characters. So do additional checks only 3424 // if base is valid. 3425 bool is_valid_base = (base == 0) || (2 <= base && base <= 36); 3426 if (is_valid_base) { 3427 FixRealStrtolEndptr(nptr, &real_endptr); 3428 } 3429 COMMON_INTERCEPTOR_READ_STRING(ctx, nptr, is_valid_base ? 3430 (real_endptr - nptr) + 1 : 0); 3431} 3432 3433 3434#if SANITIZER_INTERCEPT_STRTOIMAX 3435INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 3436 void *ctx; 3437 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 3438 // FIXME: under ASan the call below may write to freed memory and corrupt 3439 // its metadata. See 3440 // https://github.com/google/sanitizers/issues/321. 3441 char *real_endptr; 3442 INTMAX_T res = REAL(strtoimax)(nptr, &real_endptr, base); 3443 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3444 return res; 3445} 3446 3447INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 3448 void *ctx; 3449 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 3450 // FIXME: under ASan the call below may write to freed memory and corrupt 3451 // its metadata. See 3452 // https://github.com/google/sanitizers/issues/321. 3453 char *real_endptr; 3454 UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); 3455 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 3456 return res; 3457} 3458 3459#define INIT_STRTOIMAX \ 3460 COMMON_INTERCEPT_FUNCTION(strtoimax); \ 3461 COMMON_INTERCEPT_FUNCTION(strtoumax); 3462#else 3463#define INIT_STRTOIMAX 3464#endif 3465 3466#if SANITIZER_INTERCEPT_MBSTOWCS 3467INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 3468 void *ctx; 3469 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 3470 // FIXME: under ASan the call below may write to freed memory and corrupt 3471 // its metadata. See 3472 // https://github.com/google/sanitizers/issues/321. 3473 SIZE_T res = REAL(mbstowcs)(dest, src, len); 3474 if (res != (SIZE_T) - 1 && dest) { 3475 SIZE_T write_cnt = res + (res < len); 3476 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3477 } 3478 return res; 3479} 3480 3481INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 3482 void *ps) { 3483 void *ctx; 3484 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 3485 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3486 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3487 // FIXME: under ASan the call below may write to freed memory and corrupt 3488 // its metadata. See 3489 // https://github.com/google/sanitizers/issues/321. 3490 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 3491 if (res != (SIZE_T)(-1) && dest && src) { 3492 // This function, and several others, may or may not write the terminating 3493 // \0 character. They write it iff they clear *src. 3494 SIZE_T write_cnt = res + !*src; 3495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3496 } 3497 return res; 3498} 3499 3500#define INIT_MBSTOWCS \ 3501 COMMON_INTERCEPT_FUNCTION(mbstowcs); \ 3502 COMMON_INTERCEPT_FUNCTION(mbsrtowcs); 3503#else 3504#define INIT_MBSTOWCS 3505#endif 3506 3507#if SANITIZER_INTERCEPT_MBSNRTOWCS 3508INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 3509 SIZE_T len, void *ps) { 3510 void *ctx; 3511 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 3512 if (src) { 3513 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3514 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3515 } 3516 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3517 // FIXME: under ASan the call below may write to freed memory and corrupt 3518 // its metadata. See 3519 // https://github.com/google/sanitizers/issues/321. 3520 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 3521 if (res != (SIZE_T)(-1) && dest && src) { 3522 SIZE_T write_cnt = res + !*src; 3523 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 3524 } 3525 return res; 3526} 3527 3528#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs); 3529#else 3530#define INIT_MBSNRTOWCS 3531#endif 3532 3533#if SANITIZER_INTERCEPT_WCSTOMBS 3534INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 3535 void *ctx; 3536 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 3537 // FIXME: under ASan the call below may write to freed memory and corrupt 3538 // its metadata. See 3539 // https://github.com/google/sanitizers/issues/321. 3540 SIZE_T res = REAL(wcstombs)(dest, src, len); 3541 if (res != (SIZE_T) - 1 && dest) { 3542 SIZE_T write_cnt = res + (res < len); 3543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3544 } 3545 return res; 3546} 3547 3548INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 3549 void *ps) { 3550 void *ctx; 3551 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 3552 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3553 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3554 // FIXME: under ASan the call below may write to freed memory and corrupt 3555 // its metadata. See 3556 // https://github.com/google/sanitizers/issues/321. 3557 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 3558 if (res != (SIZE_T) - 1 && dest && src) { 3559 SIZE_T write_cnt = res + !*src; 3560 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3561 } 3562 return res; 3563} 3564 3565#define INIT_WCSTOMBS \ 3566 COMMON_INTERCEPT_FUNCTION(wcstombs); \ 3567 COMMON_INTERCEPT_FUNCTION(wcsrtombs); 3568#else 3569#define INIT_WCSTOMBS 3570#endif 3571 3572#if SANITIZER_INTERCEPT_WCSNRTOMBS 3573INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 3574 SIZE_T len, void *ps) { 3575 void *ctx; 3576 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 3577 if (src) { 3578 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 3579 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 3580 } 3581 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3582 // FIXME: under ASan the call below may write to freed memory and corrupt 3583 // its metadata. See 3584 // https://github.com/google/sanitizers/issues/321. 3585 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 3586 if (res != ((SIZE_T)-1) && dest && src) { 3587 SIZE_T write_cnt = res + !*src; 3588 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 3589 } 3590 return res; 3591} 3592 3593#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs); 3594#else 3595#define INIT_WCSNRTOMBS 3596#endif 3597 3598 3599#if SANITIZER_INTERCEPT_WCRTOMB 3600INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { 3601 void *ctx; 3602 COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps); 3603 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 3604 3605 if (!dest) 3606 return REAL(wcrtomb)(dest, src, ps); 3607 3608 char local_dest[32]; 3609 SIZE_T res = REAL(wcrtomb)(local_dest, src, ps); 3610 if (res != ((SIZE_T)-1)) { 3611 CHECK_LE(res, sizeof(local_dest)); 3612 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); 3613 REAL(memcpy)(dest, local_dest, res); 3614 } 3615 return res; 3616} 3617 3618#define INIT_WCRTOMB COMMON_INTERCEPT_FUNCTION(wcrtomb); 3619#else 3620#define INIT_WCRTOMB 3621#endif 3622 3623#if SANITIZER_INTERCEPT_WCTOMB 3624INTERCEPTOR(int, wctomb, char *dest, wchar_t src) { 3625 void *ctx; 3626 COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src); 3627 if (!dest) 3628 return REAL(wctomb)(dest, src); 3629 3630 char local_dest[32]; 3631 int res = REAL(wctomb)(local_dest, src); 3632 if (res != -1) { 3633 CHECK_LE(res, sizeof(local_dest)); 3634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); 3635 REAL(memcpy)(dest, local_dest, res); 3636 } 3637 return res; 3638} 3639 3640#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb); 3641#else 3642#define INIT_WCTOMB 3643#endif 3644 3645#if SANITIZER_INTERCEPT_TCGETATTR 3646INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 3647 void *ctx; 3648 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 3649 // FIXME: under ASan the call below may write to freed memory and corrupt 3650 // its metadata. See 3651 // https://github.com/google/sanitizers/issues/321. 3652 int res = REAL(tcgetattr)(fd, termios_p); 3653 if (!res && termios_p) 3654 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 3655 return res; 3656} 3657 3658#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr); 3659#else 3660#define INIT_TCGETATTR 3661#endif 3662 3663#if SANITIZER_INTERCEPT_REALPATH 3664INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 3665 void *ctx; 3666 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 3667 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3668 3669 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 3670 // version of a versioned symbol. For realpath(), this gives us something 3671 // (called __old_realpath) that does not handle NULL in the second argument. 3672 // Handle it as part of the interceptor. 3673 char *allocated_path = nullptr; 3674 if (!resolved_path) 3675 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 3676 3677 char *res = REAL(realpath)(path, resolved_path); 3678 if (allocated_path && !res) WRAP(free)(allocated_path); 3679 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3680 return res; 3681} 3682#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); 3683#else 3684#define INIT_REALPATH 3685#endif 3686 3687#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 3688INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 3689 void *ctx; 3690 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 3691 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3692 char *res = REAL(canonicalize_file_name)(path); 3693 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3694 return res; 3695} 3696#define INIT_CANONICALIZE_FILE_NAME \ 3697 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name); 3698#else 3699#define INIT_CANONICALIZE_FILE_NAME 3700#endif 3701 3702#if SANITIZER_INTERCEPT_CONFSTR 3703INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 3704 void *ctx; 3705 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 3706 // FIXME: under ASan the call below may write to freed memory and corrupt 3707 // its metadata. See 3708 // https://github.com/google/sanitizers/issues/321. 3709 SIZE_T res = REAL(confstr)(name, buf, len); 3710 if (buf && res) 3711 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 3712 return res; 3713} 3714#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr); 3715#else 3716#define INIT_CONFSTR 3717#endif 3718 3719#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 3720INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 3721 void *ctx; 3722 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 3723 // FIXME: under ASan the call below may write to freed memory and corrupt 3724 // its metadata. See 3725 // https://github.com/google/sanitizers/issues/321. 3726 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 3727 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 3728 return res; 3729} 3730#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity); 3731#else 3732#define INIT_SCHED_GETAFFINITY 3733#endif 3734 3735#if SANITIZER_INTERCEPT_SCHED_GETPARAM 3736INTERCEPTOR(int, sched_getparam, int pid, void *param) { 3737 void *ctx; 3738 COMMON_INTERCEPTOR_ENTER(ctx, sched_getparam, pid, param); 3739 int res = REAL(sched_getparam)(pid, param); 3740 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, struct_sched_param_sz); 3741 return res; 3742} 3743#define INIT_SCHED_GETPARAM COMMON_INTERCEPT_FUNCTION(sched_getparam); 3744#else 3745#define INIT_SCHED_GETPARAM 3746#endif 3747 3748#if SANITIZER_INTERCEPT_STRERROR 3749INTERCEPTOR(char *, strerror, int errnum) { 3750 void *ctx; 3751 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 3752 COMMON_INTERCEPTOR_STRERROR(); 3753 char *res = REAL(strerror)(errnum); 3754 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3755 return res; 3756} 3757#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); 3758#else 3759#define INIT_STRERROR 3760#endif 3761 3762#if SANITIZER_INTERCEPT_STRERROR_R 3763// There are 2 versions of strerror_r: 3764// * POSIX version returns 0 on success, negative error code on failure, 3765// writes message to buf. 3766// * GNU version returns message pointer, which points to either buf or some 3767// static storage. 3768#if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ 3769 SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ 3770 SANITIZER_FREEBSD 3771// POSIX version. Spec is not clear on whether buf is NULL-terminated. 3772// At least on OSX, buf contents are valid even when the call fails. 3773INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3774 void *ctx; 3775 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3776 // FIXME: under ASan the call below may write to freed memory and corrupt 3777 // its metadata. See 3778 // https://github.com/google/sanitizers/issues/321. 3779 int res = REAL(strerror_r)(errnum, buf, buflen); 3780 3781 SIZE_T sz = internal_strnlen(buf, buflen); 3782 if (sz < buflen) ++sz; 3783 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 3784 return res; 3785} 3786#else 3787// GNU version. 3788INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 3789 void *ctx; 3790 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 3791 // FIXME: under ASan the call below may write to freed memory and corrupt 3792 // its metadata. See 3793 // https://github.com/google/sanitizers/issues/321. 3794 char *res = REAL(strerror_r)(errnum, buf, buflen); 3795 if (res == buf) 3796 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 3797 else 3798 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3799 return res; 3800} 3801#endif //(_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE || 3802 //SANITIZER_MAC 3803#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); 3804#else 3805#define INIT_STRERROR_R 3806#endif 3807 3808#if SANITIZER_INTERCEPT_XPG_STRERROR_R 3809INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) { 3810 void *ctx; 3811 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen); 3812 // FIXME: under ASan the call below may write to freed memory and corrupt 3813 // its metadata. See 3814 // https://github.com/google/sanitizers/issues/321. 3815 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen); 3816 // This version always returns a null-terminated string. 3817 if (buf && buflen) 3818 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 3819 return res; 3820} 3821#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r); 3822#else 3823#define INIT_XPG_STRERROR_R 3824#endif 3825 3826#if SANITIZER_INTERCEPT_SCANDIR 3827typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 3828typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 3829 const struct __sanitizer_dirent **); 3830 3831static THREADLOCAL scandir_filter_f scandir_filter; 3832static THREADLOCAL scandir_compar_f scandir_compar; 3833 3834static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 3835 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3836 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3837 return scandir_filter(dir); 3838} 3839 3840static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 3841 const struct __sanitizer_dirent **b) { 3842 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3843 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3844 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3845 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3846 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3847 return scandir_compar(a, b); 3848} 3849 3850INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 3851 scandir_filter_f filter, scandir_compar_f compar) { 3852 void *ctx; 3853 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 3854 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3855 scandir_filter = filter; 3856 scandir_compar = compar; 3857 // FIXME: under ASan the call below may write to freed memory and corrupt 3858 // its metadata. See 3859 // https://github.com/google/sanitizers/issues/321. 3860 int res = REAL(scandir)(dirp, namelist, 3861 filter ? wrapped_scandir_filter : nullptr, 3862 compar ? wrapped_scandir_compar : nullptr); 3863 scandir_filter = nullptr; 3864 scandir_compar = nullptr; 3865 if (namelist && res > 0) { 3866 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3867 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3868 for (int i = 0; i < res; ++i) 3869 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3870 (*namelist)[i]->d_reclen); 3871 } 3872 return res; 3873} 3874#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir); 3875#else 3876#define INIT_SCANDIR 3877#endif 3878 3879#if SANITIZER_INTERCEPT_SCANDIR64 3880typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 3881typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 3882 const struct __sanitizer_dirent64 **); 3883 3884static THREADLOCAL scandir64_filter_f scandir64_filter; 3885static THREADLOCAL scandir64_compar_f scandir64_compar; 3886 3887static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 3888 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 3889 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 3890 return scandir64_filter(dir); 3891} 3892 3893static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 3894 const struct __sanitizer_dirent64 **b) { 3895 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 3896 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 3897 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 3898 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 3899 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 3900 return scandir64_compar(a, b); 3901} 3902 3903INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 3904 scandir64_filter_f filter, scandir64_compar_f compar) { 3905 void *ctx; 3906 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 3907 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 3908 scandir64_filter = filter; 3909 scandir64_compar = compar; 3910 // FIXME: under ASan the call below may write to freed memory and corrupt 3911 // its metadata. See 3912 // https://github.com/google/sanitizers/issues/321. 3913 int res = 3914 REAL(scandir64)(dirp, namelist, 3915 filter ? wrapped_scandir64_filter : nullptr, 3916 compar ? wrapped_scandir64_compar : nullptr); 3917 scandir64_filter = nullptr; 3918 scandir64_compar = nullptr; 3919 if (namelist && res > 0) { 3920 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 3921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 3922 for (int i = 0; i < res; ++i) 3923 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 3924 (*namelist)[i]->d_reclen); 3925 } 3926 return res; 3927} 3928#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64); 3929#else 3930#define INIT_SCANDIR64 3931#endif 3932 3933#if SANITIZER_INTERCEPT_GETGROUPS 3934INTERCEPTOR(int, getgroups, int size, u32 *lst) { 3935 void *ctx; 3936 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 3937 // FIXME: under ASan the call below may write to freed memory and corrupt 3938 // its metadata. See 3939 // https://github.com/google/sanitizers/issues/321. 3940 int res = REAL(getgroups)(size, lst); 3941 if (res >= 0 && lst && size > 0) 3942 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 3943 return res; 3944} 3945#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups); 3946#else 3947#define INIT_GETGROUPS 3948#endif 3949 3950#if SANITIZER_INTERCEPT_POLL 3951static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 3952 __sanitizer_nfds_t nfds) { 3953 for (unsigned i = 0; i < nfds; ++i) { 3954 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 3955 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 3956 } 3957} 3958 3959static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 3960 __sanitizer_nfds_t nfds) { 3961 for (unsigned i = 0; i < nfds; ++i) 3962 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 3963 sizeof(fds[i].revents)); 3964} 3965 3966INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3967 int timeout) { 3968 void *ctx; 3969 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 3970 if (fds && nfds) read_pollfd(ctx, fds, nfds); 3971 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 3972 if (fds && nfds) write_pollfd(ctx, fds, nfds); 3973 return res; 3974} 3975#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll); 3976#else 3977#define INIT_POLL 3978#endif 3979 3980#if SANITIZER_INTERCEPT_PPOLL 3981INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 3982 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 3983 void *ctx; 3984 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 3985 if (fds && nfds) read_pollfd(ctx, fds, nfds); 3986 if (timeout_ts) 3987 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 3988 if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, sigmask, sizeof(*sigmask)); 3989 int res = 3990 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 3991 if (fds && nfds) write_pollfd(ctx, fds, nfds); 3992 return res; 3993} 3994#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll); 3995#else 3996#define INIT_PPOLL 3997#endif 3998 3999#if SANITIZER_INTERCEPT_WORDEXP 4000INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 4001 void *ctx; 4002 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 4003 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 4004 // FIXME: under ASan the call below may write to freed memory and corrupt 4005 // its metadata. See 4006 // https://github.com/google/sanitizers/issues/321. 4007 int res = REAL(wordexp)(s, p, flags); 4008 if (!res && p) { 4009 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 4010 if (p->we_wordc) 4011 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 4012 sizeof(*p->we_wordv) * p->we_wordc); 4013 for (uptr i = 0; i < p->we_wordc; ++i) { 4014 char *w = p->we_wordv[i]; 4015 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 4016 } 4017 } 4018 return res; 4019} 4020#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp); 4021#else 4022#define INIT_WORDEXP 4023#endif 4024 4025#if SANITIZER_INTERCEPT_SIGWAIT 4026INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 4027 void *ctx; 4028 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 4029 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4030 // FIXME: under ASan the call below may write to freed memory and corrupt 4031 // its metadata. See 4032 // https://github.com/google/sanitizers/issues/321. 4033 int res = REAL(sigwait)(set, sig); 4034 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 4035 return res; 4036} 4037#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait); 4038#else 4039#define INIT_SIGWAIT 4040#endif 4041 4042#if SANITIZER_INTERCEPT_SIGWAITINFO 4043INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 4044 void *ctx; 4045 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 4046 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4047 // FIXME: under ASan the call below may write to freed memory and corrupt 4048 // its metadata. See 4049 // https://github.com/google/sanitizers/issues/321. 4050 int res = REAL(sigwaitinfo)(set, info); 4051 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 4052 return res; 4053} 4054#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo); 4055#else 4056#define INIT_SIGWAITINFO 4057#endif 4058 4059#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 4060INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 4061 void *timeout) { 4062 void *ctx; 4063 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 4064 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 4065 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4066 // FIXME: under ASan the call below may write to freed memory and corrupt 4067 // its metadata. See 4068 // https://github.com/google/sanitizers/issues/321. 4069 int res = REAL(sigtimedwait)(set, info, timeout); 4070 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 4071 return res; 4072} 4073#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait); 4074#else 4075#define INIT_SIGTIMEDWAIT 4076#endif 4077 4078#if SANITIZER_INTERCEPT_SIGSETOPS 4079INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 4080 void *ctx; 4081 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 4082 // FIXME: under ASan the call below may write to freed memory and corrupt 4083 // its metadata. See 4084 // https://github.com/google/sanitizers/issues/321. 4085 int res = REAL(sigemptyset)(set); 4086 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 4087 return res; 4088} 4089 4090INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 4091 void *ctx; 4092 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 4093 // FIXME: under ASan the call below may write to freed memory and corrupt 4094 // its metadata. See 4095 // https://github.com/google/sanitizers/issues/321. 4096 int res = REAL(sigfillset)(set); 4097 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 4098 return res; 4099} 4100#define INIT_SIGSETOPS \ 4101 COMMON_INTERCEPT_FUNCTION(sigemptyset); \ 4102 COMMON_INTERCEPT_FUNCTION(sigfillset); 4103#else 4104#define INIT_SIGSETOPS 4105#endif 4106 4107#if SANITIZER_INTERCEPT_SIGSET_LOGICOPS 4108INTERCEPTOR(int, sigandset, __sanitizer_sigset_t *dst, 4109 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) { 4110 void *ctx; 4111 COMMON_INTERCEPTOR_ENTER(ctx, sigandset, dst, src1, src2); 4112 if (src1) 4113 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1)); 4114 if (src2) 4115 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2)); 4116 int res = REAL(sigandset)(dst, src1, src2); 4117 if (!res && dst) 4118 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 4119 return res; 4120} 4121 4122INTERCEPTOR(int, sigorset, __sanitizer_sigset_t *dst, 4123 __sanitizer_sigset_t *src1, __sanitizer_sigset_t *src2) { 4124 void *ctx; 4125 COMMON_INTERCEPTOR_ENTER(ctx, sigorset, dst, src1, src2); 4126 if (src1) 4127 COMMON_INTERCEPTOR_READ_RANGE(ctx, src1, sizeof(*src1)); 4128 if (src2) 4129 COMMON_INTERCEPTOR_READ_RANGE(ctx, src2, sizeof(*src2)); 4130 int res = REAL(sigorset)(dst, src1, src2); 4131 if (!res && dst) 4132 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 4133 return res; 4134} 4135#define INIT_SIGSET_LOGICOPS \ 4136 COMMON_INTERCEPT_FUNCTION(sigandset); \ 4137 COMMON_INTERCEPT_FUNCTION(sigorset); 4138#else 4139#define INIT_SIGSET_LOGICOPS 4140#endif 4141 4142#if SANITIZER_INTERCEPT_SIGPENDING 4143INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 4144 void *ctx; 4145 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 4146 // FIXME: under ASan the call below may write to freed memory and corrupt 4147 // its metadata. See 4148 // https://github.com/google/sanitizers/issues/321. 4149 int res = REAL(sigpending)(set); 4150 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 4151 return res; 4152} 4153#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending); 4154#else 4155#define INIT_SIGPENDING 4156#endif 4157 4158#if SANITIZER_INTERCEPT_SIGPROCMASK 4159INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 4160 __sanitizer_sigset_t *oldset) { 4161 void *ctx; 4162 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 4163 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4164 // FIXME: under ASan the call below may write to freed memory and corrupt 4165 // its metadata. See 4166 // https://github.com/google/sanitizers/issues/321. 4167 int res = REAL(sigprocmask)(how, set, oldset); 4168 if (!res && oldset) 4169 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 4170 return res; 4171} 4172#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask); 4173#else 4174#define INIT_SIGPROCMASK 4175#endif 4176 4177#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK 4178INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set, 4179 __sanitizer_sigset_t *oldset) { 4180 void *ctx; 4181 COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset); 4182 if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); 4183 // FIXME: under ASan the call below may write to freed memory and corrupt 4184 // its metadata. See 4185 // https://github.com/google/sanitizers/issues/321. 4186 int res = REAL(pthread_sigmask)(how, set, oldset); 4187 if (!res && oldset) 4188 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 4189 return res; 4190} 4191#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask); 4192#else 4193#define INIT_PTHREAD_SIGMASK 4194#endif 4195 4196#if SANITIZER_INTERCEPT_BACKTRACE 4197INTERCEPTOR(int, backtrace, void **buffer, int size) { 4198 void *ctx; 4199 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 4200 // FIXME: under ASan the call below may write to freed memory and corrupt 4201 // its metadata. See 4202 // https://github.com/google/sanitizers/issues/321. 4203 int res = REAL(backtrace)(buffer, size); 4204 if (res && buffer) 4205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 4206 return res; 4207} 4208 4209INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 4210 void *ctx; 4211 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 4212 if (buffer && size) 4213 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 4214 // FIXME: under ASan the call below may write to freed memory and corrupt 4215 // its metadata. See 4216 // https://github.com/google/sanitizers/issues/321. 4217 char **res = REAL(backtrace_symbols)(buffer, size); 4218 if (res && size) { 4219 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 4220 for (int i = 0; i < size; ++i) 4221 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 4222 } 4223 return res; 4224} 4225#define INIT_BACKTRACE \ 4226 COMMON_INTERCEPT_FUNCTION(backtrace); \ 4227 COMMON_INTERCEPT_FUNCTION(backtrace_symbols); 4228#else 4229#define INIT_BACKTRACE 4230#endif 4231 4232#if SANITIZER_INTERCEPT__EXIT 4233INTERCEPTOR(void, _exit, int status) { 4234 void *ctx; 4235 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 4236 COMMON_INTERCEPTOR_USER_CALLBACK_START(); 4237 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 4238 COMMON_INTERCEPTOR_USER_CALLBACK_END(); 4239 if (status == 0) status = status1; 4240 REAL(_exit)(status); 4241} 4242#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit); 4243#else 4244#define INIT__EXIT 4245#endif 4246 4247#if SANITIZER_INTERCEPT_PTHREAD_MUTEX 4248INTERCEPTOR(int, pthread_mutex_lock, void *m) { 4249 void *ctx; 4250 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 4251 COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); 4252 int res = REAL(pthread_mutex_lock)(m); 4253 if (res == errno_EOWNERDEAD) 4254 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 4255 if (res == 0 || res == errno_EOWNERDEAD) 4256 COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); 4257 if (res == errno_EINVAL) 4258 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4259 return res; 4260} 4261 4262INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 4263 void *ctx; 4264 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 4265 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 4266 int res = REAL(pthread_mutex_unlock)(m); 4267 if (res == errno_EINVAL) 4268 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4269 return res; 4270} 4271 4272#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) 4273#define INIT_PTHREAD_MUTEX_UNLOCK \ 4274 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) 4275#else 4276#define INIT_PTHREAD_MUTEX_LOCK 4277#define INIT_PTHREAD_MUTEX_UNLOCK 4278#endif 4279 4280#if SANITIZER_INTERCEPT___PTHREAD_MUTEX 4281INTERCEPTOR(int, __pthread_mutex_lock, void *m) { 4282 void *ctx; 4283 COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_lock, m); 4284 COMMON_INTERCEPTOR_MUTEX_PRE_LOCK(ctx, m); 4285 int res = REAL(__pthread_mutex_lock)(m); 4286 if (res == errno_EOWNERDEAD) 4287 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 4288 if (res == 0 || res == errno_EOWNERDEAD) 4289 COMMON_INTERCEPTOR_MUTEX_POST_LOCK(ctx, m); 4290 if (res == errno_EINVAL) 4291 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4292 return res; 4293} 4294 4295INTERCEPTOR(int, __pthread_mutex_unlock, void *m) { 4296 void *ctx; 4297 COMMON_INTERCEPTOR_ENTER(ctx, __pthread_mutex_unlock, m); 4298 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 4299 int res = REAL(__pthread_mutex_unlock)(m); 4300 if (res == errno_EINVAL) 4301 COMMON_INTERCEPTOR_MUTEX_INVALID(ctx, m); 4302 return res; 4303} 4304 4305#define INIT___PTHREAD_MUTEX_LOCK \ 4306 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock) 4307#define INIT___PTHREAD_MUTEX_UNLOCK \ 4308 COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock) 4309#else 4310#define INIT___PTHREAD_MUTEX_LOCK 4311#define INIT___PTHREAD_MUTEX_UNLOCK 4312#endif 4313 4314#if SANITIZER_INTERCEPT___LIBC_MUTEX 4315INTERCEPTOR(int, __libc_mutex_lock, void *m) 4316ALIAS(WRAPPER_NAME(pthread_mutex_lock)); 4317 4318INTERCEPTOR(int, __libc_mutex_unlock, void *m) 4319ALIAS(WRAPPER_NAME(pthread_mutex_unlock)); 4320 4321INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate) 4322ALIAS(WRAPPER_NAME(pthread_setcancelstate)); 4323 4324#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock) 4325#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock) 4326#define INIT___LIBC_THR_SETCANCELSTATE \ 4327 COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate) 4328#else 4329#define INIT___LIBC_MUTEX_LOCK 4330#define INIT___LIBC_MUTEX_UNLOCK 4331#define INIT___LIBC_THR_SETCANCELSTATE 4332#endif 4333 4334#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 4335static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 4336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 4337 if (mnt->mnt_fsname) 4338 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 4339 REAL(strlen)(mnt->mnt_fsname) + 1); 4340 if (mnt->mnt_dir) 4341 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 4342 REAL(strlen)(mnt->mnt_dir) + 1); 4343 if (mnt->mnt_type) 4344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 4345 REAL(strlen)(mnt->mnt_type) + 1); 4346 if (mnt->mnt_opts) 4347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 4348 REAL(strlen)(mnt->mnt_opts) + 1); 4349} 4350#endif 4351 4352#if SANITIZER_INTERCEPT_GETMNTENT 4353INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 4354 void *ctx; 4355 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 4356 __sanitizer_mntent *res = REAL(getmntent)(fp); 4357 if (res) write_mntent(ctx, res); 4358 return res; 4359} 4360#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent); 4361#else 4362#define INIT_GETMNTENT 4363#endif 4364 4365#if SANITIZER_INTERCEPT_GETMNTENT_R 4366INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 4367 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 4368 void *ctx; 4369 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 4370 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 4371 if (res) write_mntent(ctx, res); 4372 return res; 4373} 4374#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r); 4375#else 4376#define INIT_GETMNTENT_R 4377#endif 4378 4379#if SANITIZER_INTERCEPT_STATFS 4380INTERCEPTOR(int, statfs, char *path, void *buf) { 4381 void *ctx; 4382 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 4383 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4384 // FIXME: under ASan the call below may write to freed memory and corrupt 4385 // its metadata. See 4386 // https://github.com/google/sanitizers/issues/321. 4387 int res = REAL(statfs)(path, buf); 4388 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4389 return res; 4390} 4391INTERCEPTOR(int, fstatfs, int fd, void *buf) { 4392 void *ctx; 4393 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 4394 // FIXME: under ASan the call below may write to freed memory and corrupt 4395 // its metadata. See 4396 // https://github.com/google/sanitizers/issues/321. 4397 int res = REAL(fstatfs)(fd, buf); 4398 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 4399 return res; 4400} 4401#define INIT_STATFS \ 4402 COMMON_INTERCEPT_FUNCTION(statfs); \ 4403 COMMON_INTERCEPT_FUNCTION(fstatfs); 4404#else 4405#define INIT_STATFS 4406#endif 4407 4408#if SANITIZER_INTERCEPT_STATFS64 4409INTERCEPTOR(int, statfs64, char *path, void *buf) { 4410 void *ctx; 4411 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 4412 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4413 // FIXME: under ASan the call below may write to freed memory and corrupt 4414 // its metadata. See 4415 // https://github.com/google/sanitizers/issues/321. 4416 int res = REAL(statfs64)(path, buf); 4417 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4418 return res; 4419} 4420INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 4421 void *ctx; 4422 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 4423 // FIXME: under ASan the call below may write to freed memory and corrupt 4424 // its metadata. See 4425 // https://github.com/google/sanitizers/issues/321. 4426 int res = REAL(fstatfs64)(fd, buf); 4427 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 4428 return res; 4429} 4430#define INIT_STATFS64 \ 4431 COMMON_INTERCEPT_FUNCTION(statfs64); \ 4432 COMMON_INTERCEPT_FUNCTION(fstatfs64); 4433#else 4434#define INIT_STATFS64 4435#endif 4436 4437#if SANITIZER_INTERCEPT_STATVFS 4438INTERCEPTOR(int, statvfs, char *path, void *buf) { 4439 void *ctx; 4440 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 4441 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4442 // FIXME: under ASan the call below may write to freed memory and corrupt 4443 // its metadata. See 4444 // https://github.com/google/sanitizers/issues/321. 4445 int res = REAL(statvfs)(path, buf); 4446 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4447 return res; 4448} 4449INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 4450 void *ctx; 4451 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 4452 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 4453 // FIXME: under ASan the call below may write to freed memory and corrupt 4454 // its metadata. See 4455 // https://github.com/google/sanitizers/issues/321. 4456 int res = REAL(fstatvfs)(fd, buf); 4457 if (!res) { 4458 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 4459 if (fd >= 0) 4460 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 4461 } 4462 return res; 4463} 4464#define INIT_STATVFS \ 4465 COMMON_INTERCEPT_FUNCTION(statvfs); \ 4466 COMMON_INTERCEPT_FUNCTION(fstatvfs); 4467#else 4468#define INIT_STATVFS 4469#endif 4470 4471#if SANITIZER_INTERCEPT_STATVFS64 4472INTERCEPTOR(int, statvfs64, char *path, void *buf) { 4473 void *ctx; 4474 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 4475 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 4476 // FIXME: under ASan the call below may write to freed memory and corrupt 4477 // its metadata. See 4478 // https://github.com/google/sanitizers/issues/321. 4479 int res = REAL(statvfs64)(path, buf); 4480 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4481 return res; 4482} 4483INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 4484 void *ctx; 4485 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 4486 // FIXME: under ASan the call below may write to freed memory and corrupt 4487 // its metadata. See 4488 // https://github.com/google/sanitizers/issues/321. 4489 int res = REAL(fstatvfs64)(fd, buf); 4490 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 4491 return res; 4492} 4493#define INIT_STATVFS64 \ 4494 COMMON_INTERCEPT_FUNCTION(statvfs64); \ 4495 COMMON_INTERCEPT_FUNCTION(fstatvfs64); 4496#else 4497#define INIT_STATVFS64 4498#endif 4499 4500#if SANITIZER_INTERCEPT_INITGROUPS 4501INTERCEPTOR(int, initgroups, char *user, u32 group) { 4502 void *ctx; 4503 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 4504 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 4505 int res = REAL(initgroups)(user, group); 4506 return res; 4507} 4508#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups); 4509#else 4510#define INIT_INITGROUPS 4511#endif 4512 4513#if SANITIZER_INTERCEPT_ETHER_NTOA_ATON 4514INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 4515 void *ctx; 4516 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 4517 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4518 char *res = REAL(ether_ntoa)(addr); 4519 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4520 return res; 4521} 4522INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 4523 void *ctx; 4524 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 4525 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4526 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 4527 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res)); 4528 return res; 4529} 4530#define INIT_ETHER_NTOA_ATON \ 4531 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \ 4532 COMMON_INTERCEPT_FUNCTION(ether_aton); 4533#else 4534#define INIT_ETHER_NTOA_ATON 4535#endif 4536 4537#if SANITIZER_INTERCEPT_ETHER_HOST 4538INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 4539 void *ctx; 4540 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 4541 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4542 // FIXME: under ASan the call below may write to freed memory and corrupt 4543 // its metadata. See 4544 // https://github.com/google/sanitizers/issues/321. 4545 int res = REAL(ether_ntohost)(hostname, addr); 4546 if (!res && hostname) 4547 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4548 return res; 4549} 4550INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 4551 void *ctx; 4552 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 4553 if (hostname) 4554 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 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 int res = REAL(ether_hostton)(hostname, addr); 4559 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4560 return res; 4561} 4562INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 4563 char *hostname) { 4564 void *ctx; 4565 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 4566 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 4567 // FIXME: under ASan the call below may write to freed memory and corrupt 4568 // its metadata. See 4569 // https://github.com/google/sanitizers/issues/321. 4570 int res = REAL(ether_line)(line, addr, hostname); 4571 if (!res) { 4572 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4573 if (hostname) 4574 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 4575 } 4576 return res; 4577} 4578#define INIT_ETHER_HOST \ 4579 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \ 4580 COMMON_INTERCEPT_FUNCTION(ether_hostton); \ 4581 COMMON_INTERCEPT_FUNCTION(ether_line); 4582#else 4583#define INIT_ETHER_HOST 4584#endif 4585 4586#if SANITIZER_INTERCEPT_ETHER_R 4587INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 4588 void *ctx; 4589 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 4590 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 4591 // FIXME: under ASan the call below may write to freed memory and corrupt 4592 // its metadata. See 4593 // https://github.com/google/sanitizers/issues/321. 4594 char *res = REAL(ether_ntoa_r)(addr, buf); 4595 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 4596 return res; 4597} 4598INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 4599 __sanitizer_ether_addr *addr) { 4600 void *ctx; 4601 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 4602 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 4603 // FIXME: under ASan the call below may write to freed memory and corrupt 4604 // its metadata. See 4605 // https://github.com/google/sanitizers/issues/321. 4606 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 4607 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 4608 return res; 4609} 4610#define INIT_ETHER_R \ 4611 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \ 4612 COMMON_INTERCEPT_FUNCTION(ether_aton_r); 4613#else 4614#define INIT_ETHER_R 4615#endif 4616 4617#if SANITIZER_INTERCEPT_SHMCTL 4618INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 4619 void *ctx; 4620 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 4621 // FIXME: under ASan the call below may write to freed memory and corrupt 4622 // its metadata. See 4623 // https://github.com/google/sanitizers/issues/321. 4624 int res = REAL(shmctl)(shmid, cmd, buf); 4625 if (res >= 0) { 4626 unsigned sz = 0; 4627 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 4628 sz = sizeof(__sanitizer_shmid_ds); 4629 else if (cmd == shmctl_ipc_info) 4630 sz = struct_shminfo_sz; 4631 else if (cmd == shmctl_shm_info) 4632 sz = struct_shm_info_sz; 4633 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 4634 } 4635 return res; 4636} 4637#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); 4638#else 4639#define INIT_SHMCTL 4640#endif 4641 4642#if SANITIZER_INTERCEPT_RANDOM_R 4643INTERCEPTOR(int, random_r, void *buf, u32 *result) { 4644 void *ctx; 4645 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 4646 // FIXME: under ASan the call below may write to freed memory and corrupt 4647 // its metadata. See 4648 // https://github.com/google/sanitizers/issues/321. 4649 int res = REAL(random_r)(buf, result); 4650 if (!res && result) 4651 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 4652 return res; 4653} 4654#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r); 4655#else 4656#define INIT_RANDOM_R 4657#endif 4658 4659// FIXME: under ASan the REAL() call below may write to freed memory and corrupt 4660// its metadata. See 4661// https://github.com/google/sanitizers/issues/321. 4662#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 4663 SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \ 4664 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \ 4665 SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \ 4666 SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \ 4667 SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GET || \ 4668 SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GET 4669#define INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(fn, sz) \ 4670 INTERCEPTOR(int, fn, void *attr, void *r) { \ 4671 void *ctx; \ 4672 COMMON_INTERCEPTOR_ENTER(ctx, fn, attr, r); \ 4673 int res = REAL(fn)(attr, r); \ 4674 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 4675 return res; \ 4676 } 4677#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 4678 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_attr_get##what, sz) 4679#define INTERCEPTOR_PTHREAD_MUTEXATTR_GET(what, sz) \ 4680 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_mutexattr_get##what, sz) 4681#define INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(what, sz) \ 4682 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_rwlockattr_get##what, sz) 4683#define INTERCEPTOR_PTHREAD_CONDATTR_GET(what, sz) \ 4684 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_condattr_get##what, sz) 4685#define INTERCEPTOR_PTHREAD_BARRIERATTR_GET(what, sz) \ 4686 INTERCEPTOR_PTHREAD_OBJECT_ATTR_GET(pthread_barrierattr_get##what, sz) 4687#endif 4688 4689#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 4690INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 4691INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 4692INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 4693INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 4694INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 4695 void *ctx; 4696 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 4697 // FIXME: under ASan the call below may write to freed memory and corrupt 4698 // its metadata. See 4699 // https://github.com/google/sanitizers/issues/321. 4700 int res = REAL(pthread_attr_getstack)(attr, addr, size); 4701 if (!res) { 4702 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 4703 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 4704 } 4705 return res; 4706} 4707 4708// We may need to call the real pthread_attr_getstack from the run-time 4709// in sanitizer_common, but we don't want to include the interception headers 4710// there. So, just define this function here. 4711namespace __sanitizer { 4712extern "C" { 4713int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { 4714 return REAL(pthread_attr_getstack)(attr, addr, size); 4715} 4716} // extern "C" 4717} // namespace __sanitizer 4718 4719#define INIT_PTHREAD_ATTR_GET \ 4720 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 4721 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 4722 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ 4723 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 4724 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); 4725#else 4726#define INIT_PTHREAD_ATTR_GET 4727#endif 4728 4729#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED 4730INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 4731INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 4732 4733#define INIT_PTHREAD_ATTR_GET_SCHED \ 4734 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 4735 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); 4736#else 4737#define INIT_PTHREAD_ATTR_GET_SCHED 4738#endif 4739 4740#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 4741INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 4742 4743#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 4744 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 4745#else 4746#define INIT_PTHREAD_ATTR_GETINHERITSCHED 4747#endif 4748 4749#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 4750INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 4751 void *cpuset) { 4752 void *ctx; 4753 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 4754 cpuset); 4755 // FIXME: under ASan the call below may write to freed memory and corrupt 4756 // its metadata. See 4757 // https://github.com/google/sanitizers/issues/321. 4758 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 4759 if (!res && cpusetsize && cpuset) 4760 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 4761 return res; 4762} 4763 4764#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 4765 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 4766#else 4767#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 4768#endif 4769 4770#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED 4771INTERCEPTOR_PTHREAD_MUTEXATTR_GET(pshared, sizeof(int)) 4772#define INIT_PTHREAD_MUTEXATTR_GETPSHARED \ 4773 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getpshared); 4774#else 4775#define INIT_PTHREAD_MUTEXATTR_GETPSHARED 4776#endif 4777 4778#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE 4779INTERCEPTOR_PTHREAD_MUTEXATTR_GET(type, sizeof(int)) 4780#define INIT_PTHREAD_MUTEXATTR_GETTYPE \ 4781 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_gettype); 4782#else 4783#define INIT_PTHREAD_MUTEXATTR_GETTYPE 4784#endif 4785 4786#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL 4787INTERCEPTOR_PTHREAD_MUTEXATTR_GET(protocol, sizeof(int)) 4788#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL \ 4789 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprotocol); 4790#else 4791#define INIT_PTHREAD_MUTEXATTR_GETPROTOCOL 4792#endif 4793 4794#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4795INTERCEPTOR_PTHREAD_MUTEXATTR_GET(prioceiling, sizeof(int)) 4796#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ 4797 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getprioceiling); 4798#else 4799#define INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING 4800#endif 4801 4802#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST 4803INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust, sizeof(int)) 4804#define INIT_PTHREAD_MUTEXATTR_GETROBUST \ 4805 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust); 4806#else 4807#define INIT_PTHREAD_MUTEXATTR_GETROBUST 4808#endif 4809 4810#if SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP 4811INTERCEPTOR_PTHREAD_MUTEXATTR_GET(robust_np, sizeof(int)) 4812#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP \ 4813 COMMON_INTERCEPT_FUNCTION(pthread_mutexattr_getrobust_np); 4814#else 4815#define INIT_PTHREAD_MUTEXATTR_GETROBUST_NP 4816#endif 4817 4818#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED 4819INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(pshared, sizeof(int)) 4820#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED \ 4821 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getpshared); 4822#else 4823#define INIT_PTHREAD_RWLOCKATTR_GETPSHARED 4824#endif 4825 4826#if SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP 4827INTERCEPTOR_PTHREAD_RWLOCKATTR_GET(kind_np, sizeof(int)) 4828#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP \ 4829 COMMON_INTERCEPT_FUNCTION(pthread_rwlockattr_getkind_np); 4830#else 4831#define INIT_PTHREAD_RWLOCKATTR_GETKIND_NP 4832#endif 4833 4834#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED 4835INTERCEPTOR_PTHREAD_CONDATTR_GET(pshared, sizeof(int)) 4836#define INIT_PTHREAD_CONDATTR_GETPSHARED \ 4837 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getpshared); 4838#else 4839#define INIT_PTHREAD_CONDATTR_GETPSHARED 4840#endif 4841 4842#if SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK 4843INTERCEPTOR_PTHREAD_CONDATTR_GET(clock, sizeof(int)) 4844#define INIT_PTHREAD_CONDATTR_GETCLOCK \ 4845 COMMON_INTERCEPT_FUNCTION(pthread_condattr_getclock); 4846#else 4847#define INIT_PTHREAD_CONDATTR_GETCLOCK 4848#endif 4849 4850#if SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED 4851INTERCEPTOR_PTHREAD_BARRIERATTR_GET(pshared, sizeof(int)) // !mac !android 4852#define INIT_PTHREAD_BARRIERATTR_GETPSHARED \ 4853 COMMON_INTERCEPT_FUNCTION(pthread_barrierattr_getpshared); 4854#else 4855#define INIT_PTHREAD_BARRIERATTR_GETPSHARED 4856#endif 4857 4858#if SANITIZER_INTERCEPT_TMPNAM 4859INTERCEPTOR(char *, tmpnam, char *s) { 4860 void *ctx; 4861 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 4862 char *res = REAL(tmpnam)(s); 4863 if (res) { 4864 if (s) 4865 // FIXME: under ASan the call below may write to freed memory and corrupt 4866 // its metadata. See 4867 // https://github.com/google/sanitizers/issues/321. 4868 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4869 else 4870 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4871 } 4872 return res; 4873} 4874#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam); 4875#else 4876#define INIT_TMPNAM 4877#endif 4878 4879#if SANITIZER_INTERCEPT_TMPNAM_R 4880INTERCEPTOR(char *, tmpnam_r, char *s) { 4881 void *ctx; 4882 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 4883 // FIXME: under ASan the call below may write to freed memory and corrupt 4884 // its metadata. See 4885 // https://github.com/google/sanitizers/issues/321. 4886 char *res = REAL(tmpnam_r)(s); 4887 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 4888 return res; 4889} 4890#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); 4891#else 4892#define INIT_TMPNAM_R 4893#endif 4894 4895#if SANITIZER_INTERCEPT_PTSNAME 4896INTERCEPTOR(char *, ptsname, int fd) { 4897 void *ctx; 4898 COMMON_INTERCEPTOR_ENTER(ctx, ptsname, fd); 4899 char *res = REAL(ptsname)(fd); 4900 if (res != nullptr) 4901 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4902 return res; 4903} 4904#define INIT_PTSNAME COMMON_INTERCEPT_FUNCTION(ptsname); 4905#else 4906#define INIT_PTSNAME 4907#endif 4908 4909#if SANITIZER_INTERCEPT_PTSNAME_R 4910INTERCEPTOR(int, ptsname_r, int fd, char *name, SIZE_T namesize) { 4911 void *ctx; 4912 COMMON_INTERCEPTOR_ENTER(ctx, ptsname_r, fd, name, namesize); 4913 int res = REAL(ptsname_r)(fd, name, namesize); 4914 if (res == 0) 4915 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 4916 return res; 4917} 4918#define INIT_PTSNAME_R COMMON_INTERCEPT_FUNCTION(ptsname_r); 4919#else 4920#define INIT_PTSNAME_R 4921#endif 4922 4923#if SANITIZER_INTERCEPT_TTYNAME 4924INTERCEPTOR(char *, ttyname, int fd) { 4925 void *ctx; 4926 COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd); 4927 char *res = REAL(ttyname)(fd); 4928 if (res != nullptr) 4929 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4930 return res; 4931} 4932#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname); 4933#else 4934#define INIT_TTYNAME 4935#endif 4936 4937#if SANITIZER_INTERCEPT_TTYNAME_R 4938INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { 4939 void *ctx; 4940 COMMON_INTERCEPTOR_ENTER(ctx, ttyname_r, fd, name, namesize); 4941 int res = REAL(ttyname_r)(fd, name, namesize); 4942 if (res == 0) 4943 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 4944 return res; 4945} 4946#define INIT_TTYNAME_R COMMON_INTERCEPT_FUNCTION(ttyname_r); 4947#else 4948#define INIT_TTYNAME_R 4949#endif 4950 4951#if SANITIZER_INTERCEPT_TEMPNAM 4952INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 4953 void *ctx; 4954 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 4955 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 4956 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 4957 char *res = REAL(tempnam)(dir, pfx); 4958 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 4959 return res; 4960} 4961#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); 4962#else 4963#define INIT_TEMPNAM 4964#endif 4965 4966#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD 4967INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 4968 void *ctx; 4969 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 4970 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4971 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 4972 return REAL(pthread_setname_np)(thread, name); 4973} 4974#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4975#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD 4976INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) { 4977 void *ctx; 4978 char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32 4979 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg); 4980 COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); 4981 internal_snprintf(newname, sizeof(newname), name, arg); 4982 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname); 4983 return REAL(pthread_setname_np)(thread, name, arg); 4984} 4985#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 4986#else 4987#define INIT_PTHREAD_SETNAME_NP 4988#endif 4989 4990#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP 4991INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) { 4992 void *ctx; 4993 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len); 4994 int res = REAL(pthread_getname_np)(thread, name, len); 4995 if (!res) 4996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1); 4997 return res; 4998} 4999#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np); 5000#else 5001#define INIT_PTHREAD_GETNAME_NP 5002#endif 5003 5004#if SANITIZER_INTERCEPT_SINCOS 5005INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 5006 void *ctx; 5007 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 5008 // FIXME: under ASan the call below may write to freed memory and corrupt 5009 // its metadata. See 5010 // https://github.com/google/sanitizers/issues/321. 5011 REAL(sincos)(x, sin, cos); 5012 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 5013 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 5014} 5015INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 5016 void *ctx; 5017 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 5018 // FIXME: under ASan the call below may write to freed memory and corrupt 5019 // its metadata. See 5020 // https://github.com/google/sanitizers/issues/321. 5021 REAL(sincosf)(x, sin, cos); 5022 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 5023 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 5024} 5025INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 5026 void *ctx; 5027 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 5028 // FIXME: under ASan the call below may write to freed memory and corrupt 5029 // its metadata. See 5030 // https://github.com/google/sanitizers/issues/321. 5031 REAL(sincosl)(x, sin, cos); 5032 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 5033 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 5034} 5035#define INIT_SINCOS \ 5036 COMMON_INTERCEPT_FUNCTION(sincos); \ 5037 COMMON_INTERCEPT_FUNCTION(sincosf); \ 5038 COMMON_INTERCEPT_FUNCTION_LDBL(sincosl); 5039#else 5040#define INIT_SINCOS 5041#endif 5042 5043#if SANITIZER_INTERCEPT_REMQUO 5044INTERCEPTOR(double, remquo, double x, double y, int *quo) { 5045 void *ctx; 5046 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 5047 // FIXME: under ASan the call below may write to freed memory and corrupt 5048 // its metadata. See 5049 // https://github.com/google/sanitizers/issues/321. 5050 double res = REAL(remquo)(x, y, quo); 5051 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 5052 return res; 5053} 5054INTERCEPTOR(float, remquof, float x, float y, int *quo) { 5055 void *ctx; 5056 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 5057 // FIXME: under ASan the call below may write to freed memory and corrupt 5058 // its metadata. See 5059 // https://github.com/google/sanitizers/issues/321. 5060 float res = REAL(remquof)(x, y, quo); 5061 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 5062 return res; 5063} 5064#define INIT_REMQUO \ 5065 COMMON_INTERCEPT_FUNCTION(remquo); \ 5066 COMMON_INTERCEPT_FUNCTION(remquof); 5067#else 5068#define INIT_REMQUO 5069#endif 5070 5071#if SANITIZER_INTERCEPT_REMQUOL 5072INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 5073 void *ctx; 5074 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 5075 // FIXME: under ASan the call below may write to freed memory and corrupt 5076 // its metadata. See 5077 // https://github.com/google/sanitizers/issues/321. 5078 long double res = REAL(remquol)(x, y, quo); 5079 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 5080 return res; 5081} 5082#define INIT_REMQUOL \ 5083 COMMON_INTERCEPT_FUNCTION_LDBL(remquol); 5084#else 5085#define INIT_REMQUOL 5086#endif 5087 5088#if SANITIZER_INTERCEPT_LGAMMA 5089extern int signgam; 5090INTERCEPTOR(double, lgamma, double x) { 5091 void *ctx; 5092 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 5093 double res = REAL(lgamma)(x); 5094 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 5095 return res; 5096} 5097INTERCEPTOR(float, lgammaf, float x) { 5098 void *ctx; 5099 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 5100 float res = REAL(lgammaf)(x); 5101 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 5102 return res; 5103} 5104#define INIT_LGAMMA \ 5105 COMMON_INTERCEPT_FUNCTION(lgamma); \ 5106 COMMON_INTERCEPT_FUNCTION(lgammaf); 5107#else 5108#define INIT_LGAMMA 5109#endif 5110 5111#if SANITIZER_INTERCEPT_LGAMMAL 5112INTERCEPTOR(long double, lgammal, long double x) { 5113 void *ctx; 5114 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 5115 long double res = REAL(lgammal)(x); 5116 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 5117 return res; 5118} 5119#define INIT_LGAMMAL \ 5120 COMMON_INTERCEPT_FUNCTION_LDBL(lgammal); 5121#else 5122#define INIT_LGAMMAL 5123#endif 5124 5125#if SANITIZER_INTERCEPT_LGAMMA_R 5126INTERCEPTOR(double, lgamma_r, double x, int *signp) { 5127 void *ctx; 5128 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 5129 // FIXME: under ASan the call below may write to freed memory and corrupt 5130 // its metadata. See 5131 // https://github.com/google/sanitizers/issues/321. 5132 double res = REAL(lgamma_r)(x, signp); 5133 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 5134 return res; 5135} 5136INTERCEPTOR(float, lgammaf_r, float x, int *signp) { 5137 void *ctx; 5138 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 5139 // FIXME: under ASan the call below may write to freed memory and corrupt 5140 // its metadata. See 5141 // https://github.com/google/sanitizers/issues/321. 5142 float res = REAL(lgammaf_r)(x, signp); 5143 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 5144 return res; 5145} 5146#define INIT_LGAMMA_R \ 5147 COMMON_INTERCEPT_FUNCTION(lgamma_r); \ 5148 COMMON_INTERCEPT_FUNCTION(lgammaf_r); 5149#else 5150#define INIT_LGAMMA_R 5151#endif 5152 5153#if SANITIZER_INTERCEPT_LGAMMAL_R 5154INTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 5155 void *ctx; 5156 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 5157 // FIXME: under ASan the call below may write to freed memory and corrupt 5158 // its metadata. See 5159 // https://github.com/google/sanitizers/issues/321. 5160 long double res = REAL(lgammal_r)(x, signp); 5161 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 5162 return res; 5163} 5164#define INIT_LGAMMAL_R COMMON_INTERCEPT_FUNCTION_LDBL(lgammal_r); 5165#else 5166#define INIT_LGAMMAL_R 5167#endif 5168 5169#if SANITIZER_INTERCEPT_DRAND48_R 5170INTERCEPTOR(int, drand48_r, void *buffer, double *result) { 5171 void *ctx; 5172 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 5173 // FIXME: under ASan the call below may write to freed memory and corrupt 5174 // its metadata. See 5175 // https://github.com/google/sanitizers/issues/321. 5176 int res = REAL(drand48_r)(buffer, result); 5177 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 5178 return res; 5179} 5180INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 5181 void *ctx; 5182 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 5183 // FIXME: under ASan the call below may write to freed memory and corrupt 5184 // its metadata. See 5185 // https://github.com/google/sanitizers/issues/321. 5186 int res = REAL(lrand48_r)(buffer, result); 5187 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 5188 return res; 5189} 5190#define INIT_DRAND48_R \ 5191 COMMON_INTERCEPT_FUNCTION(drand48_r); \ 5192 COMMON_INTERCEPT_FUNCTION(lrand48_r); 5193#else 5194#define INIT_DRAND48_R 5195#endif 5196 5197#if SANITIZER_INTERCEPT_RAND_R 5198INTERCEPTOR(int, rand_r, unsigned *seedp) { 5199 void *ctx; 5200 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp); 5201 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp)); 5202 return REAL(rand_r)(seedp); 5203} 5204#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r); 5205#else 5206#define INIT_RAND_R 5207#endif 5208 5209#if SANITIZER_INTERCEPT_GETLINE 5210INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { 5211 void *ctx; 5212 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); 5213 // FIXME: under ASan the call below may write to freed memory and corrupt 5214 // its metadata. See 5215 // https://github.com/google/sanitizers/issues/321. 5216 SSIZE_T res = REAL(getline)(lineptr, n, stream); 5217 if (res > 0) { 5218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 5219 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 5220 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 5221 } 5222 return res; 5223} 5224 5225// FIXME: under ASan the call below may write to freed memory and corrupt its 5226// metadata. See 5227// https://github.com/google/sanitizers/issues/321. 5228#define GETDELIM_INTERCEPTOR_IMPL(vname) \ 5229 { \ 5230 void *ctx; \ 5231 COMMON_INTERCEPTOR_ENTER(ctx, vname, lineptr, n, delim, stream); \ 5232 SSIZE_T res = REAL(vname)(lineptr, n, delim, stream); \ 5233 if (res > 0) { \ 5234 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); \ 5235 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); \ 5236 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); \ 5237 } \ 5238 return res; \ 5239 } 5240 5241INTERCEPTOR(SSIZE_T, __getdelim, char **lineptr, SIZE_T *n, int delim, 5242 void *stream) 5243GETDELIM_INTERCEPTOR_IMPL(__getdelim) 5244 5245// There's no __getdelim() on FreeBSD so we supply the getdelim() interceptor 5246// with its own body. 5247INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, 5248 void *stream) 5249GETDELIM_INTERCEPTOR_IMPL(getdelim) 5250 5251#define INIT_GETLINE \ 5252 COMMON_INTERCEPT_FUNCTION(getline); \ 5253 COMMON_INTERCEPT_FUNCTION(__getdelim); \ 5254 COMMON_INTERCEPT_FUNCTION(getdelim); 5255#else 5256#define INIT_GETLINE 5257#endif 5258 5259#if SANITIZER_INTERCEPT_ICONV 5260INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft, 5261 char **outbuf, SIZE_T *outbytesleft) { 5262 void *ctx; 5263 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf, 5264 outbytesleft); 5265 if (inbytesleft) 5266 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft)); 5267 if (inbuf && inbytesleft) 5268 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft); 5269 if (outbytesleft) 5270 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft)); 5271 void *outbuf_orig = outbuf ? *outbuf : nullptr; 5272 // FIXME: under ASan the call below may write to freed memory and corrupt 5273 // its metadata. See 5274 // https://github.com/google/sanitizers/issues/321. 5275 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft); 5276 if (outbuf && *outbuf > outbuf_orig) { 5277 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig; 5278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz); 5279 } 5280 return res; 5281} 5282#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv); 5283#else 5284#define INIT_ICONV 5285#endif 5286 5287#if SANITIZER_INTERCEPT_TIMES 5288INTERCEPTOR(__sanitizer_clock_t, times, void *tms) { 5289 void *ctx; 5290 COMMON_INTERCEPTOR_ENTER(ctx, times, tms); 5291 // FIXME: under ASan the call below may write to freed memory and corrupt 5292 // its metadata. See 5293 // https://github.com/google/sanitizers/issues/321. 5294 __sanitizer_clock_t res = REAL(times)(tms); 5295 if (res != (__sanitizer_clock_t)-1 && tms) 5296 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz); 5297 return res; 5298} 5299#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times); 5300#else 5301#define INIT_TIMES 5302#endif 5303 5304#if SANITIZER_INTERCEPT_TLS_GET_ADDR 5305#if !SANITIZER_S390 5306#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr) 5307// If you see any crashes around this functions, there are 2 known issues with 5308// it: 1. __tls_get_addr can be called with mis-aligned stack due to: 5309// https://gcc.gnu.org/bugzilla/show_bug.cgi?id=58066 5310// 2. It can be called recursively if sanitizer code uses __tls_get_addr 5311// to access thread local variables (it should not happen normally, 5312// because sanitizers use initial-exec tls model). 5313INTERCEPTOR(void *, __tls_get_addr, void *arg) { 5314 void *ctx; 5315 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg); 5316 void *res = REAL(__tls_get_addr)(arg); 5317 uptr tls_begin, tls_end; 5318 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5319 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, tls_begin, tls_end); 5320 if (dtv) { 5321 // New DTLS block has been allocated. 5322 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5323 } 5324 return res; 5325} 5326#if SANITIZER_PPC 5327// On PowerPC, we also need to intercept __tls_get_addr_opt, which has 5328// mostly the same semantics as __tls_get_addr, but its presence enables 5329// some optimizations in linker (which are safe to ignore here). 5330extern "C" __attribute__((alias("__interceptor___tls_get_addr"), 5331 visibility("default"))) 5332void *__tls_get_addr_opt(void *arg); 5333#endif 5334#else // SANITIZER_S390 5335// On s390, we have to intercept two functions here: 5336// - __tls_get_addr_internal, which is a glibc-internal function that is like 5337// the usual __tls_get_addr, but returns a TP-relative offset instead of 5338// a proper pointer. It is used by dlsym for TLS symbols. 5339// - __tls_get_offset, which is like the above, but also takes a GOT-relative 5340// descriptor offset as an argument instead of a pointer. GOT address 5341// is passed in r12, so it's necessary to write it in assembly. This is 5342// the function used by the compiler. 5343extern "C" uptr __tls_get_offset_wrapper(void *arg, uptr (*fn)(void *arg)); 5344#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_offset) 5345DEFINE_REAL(uptr, __tls_get_offset, void *arg) 5346extern "C" uptr __tls_get_offset(void *arg); 5347extern "C" uptr __interceptor___tls_get_offset(void *arg); 5348INTERCEPTOR(uptr, __tls_get_addr_internal, void *arg) { 5349 void *ctx; 5350 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr_internal, arg); 5351 uptr res = __tls_get_offset_wrapper(arg, REAL(__tls_get_offset)); 5352 uptr tp = reinterpret_cast<uptr>(__builtin_thread_pointer()); 5353 void *ptr = reinterpret_cast<void *>(res + tp); 5354 uptr tls_begin, tls_end; 5355 COMMON_INTERCEPTOR_GET_TLS_RANGE(&tls_begin, &tls_end); 5356 DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, ptr, tls_begin, tls_end); 5357 if (dtv) { 5358 // New DTLS block has been allocated. 5359 COMMON_INTERCEPTOR_INITIALIZE_RANGE((void *)dtv->beg, dtv->size); 5360 } 5361 return res; 5362} 5363// We need a hidden symbol aliasing the above, so that we can jump 5364// directly to it from the assembly below. 5365extern "C" __attribute__((alias("__interceptor___tls_get_addr_internal"), 5366 visibility("hidden"))) 5367uptr __tls_get_addr_hidden(void *arg); 5368// Now carefully intercept __tls_get_offset. 5369asm( 5370 ".text\n" 5371// The __intercept_ version has to exist, so that gen_dynamic_list.py 5372// exports our symbol. 5373 ".weak __tls_get_offset\n" 5374 ".type __tls_get_offset, @function\n" 5375 "__tls_get_offset:\n" 5376 ".global __interceptor___tls_get_offset\n" 5377 ".type __interceptor___tls_get_offset, @function\n" 5378 "__interceptor___tls_get_offset:\n" 5379#ifdef __s390x__ 5380 "la %r2, 0(%r2,%r12)\n" 5381 "jg __tls_get_addr_hidden\n" 5382#else 5383 "basr %r3,0\n" 5384 "0: la %r2,0(%r2,%r12)\n" 5385 "l %r4,1f-0b(%r3)\n" 5386 "b 0(%r4,%r3)\n" 5387 "1: .long __tls_get_addr_hidden - 0b\n" 5388#endif 5389 ".size __interceptor___tls_get_offset, .-__interceptor___tls_get_offset\n" 5390// Assembly wrapper to call REAL(__tls_get_offset)(arg) 5391 ".type __tls_get_offset_wrapper, @function\n" 5392 "__tls_get_offset_wrapper:\n" 5393#ifdef __s390x__ 5394 "sgr %r2,%r12\n" 5395#else 5396 "sr %r2,%r12\n" 5397#endif 5398 "br %r3\n" 5399 ".size __tls_get_offset_wrapper, .-__tls_get_offset_wrapper\n" 5400); 5401#endif // SANITIZER_S390 5402#else 5403#define INIT_TLS_GET_ADDR 5404#endif 5405 5406#if SANITIZER_INTERCEPT_LISTXATTR 5407INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { 5408 void *ctx; 5409 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size); 5410 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5411 // FIXME: under ASan the call below may write to freed memory and corrupt 5412 // its metadata. See 5413 // https://github.com/google/sanitizers/issues/321. 5414 SSIZE_T res = REAL(listxattr)(path, list, size); 5415 // Here and below, size == 0 is a special case where nothing is written to the 5416 // buffer, and res contains the desired buffer size. 5417 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5418 return res; 5419} 5420INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) { 5421 void *ctx; 5422 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size); 5423 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5424 // FIXME: under ASan the call below may write to freed memory and corrupt 5425 // its metadata. See 5426 // https://github.com/google/sanitizers/issues/321. 5427 SSIZE_T res = REAL(llistxattr)(path, list, size); 5428 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5429 return res; 5430} 5431INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) { 5432 void *ctx; 5433 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size); 5434 // FIXME: under ASan the call below may write to freed memory and corrupt 5435 // its metadata. See 5436 // https://github.com/google/sanitizers/issues/321. 5437 SSIZE_T res = REAL(flistxattr)(fd, list, size); 5438 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 5439 return res; 5440} 5441#define INIT_LISTXATTR \ 5442 COMMON_INTERCEPT_FUNCTION(listxattr); \ 5443 COMMON_INTERCEPT_FUNCTION(llistxattr); \ 5444 COMMON_INTERCEPT_FUNCTION(flistxattr); 5445#else 5446#define INIT_LISTXATTR 5447#endif 5448 5449#if SANITIZER_INTERCEPT_GETXATTR 5450INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value, 5451 SIZE_T size) { 5452 void *ctx; 5453 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size); 5454 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5455 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5456 // FIXME: under ASan the call below may write to freed memory and corrupt 5457 // its metadata. See 5458 // https://github.com/google/sanitizers/issues/321. 5459 SSIZE_T res = REAL(getxattr)(path, name, value, size); 5460 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5461 return res; 5462} 5463INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value, 5464 SIZE_T size) { 5465 void *ctx; 5466 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size); 5467 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 5468 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5469 // FIXME: under ASan the call below may write to freed memory and corrupt 5470 // its metadata. See 5471 // https://github.com/google/sanitizers/issues/321. 5472 SSIZE_T res = REAL(lgetxattr)(path, name, value, size); 5473 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5474 return res; 5475} 5476INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value, 5477 SIZE_T size) { 5478 void *ctx; 5479 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size); 5480 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 5481 // FIXME: under ASan the call below may write to freed memory and corrupt 5482 // its metadata. See 5483 // https://github.com/google/sanitizers/issues/321. 5484 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size); 5485 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 5486 return res; 5487} 5488#define INIT_GETXATTR \ 5489 COMMON_INTERCEPT_FUNCTION(getxattr); \ 5490 COMMON_INTERCEPT_FUNCTION(lgetxattr); \ 5491 COMMON_INTERCEPT_FUNCTION(fgetxattr); 5492#else 5493#define INIT_GETXATTR 5494#endif 5495 5496#if SANITIZER_INTERCEPT_GETRESID 5497INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) { 5498 void *ctx; 5499 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid); 5500 // FIXME: under ASan the call below may write to freed memory and corrupt 5501 // its metadata. See 5502 // https://github.com/google/sanitizers/issues/321. 5503 int res = REAL(getresuid)(ruid, euid, suid); 5504 if (res >= 0) { 5505 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz); 5506 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz); 5507 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz); 5508 } 5509 return res; 5510} 5511INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) { 5512 void *ctx; 5513 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid); 5514 // FIXME: under ASan the call below may write to freed memory and corrupt 5515 // its metadata. See 5516 // https://github.com/google/sanitizers/issues/321. 5517 int res = REAL(getresgid)(rgid, egid, sgid); 5518 if (res >= 0) { 5519 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz); 5520 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz); 5521 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz); 5522 } 5523 return res; 5524} 5525#define INIT_GETRESID \ 5526 COMMON_INTERCEPT_FUNCTION(getresuid); \ 5527 COMMON_INTERCEPT_FUNCTION(getresgid); 5528#else 5529#define INIT_GETRESID 5530#endif 5531 5532#if SANITIZER_INTERCEPT_GETIFADDRS 5533// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to 5534// intercept freeifaddrs(). If that ceases to be the case, we might need to 5535// intercept it to poison the memory again. 5536INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) { 5537 void *ctx; 5538 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap); 5539 // FIXME: under ASan the call below may write to freed memory and corrupt 5540 // its metadata. See 5541 // https://github.com/google/sanitizers/issues/321. 5542 int res = REAL(getifaddrs)(ifap); 5543 if (res == 0 && ifap) { 5544 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *)); 5545 __sanitizer_ifaddrs *p = *ifap; 5546 while (p) { 5547 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs)); 5548 if (p->ifa_name) 5549 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name, 5550 REAL(strlen)(p->ifa_name) + 1); 5551 if (p->ifa_addr) 5552 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz); 5553 if (p->ifa_netmask) 5554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz); 5555 // On Linux this is a union, but the other member also points to a 5556 // struct sockaddr, so the following is sufficient. 5557 if (p->ifa_dstaddr) 5558 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz); 5559 // FIXME(smatveev): Unpoison p->ifa_data as well. 5560 p = p->ifa_next; 5561 } 5562 } 5563 return res; 5564} 5565#define INIT_GETIFADDRS \ 5566 COMMON_INTERCEPT_FUNCTION(getifaddrs); 5567#else 5568#define INIT_GETIFADDRS 5569#endif 5570 5571#if SANITIZER_INTERCEPT_IF_INDEXTONAME 5572INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) { 5573 void *ctx; 5574 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname); 5575 // FIXME: under ASan the call below may write to freed memory and corrupt 5576 // its metadata. See 5577 // https://github.com/google/sanitizers/issues/321. 5578 char *res = REAL(if_indextoname)(ifindex, ifname); 5579 if (res && ifname) 5580 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5581 return res; 5582} 5583INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) { 5584 void *ctx; 5585 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname); 5586 if (ifname) 5587 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 5588 return REAL(if_nametoindex)(ifname); 5589} 5590#define INIT_IF_INDEXTONAME \ 5591 COMMON_INTERCEPT_FUNCTION(if_indextoname); \ 5592 COMMON_INTERCEPT_FUNCTION(if_nametoindex); 5593#else 5594#define INIT_IF_INDEXTONAME 5595#endif 5596 5597#if SANITIZER_INTERCEPT_CAPGET 5598INTERCEPTOR(int, capget, void *hdrp, void *datap) { 5599 void *ctx; 5600 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap); 5601 if (hdrp) 5602 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5603 // FIXME: under ASan the call below may write to freed memory and corrupt 5604 // its metadata. See 5605 // https://github.com/google/sanitizers/issues/321. 5606 int res = REAL(capget)(hdrp, datap); 5607 if (res == 0 && datap) 5608 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz); 5609 // We can also return -1 and write to hdrp->version if the version passed in 5610 // hdrp->version is unsupported. But that's not a trivial condition to check, 5611 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent. 5612 return res; 5613} 5614INTERCEPTOR(int, capset, void *hdrp, const void *datap) { 5615 void *ctx; 5616 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap); 5617 if (hdrp) 5618 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 5619 if (datap) 5620 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz); 5621 return REAL(capset)(hdrp, datap); 5622} 5623#define INIT_CAPGET \ 5624 COMMON_INTERCEPT_FUNCTION(capget); \ 5625 COMMON_INTERCEPT_FUNCTION(capset); 5626#else 5627#define INIT_CAPGET 5628#endif 5629 5630#if SANITIZER_INTERCEPT_AEABI_MEM 5631INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { 5632 void *ctx; 5633 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5634} 5635 5636INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { 5637 void *ctx; 5638 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5639} 5640 5641INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { 5642 void *ctx; 5643 COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size); 5644} 5645 5646INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { 5647 void *ctx; 5648 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5649} 5650 5651INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { 5652 void *ctx; 5653 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5654} 5655 5656INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { 5657 void *ctx; 5658 COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size); 5659} 5660 5661// Note the argument order. 5662INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { 5663 void *ctx; 5664 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5665} 5666 5667INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { 5668 void *ctx; 5669 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5670} 5671 5672INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { 5673 void *ctx; 5674 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size); 5675} 5676 5677INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { 5678 void *ctx; 5679 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5680} 5681 5682INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { 5683 void *ctx; 5684 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5685} 5686 5687INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { 5688 void *ctx; 5689 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5690} 5691 5692#define INIT_AEABI_MEM \ 5693 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \ 5694 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \ 5695 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \ 5696 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \ 5697 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \ 5698 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \ 5699 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \ 5700 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \ 5701 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \ 5702 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \ 5703 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \ 5704 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8); 5705#else 5706#define INIT_AEABI_MEM 5707#endif // SANITIZER_INTERCEPT_AEABI_MEM 5708 5709#if SANITIZER_INTERCEPT___BZERO 5710INTERCEPTOR(void *, __bzero, void *block, uptr size) { 5711 void *ctx; 5712 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5713} 5714#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); 5715#else 5716#define INIT___BZERO 5717#endif // SANITIZER_INTERCEPT___BZERO 5718 5719#if SANITIZER_INTERCEPT_BZERO 5720INTERCEPTOR(void *, bzero, void *block, uptr size) { 5721 void *ctx; 5722 COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); 5723} 5724#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero); 5725#else 5726#define INIT_BZERO 5727#endif // SANITIZER_INTERCEPT_BZERO 5728 5729#if SANITIZER_INTERCEPT_FTIME 5730INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { 5731 void *ctx; 5732 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp); 5733 // FIXME: under ASan the call below may write to freed memory and corrupt 5734 // its metadata. See 5735 // https://github.com/google/sanitizers/issues/321. 5736 int res = REAL(ftime)(tp); 5737 if (tp) 5738 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp)); 5739 return res; 5740} 5741#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime); 5742#else 5743#define INIT_FTIME 5744#endif // SANITIZER_INTERCEPT_FTIME 5745 5746#if SANITIZER_INTERCEPT_XDR 5747INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr, 5748 unsigned size, int op) { 5749 void *ctx; 5750 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op); 5751 // FIXME: under ASan the call below may write to freed memory and corrupt 5752 // its metadata. See 5753 // https://github.com/google/sanitizers/issues/321. 5754 REAL(xdrmem_create)(xdrs, addr, size, op); 5755 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5756 if (op == __sanitizer_XDR_ENCODE) { 5757 // It's not obvious how much data individual xdr_ routines write. 5758 // Simply unpoison the entire target buffer in advance. 5759 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size); 5760 } 5761} 5762 5763INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) { 5764 void *ctx; 5765 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op); 5766 // FIXME: under ASan the call below may write to freed memory and corrupt 5767 // its metadata. See 5768 // https://github.com/google/sanitizers/issues/321. 5769 REAL(xdrstdio_create)(xdrs, file, op); 5770 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 5771} 5772 5773// FIXME: under ASan the call below may write to freed memory and corrupt 5774// its metadata. See 5775// https://github.com/google/sanitizers/issues/321. 5776#define XDR_INTERCEPTOR(F, T) \ 5777 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \ 5778 void *ctx; \ 5779 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \ 5780 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \ 5781 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \ 5782 int res = REAL(F)(xdrs, p); \ 5783 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \ 5784 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \ 5785 return res; \ 5786 } 5787 5788XDR_INTERCEPTOR(xdr_short, short) 5789XDR_INTERCEPTOR(xdr_u_short, unsigned short) 5790XDR_INTERCEPTOR(xdr_int, int) 5791XDR_INTERCEPTOR(xdr_u_int, unsigned) 5792XDR_INTERCEPTOR(xdr_long, long) 5793XDR_INTERCEPTOR(xdr_u_long, unsigned long) 5794XDR_INTERCEPTOR(xdr_hyper, long long) 5795XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long) 5796XDR_INTERCEPTOR(xdr_longlong_t, long long) 5797XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long) 5798XDR_INTERCEPTOR(xdr_int8_t, u8) 5799XDR_INTERCEPTOR(xdr_uint8_t, u8) 5800XDR_INTERCEPTOR(xdr_int16_t, u16) 5801XDR_INTERCEPTOR(xdr_uint16_t, u16) 5802XDR_INTERCEPTOR(xdr_int32_t, u32) 5803XDR_INTERCEPTOR(xdr_uint32_t, u32) 5804XDR_INTERCEPTOR(xdr_int64_t, u64) 5805XDR_INTERCEPTOR(xdr_uint64_t, u64) 5806XDR_INTERCEPTOR(xdr_quad_t, long long) 5807XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long) 5808XDR_INTERCEPTOR(xdr_bool, bool) 5809XDR_INTERCEPTOR(xdr_enum, int) 5810XDR_INTERCEPTOR(xdr_char, char) 5811XDR_INTERCEPTOR(xdr_u_char, unsigned char) 5812XDR_INTERCEPTOR(xdr_float, float) 5813XDR_INTERCEPTOR(xdr_double, double) 5814 5815// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer, 5816// wrapstring, sizeof 5817 5818INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep, 5819 unsigned maxsize) { 5820 void *ctx; 5821 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize); 5822 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5823 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5824 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep)); 5825 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep); 5826 } 5827 // FIXME: under ASan the call below may write to freed memory and corrupt 5828 // its metadata. See 5829 // https://github.com/google/sanitizers/issues/321. 5830 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize); 5831 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) { 5832 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5833 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep)); 5834 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep); 5835 } 5836 return res; 5837} 5838 5839INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, 5840 unsigned maxsize) { 5841 void *ctx; 5842 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize); 5843 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) { 5844 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 5845 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5846 } 5847 // FIXME: under ASan the call below may write to freed memory and corrupt 5848 // its metadata. See 5849 // https://github.com/google/sanitizers/issues/321. 5850 int res = REAL(xdr_string)(xdrs, p, maxsize); 5851 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) { 5852 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 5853 if (res && *p) 5854 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 5855 } 5856 return res; 5857} 5858 5859#define INIT_XDR \ 5860 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \ 5861 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \ 5862 COMMON_INTERCEPT_FUNCTION(xdr_short); \ 5863 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \ 5864 COMMON_INTERCEPT_FUNCTION(xdr_int); \ 5865 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \ 5866 COMMON_INTERCEPT_FUNCTION(xdr_long); \ 5867 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \ 5868 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \ 5869 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \ 5870 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \ 5871 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \ 5872 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \ 5873 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \ 5874 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \ 5875 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \ 5876 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \ 5877 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \ 5878 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \ 5879 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \ 5880 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \ 5881 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \ 5882 COMMON_INTERCEPT_FUNCTION(xdr_bool); \ 5883 COMMON_INTERCEPT_FUNCTION(xdr_enum); \ 5884 COMMON_INTERCEPT_FUNCTION(xdr_char); \ 5885 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \ 5886 COMMON_INTERCEPT_FUNCTION(xdr_float); \ 5887 COMMON_INTERCEPT_FUNCTION(xdr_double); \ 5888 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \ 5889 COMMON_INTERCEPT_FUNCTION(xdr_string); 5890#else 5891#define INIT_XDR 5892#endif // SANITIZER_INTERCEPT_XDR 5893 5894#if SANITIZER_INTERCEPT_XDRREC 5895typedef int (*xdrrec_cb)(char*, char*, int); 5896struct XdrRecWrapper { 5897 char *handle; 5898 xdrrec_cb rd, wr; 5899}; 5900typedef AddrHashMap<XdrRecWrapper *, 11> XdrRecWrapMap; 5901static XdrRecWrapMap *xdrrec_wrap_map; 5902 5903static int xdrrec_wr_wrap(char *handle, char *buf, int count) { 5904 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 5905 COMMON_INTERCEPTOR_INITIALIZE_RANGE(buf, count); 5906 XdrRecWrapper *wrap = (XdrRecWrapper *)handle; 5907 return wrap->wr(wrap->handle, buf, count); 5908} 5909 5910static int xdrrec_rd_wrap(char *handle, char *buf, int count) { 5911 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 5912 XdrRecWrapper *wrap = (XdrRecWrapper *)handle; 5913 return wrap->rd(wrap->handle, buf, count); 5914} 5915 5916// This doesn't apply to the solaris version as it has a different function 5917// signature. 5918INTERCEPTOR(void, xdrrec_create, __sanitizer_XDR *xdr, unsigned sndsize, 5919 unsigned rcvsize, char *handle, int (*rd)(char*, char*, int), 5920 int (*wr)(char*, char*, int)) { 5921 void *ctx; 5922 COMMON_INTERCEPTOR_ENTER(ctx, xdrrec_create, xdr, sndsize, rcvsize, 5923 handle, rd, wr); 5924 COMMON_INTERCEPTOR_READ_RANGE(ctx, &xdr->x_op, sizeof xdr->x_op); 5925 5926 // We can't allocate a wrapper on the stack, as the handle is used outside 5927 // this stack frame. So we put it on the heap, and keep track of it with 5928 // the HashMap (keyed by x_private). When we later need to xdr_destroy, 5929 // we can index the map, free the wrapper, and then clean the map entry. 5930 XdrRecWrapper *wrap_data = 5931 (XdrRecWrapper *)InternalAlloc(sizeof(XdrRecWrapper)); 5932 wrap_data->handle = handle; 5933 wrap_data->rd = rd; 5934 wrap_data->wr = wr; 5935 if (wr) 5936 wr = xdrrec_wr_wrap; 5937 if (rd) 5938 rd = xdrrec_rd_wrap; 5939 handle = (char *)wrap_data; 5940 5941 REAL(xdrrec_create)(xdr, sndsize, rcvsize, handle, rd, wr); 5942 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdr, sizeof *xdr); 5943 5944 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, false, true); 5945 *wrap = wrap_data; 5946} 5947 5948// We have to intercept this to be able to free wrapper memory; 5949// otherwise it's not necessary. 5950INTERCEPTOR(void, xdr_destroy, __sanitizer_XDR *xdr) { 5951 void *ctx; 5952 COMMON_INTERCEPTOR_ENTER(ctx, xdr_destroy, xdr); 5953 5954 XdrRecWrapMap::Handle wrap(xdrrec_wrap_map, xdr->x_private, true); 5955 InternalFree(*wrap); 5956 REAL(xdr_destroy)(xdr); 5957} 5958#define INIT_XDRREC_LINUX \ 5959 static u64 xdrrec_wrap_mem[sizeof(XdrRecWrapMap) / sizeof(u64) + 1]; \ 5960 xdrrec_wrap_map = new ((void *)&xdrrec_wrap_mem) XdrRecWrapMap(); \ 5961 COMMON_INTERCEPT_FUNCTION(xdrrec_create); \ 5962 COMMON_INTERCEPT_FUNCTION(xdr_destroy); 5963#else 5964#define INIT_XDRREC_LINUX 5965#endif 5966 5967#if SANITIZER_INTERCEPT_TSEARCH 5968INTERCEPTOR(void *, tsearch, void *key, void **rootp, 5969 int (*compar)(const void *, const void *)) { 5970 void *ctx; 5971 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar); 5972 // FIXME: under ASan the call below may write to freed memory and corrupt 5973 // its metadata. See 5974 // https://github.com/google/sanitizers/issues/321. 5975 void *res = REAL(tsearch)(key, rootp, compar); 5976 if (res && *(void **)res == key) 5977 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *)); 5978 return res; 5979} 5980#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch); 5981#else 5982#define INIT_TSEARCH 5983#endif 5984 5985#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \ 5986 SANITIZER_INTERCEPT_OPEN_MEMSTREAM 5987void unpoison_file(__sanitizer_FILE *fp) { 5988#if SANITIZER_HAS_STRUCT_FILE 5989 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp)); 5990#if SANITIZER_NETBSD 5991 if (fp->_bf._base && fp->_bf._size > 0) 5992 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base, 5993 fp->_bf._size); 5994#else 5995 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) 5996 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, 5997 fp->_IO_read_end - fp->_IO_read_base); 5998#endif 5999#endif // SANITIZER_HAS_STRUCT_FILE 6000} 6001#endif 6002 6003#if SANITIZER_INTERCEPT_LIBIO_INTERNALS 6004// These guys are called when a .c source is built with -O2. 6005INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) { 6006 void *ctx; 6007 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp); 6008 int res = REAL(__uflow)(fp); 6009 unpoison_file(fp); 6010 return res; 6011} 6012INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) { 6013 void *ctx; 6014 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp); 6015 int res = REAL(__underflow)(fp); 6016 unpoison_file(fp); 6017 return res; 6018} 6019INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) { 6020 void *ctx; 6021 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch); 6022 int res = REAL(__overflow)(fp, ch); 6023 unpoison_file(fp); 6024 return res; 6025} 6026INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) { 6027 void *ctx; 6028 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp); 6029 int res = REAL(__wuflow)(fp); 6030 unpoison_file(fp); 6031 return res; 6032} 6033INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) { 6034 void *ctx; 6035 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp); 6036 int res = REAL(__wunderflow)(fp); 6037 unpoison_file(fp); 6038 return res; 6039} 6040INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) { 6041 void *ctx; 6042 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch); 6043 int res = REAL(__woverflow)(fp, ch); 6044 unpoison_file(fp); 6045 return res; 6046} 6047#define INIT_LIBIO_INTERNALS \ 6048 COMMON_INTERCEPT_FUNCTION(__uflow); \ 6049 COMMON_INTERCEPT_FUNCTION(__underflow); \ 6050 COMMON_INTERCEPT_FUNCTION(__overflow); \ 6051 COMMON_INTERCEPT_FUNCTION(__wuflow); \ 6052 COMMON_INTERCEPT_FUNCTION(__wunderflow); \ 6053 COMMON_INTERCEPT_FUNCTION(__woverflow); 6054#else 6055#define INIT_LIBIO_INTERNALS 6056#endif 6057 6058#if SANITIZER_INTERCEPT_FOPEN 6059INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { 6060 void *ctx; 6061 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode); 6062 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6063 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 6064 __sanitizer_FILE *res = REAL(fopen)(path, mode); 6065 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 6066 if (res) unpoison_file(res); 6067 return res; 6068} 6069INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) { 6070 void *ctx; 6071 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode); 6072 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 6073 __sanitizer_FILE *res = REAL(fdopen)(fd, mode); 6074 if (res) unpoison_file(res); 6075 return res; 6076} 6077INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode, 6078 __sanitizer_FILE *fp) { 6079 void *ctx; 6080 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp); 6081 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6082 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 6083 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 6084 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp); 6085 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 6086 if (res) unpoison_file(res); 6087 return res; 6088} 6089#define INIT_FOPEN \ 6090 COMMON_INTERCEPT_FUNCTION(fopen); \ 6091 COMMON_INTERCEPT_FUNCTION(fdopen); \ 6092 COMMON_INTERCEPT_FUNCTION(freopen); 6093#else 6094#define INIT_FOPEN 6095#endif 6096 6097#if SANITIZER_INTERCEPT_FOPEN64 6098INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) { 6099 void *ctx; 6100 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode); 6101 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6102 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 6103 __sanitizer_FILE *res = REAL(fopen64)(path, mode); 6104 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 6105 if (res) unpoison_file(res); 6106 return res; 6107} 6108INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode, 6109 __sanitizer_FILE *fp) { 6110 void *ctx; 6111 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp); 6112 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 6113 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 6114 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 6115 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp); 6116 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 6117 if (res) unpoison_file(res); 6118 return res; 6119} 6120#define INIT_FOPEN64 \ 6121 COMMON_INTERCEPT_FUNCTION(fopen64); \ 6122 COMMON_INTERCEPT_FUNCTION(freopen64); 6123#else 6124#define INIT_FOPEN64 6125#endif 6126 6127#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM 6128INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) { 6129 void *ctx; 6130 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc); 6131 // FIXME: under ASan the call below may write to freed memory and corrupt 6132 // its metadata. See 6133 // https://github.com/google/sanitizers/issues/321. 6134 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc); 6135 if (res) { 6136 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 6137 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 6138 unpoison_file(res); 6139 FileMetadata file = {ptr, sizeloc}; 6140 SetInterceptorMetadata(res, file); 6141 } 6142 return res; 6143} 6144INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr, 6145 SIZE_T *sizeloc) { 6146 void *ctx; 6147 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc); 6148 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc); 6149 if (res) { 6150 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 6151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 6152 unpoison_file(res); 6153 FileMetadata file = {(char **)ptr, sizeloc}; 6154 SetInterceptorMetadata(res, file); 6155 } 6156 return res; 6157} 6158INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size, 6159 const char *mode) { 6160 void *ctx; 6161 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode); 6162 // FIXME: under ASan the call below may write to freed memory and corrupt 6163 // its metadata. See 6164 // https://github.com/google/sanitizers/issues/321. 6165 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode); 6166 if (res) unpoison_file(res); 6167 return res; 6168} 6169#define INIT_OPEN_MEMSTREAM \ 6170 COMMON_INTERCEPT_FUNCTION(open_memstream); \ 6171 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \ 6172 COMMON_INTERCEPT_FUNCTION(fmemopen); 6173#else 6174#define INIT_OPEN_MEMSTREAM 6175#endif 6176 6177#if SANITIZER_INTERCEPT_OBSTACK 6178static void initialize_obstack(__sanitizer_obstack *obstack) { 6179 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack)); 6180 if (obstack->chunk) 6181 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk, 6182 sizeof(*obstack->chunk)); 6183} 6184 6185INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz, 6186 int align, void *(*alloc_fn)(uptr arg, uptr sz), 6187 void (*free_fn)(uptr arg, void *p)) { 6188 void *ctx; 6189 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn, 6190 free_fn); 6191 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn); 6192 if (res) initialize_obstack(obstack); 6193 return res; 6194} 6195INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz, 6196 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) { 6197 void *ctx; 6198 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn, 6199 free_fn); 6200 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn); 6201 if (res) initialize_obstack(obstack); 6202 return res; 6203} 6204INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) { 6205 void *ctx; 6206 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length); 6207 REAL(_obstack_newchunk)(obstack, length); 6208 if (obstack->chunk) 6209 COMMON_INTERCEPTOR_INITIALIZE_RANGE( 6210 obstack->chunk, obstack->next_free - (char *)obstack->chunk); 6211} 6212#define INIT_OBSTACK \ 6213 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \ 6214 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \ 6215 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk); 6216#else 6217#define INIT_OBSTACK 6218#endif 6219 6220#if SANITIZER_INTERCEPT_FFLUSH 6221INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) { 6222 void *ctx; 6223 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp); 6224 int res = REAL(fflush)(fp); 6225 // FIXME: handle fp == NULL 6226 if (fp) { 6227 const FileMetadata *m = GetInterceptorMetadata(fp); 6228 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 6229 } 6230 return res; 6231} 6232#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush); 6233#else 6234#define INIT_FFLUSH 6235#endif 6236 6237#if SANITIZER_INTERCEPT_FCLOSE 6238INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) { 6239 void *ctx; 6240 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp); 6241 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 6242 const FileMetadata *m = GetInterceptorMetadata(fp); 6243 int res = REAL(fclose)(fp); 6244 if (m) { 6245 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 6246 DeleteInterceptorMetadata(fp); 6247 } 6248 return res; 6249} 6250#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose); 6251#else 6252#define INIT_FCLOSE 6253#endif 6254 6255#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE 6256INTERCEPTOR(void*, dlopen, const char *filename, int flag) { 6257 void *ctx; 6258 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); 6259 if (filename) COMMON_INTERCEPTOR_READ_STRING(ctx, filename, 0); 6260 COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag); 6261 void *res = REAL(dlopen)(filename, flag); 6262 Symbolizer::GetOrInit()->InvalidateModuleList(); 6263 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); 6264 return res; 6265} 6266 6267INTERCEPTOR(int, dlclose, void *handle) { 6268 void *ctx; 6269 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); 6270 int res = REAL(dlclose)(handle); 6271 Symbolizer::GetOrInit()->InvalidateModuleList(); 6272 COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); 6273 return res; 6274} 6275#define INIT_DLOPEN_DLCLOSE \ 6276 COMMON_INTERCEPT_FUNCTION(dlopen); \ 6277 COMMON_INTERCEPT_FUNCTION(dlclose); 6278#else 6279#define INIT_DLOPEN_DLCLOSE 6280#endif 6281 6282#if SANITIZER_INTERCEPT_GETPASS 6283INTERCEPTOR(char *, getpass, const char *prompt) { 6284 void *ctx; 6285 COMMON_INTERCEPTOR_ENTER(ctx, getpass, prompt); 6286 if (prompt) 6287 COMMON_INTERCEPTOR_READ_RANGE(ctx, prompt, REAL(strlen)(prompt)+1); 6288 char *res = REAL(getpass)(prompt); 6289 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res)+1); 6290 return res; 6291} 6292 6293#define INIT_GETPASS COMMON_INTERCEPT_FUNCTION(getpass); 6294#else 6295#define INIT_GETPASS 6296#endif 6297 6298#if SANITIZER_INTERCEPT_TIMERFD 6299INTERCEPTOR(int, timerfd_settime, int fd, int flags, void *new_value, 6300 void *old_value) { 6301 void *ctx; 6302 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_settime, fd, flags, new_value, 6303 old_value); 6304 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerspec_sz); 6305 int res = REAL(timerfd_settime)(fd, flags, new_value, old_value); 6306 if (res != -1 && old_value) 6307 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerspec_sz); 6308 return res; 6309} 6310 6311INTERCEPTOR(int, timerfd_gettime, int fd, void *curr_value) { 6312 void *ctx; 6313 COMMON_INTERCEPTOR_ENTER(ctx, timerfd_gettime, fd, curr_value); 6314 int res = REAL(timerfd_gettime)(fd, curr_value); 6315 if (res != -1 && curr_value) 6316 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerspec_sz); 6317 return res; 6318} 6319#define INIT_TIMERFD \ 6320 COMMON_INTERCEPT_FUNCTION(timerfd_settime); \ 6321 COMMON_INTERCEPT_FUNCTION(timerfd_gettime); 6322#else 6323#define INIT_TIMERFD 6324#endif 6325 6326#if SANITIZER_INTERCEPT_MLOCKX 6327// Linux kernel has a bug that leads to kernel deadlock if a process 6328// maps TBs of memory and then calls mlock(). 6329static void MlockIsUnsupported() { 6330 static atomic_uint8_t printed; 6331 if (atomic_exchange(&printed, 1, memory_order_relaxed)) 6332 return; 6333 VPrintf(1, "%s ignores mlock/mlockall/munlock/munlockall\n", 6334 SanitizerToolName); 6335} 6336 6337INTERCEPTOR(int, mlock, const void *addr, uptr len) { 6338 MlockIsUnsupported(); 6339 return 0; 6340} 6341 6342INTERCEPTOR(int, munlock, const void *addr, uptr len) { 6343 MlockIsUnsupported(); 6344 return 0; 6345} 6346 6347INTERCEPTOR(int, mlockall, int flags) { 6348 MlockIsUnsupported(); 6349 return 0; 6350} 6351 6352INTERCEPTOR(int, munlockall, void) { 6353 MlockIsUnsupported(); 6354 return 0; 6355} 6356 6357#define INIT_MLOCKX \ 6358 COMMON_INTERCEPT_FUNCTION(mlock); \ 6359 COMMON_INTERCEPT_FUNCTION(munlock); \ 6360 COMMON_INTERCEPT_FUNCTION(mlockall); \ 6361 COMMON_INTERCEPT_FUNCTION(munlockall); 6362 6363#else 6364#define INIT_MLOCKX 6365#endif // SANITIZER_INTERCEPT_MLOCKX 6366 6367#if SANITIZER_INTERCEPT_FOPENCOOKIE 6368struct WrappedCookie { 6369 void *real_cookie; 6370 __sanitizer_cookie_io_functions_t real_io_funcs; 6371}; 6372 6373static uptr wrapped_read(void *cookie, char *buf, uptr size) { 6374 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6375 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6376 __sanitizer_cookie_io_read real_read = wrapped_cookie->real_io_funcs.read; 6377 return real_read ? real_read(wrapped_cookie->real_cookie, buf, size) : 0; 6378} 6379 6380static uptr wrapped_write(void *cookie, const char *buf, uptr size) { 6381 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6382 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6383 __sanitizer_cookie_io_write real_write = wrapped_cookie->real_io_funcs.write; 6384 return real_write ? real_write(wrapped_cookie->real_cookie, buf, size) : size; 6385} 6386 6387static int wrapped_seek(void *cookie, u64 *offset, int whence) { 6388 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 6389 COMMON_INTERCEPTOR_INITIALIZE_RANGE(offset, sizeof(*offset)); 6390 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6391 __sanitizer_cookie_io_seek real_seek = wrapped_cookie->real_io_funcs.seek; 6392 return real_seek ? real_seek(wrapped_cookie->real_cookie, offset, whence) 6393 : -1; 6394} 6395 6396static int wrapped_close(void *cookie) { 6397 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 6398 WrappedCookie *wrapped_cookie = (WrappedCookie *)cookie; 6399 __sanitizer_cookie_io_close real_close = wrapped_cookie->real_io_funcs.close; 6400 int res = real_close ? real_close(wrapped_cookie->real_cookie) : 0; 6401 InternalFree(wrapped_cookie); 6402 return res; 6403} 6404 6405INTERCEPTOR(__sanitizer_FILE *, fopencookie, void *cookie, const char *mode, 6406 __sanitizer_cookie_io_functions_t io_funcs) { 6407 void *ctx; 6408 COMMON_INTERCEPTOR_ENTER(ctx, fopencookie, cookie, mode, io_funcs); 6409 WrappedCookie *wrapped_cookie = 6410 (WrappedCookie *)InternalAlloc(sizeof(WrappedCookie)); 6411 wrapped_cookie->real_cookie = cookie; 6412 wrapped_cookie->real_io_funcs = io_funcs; 6413 __sanitizer_FILE *res = 6414 REAL(fopencookie)(wrapped_cookie, mode, {wrapped_read, wrapped_write, 6415 wrapped_seek, wrapped_close}); 6416 return res; 6417} 6418 6419#define INIT_FOPENCOOKIE COMMON_INTERCEPT_FUNCTION(fopencookie); 6420#else 6421#define INIT_FOPENCOOKIE 6422#endif // SANITIZER_INTERCEPT_FOPENCOOKIE 6423 6424#if SANITIZER_INTERCEPT_SEM 6425INTERCEPTOR(int, sem_init, __sanitizer_sem_t *s, int pshared, unsigned value) { 6426 void *ctx; 6427 COMMON_INTERCEPTOR_ENTER(ctx, sem_init, s, pshared, value); 6428 // Workaround a bug in glibc's "old" semaphore implementation by 6429 // zero-initializing the sem_t contents. This has to be done here because 6430 // interceptors bind to the lowest symbols version by default, hitting the 6431 // buggy code path while the non-sanitized build of the same code works fine. 6432 REAL(memset)(s, 0, sizeof(*s)); 6433 int res = REAL(sem_init)(s, pshared, value); 6434 return res; 6435} 6436 6437INTERCEPTOR(int, sem_destroy, __sanitizer_sem_t *s) { 6438 void *ctx; 6439 COMMON_INTERCEPTOR_ENTER(ctx, sem_destroy, s); 6440 int res = REAL(sem_destroy)(s); 6441 return res; 6442} 6443 6444INTERCEPTOR(int, sem_wait, __sanitizer_sem_t *s) { 6445 void *ctx; 6446 COMMON_INTERCEPTOR_ENTER(ctx, sem_wait, s); 6447 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_wait)(s); 6448 if (res == 0) { 6449 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6450 } 6451 return res; 6452} 6453 6454INTERCEPTOR(int, sem_trywait, __sanitizer_sem_t *s) { 6455 void *ctx; 6456 COMMON_INTERCEPTOR_ENTER(ctx, sem_trywait, s); 6457 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_trywait)(s); 6458 if (res == 0) { 6459 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6460 } 6461 return res; 6462} 6463 6464INTERCEPTOR(int, sem_timedwait, __sanitizer_sem_t *s, void *abstime) { 6465 void *ctx; 6466 COMMON_INTERCEPTOR_ENTER(ctx, sem_timedwait, s, abstime); 6467 COMMON_INTERCEPTOR_READ_RANGE(ctx, abstime, struct_timespec_sz); 6468 int res = COMMON_INTERCEPTOR_BLOCK_REAL(sem_timedwait)(s, abstime); 6469 if (res == 0) { 6470 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6471 } 6472 return res; 6473} 6474 6475INTERCEPTOR(int, sem_post, __sanitizer_sem_t *s) { 6476 void *ctx; 6477 COMMON_INTERCEPTOR_ENTER(ctx, sem_post, s); 6478 COMMON_INTERCEPTOR_RELEASE(ctx, (uptr)s); 6479 int res = REAL(sem_post)(s); 6480 return res; 6481} 6482 6483INTERCEPTOR(int, sem_getvalue, __sanitizer_sem_t *s, int *sval) { 6484 void *ctx; 6485 COMMON_INTERCEPTOR_ENTER(ctx, sem_getvalue, s, sval); 6486 int res = REAL(sem_getvalue)(s, sval); 6487 if (res == 0) { 6488 COMMON_INTERCEPTOR_ACQUIRE(ctx, (uptr)s); 6489 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sval, sizeof(*sval)); 6490 } 6491 return res; 6492} 6493#define INIT_SEM \ 6494 COMMON_INTERCEPT_FUNCTION(sem_init); \ 6495 COMMON_INTERCEPT_FUNCTION(sem_destroy); \ 6496 COMMON_INTERCEPT_FUNCTION(sem_wait); \ 6497 COMMON_INTERCEPT_FUNCTION(sem_trywait); \ 6498 COMMON_INTERCEPT_FUNCTION(sem_timedwait); \ 6499 COMMON_INTERCEPT_FUNCTION(sem_post); \ 6500 COMMON_INTERCEPT_FUNCTION(sem_getvalue); 6501#else 6502#define INIT_SEM 6503#endif // SANITIZER_INTERCEPT_SEM 6504 6505#if SANITIZER_INTERCEPT_PTHREAD_SETCANCEL 6506INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { 6507 void *ctx; 6508 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); 6509 int res = REAL(pthread_setcancelstate)(state, oldstate); 6510 if (res == 0 && oldstate != nullptr) 6511 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); 6512 return res; 6513} 6514 6515INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { 6516 void *ctx; 6517 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); 6518 int res = REAL(pthread_setcanceltype)(type, oldtype); 6519 if (res == 0 && oldtype != nullptr) 6520 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); 6521 return res; 6522} 6523#define INIT_PTHREAD_SETCANCEL \ 6524 COMMON_INTERCEPT_FUNCTION(pthread_setcancelstate); \ 6525 COMMON_INTERCEPT_FUNCTION(pthread_setcanceltype); 6526#else 6527#define INIT_PTHREAD_SETCANCEL 6528#endif 6529 6530#if SANITIZER_INTERCEPT_MINCORE 6531INTERCEPTOR(int, mincore, void *addr, uptr length, unsigned char *vec) { 6532 void *ctx; 6533 COMMON_INTERCEPTOR_ENTER(ctx, mincore, addr, length, vec); 6534 int res = REAL(mincore)(addr, length, vec); 6535 if (res == 0) { 6536 uptr page_size = GetPageSizeCached(); 6537 uptr vec_size = ((length + page_size - 1) & (~(page_size - 1))) / page_size; 6538 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, vec, vec_size); 6539 } 6540 return res; 6541} 6542#define INIT_MINCORE COMMON_INTERCEPT_FUNCTION(mincore); 6543#else 6544#define INIT_MINCORE 6545#endif 6546 6547#if SANITIZER_INTERCEPT_PROCESS_VM_READV 6548INTERCEPTOR(SSIZE_T, process_vm_readv, int pid, __sanitizer_iovec *local_iov, 6549 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6550 uptr flags) { 6551 void *ctx; 6552 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_readv, pid, local_iov, liovcnt, 6553 remote_iov, riovcnt, flags); 6554 SSIZE_T res = REAL(process_vm_readv)(pid, local_iov, liovcnt, remote_iov, 6555 riovcnt, flags); 6556 if (res > 0) 6557 write_iovec(ctx, local_iov, liovcnt, res); 6558 return res; 6559} 6560 6561INTERCEPTOR(SSIZE_T, process_vm_writev, int pid, __sanitizer_iovec *local_iov, 6562 uptr liovcnt, __sanitizer_iovec *remote_iov, uptr riovcnt, 6563 uptr flags) { 6564 void *ctx; 6565 COMMON_INTERCEPTOR_ENTER(ctx, process_vm_writev, pid, local_iov, liovcnt, 6566 remote_iov, riovcnt, flags); 6567 SSIZE_T res = REAL(process_vm_writev)(pid, local_iov, liovcnt, remote_iov, 6568 riovcnt, flags); 6569 if (res > 0) 6570 read_iovec(ctx, local_iov, liovcnt, res); 6571 return res; 6572} 6573#define INIT_PROCESS_VM_READV \ 6574 COMMON_INTERCEPT_FUNCTION(process_vm_readv); \ 6575 COMMON_INTERCEPT_FUNCTION(process_vm_writev); 6576#else 6577#define INIT_PROCESS_VM_READV 6578#endif 6579 6580#if SANITIZER_INTERCEPT_CTERMID 6581INTERCEPTOR(char *, ctermid, char *s) { 6582 void *ctx; 6583 COMMON_INTERCEPTOR_ENTER(ctx, ctermid, s); 6584 char *res = REAL(ctermid)(s); 6585 if (res) { 6586 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6587 } 6588 return res; 6589} 6590#define INIT_CTERMID COMMON_INTERCEPT_FUNCTION(ctermid); 6591#else 6592#define INIT_CTERMID 6593#endif 6594 6595#if SANITIZER_INTERCEPT_CTERMID_R 6596INTERCEPTOR(char *, ctermid_r, char *s) { 6597 void *ctx; 6598 COMMON_INTERCEPTOR_ENTER(ctx, ctermid_r, s); 6599 char *res = REAL(ctermid_r)(s); 6600 if (res) { 6601 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 6602 } 6603 return res; 6604} 6605#define INIT_CTERMID_R COMMON_INTERCEPT_FUNCTION(ctermid_r); 6606#else 6607#define INIT_CTERMID_R 6608#endif 6609 6610#if SANITIZER_INTERCEPT_RECV_RECVFROM 6611INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { 6612 void *ctx; 6613 COMMON_INTERCEPTOR_ENTER(ctx, recv, fd, buf, len, flags); 6614 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6615 SSIZE_T res = REAL(recv)(fd, buf, len, flags); 6616 if (res > 0) { 6617 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6618 } 6619 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6620 return res; 6621} 6622 6623INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, 6624 void *srcaddr, int *addrlen) { 6625 void *ctx; 6626 COMMON_INTERCEPTOR_ENTER(ctx, recvfrom, fd, buf, len, flags, srcaddr, 6627 addrlen); 6628 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6629 SIZE_T srcaddr_sz; 6630 if (srcaddr) srcaddr_sz = *addrlen; 6631 (void)srcaddr_sz; // prevent "set but not used" warning 6632 SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); 6633 if (res > 0) 6634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6635 if (res >= 0 && srcaddr) 6636 COMMON_INTERCEPTOR_INITIALIZE_RANGE(srcaddr, 6637 Min((SIZE_T)*addrlen, srcaddr_sz)); 6638 return res; 6639} 6640#define INIT_RECV_RECVFROM \ 6641 COMMON_INTERCEPT_FUNCTION(recv); \ 6642 COMMON_INTERCEPT_FUNCTION(recvfrom); 6643#else 6644#define INIT_RECV_RECVFROM 6645#endif 6646 6647#if SANITIZER_INTERCEPT_SEND_SENDTO 6648INTERCEPTOR(SSIZE_T, send, int fd, void *buf, SIZE_T len, int flags) { 6649 void *ctx; 6650 COMMON_INTERCEPTOR_ENTER(ctx, send, fd, buf, len, flags); 6651 if (fd >= 0) { 6652 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6653 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6654 } 6655 SSIZE_T res = REAL(send)(fd, buf, len, flags); 6656 if (common_flags()->intercept_send && res > 0) 6657 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6658 return res; 6659} 6660 6661INTERCEPTOR(SSIZE_T, sendto, int fd, void *buf, SIZE_T len, int flags, 6662 void *dstaddr, int addrlen) { 6663 void *ctx; 6664 COMMON_INTERCEPTOR_ENTER(ctx, sendto, fd, buf, len, flags, dstaddr, addrlen); 6665 if (fd >= 0) { 6666 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6667 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6668 } 6669 // Can't check dstaddr as it may have uninitialized padding at the end. 6670 SSIZE_T res = REAL(sendto)(fd, buf, len, flags, dstaddr, addrlen); 6671 if (common_flags()->intercept_send && res > 0) 6672 COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, Min((SIZE_T)res, len)); 6673 return res; 6674} 6675#define INIT_SEND_SENDTO \ 6676 COMMON_INTERCEPT_FUNCTION(send); \ 6677 COMMON_INTERCEPT_FUNCTION(sendto); 6678#else 6679#define INIT_SEND_SENDTO 6680#endif 6681 6682#if SANITIZER_INTERCEPT_EVENTFD_READ_WRITE 6683INTERCEPTOR(int, eventfd_read, int fd, u64 *value) { 6684 void *ctx; 6685 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_read, fd, value); 6686 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6687 int res = REAL(eventfd_read)(fd, value); 6688 if (res == 0) { 6689 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, sizeof(*value)); 6690 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 6691 } 6692 return res; 6693} 6694INTERCEPTOR(int, eventfd_write, int fd, u64 value) { 6695 void *ctx; 6696 COMMON_INTERCEPTOR_ENTER(ctx, eventfd_write, fd, value); 6697 if (fd >= 0) { 6698 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 6699 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 6700 } 6701 int res = REAL(eventfd_write)(fd, value); 6702 return res; 6703} 6704#define INIT_EVENTFD_READ_WRITE \ 6705 COMMON_INTERCEPT_FUNCTION(eventfd_read); \ 6706 COMMON_INTERCEPT_FUNCTION(eventfd_write) 6707#else 6708#define INIT_EVENTFD_READ_WRITE 6709#endif 6710 6711#if SANITIZER_INTERCEPT_STAT 6712INTERCEPTOR(int, stat, const char *path, void *buf) { 6713 void *ctx; 6714 COMMON_INTERCEPTOR_ENTER(ctx, stat, path, buf); 6715 if (common_flags()->intercept_stat) 6716 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6717 int res = REAL(stat)(path, buf); 6718 if (!res) 6719 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6720 return res; 6721} 6722#define INIT_STAT COMMON_INTERCEPT_FUNCTION(stat) 6723#else 6724#define INIT_STAT 6725#endif 6726 6727#if SANITIZER_INTERCEPT_LSTAT 6728INTERCEPTOR(int, lstat, const char *path, void *buf) { 6729 void *ctx; 6730 COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf); 6731 if (common_flags()->intercept_stat) 6732 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6733 int res = REAL(lstat)(path, buf); 6734 if (!res) 6735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6736 return res; 6737} 6738#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat) 6739#else 6740#define INIT_LSTAT 6741#endif 6742 6743#if SANITIZER_INTERCEPT___XSTAT 6744INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { 6745 void *ctx; 6746 COMMON_INTERCEPTOR_ENTER(ctx, __xstat, version, path, buf); 6747 if (common_flags()->intercept_stat) 6748 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6749 int res = REAL(__xstat)(version, path, buf); 6750 if (!res) 6751 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6752 return res; 6753} 6754#define INIT___XSTAT COMMON_INTERCEPT_FUNCTION(__xstat) 6755#else 6756#define INIT___XSTAT 6757#endif 6758 6759#if SANITIZER_INTERCEPT___XSTAT64 6760INTERCEPTOR(int, __xstat64, int version, const char *path, void *buf) { 6761 void *ctx; 6762 COMMON_INTERCEPTOR_ENTER(ctx, __xstat64, version, path, buf); 6763 if (common_flags()->intercept_stat) 6764 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6765 int res = REAL(__xstat64)(version, path, buf); 6766 if (!res) 6767 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6768 return res; 6769} 6770#define INIT___XSTAT64 COMMON_INTERCEPT_FUNCTION(__xstat64) 6771#else 6772#define INIT___XSTAT64 6773#endif 6774 6775#if SANITIZER_INTERCEPT___LXSTAT 6776INTERCEPTOR(int, __lxstat, int version, const char *path, void *buf) { 6777 void *ctx; 6778 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat, version, path, buf); 6779 if (common_flags()->intercept_stat) 6780 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6781 int res = REAL(__lxstat)(version, path, buf); 6782 if (!res) 6783 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); 6784 return res; 6785} 6786#define INIT___LXSTAT COMMON_INTERCEPT_FUNCTION(__lxstat) 6787#else 6788#define INIT___LXSTAT 6789#endif 6790 6791#if SANITIZER_INTERCEPT___LXSTAT64 6792INTERCEPTOR(int, __lxstat64, int version, const char *path, void *buf) { 6793 void *ctx; 6794 COMMON_INTERCEPTOR_ENTER(ctx, __lxstat64, version, path, buf); 6795 if (common_flags()->intercept_stat) 6796 COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); 6797 int res = REAL(__lxstat64)(version, path, buf); 6798 if (!res) 6799 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat64_sz); 6800 return res; 6801} 6802#define INIT___LXSTAT64 COMMON_INTERCEPT_FUNCTION(__lxstat64) 6803#else 6804#define INIT___LXSTAT64 6805#endif 6806 6807// FIXME: add other *stat interceptor 6808 6809#if SANITIZER_INTERCEPT_UTMP 6810INTERCEPTOR(void *, getutent, int dummy) { 6811 void *ctx; 6812 COMMON_INTERCEPTOR_ENTER(ctx, getutent, dummy); 6813 void *res = REAL(getutent)(dummy); 6814 if (res) 6815 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6816 return res; 6817} 6818INTERCEPTOR(void *, getutid, void *ut) { 6819 void *ctx; 6820 COMMON_INTERCEPTOR_ENTER(ctx, getutid, ut); 6821 void *res = REAL(getutid)(ut); 6822 if (res) 6823 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6824 return res; 6825} 6826INTERCEPTOR(void *, getutline, void *ut) { 6827 void *ctx; 6828 COMMON_INTERCEPTOR_ENTER(ctx, getutline, ut); 6829 void *res = REAL(getutline)(ut); 6830 if (res) 6831 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmp_sz); 6832 return res; 6833} 6834#define INIT_UTMP \ 6835 COMMON_INTERCEPT_FUNCTION(getutent); \ 6836 COMMON_INTERCEPT_FUNCTION(getutid); \ 6837 COMMON_INTERCEPT_FUNCTION(getutline); 6838#else 6839#define INIT_UTMP 6840#endif 6841 6842#if SANITIZER_INTERCEPT_UTMPX 6843INTERCEPTOR(void *, getutxent, int dummy) { 6844 void *ctx; 6845 COMMON_INTERCEPTOR_ENTER(ctx, getutxent, dummy); 6846 void *res = REAL(getutxent)(dummy); 6847 if (res) 6848 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6849 return res; 6850} 6851INTERCEPTOR(void *, getutxid, void *ut) { 6852 void *ctx; 6853 COMMON_INTERCEPTOR_ENTER(ctx, getutxid, ut); 6854 void *res = REAL(getutxid)(ut); 6855 if (res) 6856 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6857 return res; 6858} 6859INTERCEPTOR(void *, getutxline, void *ut) { 6860 void *ctx; 6861 COMMON_INTERCEPTOR_ENTER(ctx, getutxline, ut); 6862 void *res = REAL(getutxline)(ut); 6863 if (res) 6864 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); 6865 return res; 6866} 6867INTERCEPTOR(void *, pututxline, const void *ut) { 6868 void *ctx; 6869 COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut); 6870 if (ut) 6871 COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz); 6872 void *res = REAL(pututxline)(ut); 6873 if (res) 6874 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz); 6875 return res; 6876} 6877#define INIT_UTMPX \ 6878 COMMON_INTERCEPT_FUNCTION(getutxent); \ 6879 COMMON_INTERCEPT_FUNCTION(getutxid); \ 6880 COMMON_INTERCEPT_FUNCTION(getutxline); \ 6881 COMMON_INTERCEPT_FUNCTION(pututxline); 6882#else 6883#define INIT_UTMPX 6884#endif 6885 6886#if SANITIZER_INTERCEPT_GETLOADAVG 6887INTERCEPTOR(int, getloadavg, double *loadavg, int nelem) { 6888 void *ctx; 6889 COMMON_INTERCEPTOR_ENTER(ctx, getloadavg, loadavg, nelem); 6890 int res = REAL(getloadavg)(loadavg, nelem); 6891 if (res > 0) 6892 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, loadavg, res * sizeof(*loadavg)); 6893 return res; 6894} 6895#define INIT_GETLOADAVG \ 6896 COMMON_INTERCEPT_FUNCTION(getloadavg); 6897#else 6898#define INIT_GETLOADAVG 6899#endif 6900 6901#if SANITIZER_INTERCEPT_MCHECK_MPROBE 6902INTERCEPTOR(int, mcheck, void (*abortfunc)(int mstatus)) { 6903 return 0; 6904} 6905 6906INTERCEPTOR(int, mcheck_pedantic, void (*abortfunc)(int mstatus)) { 6907 return 0; 6908} 6909 6910INTERCEPTOR(int, mprobe, void *ptr) { 6911 return 0; 6912} 6913#endif 6914 6915INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) { 6916 void *ctx; 6917 COMMON_INTERCEPTOR_ENTER(ctx, wcslen, s); 6918 SIZE_T res = REAL(wcslen)(s); 6919 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (res + 1)); 6920 return res; 6921} 6922 6923INTERCEPTOR(SIZE_T, wcsnlen, const wchar_t *s, SIZE_T n) { 6924 void *ctx; 6925 COMMON_INTERCEPTOR_ENTER(ctx, wcsnlen, s, n); 6926 SIZE_T res = REAL(wcsnlen)(s, n); 6927 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * Min(res + 1, n)); 6928 return res; 6929} 6930#define INIT_WCSLEN \ 6931 COMMON_INTERCEPT_FUNCTION(wcslen); \ 6932 COMMON_INTERCEPT_FUNCTION(wcsnlen); 6933 6934#if SANITIZER_INTERCEPT_WCSCAT 6935INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { 6936 void *ctx; 6937 COMMON_INTERCEPTOR_ENTER(ctx, wcscat, dst, src); 6938 SIZE_T src_size = REAL(wcslen)(src); 6939 SIZE_T dst_size = REAL(wcslen)(dst); 6940 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, (src_size + 1) * sizeof(wchar_t)); 6941 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6942 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6943 (src_size + 1) * sizeof(wchar_t)); 6944 return REAL(wcscat)(dst, src); 6945} 6946 6947INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { 6948 void *ctx; 6949 COMMON_INTERCEPTOR_ENTER(ctx, wcsncat, dst, src, n); 6950 SIZE_T src_size = REAL(wcsnlen)(src, n); 6951 SIZE_T dst_size = REAL(wcslen)(dst); 6952 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, 6953 Min(src_size + 1, n) * sizeof(wchar_t)); 6954 COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); 6955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, 6956 (src_size + 1) * sizeof(wchar_t)); 6957 return REAL(wcsncat)(dst, src, n); 6958} 6959#define INIT_WCSCAT \ 6960 COMMON_INTERCEPT_FUNCTION(wcscat); \ 6961 COMMON_INTERCEPT_FUNCTION(wcsncat); 6962#else 6963#define INIT_WCSCAT 6964#endif 6965 6966#if SANITIZER_INTERCEPT_WCSDUP 6967INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) { 6968 void *ctx; 6969 COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s); 6970 SIZE_T len = REAL(wcslen)(s); 6971 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1)); 6972 wchar_t *result = REAL(wcsdup)(s); 6973 if (result) 6974 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1)); 6975 return result; 6976} 6977 6978#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup); 6979#else 6980#define INIT_WCSDUP 6981#endif 6982 6983#if SANITIZER_INTERCEPT_STRXFRM 6984static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } 6985 6986static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); } 6987 6988#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \ 6989 { \ 6990 void *ctx; \ 6991 COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \ 6992 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \ 6993 sizeof(*src) * (RealStrLen(src) + 1)); \ 6994 SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \ 6995 if (res < len) \ 6996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \ 6997 return res; \ 6998 } 6999 7000INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) { 7001 STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len); 7002} 7003 7004INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len, 7005 void *locale) { 7006 STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale); 7007} 7008 7009#define INIT_STRXFRM \ 7010 COMMON_INTERCEPT_FUNCTION(strxfrm); \ 7011 COMMON_INTERCEPT_FUNCTION(strxfrm_l); 7012#else 7013#define INIT_STRXFRM 7014#endif 7015 7016#if SANITIZER_INTERCEPT___STRXFRM_L 7017INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len, 7018 void *locale) { 7019 STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale); 7020} 7021 7022#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l); 7023#else 7024#define INIT___STRXFRM_L 7025#endif 7026 7027#if SANITIZER_INTERCEPT_WCSXFRM 7028INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) { 7029 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len); 7030} 7031 7032INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 7033 void *locale) { 7034 STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale); 7035} 7036 7037#define INIT_WCSXFRM \ 7038 COMMON_INTERCEPT_FUNCTION(wcsxfrm); \ 7039 COMMON_INTERCEPT_FUNCTION(wcsxfrm_l); 7040#else 7041#define INIT_WCSXFRM 7042#endif 7043 7044#if SANITIZER_INTERCEPT___WCSXFRM_L 7045INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, 7046 void *locale) { 7047 STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale); 7048} 7049 7050#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l); 7051#else 7052#define INIT___WCSXFRM_L 7053#endif 7054 7055#if SANITIZER_INTERCEPT_ACCT 7056INTERCEPTOR(int, acct, const char *file) { 7057 void *ctx; 7058 COMMON_INTERCEPTOR_ENTER(ctx, acct, file); 7059 if (file) 7060 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); 7061 return REAL(acct)(file); 7062} 7063#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct) 7064#else 7065#define INIT_ACCT 7066#endif 7067 7068#if SANITIZER_INTERCEPT_USER_FROM_UID 7069INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) { 7070 void *ctx; 7071 const char *user; 7072 COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser); 7073 user = REAL(user_from_uid)(uid, nouser); 7074 if (user) 7075 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1); 7076 return user; 7077} 7078#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid) 7079#else 7080#define INIT_USER_FROM_UID 7081#endif 7082 7083#if SANITIZER_INTERCEPT_UID_FROM_USER 7084INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) { 7085 void *ctx; 7086 int res; 7087 COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid); 7088 if (name) 7089 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7090 res = REAL(uid_from_user)(name, uid); 7091 if (uid) 7092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid)); 7093 return res; 7094} 7095#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user) 7096#else 7097#define INIT_UID_FROM_USER 7098#endif 7099 7100#if SANITIZER_INTERCEPT_GROUP_FROM_GID 7101INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) { 7102 void *ctx; 7103 const char *group; 7104 COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup); 7105 group = REAL(group_from_gid)(gid, nogroup); 7106 if (group) 7107 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1); 7108 return group; 7109} 7110#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid) 7111#else 7112#define INIT_GROUP_FROM_GID 7113#endif 7114 7115#if SANITIZER_INTERCEPT_GID_FROM_GROUP 7116INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) { 7117 void *ctx; 7118 int res; 7119 COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid); 7120 if (group) 7121 COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1); 7122 res = REAL(gid_from_group)(group, gid); 7123 if (gid) 7124 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid)); 7125 return res; 7126} 7127#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group) 7128#else 7129#define INIT_GID_FROM_GROUP 7130#endif 7131 7132#if SANITIZER_INTERCEPT_ACCESS 7133INTERCEPTOR(int, access, const char *path, int mode) { 7134 void *ctx; 7135 COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode); 7136 if (path) 7137 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7138 return REAL(access)(path, mode); 7139} 7140#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access) 7141#else 7142#define INIT_ACCESS 7143#endif 7144 7145#if SANITIZER_INTERCEPT_FACCESSAT 7146INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) { 7147 void *ctx; 7148 COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags); 7149 if (path) 7150 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7151 return REAL(faccessat)(fd, path, mode, flags); 7152} 7153#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat) 7154#else 7155#define INIT_FACCESSAT 7156#endif 7157 7158#if SANITIZER_INTERCEPT_GETGROUPLIST 7159INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups, 7160 int *ngroups) { 7161 void *ctx; 7162 int res; 7163 COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups); 7164 if (name) 7165 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7166 if (ngroups) 7167 COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups)); 7168 res = REAL(getgrouplist)(name, basegid, groups, ngroups); 7169 if (!res && groups && ngroups) { 7170 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 7171 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 7172 } 7173 return res; 7174} 7175 7176#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist); 7177#else 7178#define INIT_GETGROUPLIST 7179#endif 7180 7181#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP 7182INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, 7183 int maxgrp, int *ngroups) { 7184 void *ctx; 7185 int res; 7186 COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, 7187 maxgrp, ngroups); 7188 if (name) 7189 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7190 res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups); 7191 if (!res && groups && ngroups) { 7192 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); 7193 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); 7194 } 7195 return res; 7196} 7197 7198#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership); 7199#else 7200#define INIT_GETGROUPMEMBERSHIP 7201#endif 7202 7203#if SANITIZER_INTERCEPT_READLINK 7204INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { 7205 void* ctx; 7206 COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz); 7207 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7208 SSIZE_T res = REAL(readlink)(path, buf, bufsiz); 7209 if (res > 0) 7210 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 7211 return res; 7212} 7213 7214#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink) 7215#else 7216#define INIT_READLINK 7217#endif 7218 7219#if SANITIZER_INTERCEPT_READLINKAT 7220INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf, 7221 SIZE_T bufsiz) { 7222 void* ctx; 7223 COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz); 7224 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7225 SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz); 7226 if (res > 0) 7227 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); 7228 return res; 7229} 7230 7231#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat) 7232#else 7233#define INIT_READLINKAT 7234#endif 7235 7236#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT 7237INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname, 7238 struct file_handle *handle, int *mount_id, int flags) { 7239 void* ctx; 7240 COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle, 7241 mount_id, flags); 7242 COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1); 7243 7244 __sanitizer_file_handle *sanitizer_handle = 7245 reinterpret_cast<__sanitizer_file_handle*>(handle); 7246 COMMON_INTERCEPTOR_READ_RANGE( 7247 ctx, &sanitizer_handle->handle_bytes, 7248 sizeof(sanitizer_handle->handle_bytes)); 7249 7250 int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags); 7251 if (!res) { 7252 COMMON_INTERCEPTOR_WRITE_RANGE( 7253 ctx, &sanitizer_handle->handle_bytes, 7254 sizeof(sanitizer_handle->handle_bytes)); 7255 COMMON_INTERCEPTOR_WRITE_RANGE( 7256 ctx, &sanitizer_handle->handle_type, 7257 sizeof(sanitizer_handle->handle_type)); 7258 COMMON_INTERCEPTOR_WRITE_RANGE( 7259 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 7260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id)); 7261 } 7262 return res; 7263} 7264 7265#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at) 7266#else 7267#define INIT_NAME_TO_HANDLE_AT 7268#endif 7269 7270#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT 7271INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle, 7272 int flags) { 7273 void* ctx; 7274 COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags); 7275 7276 __sanitizer_file_handle *sanitizer_handle = 7277 reinterpret_cast<__sanitizer_file_handle*>(handle); 7278 COMMON_INTERCEPTOR_READ_RANGE( 7279 ctx, &sanitizer_handle->handle_bytes, 7280 sizeof(sanitizer_handle->handle_bytes)); 7281 COMMON_INTERCEPTOR_READ_RANGE( 7282 ctx, &sanitizer_handle->handle_type, 7283 sizeof(sanitizer_handle->handle_type)); 7284 COMMON_INTERCEPTOR_READ_RANGE( 7285 ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); 7286 7287 return REAL(open_by_handle_at)(mount_fd, handle, flags); 7288} 7289 7290#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at) 7291#else 7292#define INIT_OPEN_BY_HANDLE_AT 7293#endif 7294 7295#if SANITIZER_INTERCEPT_STRLCPY 7296INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) { 7297 void *ctx; 7298 SIZE_T res; 7299 COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size); 7300 if (src) { 7301 // Keep strnlen as macro argument, as macro may ignore it. 7302 COMMON_INTERCEPTOR_READ_STRING( 7303 ctx, src, Min(internal_strnlen(src, size), size - 1) + 1); 7304 } 7305 res = REAL(strlcpy)(dst, src, size); 7306 COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1); 7307 return res; 7308} 7309 7310INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) { 7311 void *ctx; 7312 SIZE_T len = 0; 7313 COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size); 7314 // src is checked in the strlcpy() interceptor 7315 if (dst) { 7316 len = internal_strnlen(dst, size); 7317 COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1); 7318 } 7319 // Reuse the rest of the code in the strlcpy() interceptor 7320 return WRAP(strlcpy)(dst + len, src, size - len) + len; 7321} 7322#define INIT_STRLCPY \ 7323 COMMON_INTERCEPT_FUNCTION(strlcpy); \ 7324 COMMON_INTERCEPT_FUNCTION(strlcat); 7325#else 7326#define INIT_STRLCPY 7327#endif 7328 7329#if SANITIZER_INTERCEPT_MMAP 7330INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, 7331 OFF_T off) { 7332 void *ctx; 7333 if (common_flags()->detect_write_exec) 7334 ReportMmapWriteExec(prot); 7335 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7336 return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 7337 COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); 7338 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off); 7339} 7340 7341INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) { 7342 void *ctx; 7343 if (common_flags()->detect_write_exec) 7344 ReportMmapWriteExec(prot); 7345 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7346 return (int)internal_mprotect(addr, sz, prot); 7347 COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot); 7348 MprotectMallocZones(addr, prot); 7349 return REAL(mprotect)(addr, sz, prot); 7350} 7351#define INIT_MMAP \ 7352 COMMON_INTERCEPT_FUNCTION(mmap); \ 7353 COMMON_INTERCEPT_FUNCTION(mprotect); 7354#else 7355#define INIT_MMAP 7356#endif 7357 7358#if SANITIZER_INTERCEPT_MMAP64 7359INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, 7360 OFF64_T off) { 7361 void *ctx; 7362 if (common_flags()->detect_write_exec) 7363 ReportMmapWriteExec(prot); 7364 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7365 return (void *)internal_mmap(addr, sz, prot, flags, fd, off); 7366 COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); 7367 COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off); 7368} 7369#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64); 7370#else 7371#define INIT_MMAP64 7372#endif 7373 7374#if SANITIZER_INTERCEPT_DEVNAME 7375INTERCEPTOR(char *, devname, u64 dev, u32 type) { 7376 void *ctx; 7377 char *name; 7378 COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type); 7379 name = REAL(devname)(dev, type); 7380 if (name) 7381 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 7382 return name; 7383} 7384#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname); 7385#else 7386#define INIT_DEVNAME 7387#endif 7388 7389#if SANITIZER_INTERCEPT_DEVNAME_R 7390#if SANITIZER_NETBSD 7391#define DEVNAME_R_RETTYPE int 7392#define DEVNAME_R_SUCCESS(x) (!(x)) 7393#else 7394#define DEVNAME_R_RETTYPE char* 7395#define DEVNAME_R_SUCCESS(x) (x) 7396#endif 7397INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path, 7398 uptr len) { 7399 void *ctx; 7400 COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len); 7401 DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len); 7402 if (DEVNAME_R_SUCCESS(res)) 7403 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); 7404 return res; 7405} 7406#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r); 7407#else 7408#define INIT_DEVNAME_R 7409#endif 7410 7411#if SANITIZER_INTERCEPT_FGETLN 7412INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) { 7413 void *ctx; 7414 COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len); 7415 char *str = REAL(fgetln)(stream, len); 7416 if (str && len) { 7417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7418 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len); 7419 } 7420 return str; 7421} 7422#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln) 7423#else 7424#define INIT_FGETLN 7425#endif 7426 7427#if SANITIZER_INTERCEPT_STRMODE 7428INTERCEPTOR(void, strmode, u32 mode, char *bp) { 7429 void *ctx; 7430 COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp); 7431 REAL(strmode)(mode, bp); 7432 if (bp) 7433 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1); 7434} 7435#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode) 7436#else 7437#define INIT_STRMODE 7438#endif 7439 7440#if SANITIZER_INTERCEPT_TTYENT 7441INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) { 7442 void *ctx; 7443 COMMON_INTERCEPTOR_ENTER(ctx, getttyent); 7444 struct __sanitizer_ttyent *ttyent = REAL(getttyent)(); 7445 if (ttyent) 7446 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7447 return ttyent; 7448} 7449INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) { 7450 void *ctx; 7451 COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name); 7452 if (name) 7453 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7454 struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name); 7455 if (ttyent) 7456 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); 7457 return ttyent; 7458} 7459INTERCEPTOR(int, setttyentpath, char *path) { 7460 void *ctx; 7461 COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path); 7462 if (path) 7463 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 7464 return REAL(setttyentpath)(path); 7465} 7466#define INIT_TTYENT \ 7467 COMMON_INTERCEPT_FUNCTION(getttyent); \ 7468 COMMON_INTERCEPT_FUNCTION(getttynam); \ 7469 COMMON_INTERCEPT_FUNCTION(setttyentpath) 7470#else 7471#define INIT_TTYENT 7472#endif 7473 7474#if SANITIZER_INTERCEPT_PROTOENT 7475static void write_protoent(void *ctx, struct __sanitizer_protoent *p) { 7476 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 7477 7478 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); 7479 7480 SIZE_T pp_size = 1; // One handles the trailing \0 7481 7482 for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) 7483 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); 7484 7485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, 7486 pp_size * sizeof(char **)); 7487} 7488 7489INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { 7490 void *ctx; 7491 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); 7492 struct __sanitizer_protoent *p = REAL(getprotoent)(); 7493 if (p) 7494 write_protoent(ctx, p); 7495 return p; 7496} 7497 7498INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { 7499 void *ctx; 7500 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name); 7501 if (name) 7502 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7503 struct __sanitizer_protoent *p = REAL(getprotobyname)(name); 7504 if (p) 7505 write_protoent(ctx, p); 7506 return p; 7507} 7508 7509INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { 7510 void *ctx; 7511 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); 7512 struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); 7513 if (p) 7514 write_protoent(ctx, p); 7515 return p; 7516} 7517#define INIT_PROTOENT \ 7518 COMMON_INTERCEPT_FUNCTION(getprotoent); \ 7519 COMMON_INTERCEPT_FUNCTION(getprotobyname); \ 7520 COMMON_INTERCEPT_FUNCTION(getprotobynumber) 7521#else 7522#define INIT_PROTOENT 7523#endif 7524 7525#if SANITIZER_INTERCEPT_PROTOENT_R 7526INTERCEPTOR(int, getprotoent_r, struct __sanitizer_protoent *result_buf, 7527 char *buf, SIZE_T buflen, struct __sanitizer_protoent **result) { 7528 void *ctx; 7529 COMMON_INTERCEPTOR_ENTER(ctx, getprotoent_r, result_buf, buf, buflen, 7530 result); 7531 int res = REAL(getprotoent_r)(result_buf, buf, buflen, result); 7532 7533 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); 7534 if (!res && *result) 7535 write_protoent(ctx, *result); 7536 return res; 7537} 7538 7539INTERCEPTOR(int, getprotobyname_r, const char *name, 7540 struct __sanitizer_protoent *result_buf, char *buf, SIZE_T buflen, 7541 struct __sanitizer_protoent **result) { 7542 void *ctx; 7543 COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname_r, name, result_buf, buf, 7544 buflen, result); 7545 if (name) 7546 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7547 int res = REAL(getprotobyname_r)(name, result_buf, buf, buflen, result); 7548 7549 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); 7550 if (!res && *result) 7551 write_protoent(ctx, *result); 7552 return res; 7553} 7554 7555INTERCEPTOR(int, getprotobynumber_r, int num, 7556 struct __sanitizer_protoent *result_buf, char *buf, 7557 SIZE_T buflen, struct __sanitizer_protoent **result) { 7558 void *ctx; 7559 COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber_r, num, result_buf, buf, 7560 buflen, result); 7561 int res = REAL(getprotobynumber_r)(num, result_buf, buf, buflen, result); 7562 7563 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof *result); 7564 if (!res && *result) 7565 write_protoent(ctx, *result); 7566 return res; 7567} 7568 7569#define INIT_PROTOENT_R \ 7570 COMMON_INTERCEPT_FUNCTION(getprotoent_r); \ 7571 COMMON_INTERCEPT_FUNCTION(getprotobyname_r); \ 7572 COMMON_INTERCEPT_FUNCTION(getprotobynumber_r); 7573#else 7574#define INIT_PROTOENT_R 7575#endif 7576 7577#if SANITIZER_INTERCEPT_NETENT 7578INTERCEPTOR(struct __sanitizer_netent *, getnetent) { 7579 void *ctx; 7580 COMMON_INTERCEPTOR_ENTER(ctx, getnetent); 7581 struct __sanitizer_netent *n = REAL(getnetent)(); 7582 if (n) { 7583 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7584 7585 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7586 7587 SIZE_T nn_size = 1; // One handles the trailing \0 7588 7589 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7590 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7591 7592 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7593 nn_size * sizeof(char **)); 7594 } 7595 return n; 7596} 7597 7598INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { 7599 void *ctx; 7600 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); 7601 if (name) 7602 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 7603 struct __sanitizer_netent *n = REAL(getnetbyname)(name); 7604 if (n) { 7605 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7606 7607 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7608 7609 SIZE_T nn_size = 1; // One handles the trailing \0 7610 7611 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7612 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7613 7614 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7615 nn_size * sizeof(char **)); 7616 } 7617 return n; 7618} 7619 7620INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { 7621 void *ctx; 7622 COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type); 7623 struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type); 7624 if (n) { 7625 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 7626 7627 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); 7628 7629 SIZE_T nn_size = 1; // One handles the trailing \0 7630 7631 for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) 7632 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); 7633 7634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, 7635 nn_size * sizeof(char **)); 7636 } 7637 return n; 7638} 7639#define INIT_NETENT \ 7640 COMMON_INTERCEPT_FUNCTION(getnetent); \ 7641 COMMON_INTERCEPT_FUNCTION(getnetbyname); \ 7642 COMMON_INTERCEPT_FUNCTION(getnetbyaddr) 7643#else 7644#define INIT_NETENT 7645#endif 7646 7647#if SANITIZER_INTERCEPT_GETMNTINFO 7648INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) { 7649 void *ctx; 7650 COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags); 7651 int cnt = REAL(getmntinfo)(mntbufp, flags); 7652 if (cnt > 0 && mntbufp) { 7653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); 7654 if (*mntbufp) 7655#if SANITIZER_NETBSD 7656 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz); 7657#else 7658 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz); 7659#endif 7660 } 7661 return cnt; 7662} 7663#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo) 7664#else 7665#define INIT_GETMNTINFO 7666#endif 7667 7668#if SANITIZER_INTERCEPT_MI_VECTOR_HASH 7669INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed, 7670 u32 hashes[3]) { 7671 void *ctx; 7672 COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes); 7673 if (key) 7674 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len); 7675 REAL(mi_vector_hash)(key, len, seed, hashes); 7676 if (hashes) 7677 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3); 7678} 7679#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash) 7680#else 7681#define INIT_MI_VECTOR_HASH 7682#endif 7683 7684#if SANITIZER_INTERCEPT_SETVBUF 7685INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode, 7686 SIZE_T size) { 7687 void *ctx; 7688 COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size); 7689 int ret = REAL(setvbuf)(stream, buf, mode, size); 7690 if (buf) 7691 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size); 7692 if (stream) 7693 unpoison_file(stream); 7694 return ret; 7695} 7696 7697INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) { 7698 void *ctx; 7699 COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf); 7700 REAL(setbuf)(stream, buf); 7701 if (buf) { 7702 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); 7703 } 7704 if (stream) 7705 unpoison_file(stream); 7706} 7707 7708INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) { 7709 void *ctx; 7710 COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode); 7711 REAL(setbuffer)(stream, buf, mode); 7712 if (buf) { 7713 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); 7714 } 7715 if (stream) 7716 unpoison_file(stream); 7717} 7718 7719INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) { 7720 void *ctx; 7721 COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream); 7722 REAL(setlinebuf)(stream); 7723 if (stream) 7724 unpoison_file(stream); 7725} 7726#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \ 7727 COMMON_INTERCEPT_FUNCTION(setbuf); \ 7728 COMMON_INTERCEPT_FUNCTION(setbuffer); \ 7729 COMMON_INTERCEPT_FUNCTION(setlinebuf) 7730#else 7731#define INIT_SETVBUF 7732#endif 7733 7734#if SANITIZER_INTERCEPT_GETVFSSTAT 7735INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { 7736 void *ctx; 7737 COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); 7738 int ret = REAL(getvfsstat)(buf, bufsize, flags); 7739 if (buf && ret > 0) 7740 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz); 7741 return ret; 7742} 7743#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat) 7744#else 7745#define INIT_GETVFSSTAT 7746#endif 7747 7748#if SANITIZER_INTERCEPT_REGEX 7749INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) { 7750 void *ctx; 7751 COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags); 7752 if (pattern) 7753 COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1); 7754 int res = REAL(regcomp)(preg, pattern, cflags); 7755 if (!res) 7756 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz); 7757 return res; 7758} 7759INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch, 7760 struct __sanitizer_regmatch *pmatch[], int eflags) { 7761 void *ctx; 7762 COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags); 7763 if (preg) 7764 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7765 if (string) 7766 COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1); 7767 int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags); 7768 if (!res && pmatch) 7769 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz); 7770 return res; 7771} 7772INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf, 7773 SIZE_T errbuf_size) { 7774 void *ctx; 7775 COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size); 7776 if (preg) 7777 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7778 SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size); 7779 if (errbuf) 7780 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1); 7781 return res; 7782} 7783INTERCEPTOR(void, regfree, const void *preg) { 7784 void *ctx; 7785 COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg); 7786 if (preg) 7787 COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); 7788 REAL(regfree)(preg); 7789} 7790#define INIT_REGEX \ 7791 COMMON_INTERCEPT_FUNCTION(regcomp); \ 7792 COMMON_INTERCEPT_FUNCTION_GLIBC_VER_MIN(regexec, "GLIBC_2.3.4"); \ 7793 COMMON_INTERCEPT_FUNCTION(regerror); \ 7794 COMMON_INTERCEPT_FUNCTION(regfree); 7795#else 7796#define INIT_REGEX 7797#endif 7798 7799#if SANITIZER_INTERCEPT_REGEXSUB 7800INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub, 7801 const struct __sanitizer_regmatch *rm, const char *str) { 7802 void *ctx; 7803 COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str); 7804 if (sub) 7805 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); 7806 // The implementation demands and hardcodes 10 elements 7807 if (rm) 7808 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); 7809 if (str) 7810 COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); 7811 SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str); 7812 if (res > 0 && buf) 7813 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 7814 return res; 7815} 7816INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub, 7817 const struct __sanitizer_regmatch *rm, const char *sstr) { 7818 void *ctx; 7819 COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr); 7820 if (sub) 7821 COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); 7822 // Hardcode 10 elements as this is hardcoded size 7823 if (rm) 7824 COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); 7825 if (sstr) 7826 COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1); 7827 SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr); 7828 if (res > 0 && buf) { 7829 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *)); 7830 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1); 7831 } 7832 return res; 7833} 7834 7835#define INIT_REGEXSUB \ 7836 COMMON_INTERCEPT_FUNCTION(regnsub); \ 7837 COMMON_INTERCEPT_FUNCTION(regasub); 7838#else 7839#define INIT_REGEXSUB 7840#endif 7841 7842#if SANITIZER_INTERCEPT_FTS 7843INTERCEPTOR(void *, fts_open, char *const *path_argv, int options, 7844 int (*compar)(void **, void **)) { 7845 void *ctx; 7846 COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar); 7847 if (path_argv) { 7848 for (char *const *pa = path_argv; ; ++pa) { 7849 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 7850 if (!*pa) 7851 break; 7852 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 7853 } 7854 } 7855 // TODO(kamil): handle compar callback 7856 void *fts = REAL(fts_open)(path_argv, options, compar); 7857 if (fts) 7858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz); 7859 return fts; 7860} 7861 7862INTERCEPTOR(void *, fts_read, void *ftsp) { 7863 void *ctx; 7864 COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp); 7865 if (ftsp) 7866 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7867 void *ftsent = REAL(fts_read)(ftsp); 7868 if (ftsent) 7869 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); 7870 return ftsent; 7871} 7872 7873INTERCEPTOR(void *, fts_children, void *ftsp, int options) { 7874 void *ctx; 7875 COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options); 7876 if (ftsp) 7877 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7878 void *ftsent = REAL(fts_children)(ftsp, options); 7879 if (ftsent) 7880 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); 7881 return ftsent; 7882} 7883 7884INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) { 7885 void *ctx; 7886 COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options); 7887 if (ftsp) 7888 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7889 if (f) 7890 COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz); 7891 return REAL(fts_set)(ftsp, f, options); 7892} 7893 7894INTERCEPTOR(int, fts_close, void *ftsp) { 7895 void *ctx; 7896 COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp); 7897 if (ftsp) 7898 COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); 7899 return REAL(fts_close)(ftsp); 7900} 7901#define INIT_FTS \ 7902 COMMON_INTERCEPT_FUNCTION(fts_open); \ 7903 COMMON_INTERCEPT_FUNCTION(fts_read); \ 7904 COMMON_INTERCEPT_FUNCTION(fts_children); \ 7905 COMMON_INTERCEPT_FUNCTION(fts_set); \ 7906 COMMON_INTERCEPT_FUNCTION(fts_close); 7907#else 7908#define INIT_FTS 7909#endif 7910 7911#if SANITIZER_INTERCEPT_SYSCTL 7912INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp, 7913 SIZE_T *oldlenp, void *newp, SIZE_T newlen) { 7914 void *ctx; 7915 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7916 return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen); 7917 COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp, 7918 newlen); 7919 if (name) 7920 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name)); 7921 if (oldlenp) 7922 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7923 if (newp && newlen) 7924 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); 7925 int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen); 7926 if (!res) { 7927 if (oldlenp) { 7928 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7929 if (oldp) 7930 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); 7931 } 7932 } 7933 return res; 7934} 7935 7936INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp, 7937 void *newp, SIZE_T newlen) { 7938 void *ctx; 7939 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 7940 return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen); 7941 COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp, 7942 newlen); 7943 if (sname) 7944 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7945 if (oldlenp) 7946 COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7947 if (newp && newlen) 7948 COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); 7949 int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen); 7950 if (!res) { 7951 if (oldlenp) { 7952 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); 7953 if (oldp) 7954 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); 7955 } 7956 } 7957 return res; 7958} 7959 7960INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name, 7961 SIZE_T *namelenp) { 7962 void *ctx; 7963 COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp); 7964 if (sname) 7965 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 7966 if (namelenp) 7967 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); 7968 int res = REAL(sysctlnametomib)(sname, name, namelenp); 7969 if (!res) { 7970 if (namelenp) { 7971 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); 7972 if (name) 7973 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); 7974 } 7975 } 7976 return res; 7977} 7978 7979#define INIT_SYSCTL \ 7980 COMMON_INTERCEPT_FUNCTION(sysctl); \ 7981 COMMON_INTERCEPT_FUNCTION(sysctlbyname); \ 7982 COMMON_INTERCEPT_FUNCTION(sysctlnametomib); 7983#else 7984#define INIT_SYSCTL 7985#endif 7986 7987#if SANITIZER_INTERCEPT_ASYSCTL 7988INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) { 7989 void *ctx; 7990 COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len); 7991 if (name) 7992 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen); 7993 void *res = REAL(asysctl)(name, namelen, len); 7994 if (res && len) { 7995 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 7996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); 7997 } 7998 return res; 7999} 8000 8001INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) { 8002 void *ctx; 8003 COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len); 8004 if (sname) 8005 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 8006 void *res = REAL(asysctlbyname)(sname, len); 8007 if (res && len) { 8008 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 8009 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); 8010 } 8011 return res; 8012} 8013#define INIT_ASYSCTL \ 8014 COMMON_INTERCEPT_FUNCTION(asysctl); \ 8015 COMMON_INTERCEPT_FUNCTION(asysctlbyname); 8016#else 8017#define INIT_ASYSCTL 8018#endif 8019 8020#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO 8021INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name, 8022 unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode, 8023 int v) { 8024 void *ctx; 8025 COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname, 8026 csz, rnode, v); 8027 if (sname) 8028 COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); 8029 if (namelenp) 8030 COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); 8031 if (csz) 8032 COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz)); 8033 // Skip rnode, it's rarely used and not trivial to sanitize 8034 // It's also used mostly internally 8035 int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v); 8036 if (!res) { 8037 if (namelenp) { 8038 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); 8039 if (name) 8040 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); 8041 } 8042 if (csz) { 8043 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz)); 8044 if (cname) 8045 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz); 8046 } 8047 } 8048 return res; 8049} 8050#define INIT_SYSCTLGETMIBINFO \ 8051 COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo); 8052#else 8053#define INIT_SYSCTLGETMIBINFO 8054#endif 8055 8056#if SANITIZER_INTERCEPT_NL_LANGINFO 8057INTERCEPTOR(char *, nl_langinfo, long item) { 8058 void *ctx; 8059 COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item); 8060 char *ret = REAL(nl_langinfo)(item); 8061 if (ret) 8062 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); 8063 return ret; 8064} 8065#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo) 8066#else 8067#define INIT_NL_LANGINFO 8068#endif 8069 8070#if SANITIZER_INTERCEPT_MODCTL 8071INTERCEPTOR(int, modctl, int operation, void *argp) { 8072 void *ctx; 8073 int ret; 8074 COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp); 8075 8076 if (operation == modctl_load) { 8077 if (argp) { 8078 __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp; 8079 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml)); 8080 if (ml->ml_filename) 8081 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename, 8082 REAL(strlen)(ml->ml_filename) + 1); 8083 if (ml->ml_props) 8084 COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen); 8085 } 8086 ret = REAL(modctl)(operation, argp); 8087 } else if (operation == modctl_unload) { 8088 if (argp) { 8089 const char *name = (const char *)argp; 8090 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 8091 } 8092 ret = REAL(modctl)(operation, argp); 8093 } else if (operation == modctl_stat) { 8094 uptr iov_len; 8095 struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp; 8096 if (iov) { 8097 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov)); 8098 iov_len = iov->iov_len; 8099 } 8100 ret = REAL(modctl)(operation, argp); 8101 if (iov) 8102 COMMON_INTERCEPTOR_WRITE_RANGE( 8103 ctx, iov->iov_base, Min(iov_len, iov->iov_len)); 8104 } else if (operation == modctl_exists) { 8105 ret = REAL(modctl)(operation, argp); 8106 } else { 8107 ret = REAL(modctl)(operation, argp); 8108 } 8109 8110 return ret; 8111} 8112#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl) 8113#else 8114#define INIT_MODCTL 8115#endif 8116 8117#if SANITIZER_INTERCEPT_STRTONUM 8118INTERCEPTOR(long long, strtonum, const char *nptr, long long minval, 8119 long long maxval, const char **errstr) { 8120 void *ctx; 8121 COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr); 8122 8123 // TODO(kamil): Implement strtoll as a common inteceptor 8124 char *real_endptr; 8125 long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10); 8126 StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10); 8127 8128 ret = REAL(strtonum)(nptr, minval, maxval, errstr); 8129 if (errstr) { 8130 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *)); 8131 if (*errstr) 8132 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1); 8133 } 8134 return ret; 8135} 8136#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum) 8137#else 8138#define INIT_STRTONUM 8139#endif 8140 8141#if SANITIZER_INTERCEPT_FPARSELN 8142INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len, 8143 SIZE_T *lineno, const char delim[3], int flags) { 8144 void *ctx; 8145 COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags); 8146 if (lineno) 8147 COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno)); 8148 if (delim) 8149 COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3); 8150 char *ret = REAL(fparseln)(stream, len, lineno, delim, flags); 8151 if (ret) { 8152 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); 8153 if (len) 8154 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); 8155 if (lineno) 8156 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno)); 8157 } 8158 return ret; 8159} 8160#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln) 8161#else 8162#define INIT_FPARSELN 8163#endif 8164 8165#if SANITIZER_INTERCEPT_STATVFS1 8166INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { 8167 void *ctx; 8168 COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); 8169 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 8170 int res = REAL(statvfs1)(path, buf, flags); 8171 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 8172 return res; 8173} 8174INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { 8175 void *ctx; 8176 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); 8177 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 8178 int res = REAL(fstatvfs1)(fd, buf, flags); 8179 if (!res) { 8180 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 8181 if (fd >= 0) 8182 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 8183 } 8184 return res; 8185} 8186#define INIT_STATVFS1 \ 8187 COMMON_INTERCEPT_FUNCTION(statvfs1); \ 8188 COMMON_INTERCEPT_FUNCTION(fstatvfs1); 8189#else 8190#define INIT_STATVFS1 8191#endif 8192 8193#if SANITIZER_INTERCEPT_STRTOI 8194INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base, 8195 INTMAX_T low, INTMAX_T high, int *rstatus) { 8196 void *ctx; 8197 COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus); 8198 char *real_endptr; 8199 INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus); 8200 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 8201 if (rstatus) 8202 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); 8203 return ret; 8204} 8205 8206INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base, 8207 UINTMAX_T low, UINTMAX_T high, int *rstatus) { 8208 void *ctx; 8209 COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus); 8210 char *real_endptr; 8211 UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus); 8212 StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); 8213 if (rstatus) 8214 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); 8215 return ret; 8216} 8217#define INIT_STRTOI \ 8218 COMMON_INTERCEPT_FUNCTION(strtoi); \ 8219 COMMON_INTERCEPT_FUNCTION(strtou) 8220#else 8221#define INIT_STRTOI 8222#endif 8223 8224#if SANITIZER_INTERCEPT_CAPSICUM 8225#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \ 8226 { \ 8227 void *ctx; \ 8228 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \ 8229 if (rights) \ 8230 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 8231 __sanitizer_cap_rights_t *ret = \ 8232 REAL(cap_rights_init)(rights, ##__VA_ARGS__); \ 8233 if (ret) \ 8234 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 8235 return ret; \ 8236 } 8237 8238#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \ 8239 { \ 8240 void *ctx; \ 8241 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \ 8242 if (rights) \ 8243 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 8244 __sanitizer_cap_rights_t *ret = \ 8245 REAL(cap_rights_set)(rights, ##__VA_ARGS__); \ 8246 if (ret) \ 8247 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 8248 return ret; \ 8249 } 8250 8251#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \ 8252 { \ 8253 void *ctx; \ 8254 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \ 8255 if (rights) \ 8256 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 8257 __sanitizer_cap_rights_t *ret = \ 8258 REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \ 8259 if (ret) \ 8260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ 8261 return ret; \ 8262 } 8263 8264#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \ 8265 { \ 8266 void *ctx; \ 8267 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \ 8268 if (rights) \ 8269 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ 8270 return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \ 8271 } 8272 8273INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init, 8274 __sanitizer_cap_rights_t *rights) { 8275 CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights); 8276} 8277 8278INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set, 8279 __sanitizer_cap_rights_t *rights) { 8280 CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights); 8281} 8282 8283INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear, 8284 __sanitizer_cap_rights_t *rights) { 8285 CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights); 8286} 8287 8288INTERCEPTOR(bool, cap_rights_is_set, 8289 __sanitizer_cap_rights_t *rights) { 8290 CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights); 8291} 8292 8293INTERCEPTOR(int, cap_rights_limit, int fd, 8294 const __sanitizer_cap_rights_t *rights) { 8295 void *ctx; 8296 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights); 8297 if (rights) 8298 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); 8299 8300 return REAL(cap_rights_limit)(fd, rights); 8301} 8302 8303INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) { 8304 void *ctx; 8305 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights); 8306 int ret = REAL(cap_rights_get)(fd, rights); 8307 if (!ret && rights) 8308 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights)); 8309 8310 return ret; 8311} 8312 8313INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) { 8314 void *ctx; 8315 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights); 8316 if (rights) 8317 COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); 8318 8319 return REAL(cap_rights_is_valid(rights)); 8320} 8321 8322INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge, 8323 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { 8324 void *ctx; 8325 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src); 8326 if (src) 8327 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 8328 8329 __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src); 8330 if (dst) 8331 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 8332 8333 return ret; 8334} 8335 8336INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove, 8337 __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { 8338 void *ctx; 8339 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src); 8340 if (src) 8341 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 8342 8343 __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src); 8344 if (dst) 8345 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); 8346 8347 return ret; 8348} 8349 8350INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big, 8351 const __sanitizer_cap_rights *little) { 8352 void *ctx; 8353 COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little); 8354 if (little) 8355 COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little)); 8356 if (big) 8357 COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big)); 8358 8359 return REAL(cap_rights_contains)(big, little); 8360} 8361 8362INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) { 8363 void *ctx; 8364 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds); 8365 if (cmds) 8366 COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds); 8367 8368 return REAL(cap_ioctls_limit)(fd, cmds, ncmds); 8369} 8370 8371INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) { 8372 void *ctx; 8373 COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds); 8374 int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds); 8375 if (!ret && cmds) 8376 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds); 8377 8378 return ret; 8379} 8380#define INIT_CAPSICUM \ 8381 COMMON_INTERCEPT_FUNCTION(cap_rights_init); \ 8382 COMMON_INTERCEPT_FUNCTION(cap_rights_set); \ 8383 COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \ 8384 COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \ 8385 COMMON_INTERCEPT_FUNCTION(cap_rights_get); \ 8386 COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \ 8387 COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \ 8388 COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \ 8389 COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \ 8390 COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \ 8391 COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \ 8392 COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit) 8393#else 8394#define INIT_CAPSICUM 8395#endif 8396 8397#if SANITIZER_INTERCEPT_SHA1 8398INTERCEPTOR(void, SHA1Init, void *context) { 8399 void *ctx; 8400 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context); 8401 REAL(SHA1Init)(context); 8402 if (context) 8403 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); 8404} 8405INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) { 8406 void *ctx; 8407 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len); 8408 if (data && len > 0) 8409 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8410 if (context) 8411 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8412 REAL(SHA1Update)(context, data, len); 8413 if (context) 8414 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); 8415} 8416INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) { 8417 void *ctx; 8418 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context); 8419 if (context) 8420 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8421 REAL(SHA1Final)(digest, context); 8422 if (digest) 8423 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); 8424} 8425INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) { 8426 void *ctx; 8427 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer); 8428 if (state) 8429 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); 8430 if (buffer) 8431 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64); 8432 REAL(SHA1Transform)(state, buffer); 8433 if (state) 8434 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); 8435} 8436INTERCEPTOR(char *, SHA1End, void *context, char *buf) { 8437 void *ctx; 8438 COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf); 8439 if (context) 8440 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); 8441 char *ret = REAL(SHA1End)(context, buf); 8442 if (ret) 8443 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8444 return ret; 8445} 8446INTERCEPTOR(char *, SHA1File, char *filename, char *buf) { 8447 void *ctx; 8448 COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf); 8449 if (filename) 8450 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8451 char *ret = REAL(SHA1File)(filename, buf); 8452 if (ret) 8453 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8454 return ret; 8455} 8456INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset, 8457 OFF_T length) { 8458 void *ctx; 8459 COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length); 8460 if (filename) 8461 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8462 char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length); 8463 if (ret) 8464 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8465 return ret; 8466} 8467INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) { 8468 void *ctx; 8469 COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf); 8470 if (data) 8471 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8472 char *ret = REAL(SHA1Data)(data, len, buf); 8473 if (ret) 8474 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); 8475 return ret; 8476} 8477#define INIT_SHA1 \ 8478 COMMON_INTERCEPT_FUNCTION(SHA1Init); \ 8479 COMMON_INTERCEPT_FUNCTION(SHA1Update); \ 8480 COMMON_INTERCEPT_FUNCTION(SHA1Final); \ 8481 COMMON_INTERCEPT_FUNCTION(SHA1Transform); \ 8482 COMMON_INTERCEPT_FUNCTION(SHA1End); \ 8483 COMMON_INTERCEPT_FUNCTION(SHA1File); \ 8484 COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \ 8485 COMMON_INTERCEPT_FUNCTION(SHA1Data) 8486#else 8487#define INIT_SHA1 8488#endif 8489 8490#if SANITIZER_INTERCEPT_MD4 8491INTERCEPTOR(void, MD4Init, void *context) { 8492 void *ctx; 8493 COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context); 8494 REAL(MD4Init)(context); 8495 if (context) 8496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); 8497} 8498 8499INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data, 8500 unsigned int len) { 8501 void *ctx; 8502 COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len); 8503 if (data && len > 0) 8504 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8505 if (context) 8506 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8507 REAL(MD4Update)(context, data, len); 8508 if (context) 8509 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); 8510} 8511 8512INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) { 8513 void *ctx; 8514 COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context); 8515 if (context) 8516 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8517 REAL(MD4Final)(digest, context); 8518 if (digest) 8519 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8520} 8521 8522INTERCEPTOR(char *, MD4End, void *context, char *buf) { 8523 void *ctx; 8524 COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf); 8525 if (context) 8526 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); 8527 char *ret = REAL(MD4End)(context, buf); 8528 if (ret) 8529 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8530 return ret; 8531} 8532 8533INTERCEPTOR(char *, MD4File, const char *filename, char *buf) { 8534 void *ctx; 8535 COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf); 8536 if (filename) 8537 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8538 char *ret = REAL(MD4File)(filename, buf); 8539 if (ret) 8540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8541 return ret; 8542} 8543 8544INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len, 8545 char *buf) { 8546 void *ctx; 8547 COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf); 8548 if (data && len > 0) 8549 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8550 char *ret = REAL(MD4Data)(data, len, buf); 8551 if (ret) 8552 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); 8553 return ret; 8554} 8555 8556#define INIT_MD4 \ 8557 COMMON_INTERCEPT_FUNCTION(MD4Init); \ 8558 COMMON_INTERCEPT_FUNCTION(MD4Update); \ 8559 COMMON_INTERCEPT_FUNCTION(MD4Final); \ 8560 COMMON_INTERCEPT_FUNCTION(MD4End); \ 8561 COMMON_INTERCEPT_FUNCTION(MD4File); \ 8562 COMMON_INTERCEPT_FUNCTION(MD4Data) 8563#else 8564#define INIT_MD4 8565#endif 8566 8567#if SANITIZER_INTERCEPT_RMD160 8568INTERCEPTOR(void, RMD160Init, void *context) { 8569 void *ctx; 8570 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context); 8571 REAL(RMD160Init)(context); 8572 if (context) 8573 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); 8574} 8575INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) { 8576 void *ctx; 8577 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len); 8578 if (data && len > 0) 8579 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8580 if (context) 8581 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8582 REAL(RMD160Update)(context, data, len); 8583 if (context) 8584 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); 8585} 8586INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) { 8587 void *ctx; 8588 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context); 8589 if (context) 8590 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8591 REAL(RMD160Final)(digest, context); 8592 if (digest) 8593 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); 8594} 8595INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) { 8596 void *ctx; 8597 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer); 8598 if (state) 8599 COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); 8600 if (buffer) 8601 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16); 8602 REAL(RMD160Transform)(state, buffer); 8603 if (state) 8604 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); 8605} 8606INTERCEPTOR(char *, RMD160End, void *context, char *buf) { 8607 void *ctx; 8608 COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf); 8609 if (context) 8610 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); 8611 char *ret = REAL(RMD160End)(context, buf); 8612 if (ret) 8613 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8614 return ret; 8615} 8616INTERCEPTOR(char *, RMD160File, char *filename, char *buf) { 8617 void *ctx; 8618 COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf); 8619 if (filename) 8620 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8621 char *ret = REAL(RMD160File)(filename, buf); 8622 if (ret) 8623 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8624 return ret; 8625} 8626INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset, 8627 OFF_T length) { 8628 void *ctx; 8629 COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length); 8630 if (filename) 8631 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8632 char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length); 8633 if (ret) 8634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8635 return ret; 8636} 8637INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) { 8638 void *ctx; 8639 COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf); 8640 if (data && len > 0) 8641 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8642 char *ret = REAL(RMD160Data)(data, len, buf); 8643 if (ret) 8644 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); 8645 return ret; 8646} 8647#define INIT_RMD160 \ 8648 COMMON_INTERCEPT_FUNCTION(RMD160Init); \ 8649 COMMON_INTERCEPT_FUNCTION(RMD160Update); \ 8650 COMMON_INTERCEPT_FUNCTION(RMD160Final); \ 8651 COMMON_INTERCEPT_FUNCTION(RMD160Transform); \ 8652 COMMON_INTERCEPT_FUNCTION(RMD160End); \ 8653 COMMON_INTERCEPT_FUNCTION(RMD160File); \ 8654 COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \ 8655 COMMON_INTERCEPT_FUNCTION(RMD160Data) 8656#else 8657#define INIT_RMD160 8658#endif 8659 8660#if SANITIZER_INTERCEPT_MD5 8661INTERCEPTOR(void, MD5Init, void *context) { 8662 void *ctx; 8663 COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context); 8664 REAL(MD5Init)(context); 8665 if (context) 8666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); 8667} 8668 8669INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data, 8670 unsigned int len) { 8671 void *ctx; 8672 COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len); 8673 if (data && len > 0) 8674 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8675 if (context) 8676 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8677 REAL(MD5Update)(context, data, len); 8678 if (context) 8679 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); 8680} 8681 8682INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) { 8683 void *ctx; 8684 COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context); 8685 if (context) 8686 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8687 REAL(MD5Final)(digest, context); 8688 if (digest) 8689 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8690} 8691 8692INTERCEPTOR(char *, MD5End, void *context, char *buf) { 8693 void *ctx; 8694 COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf); 8695 if (context) 8696 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); 8697 char *ret = REAL(MD5End)(context, buf); 8698 if (ret) 8699 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8700 return ret; 8701} 8702 8703INTERCEPTOR(char *, MD5File, const char *filename, char *buf) { 8704 void *ctx; 8705 COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf); 8706 if (filename) 8707 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8708 char *ret = REAL(MD5File)(filename, buf); 8709 if (ret) 8710 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8711 return ret; 8712} 8713 8714INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len, 8715 char *buf) { 8716 void *ctx; 8717 COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf); 8718 if (data && len > 0) 8719 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8720 char *ret = REAL(MD5Data)(data, len, buf); 8721 if (ret) 8722 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); 8723 return ret; 8724} 8725 8726#define INIT_MD5 \ 8727 COMMON_INTERCEPT_FUNCTION(MD5Init); \ 8728 COMMON_INTERCEPT_FUNCTION(MD5Update); \ 8729 COMMON_INTERCEPT_FUNCTION(MD5Final); \ 8730 COMMON_INTERCEPT_FUNCTION(MD5End); \ 8731 COMMON_INTERCEPT_FUNCTION(MD5File); \ 8732 COMMON_INTERCEPT_FUNCTION(MD5Data) 8733#else 8734#define INIT_MD5 8735#endif 8736 8737#if SANITIZER_INTERCEPT_FSEEK 8738INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) { 8739 void *ctx; 8740 COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence); 8741 return REAL(fseek)(stream, offset, whence); 8742} 8743INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) { 8744 void *ctx; 8745 COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence); 8746 return REAL(fseeko)(stream, offset, whence); 8747} 8748INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) { 8749 void *ctx; 8750 COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream); 8751 return REAL(ftell)(stream); 8752} 8753INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) { 8754 void *ctx; 8755 COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream); 8756 return REAL(ftello)(stream); 8757} 8758INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) { 8759 void *ctx; 8760 COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream); 8761 return REAL(rewind)(stream); 8762} 8763INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) { 8764 void *ctx; 8765 COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos); 8766 int ret = REAL(fgetpos)(stream, pos); 8767 if (pos && !ret) 8768 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz); 8769 return ret; 8770} 8771INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) { 8772 void *ctx; 8773 COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos); 8774 if (pos) 8775 COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz); 8776 return REAL(fsetpos)(stream, pos); 8777} 8778#define INIT_FSEEK \ 8779 COMMON_INTERCEPT_FUNCTION(fseek); \ 8780 COMMON_INTERCEPT_FUNCTION(fseeko); \ 8781 COMMON_INTERCEPT_FUNCTION(ftell); \ 8782 COMMON_INTERCEPT_FUNCTION(ftello); \ 8783 COMMON_INTERCEPT_FUNCTION(rewind); \ 8784 COMMON_INTERCEPT_FUNCTION(fgetpos); \ 8785 COMMON_INTERCEPT_FUNCTION(fsetpos) 8786#else 8787#define INIT_FSEEK 8788#endif 8789 8790#if SANITIZER_INTERCEPT_MD2 8791INTERCEPTOR(void, MD2Init, void *context) { 8792 void *ctx; 8793 COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context); 8794 REAL(MD2Init)(context); 8795 if (context) 8796 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); 8797} 8798 8799INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data, 8800 unsigned int len) { 8801 void *ctx; 8802 COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len); 8803 if (data && len > 0) 8804 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8805 if (context) 8806 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8807 REAL(MD2Update)(context, data, len); 8808 if (context) 8809 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); 8810} 8811 8812INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) { 8813 void *ctx; 8814 COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context); 8815 if (context) 8816 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8817 REAL(MD2Final)(digest, context); 8818 if (digest) 8819 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); 8820} 8821 8822INTERCEPTOR(char *, MD2End, void *context, char *buf) { 8823 void *ctx; 8824 COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf); 8825 if (context) 8826 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); 8827 char *ret = REAL(MD2End)(context, buf); 8828 if (ret) 8829 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8830 return ret; 8831} 8832 8833INTERCEPTOR(char *, MD2File, const char *filename, char *buf) { 8834 void *ctx; 8835 COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf); 8836 if (filename) 8837 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); 8838 char *ret = REAL(MD2File)(filename, buf); 8839 if (ret) 8840 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8841 return ret; 8842} 8843 8844INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len, 8845 char *buf) { 8846 void *ctx; 8847 COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf); 8848 if (data && len > 0) 8849 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); 8850 char *ret = REAL(MD2Data)(data, len, buf); 8851 if (ret) 8852 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); 8853 return ret; 8854} 8855 8856#define INIT_MD2 \ 8857 COMMON_INTERCEPT_FUNCTION(MD2Init); \ 8858 COMMON_INTERCEPT_FUNCTION(MD2Update); \ 8859 COMMON_INTERCEPT_FUNCTION(MD2Final); \ 8860 COMMON_INTERCEPT_FUNCTION(MD2End); \ 8861 COMMON_INTERCEPT_FUNCTION(MD2File); \ 8862 COMMON_INTERCEPT_FUNCTION(MD2Data) 8863#else 8864#define INIT_MD2 8865#endif 8866 8867#if SANITIZER_INTERCEPT_SHA2 8868#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \ 8869 INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \ 8870 void *ctx; \ 8871 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \ 8872 REAL(SHA##LEN##_Init)(context); \ 8873 if (context) \ 8874 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8875 } \ 8876 INTERCEPTOR(void, SHA##LEN##_Update, void *context, \ 8877 const u8 *data, SIZE_T len) { \ 8878 void *ctx; \ 8879 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \ 8880 if (data && len > 0) \ 8881 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ 8882 if (context) \ 8883 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8884 REAL(SHA##LEN##_Update)(context, data, len); \ 8885 if (context) \ 8886 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8887 } \ 8888 INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \ 8889 void *context) { \ 8890 void *ctx; \ 8891 CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \ 8892 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \ 8893 if (context) \ 8894 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8895 REAL(SHA##LEN##_Final)(digest, context); \ 8896 if (digest) \ 8897 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \ 8898 sizeof(digest[0]) * \ 8899 SHA##LEN##_digest_length); \ 8900 } \ 8901 INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \ 8902 void *ctx; \ 8903 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \ 8904 if (context) \ 8905 COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ 8906 char *ret = REAL(SHA##LEN##_End)(context, buf); \ 8907 if (ret) \ 8908 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8909 return ret; \ 8910 } \ 8911 INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \ 8912 void *ctx; \ 8913 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \ 8914 if (filename) \ 8915 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ 8916 char *ret = REAL(SHA##LEN##_File)(filename, buf); \ 8917 if (ret) \ 8918 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8919 return ret; \ 8920 } \ 8921 INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \ 8922 OFF_T offset, OFF_T length) { \ 8923 void *ctx; \ 8924 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \ 8925 length); \ 8926 if (filename) \ 8927 COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ 8928 char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \ 8929 if (ret) \ 8930 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8931 return ret; \ 8932 } \ 8933 INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \ 8934 void *ctx; \ 8935 COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \ 8936 if (data && len > 0) \ 8937 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ 8938 char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \ 8939 if (ret) \ 8940 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ 8941 return ret; \ 8942 } 8943 8944SHA2_INTERCEPTORS(224, u32); 8945SHA2_INTERCEPTORS(256, u32); 8946SHA2_INTERCEPTORS(384, u64); 8947SHA2_INTERCEPTORS(512, u64); 8948 8949#define INIT_SHA2_INTECEPTORS(LEN) \ 8950 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \ 8951 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \ 8952 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \ 8953 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \ 8954 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \ 8955 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \ 8956 COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data) 8957 8958#define INIT_SHA2 \ 8959 INIT_SHA2_INTECEPTORS(224); \ 8960 INIT_SHA2_INTECEPTORS(256); \ 8961 INIT_SHA2_INTECEPTORS(384); \ 8962 INIT_SHA2_INTECEPTORS(512) 8963#undef SHA2_INTERCEPTORS 8964#else 8965#define INIT_SHA2 8966#endif 8967 8968#if SANITIZER_INTERCEPT_VIS 8969INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) { 8970 void *ctx; 8971 COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc); 8972 char *end = REAL(vis)(dst, c, flag, nextc); 8973 // dst is NULL terminated and end points to the NULL char 8974 if (dst && end) 8975 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 8976 return end; 8977} 8978INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) { 8979 void *ctx; 8980 COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc); 8981 char *end = REAL(nvis)(dst, dlen, c, flag, nextc); 8982 // nvis cannot make sure the dst is NULL terminated 8983 if (dst && end) 8984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 8985 return end; 8986} 8987INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) { 8988 void *ctx; 8989 COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag); 8990 if (src) 8991 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 8992 int len = REAL(strvis)(dst, src, flag); 8993 if (dst) 8994 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 8995 return len; 8996} 8997INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) { 8998 void *ctx; 8999 COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag); 9000 if (src) 9001 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9002 int len = REAL(stravis)(dst, src, flag); 9003 if (dst) { 9004 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *)); 9005 if (*dst) 9006 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1); 9007 } 9008 return len; 9009} 9010INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) { 9011 void *ctx; 9012 COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag); 9013 if (src) 9014 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9015 int len = REAL(strnvis)(dst, dlen, src, flag); 9016 // The interface will be valid even if there is no space for NULL char 9017 if (dst && len > 0) 9018 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 9019 return len; 9020} 9021INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) { 9022 void *ctx; 9023 COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag); 9024 if (src) 9025 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9026 int ret = REAL(strvisx)(dst, src, len, flag); 9027 if (dst) 9028 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9029 return ret; 9030} 9031INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 9032 int flag) { 9033 void *ctx; 9034 COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag); 9035 if (src) 9036 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9037 int ret = REAL(strnvisx)(dst, dlen, src, len, flag); 9038 if (dst && ret >= 0) 9039 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9040 return ret; 9041} 9042INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 9043 int flag, int *cerr_ptr) { 9044 void *ctx; 9045 COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr); 9046 if (src) 9047 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9048 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold 9049 // according to the implementation 9050 if (cerr_ptr) 9051 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); 9052 int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr); 9053 if (dst && ret >= 0) 9054 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9055 if (cerr_ptr) 9056 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); 9057 return ret; 9058} 9059INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc, 9060 const char *extra) { 9061 void *ctx; 9062 COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra); 9063 if (extra) 9064 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9065 char *end = REAL(svis)(dst, c, flag, nextc, extra); 9066 if (dst && end) 9067 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); 9068 return end; 9069} 9070INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc, 9071 const char *extra) { 9072 void *ctx; 9073 COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra); 9074 if (extra) 9075 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9076 char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra); 9077 if (dst && end) 9078 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, 9079 Min((SIZE_T)(end - dst + 1), dlen)); 9080 return end; 9081} 9082INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag, 9083 const char *extra) { 9084 void *ctx; 9085 COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra); 9086 if (src) 9087 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9088 if (extra) 9089 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9090 int len = REAL(strsvis)(dst, src, flag, extra); 9091 if (dst) 9092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 9093 return len; 9094} 9095INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag, 9096 const char *extra) { 9097 void *ctx; 9098 COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra); 9099 if (src) 9100 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9101 if (extra) 9102 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9103 int len = REAL(strsnvis)(dst, dlen, src, flag, extra); 9104 // The interface will be valid even if there is no space for NULL char 9105 if (dst && len >= 0) 9106 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); 9107 return len; 9108} 9109INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag, 9110 const char *extra) { 9111 void *ctx; 9112 COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra); 9113 if (src) 9114 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9115 if (extra) 9116 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9117 int ret = REAL(strsvisx)(dst, src, len, flag, extra); 9118 if (dst) 9119 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9120 return ret; 9121} 9122INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, 9123 int flag, const char *extra) { 9124 void *ctx; 9125 COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra); 9126 if (src) 9127 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9128 if (extra) 9129 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9130 int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra); 9131 if (dst && ret >= 0) 9132 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9133 return ret; 9134} 9135INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src, 9136 SIZE_T len, int flag, const char *extra, int *cerr_ptr) { 9137 void *ctx; 9138 COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra, 9139 cerr_ptr); 9140 if (src) 9141 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); 9142 if (extra) 9143 COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); 9144 // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold 9145 // according to the implementation 9146 if (cerr_ptr) 9147 COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); 9148 int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr); 9149 if (dst && ret >= 0) 9150 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9151 if (cerr_ptr) 9152 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); 9153 return ret; 9154} 9155INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) { 9156 void *ctx; 9157 COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag); 9158 if (astate) 9159 COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate)); 9160 int ret = REAL(unvis)(cp, c, astate, flag); 9161 if (ret == unvis_valid || ret == unvis_validpush) { 9162 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp)); 9163 } 9164 return ret; 9165} 9166INTERCEPTOR(int, strunvis, char *dst, const char *src) { 9167 void *ctx; 9168 COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src); 9169 if (src) 9170 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9171 int ret = REAL(strunvis)(dst, src); 9172 if (ret != -1) 9173 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9174 return ret; 9175} 9176INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) { 9177 void *ctx; 9178 COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src); 9179 if (src) 9180 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9181 int ret = REAL(strnunvis)(dst, dlen, src); 9182 if (ret != -1) 9183 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9184 return ret; 9185} 9186INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) { 9187 void *ctx; 9188 COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag); 9189 if (src) 9190 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9191 int ret = REAL(strunvisx)(dst, src, flag); 9192 if (ret != -1) 9193 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9194 return ret; 9195} 9196INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src, 9197 int flag) { 9198 void *ctx; 9199 COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag); 9200 if (src) 9201 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); 9202 int ret = REAL(strnunvisx)(dst, dlen, src, flag); 9203 if (ret != -1) 9204 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); 9205 return ret; 9206} 9207#define INIT_VIS \ 9208 COMMON_INTERCEPT_FUNCTION(vis); \ 9209 COMMON_INTERCEPT_FUNCTION(nvis); \ 9210 COMMON_INTERCEPT_FUNCTION(strvis); \ 9211 COMMON_INTERCEPT_FUNCTION(stravis); \ 9212 COMMON_INTERCEPT_FUNCTION(strnvis); \ 9213 COMMON_INTERCEPT_FUNCTION(strvisx); \ 9214 COMMON_INTERCEPT_FUNCTION(strnvisx); \ 9215 COMMON_INTERCEPT_FUNCTION(strenvisx); \ 9216 COMMON_INTERCEPT_FUNCTION(svis); \ 9217 COMMON_INTERCEPT_FUNCTION(snvis); \ 9218 COMMON_INTERCEPT_FUNCTION(strsvis); \ 9219 COMMON_INTERCEPT_FUNCTION(strsnvis); \ 9220 COMMON_INTERCEPT_FUNCTION(strsvisx); \ 9221 COMMON_INTERCEPT_FUNCTION(strsnvisx); \ 9222 COMMON_INTERCEPT_FUNCTION(strsenvisx); \ 9223 COMMON_INTERCEPT_FUNCTION(unvis); \ 9224 COMMON_INTERCEPT_FUNCTION(strunvis); \ 9225 COMMON_INTERCEPT_FUNCTION(strnunvis); \ 9226 COMMON_INTERCEPT_FUNCTION(strunvisx); \ 9227 COMMON_INTERCEPT_FUNCTION(strnunvisx) 9228#else 9229#define INIT_VIS 9230#endif 9231 9232#if SANITIZER_INTERCEPT_CDB 9233INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) { 9234 void *ctx; 9235 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags); 9236 if (path) 9237 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 9238 struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags); 9239 if (cdbr) 9240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); 9241 return cdbr; 9242} 9243 9244INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size, 9245 int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) { 9246 void *ctx; 9247 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap, 9248 cookie); 9249 if (base && size) 9250 COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size); 9251 struct __sanitizer_cdbr *cdbr = 9252 REAL(cdbr_open_mem)(base, size, flags, unmap, cookie); 9253 if (cdbr) 9254 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); 9255 return cdbr; 9256} 9257 9258INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) { 9259 void *ctx; 9260 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr); 9261 if (cdbr) 9262 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 9263 return REAL(cdbr_entries)(cdbr); 9264} 9265 9266INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index, 9267 const void **data, SIZE_T *datalen) { 9268 void *ctx; 9269 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen); 9270 if (cdbr) 9271 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 9272 int ret = REAL(cdbr_get)(cdbr, index, data, datalen); 9273 if (!ret) { 9274 if (data) 9275 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); 9276 if (datalen) 9277 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); 9278 if (data && datalen) 9279 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); 9280 } 9281 return ret; 9282} 9283 9284INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key, 9285 SIZE_T keylen, const void **data, SIZE_T *datalen) { 9286 void *ctx; 9287 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen); 9288 if (cdbr) 9289 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 9290 if (key) 9291 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 9292 int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen); 9293 if (!ret) { 9294 if (data) 9295 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); 9296 if (datalen) 9297 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); 9298 if (data && datalen) 9299 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); 9300 } 9301 return ret; 9302} 9303 9304INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) { 9305 void *ctx; 9306 COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr); 9307 if (cdbr) 9308 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); 9309 REAL(cdbr_close)(cdbr); 9310} 9311 9312INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) { 9313 void *ctx; 9314 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open); 9315 struct __sanitizer_cdbw *ret = REAL(cdbw_open)(); 9316 if (ret) 9317 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); 9318 return ret; 9319} 9320 9321INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key, 9322 SIZE_T keylen, const void *data, SIZE_T datalen) { 9323 void *ctx; 9324 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen); 9325 if (cdbw) 9326 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9327 if (data && datalen) 9328 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); 9329 if (key && keylen) 9330 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 9331 int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen); 9332 if (!ret && cdbw) 9333 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9334 return ret; 9335} 9336 9337INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data, 9338 SIZE_T datalen, u32 *index) { 9339 void *ctx; 9340 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index); 9341 if (cdbw) 9342 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9343 if (data && datalen) 9344 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); 9345 int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index); 9346 if (!ret) { 9347 if (index) 9348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index)); 9349 if (cdbw) 9350 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9351 } 9352 return ret; 9353} 9354 9355INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key, 9356 SIZE_T keylen, u32 index) { 9357 void *ctx; 9358 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index); 9359 if (cdbw) 9360 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9361 if (key && keylen) 9362 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); 9363 int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index); 9364 if (!ret && cdbw) 9365 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9366 return ret; 9367} 9368 9369INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output, 9370 const char descr[16], u32 (*seedgen)(void)) { 9371 void *ctx; 9372 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen); 9373 COMMON_INTERCEPTOR_FD_ACCESS(ctx, output); 9374 if (cdbw) 9375 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9376 if (descr) 9377 COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16)); 9378 if (seedgen) 9379 COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen)); 9380 int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen); 9381 if (!ret) { 9382 if (cdbw) 9383 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); 9384 if (output >= 0) 9385 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output); 9386 } 9387 return ret; 9388} 9389 9390INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) { 9391 void *ctx; 9392 COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw); 9393 if (cdbw) 9394 COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); 9395 REAL(cdbw_close)(cdbw); 9396} 9397 9398#define INIT_CDB \ 9399 COMMON_INTERCEPT_FUNCTION(cdbr_open); \ 9400 COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \ 9401 COMMON_INTERCEPT_FUNCTION(cdbr_entries); \ 9402 COMMON_INTERCEPT_FUNCTION(cdbr_get); \ 9403 COMMON_INTERCEPT_FUNCTION(cdbr_find); \ 9404 COMMON_INTERCEPT_FUNCTION(cdbr_close); \ 9405 COMMON_INTERCEPT_FUNCTION(cdbw_open); \ 9406 COMMON_INTERCEPT_FUNCTION(cdbw_put); \ 9407 COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \ 9408 COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \ 9409 COMMON_INTERCEPT_FUNCTION(cdbw_output); \ 9410 COMMON_INTERCEPT_FUNCTION(cdbw_close) 9411#else 9412#define INIT_CDB 9413#endif 9414 9415#if SANITIZER_INTERCEPT_GETFSENT 9416INTERCEPTOR(void *, getfsent) { 9417 void *ctx; 9418 COMMON_INTERCEPTOR_ENTER(ctx, getfsent); 9419 void *ret = REAL(getfsent)(); 9420 if (ret) 9421 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9422 return ret; 9423} 9424 9425INTERCEPTOR(void *, getfsspec, const char *spec) { 9426 void *ctx; 9427 COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec); 9428 if (spec) 9429 COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1); 9430 void *ret = REAL(getfsspec)(spec); 9431 if (ret) 9432 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9433 return ret; 9434} 9435 9436INTERCEPTOR(void *, getfsfile, const char *file) { 9437 void *ctx; 9438 COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file); 9439 if (file) 9440 COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); 9441 void *ret = REAL(getfsfile)(file); 9442 if (ret) 9443 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); 9444 return ret; 9445} 9446 9447#define INIT_GETFSENT \ 9448 COMMON_INTERCEPT_FUNCTION(getfsent); \ 9449 COMMON_INTERCEPT_FUNCTION(getfsspec); \ 9450 COMMON_INTERCEPT_FUNCTION(getfsfile); 9451#else 9452#define INIT_GETFSENT 9453#endif 9454 9455#if SANITIZER_INTERCEPT_ARC4RANDOM 9456INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) { 9457 void *ctx; 9458 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len); 9459 REAL(arc4random_buf)(buf, len); 9460 if (buf && len) 9461 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len); 9462} 9463 9464INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) { 9465 void *ctx; 9466 COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen); 9467 if (dat && datlen) 9468 COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen); 9469 REAL(arc4random_addrandom)(dat, datlen); 9470} 9471 9472#define INIT_ARC4RANDOM \ 9473 COMMON_INTERCEPT_FUNCTION(arc4random_buf); \ 9474 COMMON_INTERCEPT_FUNCTION(arc4random_addrandom); 9475#else 9476#define INIT_ARC4RANDOM 9477#endif 9478 9479#if SANITIZER_INTERCEPT_POPEN 9480INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) { 9481 void *ctx; 9482 COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type); 9483 if (command) 9484 COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1); 9485 if (type) 9486 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); 9487 __sanitizer_FILE *res = REAL(popen)(command, type); 9488 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); 9489 if (res) unpoison_file(res); 9490 return res; 9491} 9492#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen) 9493#else 9494#define INIT_POPEN 9495#endif 9496 9497#if SANITIZER_INTERCEPT_POPENVE 9498INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path, 9499 char *const *argv, char *const *envp, const char *type) { 9500 void *ctx; 9501 COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type); 9502 if (path) 9503 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 9504 if (argv) { 9505 for (char *const *pa = argv; ; ++pa) { 9506 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 9507 if (!*pa) 9508 break; 9509 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 9510 } 9511 } 9512 if (envp) { 9513 for (char *const *pa = envp; ; ++pa) { 9514 COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); 9515 if (!*pa) 9516 break; 9517 COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); 9518 } 9519 } 9520 if (type) 9521 COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); 9522 __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type); 9523 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); 9524 if (res) unpoison_file(res); 9525 return res; 9526} 9527#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve) 9528#else 9529#define INIT_POPENVE 9530#endif 9531 9532#if SANITIZER_INTERCEPT_PCLOSE 9533INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) { 9534 void *ctx; 9535 COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp); 9536 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 9537 const FileMetadata *m = GetInterceptorMetadata(fp); 9538 int res = REAL(pclose)(fp); 9539 if (m) { 9540 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 9541 DeleteInterceptorMetadata(fp); 9542 } 9543 return res; 9544} 9545#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose); 9546#else 9547#define INIT_PCLOSE 9548#endif 9549 9550#if SANITIZER_INTERCEPT_FUNOPEN 9551typedef int (*funopen_readfn)(void *cookie, char *buf, int len); 9552typedef int (*funopen_writefn)(void *cookie, const char *buf, int len); 9553typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence); 9554typedef int (*funopen_closefn)(void *cookie); 9555 9556struct WrappedFunopenCookie { 9557 void *real_cookie; 9558 funopen_readfn real_read; 9559 funopen_writefn real_write; 9560 funopen_seekfn real_seek; 9561 funopen_closefn real_close; 9562}; 9563 9564static int wrapped_funopen_read(void *cookie, char *buf, int len) { 9565 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9566 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9567 funopen_readfn real_read = wrapped_cookie->real_read; 9568 return real_read(wrapped_cookie->real_cookie, buf, len); 9569} 9570 9571static int wrapped_funopen_write(void *cookie, const char *buf, int len) { 9572 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9573 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9574 funopen_writefn real_write = wrapped_cookie->real_write; 9575 return real_write(wrapped_cookie->real_cookie, buf, len); 9576} 9577 9578static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) { 9579 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9580 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9581 funopen_seekfn real_seek = wrapped_cookie->real_seek; 9582 return real_seek(wrapped_cookie->real_cookie, offset, whence); 9583} 9584 9585static int wrapped_funopen_close(void *cookie) { 9586 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9587 WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; 9588 funopen_closefn real_close = wrapped_cookie->real_close; 9589 int res = real_close(wrapped_cookie->real_cookie); 9590 InternalFree(wrapped_cookie); 9591 return res; 9592} 9593 9594INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn, 9595 funopen_writefn writefn, funopen_seekfn seekfn, 9596 funopen_closefn closefn) { 9597 void *ctx; 9598 COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn, 9599 closefn); 9600 9601 WrappedFunopenCookie *wrapped_cookie = 9602 (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie)); 9603 wrapped_cookie->real_cookie = cookie; 9604 wrapped_cookie->real_read = readfn; 9605 wrapped_cookie->real_write = writefn; 9606 wrapped_cookie->real_seek = seekfn; 9607 wrapped_cookie->real_close = closefn; 9608 9609 __sanitizer_FILE *res = 9610 REAL(funopen)(wrapped_cookie, 9611 readfn ? wrapped_funopen_read : nullptr, 9612 writefn ? wrapped_funopen_write : nullptr, 9613 seekfn ? wrapped_funopen_seek : nullptr, 9614 closefn ? wrapped_funopen_close : nullptr); 9615 if (res) 9616 unpoison_file(res); 9617 return res; 9618} 9619#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen) 9620#else 9621#define INIT_FUNOPEN 9622#endif 9623 9624#if SANITIZER_INTERCEPT_FUNOPEN2 9625typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len); 9626typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len); 9627typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence); 9628typedef int (*funopen2_flushfn)(void *cookie); 9629typedef int (*funopen2_closefn)(void *cookie); 9630 9631struct WrappedFunopen2Cookie { 9632 void *real_cookie; 9633 funopen2_readfn real_read; 9634 funopen2_writefn real_write; 9635 funopen2_seekfn real_seek; 9636 funopen2_flushfn real_flush; 9637 funopen2_closefn real_close; 9638}; 9639 9640static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) { 9641 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9642 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9643 funopen2_readfn real_read = wrapped_cookie->real_read; 9644 return real_read(wrapped_cookie->real_cookie, buf, len); 9645} 9646 9647static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf, 9648 SIZE_T len) { 9649 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9650 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9651 funopen2_writefn real_write = wrapped_cookie->real_write; 9652 return real_write(wrapped_cookie->real_cookie, buf, len); 9653} 9654 9655static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) { 9656 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9657 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9658 funopen2_seekfn real_seek = wrapped_cookie->real_seek; 9659 return real_seek(wrapped_cookie->real_cookie, offset, whence); 9660} 9661 9662static int wrapped_funopen2_flush(void *cookie) { 9663 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9664 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9665 funopen2_flushfn real_flush = wrapped_cookie->real_flush; 9666 return real_flush(wrapped_cookie->real_cookie); 9667} 9668 9669static int wrapped_funopen2_close(void *cookie) { 9670 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 9671 WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; 9672 funopen2_closefn real_close = wrapped_cookie->real_close; 9673 int res = real_close(wrapped_cookie->real_cookie); 9674 InternalFree(wrapped_cookie); 9675 return res; 9676} 9677 9678INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn, 9679 funopen2_writefn writefn, funopen2_seekfn seekfn, 9680 funopen2_flushfn flushfn, funopen2_closefn closefn) { 9681 void *ctx; 9682 COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn, 9683 flushfn, closefn); 9684 9685 WrappedFunopen2Cookie *wrapped_cookie = 9686 (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie)); 9687 wrapped_cookie->real_cookie = cookie; 9688 wrapped_cookie->real_read = readfn; 9689 wrapped_cookie->real_write = writefn; 9690 wrapped_cookie->real_seek = seekfn; 9691 wrapped_cookie->real_flush = flushfn; 9692 wrapped_cookie->real_close = closefn; 9693 9694 __sanitizer_FILE *res = 9695 REAL(funopen2)(wrapped_cookie, 9696 readfn ? wrapped_funopen2_read : nullptr, 9697 writefn ? wrapped_funopen2_write : nullptr, 9698 seekfn ? wrapped_funopen2_seek : nullptr, 9699 flushfn ? wrapped_funopen2_flush : nullptr, 9700 closefn ? wrapped_funopen2_close : nullptr); 9701 if (res) 9702 unpoison_file(res); 9703 return res; 9704} 9705#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2) 9706#else 9707#define INIT_FUNOPEN2 9708#endif 9709 9710#if SANITIZER_INTERCEPT_FDEVNAME 9711INTERCEPTOR(char *, fdevname, int fd) { 9712 void *ctx; 9713 COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd); 9714 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 9715 char *name = REAL(fdevname)(fd); 9716 if (name) { 9717 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); 9718 if (fd > 0) 9719 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 9720 } 9721 return name; 9722} 9723 9724INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) { 9725 void *ctx; 9726 COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len); 9727 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 9728 char *name = REAL(fdevname_r)(fd, buf, len); 9729 if (name && buf && len > 0) { 9730 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 9731 if (fd > 0) 9732 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 9733 } 9734 return name; 9735} 9736 9737#define INIT_FDEVNAME \ 9738 COMMON_INTERCEPT_FUNCTION(fdevname); \ 9739 COMMON_INTERCEPT_FUNCTION(fdevname_r); 9740#else 9741#define INIT_FDEVNAME 9742#endif 9743 9744#if SANITIZER_INTERCEPT_GETUSERSHELL 9745INTERCEPTOR(char *, getusershell) { 9746 void *ctx; 9747 COMMON_INTERCEPTOR_ENTER(ctx, getusershell); 9748 char *res = REAL(getusershell)(); 9749 if (res) 9750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 9751 return res; 9752} 9753 9754#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell); 9755#else 9756#define INIT_GETUSERSHELL 9757#endif 9758 9759#if SANITIZER_INTERCEPT_SL_INIT 9760INTERCEPTOR(void *, sl_init) { 9761 void *ctx; 9762 COMMON_INTERCEPTOR_ENTER(ctx, sl_init); 9763 void *res = REAL(sl_init)(); 9764 if (res) 9765 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz); 9766 return res; 9767} 9768 9769INTERCEPTOR(int, sl_add, void *sl, char *item) { 9770 void *ctx; 9771 COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item); 9772 if (sl) 9773 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); 9774 if (item) 9775 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); 9776 int res = REAL(sl_add)(sl, item); 9777 if (!res) 9778 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); 9779 return res; 9780} 9781 9782INTERCEPTOR(char *, sl_find, void *sl, const char *item) { 9783 void *ctx; 9784 COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item); 9785 if (sl) 9786 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); 9787 if (item) 9788 COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); 9789 char *res = REAL(sl_find)(sl, item); 9790 if (res) 9791 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 9792 return res; 9793} 9794 9795INTERCEPTOR(void, sl_free, void *sl, int freeall) { 9796 void *ctx; 9797 COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall); 9798 if (sl) 9799 COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); 9800 REAL(sl_free)(sl, freeall); 9801} 9802 9803#define INIT_SL_INIT \ 9804 COMMON_INTERCEPT_FUNCTION(sl_init); \ 9805 COMMON_INTERCEPT_FUNCTION(sl_add); \ 9806 COMMON_INTERCEPT_FUNCTION(sl_find); \ 9807 COMMON_INTERCEPT_FUNCTION(sl_free); 9808#else 9809#define INIT_SL_INIT 9810#endif 9811 9812#if SANITIZER_INTERCEPT_GETRANDOM 9813INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) { 9814 void *ctx; 9815 COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags); 9816 SSIZE_T n = REAL(getrandom)(buf, buflen, flags); 9817 if (n > 0) { 9818 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n); 9819 } 9820 return n; 9821} 9822#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom) 9823#else 9824#define INIT_GETRANDOM 9825#endif 9826 9827#if SANITIZER_INTERCEPT_CRYPT 9828INTERCEPTOR(char *, crypt, char *key, char *salt) { 9829 void *ctx; 9830 COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt); 9831 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); 9832 COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); 9833 char *res = REAL(crypt)(key, salt); 9834 if (res != nullptr) 9835 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); 9836 return res; 9837} 9838#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt); 9839#else 9840#define INIT_CRYPT 9841#endif 9842 9843#if SANITIZER_INTERCEPT_CRYPT_R 9844INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) { 9845 void *ctx; 9846 COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data); 9847 COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); 9848 COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); 9849 char *res = REAL(crypt_r)(key, salt, data); 9850 if (res != nullptr) { 9851 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, 9852 __sanitizer::struct_crypt_data_sz); 9853 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); 9854 } 9855 return res; 9856} 9857#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r); 9858#else 9859#define INIT_CRYPT_R 9860#endif 9861 9862#if SANITIZER_INTERCEPT_GETENTROPY 9863INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { 9864 void *ctx; 9865 COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen); 9866 int r = REAL(getentropy)(buf, buflen); 9867 if (r == 0) { 9868 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 9869 } 9870 return r; 9871} 9872#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy) 9873#else 9874#define INIT_GETENTROPY 9875#endif 9876 9877#if SANITIZER_INTERCEPT_QSORT 9878// Glibc qsort uses a temporary buffer allocated either on stack or on heap. 9879// Poisoned memory from there may get copied into the comparator arguments, 9880// where it needs to be dealt with. But even that is not enough - the results of 9881// the sort may be copied into the input/output array based on the results of 9882// the comparator calls, but directly from the temp memory, bypassing the 9883// unpoisoning done in wrapped_qsort_compar. We deal with this by, again, 9884// unpoisoning the entire array after the sort is done. 9885// 9886// We can not check that the entire array is initialized at the beginning. IMHO, 9887// it's fine for parts of the sorted objects to contain uninitialized memory, 9888// ex. as padding in structs. 9889typedef int (*qsort_compar_f)(const void *, const void *); 9890static THREADLOCAL qsort_compar_f qsort_compar; 9891static THREADLOCAL SIZE_T qsort_size; 9892int wrapped_qsort_compar(const void *a, const void *b) { 9893 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 9894 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_size); 9895 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_size); 9896 return qsort_compar(a, b); 9897} 9898 9899INTERCEPTOR(void, qsort, void *base, SIZE_T nmemb, SIZE_T size, 9900 qsort_compar_f compar) { 9901 void *ctx; 9902 COMMON_INTERCEPTOR_ENTER(ctx, qsort, base, nmemb, size, compar); 9903 // Run the comparator over all array elements to detect any memory issues. 9904 if (nmemb > 1) { 9905 for (SIZE_T i = 0; i < nmemb - 1; ++i) { 9906 void *p = (void *)((char *)base + i * size); 9907 void *q = (void *)((char *)base + (i + 1) * size); 9908 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 9909 compar(p, q); 9910 } 9911 } 9912 qsort_compar_f old_compar = qsort_compar; 9913 SIZE_T old_size = qsort_size; 9914 // Handle qsort() implementations that recurse using an 9915 // interposable function call: 9916 bool already_wrapped = compar == wrapped_qsort_compar; 9917 if (already_wrapped) { 9918 // This case should only happen if the qsort() implementation calls itself 9919 // using a preemptible function call (e.g. the FreeBSD libc version). 9920 // Check that the size and comparator arguments are as expected. 9921 CHECK_NE(compar, qsort_compar); 9922 CHECK_EQ(qsort_size, size); 9923 } else { 9924 qsort_compar = compar; 9925 qsort_size = size; 9926 } 9927 REAL(qsort)(base, nmemb, size, wrapped_qsort_compar); 9928 if (!already_wrapped) { 9929 qsort_compar = old_compar; 9930 qsort_size = old_size; 9931 } 9932 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); 9933} 9934#define INIT_QSORT COMMON_INTERCEPT_FUNCTION(qsort) 9935#else 9936#define INIT_QSORT 9937#endif 9938 9939#if SANITIZER_INTERCEPT_QSORT_R 9940typedef int (*qsort_r_compar_f)(const void *, const void *, void *); 9941static THREADLOCAL qsort_r_compar_f qsort_r_compar; 9942static THREADLOCAL SIZE_T qsort_r_size; 9943int wrapped_qsort_r_compar(const void *a, const void *b, void *arg) { 9944 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9945 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, qsort_r_size); 9946 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, qsort_r_size); 9947 return qsort_r_compar(a, b, arg); 9948} 9949 9950INTERCEPTOR(void, qsort_r, void *base, SIZE_T nmemb, SIZE_T size, 9951 qsort_r_compar_f compar, void *arg) { 9952 void *ctx; 9953 COMMON_INTERCEPTOR_ENTER(ctx, qsort_r, base, nmemb, size, compar, arg); 9954 // Run the comparator over all array elements to detect any memory issues. 9955 if (nmemb > 1) { 9956 for (SIZE_T i = 0; i < nmemb - 1; ++i) { 9957 void *p = (void *)((char *)base + i * size); 9958 void *q = (void *)((char *)base + (i + 1) * size); 9959 COMMON_INTERCEPTOR_UNPOISON_PARAM(3); 9960 compar(p, q, arg); 9961 } 9962 } 9963 qsort_r_compar_f old_compar = qsort_r_compar; 9964 SIZE_T old_size = qsort_r_size; 9965 // Handle qsort_r() implementations that recurse using an 9966 // interposable function call: 9967 bool already_wrapped = compar == wrapped_qsort_r_compar; 9968 if (already_wrapped) { 9969 // This case should only happen if the qsort() implementation calls itself 9970 // using a preemptible function call (e.g. the FreeBSD libc version). 9971 // Check that the size and comparator arguments are as expected. 9972 CHECK_NE(compar, qsort_r_compar); 9973 CHECK_EQ(qsort_r_size, size); 9974 } else { 9975 qsort_r_compar = compar; 9976 qsort_r_size = size; 9977 } 9978 REAL(qsort_r)(base, nmemb, size, wrapped_qsort_r_compar, arg); 9979 if (!already_wrapped) { 9980 qsort_r_compar = old_compar; 9981 qsort_r_size = old_size; 9982 } 9983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, base, nmemb * size); 9984} 9985#define INIT_QSORT_R COMMON_INTERCEPT_FUNCTION(qsort_r) 9986#else 9987#define INIT_QSORT_R 9988#endif 9989 9990#if SANITIZER_INTERCEPT_SIGALTSTACK 9991INTERCEPTOR(int, sigaltstack, void *ss, void *oss) { 9992 void *ctx; 9993 COMMON_INTERCEPTOR_ENTER(ctx, sigaltstack, ss, oss); 9994 int r = REAL(sigaltstack)(ss, oss); 9995 if (r == 0 && oss != nullptr) { 9996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oss, struct_stack_t_sz); 9997 } 9998 return r; 9999} 10000#define INIT_SIGALTSTACK COMMON_INTERCEPT_FUNCTION(sigaltstack) 10001#else 10002#define INIT_SIGALTSTACK 10003#endif 10004 10005#if SANITIZER_INTERCEPT_UNAME 10006INTERCEPTOR(int, uname, struct utsname *utsname) { 10007#if SANITIZER_LINUX 10008 if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) 10009 return internal_uname(utsname); 10010#endif 10011 void *ctx; 10012 COMMON_INTERCEPTOR_ENTER(ctx, uname, utsname); 10013 int res = REAL(uname)(utsname); 10014 if (!res) 10015 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname, 10016 __sanitizer::struct_utsname_sz); 10017 return res; 10018} 10019#define INIT_UNAME COMMON_INTERCEPT_FUNCTION(uname) 10020#else 10021#define INIT_UNAME 10022#endif 10023 10024#if SANITIZER_INTERCEPT___XUNAME 10025// FreeBSD's <sys/utsname.h> define uname() as 10026// static __inline int uname(struct utsname *name) { 10027// return __xuname(SYS_NMLN, (void*)name); 10028// } 10029INTERCEPTOR(int, __xuname, int size, void *utsname) { 10030 void *ctx; 10031 COMMON_INTERCEPTOR_ENTER(ctx, __xuname, size, utsname); 10032 int res = REAL(__xuname)(size, utsname); 10033 if (!res) 10034 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, utsname, 10035 __sanitizer::struct_utsname_sz); 10036 return res; 10037} 10038#define INIT___XUNAME COMMON_INTERCEPT_FUNCTION(__xuname) 10039#else 10040#define INIT___XUNAME 10041#endif 10042 10043#include "sanitizer_common_interceptors_netbsd_compat.inc" 10044 10045static void InitializeCommonInterceptors() { 10046#if SI_POSIX 10047 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; 10048 interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap(); 10049#endif 10050 10051 INIT_MMAP; 10052 INIT_MMAP64; 10053 INIT_TEXTDOMAIN; 10054 INIT_STRLEN; 10055 INIT_STRNLEN; 10056 INIT_STRNDUP; 10057 INIT___STRNDUP; 10058 INIT_STRCMP; 10059 INIT_STRNCMP; 10060 INIT_STRCASECMP; 10061 INIT_STRNCASECMP; 10062 INIT_STRSTR; 10063 INIT_STRCASESTR; 10064 INIT_STRCHR; 10065 INIT_STRCHRNUL; 10066 INIT_STRRCHR; 10067 INIT_STRSPN; 10068 INIT_STRTOK; 10069 INIT_STRPBRK; 10070 INIT_STRXFRM; 10071 INIT___STRXFRM_L; 10072 INIT_MEMSET; 10073 INIT_MEMMOVE; 10074 INIT_MEMCPY; 10075 INIT_MEMCHR; 10076 INIT_MEMCMP; 10077 INIT_BCMP; 10078 INIT_MEMRCHR; 10079 INIT_MEMMEM; 10080 INIT_READ; 10081 INIT_FREAD; 10082 INIT_PREAD; 10083 INIT_PREAD64; 10084 INIT_READV; 10085 INIT_PREADV; 10086 INIT_PREADV64; 10087 INIT_WRITE; 10088 INIT_FWRITE; 10089 INIT_PWRITE; 10090 INIT_PWRITE64; 10091 INIT_WRITEV; 10092 INIT_PWRITEV; 10093 INIT_PWRITEV64; 10094 INIT_FGETS; 10095 INIT_FPUTS; 10096 INIT_PUTS; 10097 INIT_PRCTL; 10098 INIT_LOCALTIME_AND_FRIENDS; 10099 INIT_STRPTIME; 10100 INIT_SCANF; 10101 INIT_ISOC99_SCANF; 10102 INIT_PRINTF; 10103 INIT_PRINTF_L; 10104 INIT_ISOC99_PRINTF; 10105 INIT_FREXP; 10106 INIT_FREXPF_FREXPL; 10107 INIT_GETPWNAM_AND_FRIENDS; 10108 INIT_GETPWNAM_R_AND_FRIENDS; 10109 INIT_GETPWENT; 10110 INIT_FGETPWENT; 10111 INIT_GETPWENT_R; 10112 INIT_FGETPWENT_R; 10113 INIT_FGETGRENT_R; 10114 INIT_SETPWENT; 10115 INIT_CLOCK_GETTIME; 10116 INIT_CLOCK_GETCPUCLOCKID; 10117 INIT_GETITIMER; 10118 INIT_TIME; 10119 INIT_GLOB; 10120 INIT_GLOB64; 10121 INIT_WAIT; 10122 INIT_WAIT4; 10123 INIT_INET; 10124 INIT_PTHREAD_GETSCHEDPARAM; 10125 INIT_GETADDRINFO; 10126 INIT_GETNAMEINFO; 10127 INIT_GETSOCKNAME; 10128 INIT_GETHOSTBYNAME; 10129 INIT_GETHOSTBYNAME2; 10130 INIT_GETHOSTBYNAME_R; 10131 INIT_GETHOSTBYNAME2_R; 10132 INIT_GETHOSTBYADDR_R; 10133 INIT_GETHOSTENT_R; 10134 INIT_GETSOCKOPT; 10135 INIT_ACCEPT; 10136 INIT_ACCEPT4; 10137 INIT_PACCEPT; 10138 INIT_MODF; 10139 INIT_RECVMSG; 10140 INIT_SENDMSG; 10141 INIT_RECVMMSG; 10142 INIT_SENDMMSG; 10143 INIT_SYSMSG; 10144 INIT_GETPEERNAME; 10145 INIT_IOCTL; 10146 INIT_INET_ATON; 10147 INIT_SYSINFO; 10148 INIT_READDIR; 10149 INIT_READDIR64; 10150 INIT_PTRACE; 10151 INIT_SETLOCALE; 10152 INIT_GETCWD; 10153 INIT_GET_CURRENT_DIR_NAME; 10154 INIT_STRTOIMAX; 10155 INIT_MBSTOWCS; 10156 INIT_MBSNRTOWCS; 10157 INIT_WCSTOMBS; 10158 INIT_WCSNRTOMBS; 10159 INIT_WCRTOMB; 10160 INIT_WCTOMB; 10161 INIT_TCGETATTR; 10162 INIT_REALPATH; 10163 INIT_CANONICALIZE_FILE_NAME; 10164 INIT_CONFSTR; 10165 INIT_SCHED_GETAFFINITY; 10166 INIT_SCHED_GETPARAM; 10167 INIT_STRERROR; 10168 INIT_STRERROR_R; 10169 INIT_XPG_STRERROR_R; 10170 INIT_SCANDIR; 10171 INIT_SCANDIR64; 10172 INIT_GETGROUPS; 10173 INIT_POLL; 10174 INIT_PPOLL; 10175 INIT_WORDEXP; 10176 INIT_SIGWAIT; 10177 INIT_SIGWAITINFO; 10178 INIT_SIGTIMEDWAIT; 10179 INIT_SIGSETOPS; 10180 INIT_SIGSET_LOGICOPS; 10181 INIT_SIGPENDING; 10182 INIT_SIGPROCMASK; 10183 INIT_PTHREAD_SIGMASK; 10184 INIT_BACKTRACE; 10185 INIT__EXIT; 10186 INIT_PTHREAD_MUTEX_LOCK; 10187 INIT_PTHREAD_MUTEX_UNLOCK; 10188 INIT___PTHREAD_MUTEX_LOCK; 10189 INIT___PTHREAD_MUTEX_UNLOCK; 10190 INIT___LIBC_MUTEX_LOCK; 10191 INIT___LIBC_MUTEX_UNLOCK; 10192 INIT___LIBC_THR_SETCANCELSTATE; 10193 INIT_GETMNTENT; 10194 INIT_GETMNTENT_R; 10195 INIT_STATFS; 10196 INIT_STATFS64; 10197 INIT_STATVFS; 10198 INIT_STATVFS64; 10199 INIT_INITGROUPS; 10200 INIT_ETHER_NTOA_ATON; 10201 INIT_ETHER_HOST; 10202 INIT_ETHER_R; 10203 INIT_SHMCTL; 10204 INIT_RANDOM_R; 10205 INIT_PTHREAD_ATTR_GET; 10206 INIT_PTHREAD_ATTR_GET_SCHED; 10207 INIT_PTHREAD_ATTR_GETINHERITSCHED; 10208 INIT_PTHREAD_ATTR_GETAFFINITY_NP; 10209 INIT_PTHREAD_MUTEXATTR_GETPSHARED; 10210 INIT_PTHREAD_MUTEXATTR_GETTYPE; 10211 INIT_PTHREAD_MUTEXATTR_GETPROTOCOL; 10212 INIT_PTHREAD_MUTEXATTR_GETPRIOCEILING; 10213 INIT_PTHREAD_MUTEXATTR_GETROBUST; 10214 INIT_PTHREAD_MUTEXATTR_GETROBUST_NP; 10215 INIT_PTHREAD_RWLOCKATTR_GETPSHARED; 10216 INIT_PTHREAD_RWLOCKATTR_GETKIND_NP; 10217 INIT_PTHREAD_CONDATTR_GETPSHARED; 10218 INIT_PTHREAD_CONDATTR_GETCLOCK; 10219 INIT_PTHREAD_BARRIERATTR_GETPSHARED; 10220 INIT_TMPNAM; 10221 INIT_TMPNAM_R; 10222 INIT_PTSNAME; 10223 INIT_PTSNAME_R; 10224 INIT_TTYNAME; 10225 INIT_TTYNAME_R; 10226 INIT_TEMPNAM; 10227 INIT_PTHREAD_SETNAME_NP; 10228 INIT_PTHREAD_GETNAME_NP; 10229 INIT_SINCOS; 10230 INIT_REMQUO; 10231 INIT_REMQUOL; 10232 INIT_LGAMMA; 10233 INIT_LGAMMAL; 10234 INIT_LGAMMA_R; 10235 INIT_LGAMMAL_R; 10236 INIT_DRAND48_R; 10237 INIT_RAND_R; 10238 INIT_GETLINE; 10239 INIT_ICONV; 10240 INIT_TIMES; 10241 INIT_TLS_GET_ADDR; 10242 INIT_LISTXATTR; 10243 INIT_GETXATTR; 10244 INIT_GETRESID; 10245 INIT_GETIFADDRS; 10246 INIT_IF_INDEXTONAME; 10247 INIT_CAPGET; 10248 INIT_AEABI_MEM; 10249 INIT___BZERO; 10250 INIT_BZERO; 10251 INIT_FTIME; 10252 INIT_XDR; 10253 INIT_XDRREC_LINUX; 10254 INIT_TSEARCH; 10255 INIT_LIBIO_INTERNALS; 10256 INIT_FOPEN; 10257 INIT_FOPEN64; 10258 INIT_OPEN_MEMSTREAM; 10259 INIT_OBSTACK; 10260 INIT_FFLUSH; 10261 INIT_FCLOSE; 10262 INIT_DLOPEN_DLCLOSE; 10263 INIT_GETPASS; 10264 INIT_TIMERFD; 10265 INIT_MLOCKX; 10266 INIT_FOPENCOOKIE; 10267 INIT_SEM; 10268 INIT_PTHREAD_SETCANCEL; 10269 INIT_MINCORE; 10270 INIT_PROCESS_VM_READV; 10271 INIT_CTERMID; 10272 INIT_CTERMID_R; 10273 INIT_RECV_RECVFROM; 10274 INIT_SEND_SENDTO; 10275 INIT_STAT; 10276 INIT_EVENTFD_READ_WRITE; 10277 INIT_LSTAT; 10278 INIT___XSTAT; 10279 INIT___XSTAT64; 10280 INIT___LXSTAT; 10281 INIT___LXSTAT64; 10282 // FIXME: add other *stat interceptors. 10283 INIT_UTMP; 10284 INIT_UTMPX; 10285 INIT_GETLOADAVG; 10286 INIT_WCSLEN; 10287 INIT_WCSCAT; 10288 INIT_WCSDUP; 10289 INIT_WCSXFRM; 10290 INIT___WCSXFRM_L; 10291 INIT_ACCT; 10292 INIT_USER_FROM_UID; 10293 INIT_UID_FROM_USER; 10294 INIT_GROUP_FROM_GID; 10295 INIT_GID_FROM_GROUP; 10296 INIT_ACCESS; 10297 INIT_FACCESSAT; 10298 INIT_GETGROUPLIST; 10299 INIT_GETGROUPMEMBERSHIP; 10300 INIT_READLINK; 10301 INIT_READLINKAT; 10302 INIT_NAME_TO_HANDLE_AT; 10303 INIT_OPEN_BY_HANDLE_AT; 10304 INIT_STRLCPY; 10305 INIT_DEVNAME; 10306 INIT_DEVNAME_R; 10307 INIT_FGETLN; 10308 INIT_STRMODE; 10309 INIT_TTYENT; 10310 INIT_PROTOENT; 10311 INIT_PROTOENT_R; 10312 INIT_NETENT; 10313 INIT_GETMNTINFO; 10314 INIT_MI_VECTOR_HASH; 10315 INIT_SETVBUF; 10316 INIT_GETVFSSTAT; 10317 INIT_REGEX; 10318 INIT_REGEXSUB; 10319 INIT_FTS; 10320 INIT_SYSCTL; 10321 INIT_ASYSCTL; 10322 INIT_SYSCTLGETMIBINFO; 10323 INIT_NL_LANGINFO; 10324 INIT_MODCTL; 10325 INIT_STRTONUM; 10326 INIT_FPARSELN; 10327 INIT_STATVFS1; 10328 INIT_STRTOI; 10329 INIT_CAPSICUM; 10330 INIT_SHA1; 10331 INIT_MD4; 10332 INIT_RMD160; 10333 INIT_MD5; 10334 INIT_FSEEK; 10335 INIT_MD2; 10336 INIT_SHA2; 10337 INIT_VIS; 10338 INIT_CDB; 10339 INIT_GETFSENT; 10340 INIT_ARC4RANDOM; 10341 INIT_POPEN; 10342 INIT_POPENVE; 10343 INIT_PCLOSE; 10344 INIT_FUNOPEN; 10345 INIT_FUNOPEN2; 10346 INIT_FDEVNAME; 10347 INIT_GETUSERSHELL; 10348 INIT_SL_INIT; 10349 INIT_GETRANDOM; 10350 INIT_CRYPT; 10351 INIT_CRYPT_R; 10352 INIT_GETENTROPY; 10353 INIT_QSORT; 10354 INIT_QSORT_R; 10355 INIT_SIGALTSTACK; 10356 INIT_UNAME; 10357 INIT___XUNAME; 10358 10359 INIT___PRINTF_CHK; 10360} 10361