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