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