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