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