sanitizer_common_interceptors.inc revision 2d1fdb26e458c4ddc04155c1d421bced3ba90cd0
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Common function interceptors for tools like AddressSanitizer, 11// ThreadSanitizer, MemorySanitizer, etc. 12// 13// This file should be included into the tool's interceptor file, 14// which has to define it's own macros: 15// COMMON_INTERCEPTOR_ENTER 16// COMMON_INTERCEPTOR_READ_RANGE 17// COMMON_INTERCEPTOR_WRITE_RANGE 18// COMMON_INTERCEPTOR_INITIALIZE_RANGE 19// COMMON_INTERCEPTOR_FD_ACQUIRE 20// COMMON_INTERCEPTOR_FD_RELEASE 21// COMMON_INTERCEPTOR_FD_ACCESS 22// COMMON_INTERCEPTOR_SET_THREAD_NAME 23// COMMON_INTERCEPTOR_ON_EXIT 24// COMMON_INTERCEPTOR_MUTEX_LOCK 25// COMMON_INTERCEPTOR_MUTEX_UNLOCK 26// COMMON_INTERCEPTOR_MUTEX_REPAIR 27// COMMON_INTERCEPTOR_SET_PTHREAD_NAME 28// COMMON_INTERCEPTOR_HANDLE_RECVMSG 29//===----------------------------------------------------------------------===// 30#include "interception/interception.h" 31#include "sanitizer_addrhashmap.h" 32#include "sanitizer_placement_new.h" 33#include "sanitizer_platform_interceptors.h" 34#include "sanitizer_tls_get_addr.h" 35 36#include <stdarg.h> 37 38#if SANITIZER_WINDOWS && !defined(va_copy) 39#define va_copy(dst, src) ((dst) = (src)) 40#endif // _WIN32 41 42#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 43#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(p, size) {} 44#endif 45 46#ifndef COMMON_INTERCEPTOR_UNPOISON_PARAM 47#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) {} 48#endif 49 50#ifndef COMMON_INTERCEPTOR_FD_ACCESS 51#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 52#endif 53 54#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK 55#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {} 56#endif 57 58#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 59#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 60#endif 61 62#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR 63#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} 64#endif 65 66#ifndef COMMON_INTERCEPTOR_HANDLE_RECVMSG 67#define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) ((void)(msg)) 68#endif 69 70#ifndef COMMON_INTERCEPTOR_FILE_OPEN 71#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) {} 72#endif 73 74#ifndef COMMON_INTERCEPTOR_FILE_CLOSE 75#define COMMON_INTERCEPTOR_FILE_CLOSE(ctx, file) {} 76#endif 77 78#ifndef COMMON_INTERCEPTOR_LIBRARY_LOADED 79#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, map) {} 80#endif 81 82#ifndef COMMON_INTERCEPTOR_LIBRARY_UNLOADED 83#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED() {} 84#endif 85 86#ifndef COMMON_INTERCEPTOR_ENTER_NOIGNORE 87#define COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, ...) \ 88 COMMON_INTERCEPTOR_ENTER(ctx, __VA_ARGS__) 89#endif 90 91struct FileMetadata { 92 // For open_memstream(). 93 char **addr; 94 SIZE_T *size; 95}; 96 97struct CommonInterceptorMetadata { 98 enum { 99 CIMT_INVALID = 0, 100 CIMT_FILE 101 } type; 102 union { 103 FileMetadata file; 104 }; 105}; 106 107typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; 108 109static MetadataHashMap *interceptor_metadata_map; 110 111#if SI_NOT_WINDOWS 112UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, 113 const FileMetadata &file) { 114 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); 115 CHECK(h.created()); 116 h->type = CommonInterceptorMetadata::CIMT_FILE; 117 h->file = file; 118} 119 120UNUSED static const FileMetadata *GetInterceptorMetadata( 121 __sanitizer_FILE *addr) { 122 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, 123 /* remove */ false, 124 /* create */ false); 125 if (h.exists()) { 126 CHECK(!h.created()); 127 CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE); 128 return &h->file; 129 } else { 130 return 0; 131 } 132} 133 134UNUSED static void DeleteInterceptorMetadata(void *addr) { 135 MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, true); 136 CHECK(h.exists()); 137} 138#endif // SI_NOT_WINDOWS 139 140#if SANITIZER_INTERCEPT_TEXTDOMAIN 141INTERCEPTOR(char*, textdomain, const char *domainname) { 142 void *ctx; 143 COMMON_INTERCEPTOR_ENTER(ctx, textdomain, domainname); 144 char* domain = REAL(textdomain)(domainname); 145 if (domain) { 146 COMMON_INTERCEPTOR_INITIALIZE_RANGE(domain, REAL(strlen)(domain) + 1); 147 } 148 return domain; 149} 150#define INIT_TEXTDOMAIN COMMON_INTERCEPT_FUNCTION(textdomain) 151#else 152#define INIT_TEXTDOMAIN 153#endif 154 155#if SANITIZER_INTERCEPT_STRCMP 156static inline int CharCmpX(unsigned char c1, unsigned char c2) { 157 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 158} 159 160INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 161 void *ctx; 162 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 163 unsigned char c1, c2; 164 uptr i; 165 for (i = 0;; i++) { 166 c1 = (unsigned char)s1[i]; 167 c2 = (unsigned char)s2[i]; 168 if (c1 != c2 || c1 == '\0') break; 169 } 170 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 171 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 172 return CharCmpX(c1, c2); 173} 174 175INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 176 void *ctx; 177 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 178 unsigned char c1 = 0, c2 = 0; 179 uptr i; 180 for (i = 0; i < size; i++) { 181 c1 = (unsigned char)s1[i]; 182 c2 = (unsigned char)s2[i]; 183 if (c1 != c2 || c1 == '\0') break; 184 } 185 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 186 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 187 return CharCmpX(c1, c2); 188} 189 190#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) 191#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp) 192#else 193#define INIT_STRCMP 194#define INIT_STRNCMP 195#endif 196 197#if SANITIZER_INTERCEPT_STRCASECMP 198static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 199 int c1_low = ToLower(c1); 200 int c2_low = ToLower(c2); 201 return c1_low - c2_low; 202} 203 204INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 205 void *ctx; 206 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 207 unsigned char c1 = 0, c2 = 0; 208 uptr i; 209 for (i = 0;; i++) { 210 c1 = (unsigned char)s1[i]; 211 c2 = (unsigned char)s2[i]; 212 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 213 } 214 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 215 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 216 return CharCaseCmp(c1, c2); 217} 218 219INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 220 void *ctx; 221 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 222 unsigned char c1 = 0, c2 = 0; 223 uptr i; 224 for (i = 0; i < n; i++) { 225 c1 = (unsigned char)s1[i]; 226 c2 = (unsigned char)s2[i]; 227 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 228 } 229 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 230 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 231 return CharCaseCmp(c1, c2); 232} 233 234#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp) 235#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp) 236#else 237#define INIT_STRCASECMP 238#define INIT_STRNCASECMP 239#endif 240 241#if SANITIZER_INTERCEPT_MEMCHR 242INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) { 243 void *ctx; 244 COMMON_INTERCEPTOR_ENTER(ctx, memchr, s, c, n); 245 void *res = REAL(memchr)(s, c, n); 246 uptr len = res ? (char*)res - (char*)s + 1 : n; 247 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, len); 248 return res; 249} 250 251#define INIT_MEMCHR COMMON_INTERCEPT_FUNCTION(memchr) 252#else 253#define INIT_MEMCHR 254#endif 255 256#if SANITIZER_INTERCEPT_MEMRCHR 257INTERCEPTOR(void*, memrchr, const void *s, int c, SIZE_T n) { 258 void *ctx; 259 COMMON_INTERCEPTOR_ENTER(ctx, memrchr, s, c, n); 260 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, n); 261 return REAL(memrchr)(s, c, n); 262} 263 264#define INIT_MEMRCHR COMMON_INTERCEPT_FUNCTION(memrchr) 265#else 266#define INIT_MEMRCHR 267#endif 268 269#if SANITIZER_INTERCEPT_FREXP 270INTERCEPTOR(double, frexp, double x, int *exp) { 271 void *ctx; 272 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 273 double res = REAL(frexp)(x, exp); 274 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 275 return res; 276} 277 278#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp); 279#else 280#define INIT_FREXP 281#endif // SANITIZER_INTERCEPT_FREXP 282 283#if SANITIZER_INTERCEPT_FREXPF_FREXPL 284INTERCEPTOR(float, frexpf, float x, int *exp) { 285 void *ctx; 286 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 287 float res = REAL(frexpf)(x, exp); 288 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 289 return res; 290} 291 292INTERCEPTOR(long double, frexpl, long double x, int *exp) { 293 void *ctx; 294 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 295 long double res = REAL(frexpl)(x, exp); 296 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 297 return res; 298} 299 300#define INIT_FREXPF_FREXPL \ 301 COMMON_INTERCEPT_FUNCTION(frexpf); \ 302 COMMON_INTERCEPT_FUNCTION(frexpl) 303#else 304#define INIT_FREXPF_FREXPL 305#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 306 307#if SI_NOT_WINDOWS 308static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 309 SIZE_T iovlen, SIZE_T maxlen) { 310 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 311 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 312 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 313 maxlen -= sz; 314 } 315} 316 317static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 318 SIZE_T iovlen, SIZE_T maxlen) { 319 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 320 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 321 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 322 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 323 maxlen -= sz; 324 } 325} 326#endif 327 328#if SANITIZER_INTERCEPT_READ 329INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 330 void *ctx; 331 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 332 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 333 SSIZE_T res = REAL(read)(fd, ptr, count); 334 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 335 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 336 return res; 337} 338#define INIT_READ COMMON_INTERCEPT_FUNCTION(read) 339#else 340#define INIT_READ 341#endif 342 343#if SANITIZER_INTERCEPT_PREAD 344INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 345 void *ctx; 346 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 347 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 348 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 349 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 350 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 351 return res; 352} 353#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread) 354#else 355#define INIT_PREAD 356#endif 357 358#if SANITIZER_INTERCEPT_PREAD64 359INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 360 void *ctx; 361 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 362 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 363 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 364 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 365 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 366 return res; 367} 368#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64) 369#else 370#define INIT_PREAD64 371#endif 372 373#if SANITIZER_INTERCEPT_READV 374INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 375 int iovcnt) { 376 void *ctx; 377 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 378 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 379 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 380 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 381 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 382 return res; 383} 384#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv) 385#else 386#define INIT_READV 387#endif 388 389#if SANITIZER_INTERCEPT_PREADV 390INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 391 OFF_T offset) { 392 void *ctx; 393 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 394 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 395 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 396 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 397 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 398 return res; 399} 400#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv) 401#else 402#define INIT_PREADV 403#endif 404 405#if SANITIZER_INTERCEPT_PREADV64 406INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 407 OFF64_T offset) { 408 void *ctx; 409 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 410 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 411 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 412 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 413 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 414 return res; 415} 416#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64) 417#else 418#define INIT_PREADV64 419#endif 420 421#if SANITIZER_INTERCEPT_WRITE 422INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 423 void *ctx; 424 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 425 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 426 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 427 SSIZE_T res = REAL(write)(fd, ptr, count); 428 // FIXME: this check should be _before_ the call to REAL(write), not after 429 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 430 return res; 431} 432#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write) 433#else 434#define INIT_WRITE 435#endif 436 437#if SANITIZER_INTERCEPT_PWRITE 438INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 439 void *ctx; 440 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 441 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 442 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 443 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 444 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 445 return res; 446} 447#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite) 448#else 449#define INIT_PWRITE 450#endif 451 452#if SANITIZER_INTERCEPT_PWRITE64 453INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 454 OFF64_T offset) { 455 void *ctx; 456 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 457 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 458 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 459 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 460 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 461 return res; 462} 463#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64) 464#else 465#define INIT_PWRITE64 466#endif 467 468#if SANITIZER_INTERCEPT_WRITEV 469INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 470 int iovcnt) { 471 void *ctx; 472 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 473 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 474 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 475 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 476 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 477 return res; 478} 479#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev) 480#else 481#define INIT_WRITEV 482#endif 483 484#if SANITIZER_INTERCEPT_PWRITEV 485INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 486 OFF_T offset) { 487 void *ctx; 488 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 489 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 490 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 491 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 492 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 493 return res; 494} 495#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev) 496#else 497#define INIT_PWRITEV 498#endif 499 500#if SANITIZER_INTERCEPT_PWRITEV64 501INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 502 OFF64_T offset) { 503 void *ctx; 504 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 505 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 506 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 507 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 508 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 509 return res; 510} 511#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64) 512#else 513#define INIT_PWRITEV64 514#endif 515 516#if SANITIZER_INTERCEPT_PRCTL 517INTERCEPTOR(int, prctl, int option, unsigned long arg2, 518 unsigned long arg3, // NOLINT 519 unsigned long arg4, unsigned long arg5) { // NOLINT 520 void *ctx; 521 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 522 static const int PR_SET_NAME = 15; 523 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 524 if (option == PR_SET_NAME) { 525 char buff[16]; 526 internal_strncpy(buff, (char *)arg2, 15); 527 buff[15] = 0; 528 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 529 } 530 return res; 531} 532#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) 533#else 534#define INIT_PRCTL 535#endif // SANITIZER_INTERCEPT_PRCTL 536 537#if SANITIZER_INTERCEPT_TIME 538INTERCEPTOR(unsigned long, time, unsigned long *t) { 539 void *ctx; 540 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 541 unsigned long res = REAL(time)(t); 542 if (t && res != (unsigned long)-1) { 543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 544 } 545 return res; 546} 547#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time); 548#else 549#define INIT_TIME 550#endif // SANITIZER_INTERCEPT_TIME 551 552#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 553static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 555 if (tm->tm_zone) { 556 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 557 // can point to shared memory and tsan would report a data race. 558 COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, 559 REAL(strlen(tm->tm_zone)) + 1); 560 } 561} 562INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 563 void *ctx; 564 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 565 __sanitizer_tm *res = REAL(localtime)(timep); 566 if (res) { 567 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 568 unpoison_tm(ctx, res); 569 } 570 return res; 571} 572INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 573 void *ctx; 574 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 575 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 576 if (res) { 577 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 578 unpoison_tm(ctx, res); 579 } 580 return res; 581} 582INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 583 void *ctx; 584 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 585 __sanitizer_tm *res = REAL(gmtime)(timep); 586 if (res) { 587 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 588 unpoison_tm(ctx, res); 589 } 590 return res; 591} 592INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 593 void *ctx; 594 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 595 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 596 if (res) { 597 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 598 unpoison_tm(ctx, res); 599 } 600 return res; 601} 602INTERCEPTOR(char *, ctime, unsigned long *timep) { 603 void *ctx; 604 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 605 char *res = REAL(ctime)(timep); 606 if (res) { 607 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 608 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 609 } 610 return res; 611} 612INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 613 void *ctx; 614 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 615 char *res = REAL(ctime_r)(timep, result); 616 if (res) { 617 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 618 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 619 } 620 return res; 621} 622INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 623 void *ctx; 624 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 625 char *res = REAL(asctime)(tm); 626 if (res) { 627 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 628 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 629 } 630 return res; 631} 632INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 633 void *ctx; 634 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 635 char *res = REAL(asctime_r)(tm, result); 636 if (res) { 637 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 639 } 640 return res; 641} 642INTERCEPTOR(long, mktime, __sanitizer_tm *tm) { 643 void *ctx; 644 COMMON_INTERCEPTOR_ENTER(ctx, mktime, tm); 645 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_sec, sizeof(tm->tm_sec)); 646 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_min, sizeof(tm->tm_min)); 647 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_hour, sizeof(tm->tm_hour)); 648 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mday, sizeof(tm->tm_mday)); 649 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_mon, sizeof(tm->tm_mon)); 650 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_year, sizeof(tm->tm_year)); 651 COMMON_INTERCEPTOR_READ_RANGE(ctx, &tm->tm_isdst, sizeof(tm->tm_isdst)); 652 long res = REAL(mktime)(tm); 653 if (res != -1) unpoison_tm(ctx, tm); 654 return res; 655} 656#define INIT_LOCALTIME_AND_FRIENDS \ 657 COMMON_INTERCEPT_FUNCTION(localtime); \ 658 COMMON_INTERCEPT_FUNCTION(localtime_r); \ 659 COMMON_INTERCEPT_FUNCTION(gmtime); \ 660 COMMON_INTERCEPT_FUNCTION(gmtime_r); \ 661 COMMON_INTERCEPT_FUNCTION(ctime); \ 662 COMMON_INTERCEPT_FUNCTION(ctime_r); \ 663 COMMON_INTERCEPT_FUNCTION(asctime); \ 664 COMMON_INTERCEPT_FUNCTION(asctime_r); \ 665 COMMON_INTERCEPT_FUNCTION(mktime); 666#else 667#define INIT_LOCALTIME_AND_FRIENDS 668#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 669 670#if SANITIZER_INTERCEPT_STRPTIME 671INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { 672 void *ctx; 673 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); 674 if (format) 675 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); 676 char *res = REAL(strptime)(s, format, tm); 677 if (res) { 678 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s); 679 // Do not call unpoison_tm here, because strptime does not, in fact, 680 // initialize the entire struct tm. For example, tm_zone pointer is left 681 // uninitialized. 682 if (tm) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 683 } 684 return res; 685} 686#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime); 687#else 688#define INIT_STRPTIME 689#endif 690 691#if SANITIZER_INTERCEPT_SCANF || SANITIZER_INTERCEPT_PRINTF 692#include "sanitizer_common_interceptors_format.inc" 693 694#define FORMAT_INTERCEPTOR_IMPL(name, vname, ...) \ 695 { \ 696 void *ctx; \ 697 va_list ap; \ 698 va_start(ap, format); \ 699 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 700 int res = WRAP(vname)(__VA_ARGS__, ap); \ 701 va_end(ap); \ 702 return res; \ 703 } 704 705#endif 706 707#if SANITIZER_INTERCEPT_SCANF 708 709#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 710 { \ 711 void *ctx; \ 712 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 713 va_list aq; \ 714 va_copy(aq, ap); \ 715 int res = REAL(vname)(__VA_ARGS__); \ 716 if (res > 0) \ 717 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 718 va_end(aq); \ 719 return res; \ 720 } 721 722INTERCEPTOR(int, vscanf, const char *format, va_list ap) 723VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 724 725INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 726VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 727 728INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 729VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 730 731#if SANITIZER_INTERCEPT_ISOC99_SCANF 732INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 733VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 734 735INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 736 va_list ap) 737VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 738 739INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 740VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 741#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 742 743INTERCEPTOR(int, scanf, const char *format, ...) 744FORMAT_INTERCEPTOR_IMPL(scanf, vscanf, format) 745 746INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 747FORMAT_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 748 749INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 750FORMAT_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 751 752#if SANITIZER_INTERCEPT_ISOC99_SCANF 753INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 754FORMAT_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 755 756INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 757FORMAT_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 758 759INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 760FORMAT_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 761#endif 762 763#endif 764 765#if SANITIZER_INTERCEPT_SCANF 766#define INIT_SCANF \ 767 COMMON_INTERCEPT_FUNCTION(scanf); \ 768 COMMON_INTERCEPT_FUNCTION(sscanf); \ 769 COMMON_INTERCEPT_FUNCTION(fscanf); \ 770 COMMON_INTERCEPT_FUNCTION(vscanf); \ 771 COMMON_INTERCEPT_FUNCTION(vsscanf); \ 772 COMMON_INTERCEPT_FUNCTION(vfscanf); 773#else 774#define INIT_SCANF 775#endif 776 777#if SANITIZER_INTERCEPT_ISOC99_SCANF 778#define INIT_ISOC99_SCANF \ 779 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \ 780 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \ 781 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ 782 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ 783 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 784 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); 785#else 786#define INIT_ISOC99_SCANF 787#endif 788 789#if SANITIZER_INTERCEPT_PRINTF 790 791#define VPRINTF_INTERCEPTOR_ENTER(vname, ...) \ 792 void *ctx; \ 793 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 794 va_list aq; \ 795 va_copy(aq, ap); 796 797#define VPRINTF_INTERCEPTOR_RETURN() \ 798 va_end(aq); 799 800#define VPRINTF_INTERCEPTOR_IMPL(vname, ...) \ 801 { \ 802 VPRINTF_INTERCEPTOR_ENTER(vname, __VA_ARGS__); \ 803 if (common_flags()->check_printf) \ 804 printf_common(ctx, format, aq); \ 805 int res = REAL(vname)(__VA_ARGS__); \ 806 VPRINTF_INTERCEPTOR_RETURN(); \ 807 return res; \ 808 } 809 810#define VSPRINTF_INTERCEPTOR_IMPL(vname, str, ...) \ 811 { \ 812 VPRINTF_INTERCEPTOR_ENTER(vname, str, __VA_ARGS__) \ 813 if (common_flags()->check_printf) { \ 814 printf_common(ctx, format, aq); \ 815 } \ 816 int res = REAL(vname)(str, __VA_ARGS__); \ 817 if (res >= 0) { \ 818 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, res + 1); \ 819 } \ 820 VPRINTF_INTERCEPTOR_RETURN(); \ 821 return res; \ 822 } 823 824#define VSNPRINTF_INTERCEPTOR_IMPL(vname, str, size, ...) \ 825 { \ 826 VPRINTF_INTERCEPTOR_ENTER(vname, str, size, __VA_ARGS__) \ 827 if (common_flags()->check_printf) { \ 828 printf_common(ctx, format, aq); \ 829 } \ 830 int res = REAL(vname)(str, size, __VA_ARGS__); \ 831 if (res >= 0) { \ 832 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, Min(size, (SIZE_T)(res + 1))); \ 833 } \ 834 VPRINTF_INTERCEPTOR_RETURN(); \ 835 return res; \ 836 } 837 838#define VASPRINTF_INTERCEPTOR_IMPL(vname, strp, ...) \ 839 { \ 840 VPRINTF_INTERCEPTOR_ENTER(vname, strp, __VA_ARGS__) \ 841 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, strp, sizeof(char *)); \ 842 if (common_flags()->check_printf) { \ 843 printf_common(ctx, format, aq); \ 844 } \ 845 int res = REAL(vname)(strp, __VA_ARGS__); \ 846 if (res >= 0) { \ 847 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *strp, res + 1); \ 848 } \ 849 VPRINTF_INTERCEPTOR_RETURN(); \ 850 return res; \ 851 } 852 853INTERCEPTOR(int, vprintf, const char *format, va_list ap) 854VPRINTF_INTERCEPTOR_IMPL(vprintf, format, ap) 855 856INTERCEPTOR(int, vfprintf, __sanitizer_FILE *stream, const char *format, 857 va_list ap) 858VPRINTF_INTERCEPTOR_IMPL(vfprintf, stream, format, ap) 859 860INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format, 861 va_list ap) 862VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) 863 864INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) 865VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) 866 867INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) 868VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) 869 870#if SANITIZER_INTERCEPT_ISOC99_PRINTF 871INTERCEPTOR(int, __isoc99_vprintf, const char *format, va_list ap) 872VPRINTF_INTERCEPTOR_IMPL(__isoc99_vprintf, format, ap) 873 874INTERCEPTOR(int, __isoc99_vfprintf, __sanitizer_FILE *stream, 875 const char *format, va_list ap) 876VPRINTF_INTERCEPTOR_IMPL(__isoc99_vfprintf, stream, format, ap) 877 878INTERCEPTOR(int, __isoc99_vsnprintf, char *str, SIZE_T size, const char *format, 879 va_list ap) 880VSNPRINTF_INTERCEPTOR_IMPL(__isoc99_vsnprintf, str, size, format, ap) 881 882INTERCEPTOR(int, __isoc99_vsprintf, char *str, const char *format, 883 va_list ap) 884VSPRINTF_INTERCEPTOR_IMPL(__isoc99_vsprintf, str, format, 885 ap) 886 887#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 888 889INTERCEPTOR(int, printf, const char *format, ...) 890FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format) 891 892INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...) 893FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format) 894 895INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT 896FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT 897 898INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) 899FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) 900 901INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) 902FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) 903 904#if SANITIZER_INTERCEPT_ISOC99_PRINTF 905INTERCEPTOR(int, __isoc99_printf, const char *format, ...) 906FORMAT_INTERCEPTOR_IMPL(__isoc99_printf, __isoc99_vprintf, format) 907 908INTERCEPTOR(int, __isoc99_fprintf, __sanitizer_FILE *stream, const char *format, 909 ...) 910FORMAT_INTERCEPTOR_IMPL(__isoc99_fprintf, __isoc99_vfprintf, stream, format) 911 912INTERCEPTOR(int, __isoc99_sprintf, char *str, const char *format, ...) 913FORMAT_INTERCEPTOR_IMPL(__isoc99_sprintf, __isoc99_vsprintf, str, format) 914 915INTERCEPTOR(int, __isoc99_snprintf, char *str, SIZE_T size, 916 const char *format, ...) 917FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, 918 format) 919 920#endif // SANITIZER_INTERCEPT_ISOC99_PRINTF 921 922#endif // SANITIZER_INTERCEPT_PRINTF 923 924#if SANITIZER_INTERCEPT_PRINTF 925#define INIT_PRINTF \ 926 COMMON_INTERCEPT_FUNCTION(printf); \ 927 COMMON_INTERCEPT_FUNCTION(sprintf); \ 928 COMMON_INTERCEPT_FUNCTION(snprintf); \ 929 COMMON_INTERCEPT_FUNCTION(asprintf); \ 930 COMMON_INTERCEPT_FUNCTION(fprintf); \ 931 COMMON_INTERCEPT_FUNCTION(vprintf); \ 932 COMMON_INTERCEPT_FUNCTION(vsprintf); \ 933 COMMON_INTERCEPT_FUNCTION(vsnprintf); \ 934 COMMON_INTERCEPT_FUNCTION(vasprintf); \ 935 COMMON_INTERCEPT_FUNCTION(vfprintf); 936#else 937#define INIT_PRINTF 938#endif 939 940#if SANITIZER_INTERCEPT_ISOC99_PRINTF 941#define INIT_ISOC99_PRINTF \ 942 COMMON_INTERCEPT_FUNCTION(__isoc99_printf); \ 943 COMMON_INTERCEPT_FUNCTION(__isoc99_sprintf); \ 944 COMMON_INTERCEPT_FUNCTION(__isoc99_snprintf); \ 945 COMMON_INTERCEPT_FUNCTION(__isoc99_fprintf); \ 946 COMMON_INTERCEPT_FUNCTION(__isoc99_vprintf); \ 947 COMMON_INTERCEPT_FUNCTION(__isoc99_vsprintf); \ 948 COMMON_INTERCEPT_FUNCTION(__isoc99_vsnprintf); \ 949 COMMON_INTERCEPT_FUNCTION(__isoc99_vfprintf); 950#else 951#define INIT_ISOC99_PRINTF 952#endif 953 954#if SANITIZER_INTERCEPT_IOCTL 955#include "sanitizer_common_interceptors_ioctl.inc" 956INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 957 void *ctx; 958 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 959 960 CHECK(ioctl_initialized); 961 962 // Note: TSan does not use common flags, and they are zero-initialized. 963 // This effectively disables ioctl handling in TSan. 964 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg); 965 966 const ioctl_desc *desc = ioctl_lookup(request); 967 ioctl_desc decoded_desc; 968 if (!desc) { 969 VPrintf(2, "Decoding unknown ioctl 0x%x\n", request); 970 if (!ioctl_decode(request, &decoded_desc)) 971 Printf("WARNING: failed decoding unknown ioctl 0x%x\n", request); 972 else 973 desc = &decoded_desc; 974 } 975 976 if (desc) ioctl_common_pre(ctx, desc, d, request, arg); 977 int res = REAL(ioctl)(d, request, arg); 978 // FIXME: some ioctls have different return values for success and failure. 979 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg); 980 return res; 981} 982#define INIT_IOCTL \ 983 ioctl_init(); \ 984 COMMON_INTERCEPT_FUNCTION(ioctl); 985#else 986#define INIT_IOCTL 987#endif 988 989#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \ 990 SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT 991static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { 992 if (pwd) { 993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); 994 if (pwd->pw_name) 995 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name, 996 REAL(strlen)(pwd->pw_name) + 1); 997 if (pwd->pw_passwd) 998 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd, 999 REAL(strlen)(pwd->pw_passwd) + 1); 1000#if !SANITIZER_ANDROID 1001 if (pwd->pw_gecos) 1002 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos, 1003 REAL(strlen)(pwd->pw_gecos) + 1); 1004#endif 1005#if SANITIZER_MAC 1006 if (pwd->pw_class) 1007 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class, 1008 REAL(strlen)(pwd->pw_class) + 1); 1009#endif 1010 if (pwd->pw_dir) 1011 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir, 1012 REAL(strlen)(pwd->pw_dir) + 1); 1013 if (pwd->pw_shell) 1014 COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell, 1015 REAL(strlen)(pwd->pw_shell) + 1); 1016 } 1017} 1018 1019static void unpoison_group(void *ctx, __sanitizer_group *grp) { 1020 if (grp) { 1021 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); 1022 if (grp->gr_name) 1023 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name, 1024 REAL(strlen)(grp->gr_name) + 1); 1025 if (grp->gr_passwd) 1026 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd, 1027 REAL(strlen)(grp->gr_passwd) + 1); 1028 char **p = grp->gr_mem; 1029 for (; *p; ++p) { 1030 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1); 1031 } 1032 COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem, 1033 (p - grp->gr_mem + 1) * sizeof(*p)); 1034 } 1035} 1036#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || 1037 // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT 1038 1039#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 1040INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { 1041 void *ctx; 1042 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 1043 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1044 __sanitizer_passwd *res = REAL(getpwnam)(name); 1045 if (res != 0) unpoison_passwd(ctx, res); 1046 return res; 1047} 1048INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { 1049 void *ctx; 1050 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 1051 __sanitizer_passwd *res = REAL(getpwuid)(uid); 1052 if (res != 0) unpoison_passwd(ctx, res); 1053 return res; 1054} 1055INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { 1056 void *ctx; 1057 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 1058 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1059 __sanitizer_group *res = REAL(getgrnam)(name); 1060 if (res != 0) unpoison_group(ctx, res); 1061 return res; 1062} 1063INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) { 1064 void *ctx; 1065 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 1066 __sanitizer_group *res = REAL(getgrgid)(gid); 1067 if (res != 0) unpoison_group(ctx, res); 1068 return res; 1069} 1070#define INIT_GETPWNAM_AND_FRIENDS \ 1071 COMMON_INTERCEPT_FUNCTION(getpwnam); \ 1072 COMMON_INTERCEPT_FUNCTION(getpwuid); \ 1073 COMMON_INTERCEPT_FUNCTION(getgrnam); \ 1074 COMMON_INTERCEPT_FUNCTION(getgrgid); 1075#else 1076#define INIT_GETPWNAM_AND_FRIENDS 1077#endif 1078 1079#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 1080INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, 1081 char *buf, SIZE_T buflen, __sanitizer_passwd **result) { 1082 void *ctx; 1083 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 1084 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1085 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 1086 if (!res) { 1087 if (result && *result) unpoison_passwd(ctx, *result); 1088 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1089 } 1090 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1091 return res; 1092} 1093INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf, 1094 SIZE_T buflen, __sanitizer_passwd **result) { 1095 void *ctx; 1096 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 1097 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 1098 if (!res) { 1099 if (result && *result) unpoison_passwd(ctx, *result); 1100 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1101 } 1102 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1103 return res; 1104} 1105INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, 1106 char *buf, SIZE_T buflen, __sanitizer_group **result) { 1107 void *ctx; 1108 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 1109 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 1110 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 1111 if (!res) { 1112 if (result && *result) unpoison_group(ctx, *result); 1113 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1114 } 1115 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1116 return res; 1117} 1118INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf, 1119 SIZE_T buflen, __sanitizer_group **result) { 1120 void *ctx; 1121 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 1122 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 1123 if (!res) { 1124 if (result && *result) unpoison_group(ctx, *result); 1125 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1126 } 1127 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1128 return res; 1129} 1130#define INIT_GETPWNAM_R_AND_FRIENDS \ 1131 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \ 1132 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \ 1133 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \ 1134 COMMON_INTERCEPT_FUNCTION(getgrgid_r); 1135#else 1136#define INIT_GETPWNAM_R_AND_FRIENDS 1137#endif 1138 1139#if SANITIZER_INTERCEPT_GETPWENT 1140INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) { 1141 void *ctx; 1142 COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy); 1143 __sanitizer_passwd *res = REAL(getpwent)(dummy); 1144 if (res != 0) unpoison_passwd(ctx, res); 1145 return res; 1146} 1147INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) { 1148 void *ctx; 1149 COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy); 1150 __sanitizer_group *res = REAL(getgrent)(dummy); 1151 if (res != 0) unpoison_group(ctx, res);; 1152 return res; 1153} 1154#define INIT_GETPWENT \ 1155 COMMON_INTERCEPT_FUNCTION(getpwent); \ 1156 COMMON_INTERCEPT_FUNCTION(getgrent); 1157#else 1158#define INIT_GETPWENT 1159#endif 1160 1161#if SANITIZER_INTERCEPT_FGETPWENT 1162INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) { 1163 void *ctx; 1164 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp); 1165 __sanitizer_passwd *res = REAL(fgetpwent)(fp); 1166 if (res != 0) unpoison_passwd(ctx, res); 1167 return res; 1168} 1169INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) { 1170 void *ctx; 1171 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp); 1172 __sanitizer_group *res = REAL(fgetgrent)(fp); 1173 if (res != 0) unpoison_group(ctx, res); 1174 return res; 1175} 1176#define INIT_FGETPWENT \ 1177 COMMON_INTERCEPT_FUNCTION(fgetpwent); \ 1178 COMMON_INTERCEPT_FUNCTION(fgetgrent); 1179#else 1180#define INIT_FGETPWENT 1181#endif 1182 1183#if SANITIZER_INTERCEPT_GETPWENT_R 1184INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf, 1185 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 1186 void *ctx; 1187 COMMON_INTERCEPTOR_ENTER(ctx, getpwent_r, pwbuf, buf, buflen, pwbufp); 1188 int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp); 1189 if (!res) { 1190 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 1191 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1192 } 1193 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 1194 return res; 1195} 1196INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, 1197 SIZE_T buflen, __sanitizer_passwd **pwbufp) { 1198 void *ctx; 1199 COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); 1200 int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); 1201 if (!res) { 1202 if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); 1203 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1204 } 1205 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 1206 return res; 1207} 1208INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, 1209 __sanitizer_group **pwbufp) { 1210 void *ctx; 1211 COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); 1212 int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); 1213 if (!res) { 1214 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 1215 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1216 } 1217 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 1218 return res; 1219} 1220INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, 1221 SIZE_T buflen, __sanitizer_group **pwbufp) { 1222 void *ctx; 1223 COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent_r, fp, pwbuf, buf, buflen, pwbufp); 1224 int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp); 1225 if (!res) { 1226 if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); 1227 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 1228 } 1229 if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); 1230 return res; 1231} 1232#define INIT_GETPWENT_R \ 1233 COMMON_INTERCEPT_FUNCTION(getpwent_r); \ 1234 COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \ 1235 COMMON_INTERCEPT_FUNCTION(getgrent_r); \ 1236 COMMON_INTERCEPT_FUNCTION(fgetgrent_r); 1237#else 1238#define INIT_GETPWENT_R 1239#endif 1240 1241#if SANITIZER_INTERCEPT_SETPWENT 1242// The only thing these interceptors do is disable any nested interceptors. 1243// These functions may open nss modules and call uninstrumented functions from 1244// them, and we don't want things like strlen() to trigger. 1245INTERCEPTOR(void, setpwent, int dummy) { 1246 void *ctx; 1247 COMMON_INTERCEPTOR_ENTER(ctx, setpwent, dummy); 1248 REAL(setpwent)(dummy); 1249} 1250INTERCEPTOR(void, endpwent, int dummy) { 1251 void *ctx; 1252 COMMON_INTERCEPTOR_ENTER(ctx, endpwent, dummy); 1253 REAL(endpwent)(dummy); 1254} 1255INTERCEPTOR(void, setgrent, int dummy) { 1256 void *ctx; 1257 COMMON_INTERCEPTOR_ENTER(ctx, setgrent, dummy); 1258 REAL(setgrent)(dummy); 1259} 1260INTERCEPTOR(void, endgrent, int dummy) { 1261 void *ctx; 1262 COMMON_INTERCEPTOR_ENTER(ctx, endgrent, dummy); 1263 REAL(endgrent)(dummy); 1264} 1265#define INIT_SETPWENT \ 1266 COMMON_INTERCEPT_FUNCTION(setpwent); \ 1267 COMMON_INTERCEPT_FUNCTION(endpwent); \ 1268 COMMON_INTERCEPT_FUNCTION(setgrent); \ 1269 COMMON_INTERCEPT_FUNCTION(endgrent); 1270#else 1271#define INIT_SETPWENT 1272#endif 1273 1274#if SANITIZER_INTERCEPT_CLOCK_GETTIME 1275INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 1276 void *ctx; 1277 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 1278 int res = REAL(clock_getres)(clk_id, tp); 1279 if (!res && tp) { 1280 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 1281 } 1282 return res; 1283} 1284INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 1285 void *ctx; 1286 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 1287 int res = REAL(clock_gettime)(clk_id, tp); 1288 if (!res) { 1289 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 1290 } 1291 return res; 1292} 1293INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 1294 void *ctx; 1295 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 1296 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 1297 return REAL(clock_settime)(clk_id, tp); 1298} 1299#define INIT_CLOCK_GETTIME \ 1300 COMMON_INTERCEPT_FUNCTION(clock_getres); \ 1301 COMMON_INTERCEPT_FUNCTION(clock_gettime); \ 1302 COMMON_INTERCEPT_FUNCTION(clock_settime); 1303#else 1304#define INIT_CLOCK_GETTIME 1305#endif 1306 1307#if SANITIZER_INTERCEPT_GETITIMER 1308INTERCEPTOR(int, getitimer, int which, void *curr_value) { 1309 void *ctx; 1310 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 1311 int res = REAL(getitimer)(which, curr_value); 1312 if (!res && curr_value) { 1313 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 1314 } 1315 return res; 1316} 1317INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 1318 void *ctx; 1319 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 1320 if (new_value) 1321 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 1322 int res = REAL(setitimer)(which, new_value, old_value); 1323 if (!res && old_value) { 1324 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 1325 } 1326 return res; 1327} 1328#define INIT_GETITIMER \ 1329 COMMON_INTERCEPT_FUNCTION(getitimer); \ 1330 COMMON_INTERCEPT_FUNCTION(setitimer); 1331#else 1332#define INIT_GETITIMER 1333#endif 1334 1335#if SANITIZER_INTERCEPT_GLOB 1336static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 1337 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 1338 // +1 for NULL pointer at the end. 1339 if (pglob->gl_pathv) 1340 COMMON_INTERCEPTOR_WRITE_RANGE( 1341 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 1342 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 1343 char *p = pglob->gl_pathv[i]; 1344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 1345 } 1346} 1347 1348static THREADLOCAL __sanitizer_glob_t *pglob_copy; 1349 1350static void wrapped_gl_closedir(void *dir) { 1351 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 1352 IndirectExternCall(pglob_copy->gl_closedir)(dir); 1353} 1354 1355static void *wrapped_gl_readdir(void *dir) { 1356 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 1357 return IndirectExternCall(pglob_copy->gl_readdir)(dir); 1358} 1359 1360static void *wrapped_gl_opendir(const char *s) { 1361 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 1362 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 1363 return IndirectExternCall(pglob_copy->gl_opendir)(s); 1364} 1365 1366static int wrapped_gl_lstat(const char *s, void *st) { 1367 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 1368 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 1369 return IndirectExternCall(pglob_copy->gl_lstat)(s, st); 1370} 1371 1372static int wrapped_gl_stat(const char *s, void *st) { 1373 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 1374 COMMON_INTERCEPTOR_INITIALIZE_RANGE(s, REAL(strlen)(s) + 1); 1375 return IndirectExternCall(pglob_copy->gl_stat)(s, st); 1376} 1377 1378INTERCEPTOR(int, glob, const char *pattern, int flags, 1379 int (*errfunc)(const char *epath, int eerrno), 1380 __sanitizer_glob_t *pglob) { 1381 void *ctx; 1382 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 1383 __sanitizer_glob_t glob_copy = { 1384 0, 0, 0, 1385 0, wrapped_gl_closedir, wrapped_gl_readdir, 1386 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 1387 if (flags & glob_altdirfunc) { 1388 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 1389 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 1390 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 1391 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 1392 Swap(pglob->gl_stat, glob_copy.gl_stat); 1393 pglob_copy = &glob_copy; 1394 } 1395 int res = REAL(glob)(pattern, flags, errfunc, pglob); 1396 if (flags & glob_altdirfunc) { 1397 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 1398 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 1399 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 1400 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 1401 Swap(pglob->gl_stat, glob_copy.gl_stat); 1402 } 1403 pglob_copy = 0; 1404 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 1405 return res; 1406} 1407 1408INTERCEPTOR(int, glob64, const char *pattern, int flags, 1409 int (*errfunc)(const char *epath, int eerrno), 1410 __sanitizer_glob_t *pglob) { 1411 void *ctx; 1412 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 1413 __sanitizer_glob_t glob_copy = { 1414 0, 0, 0, 1415 0, wrapped_gl_closedir, wrapped_gl_readdir, 1416 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 1417 if (flags & glob_altdirfunc) { 1418 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 1419 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 1420 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 1421 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 1422 Swap(pglob->gl_stat, glob_copy.gl_stat); 1423 pglob_copy = &glob_copy; 1424 } 1425 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 1426 if (flags & glob_altdirfunc) { 1427 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 1428 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 1429 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 1430 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 1431 Swap(pglob->gl_stat, glob_copy.gl_stat); 1432 } 1433 pglob_copy = 0; 1434 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 1435 return res; 1436} 1437#define INIT_GLOB \ 1438 COMMON_INTERCEPT_FUNCTION(glob); \ 1439 COMMON_INTERCEPT_FUNCTION(glob64); 1440#else // SANITIZER_INTERCEPT_GLOB 1441#define INIT_GLOB 1442#endif // SANITIZER_INTERCEPT_GLOB 1443 1444#if SANITIZER_INTERCEPT_WAIT 1445// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 1446// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 1447// details. 1448INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 1449 void *ctx; 1450 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 1451 int res = REAL(wait)(status); 1452 if (res != -1 && status) 1453 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 1454 return res; 1455} 1456INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 1457 int options) { 1458 void *ctx; 1459 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 1460 int res = REAL(waitid)(idtype, id, infop, options); 1461 if (res != -1 && infop) 1462 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 1463 return res; 1464} 1465INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 1466 void *ctx; 1467 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 1468 int res = REAL(waitpid)(pid, status, options); 1469 if (res != -1 && status) 1470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 1471 return res; 1472} 1473INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 1474 void *ctx; 1475 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 1476 int res = REAL(wait3)(status, options, rusage); 1477 if (res != -1) { 1478 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 1479 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 1480 } 1481 return res; 1482} 1483#if SANITIZER_ANDROID 1484INTERCEPTOR(int, __wait4, int pid, int *status, int options, void *rusage) { 1485 void *ctx; 1486 COMMON_INTERCEPTOR_ENTER(ctx, __wait4, pid, status, options, rusage); 1487 int res = REAL(__wait4)(pid, status, options, rusage); 1488 if (res != -1) { 1489 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 1490 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 1491 } 1492 return res; 1493} 1494#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(__wait4); 1495#else 1496INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 1497 void *ctx; 1498 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 1499 int res = REAL(wait4)(pid, status, options, rusage); 1500 if (res != -1) { 1501 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 1502 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 1503 } 1504 return res; 1505} 1506#define INIT_WAIT4 COMMON_INTERCEPT_FUNCTION(wait4); 1507#endif // SANITIZER_ANDROID 1508#define INIT_WAIT \ 1509 COMMON_INTERCEPT_FUNCTION(wait); \ 1510 COMMON_INTERCEPT_FUNCTION(waitid); \ 1511 COMMON_INTERCEPT_FUNCTION(waitpid); \ 1512 COMMON_INTERCEPT_FUNCTION(wait3); 1513#else 1514#define INIT_WAIT 1515#define INIT_WAIT4 1516#endif 1517 1518#if SANITIZER_INTERCEPT_INET 1519INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 1520 void *ctx; 1521 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 1522 uptr sz = __sanitizer_in_addr_sz(af); 1523 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 1524 // FIXME: figure out read size based on the address family. 1525 char *res = REAL(inet_ntop)(af, src, dst, size); 1526 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1527 return res; 1528} 1529INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 1530 void *ctx; 1531 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 1532 // FIXME: figure out read size based on the address family. 1533 int res = REAL(inet_pton)(af, src, dst); 1534 if (res == 1) { 1535 uptr sz = __sanitizer_in_addr_sz(af); 1536 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1537 } 1538 return res; 1539} 1540#define INIT_INET \ 1541 COMMON_INTERCEPT_FUNCTION(inet_ntop); \ 1542 COMMON_INTERCEPT_FUNCTION(inet_pton); 1543#else 1544#define INIT_INET 1545#endif 1546 1547#if SANITIZER_INTERCEPT_INET 1548INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 1549 void *ctx; 1550 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1551 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1552 int res = REAL(inet_aton)(cp, dst); 1553 if (res != 0) { 1554 uptr sz = __sanitizer_in_addr_sz(af_inet); 1555 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1556 } 1557 return res; 1558} 1559#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton); 1560#else 1561#define INIT_INET_ATON 1562#endif 1563 1564#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1565INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1566 void *ctx; 1567 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1568 int res = REAL(pthread_getschedparam)(thread, policy, param); 1569 if (res == 0) { 1570 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1571 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1572 } 1573 return res; 1574} 1575#define INIT_PTHREAD_GETSCHEDPARAM \ 1576 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam); 1577#else 1578#define INIT_PTHREAD_GETSCHEDPARAM 1579#endif 1580 1581#if SANITIZER_INTERCEPT_GETADDRINFO 1582INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1583 struct __sanitizer_addrinfo *hints, 1584 struct __sanitizer_addrinfo **out) { 1585 void *ctx; 1586 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1587 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1588 if (service) 1589 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1590 if (hints) 1591 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1592 int res = REAL(getaddrinfo)(node, service, hints, out); 1593 if (res == 0 && out) { 1594 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1595 struct __sanitizer_addrinfo *p = *out; 1596 while (p) { 1597 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1598 if (p->ai_addr) 1599 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1600 if (p->ai_canonname) 1601 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1602 REAL(strlen)(p->ai_canonname) + 1); 1603 p = p->ai_next; 1604 } 1605 } 1606 return res; 1607} 1608#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo); 1609#else 1610#define INIT_GETADDRINFO 1611#endif 1612 1613#if SANITIZER_INTERCEPT_GETNAMEINFO 1614INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1615 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1616 void *ctx; 1617 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1618 serv, servlen, flags); 1619 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1620 // There is padding in in_addr that may make this too noisy 1621 int res = 1622 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1623 if (res == 0) { 1624 if (host && hostlen) 1625 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1626 if (serv && servlen) 1627 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1628 } 1629 return res; 1630} 1631#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo); 1632#else 1633#define INIT_GETNAMEINFO 1634#endif 1635 1636#if SANITIZER_INTERCEPT_GETSOCKNAME 1637INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1638 void *ctx; 1639 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1640 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1641 int addrlen_in = *addrlen; 1642 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1643 if (res == 0) { 1644 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1645 } 1646 return res; 1647} 1648#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname); 1649#else 1650#define INIT_GETSOCKNAME 1651#endif 1652 1653#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1654static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1655 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1656 if (h->h_name) 1657 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1658 char **p = h->h_aliases; 1659 while (*p) { 1660 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1661 ++p; 1662 } 1663 COMMON_INTERCEPTOR_WRITE_RANGE( 1664 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1665 p = h->h_addr_list; 1666 while (*p) { 1667 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1668 ++p; 1669 } 1670 COMMON_INTERCEPTOR_WRITE_RANGE( 1671 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1672} 1673#endif 1674 1675#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1676INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1677 void *ctx; 1678 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1679 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1680 if (res) write_hostent(ctx, res); 1681 return res; 1682} 1683 1684INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1685 int type) { 1686 void *ctx; 1687 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1688 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1689 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1690 if (res) write_hostent(ctx, res); 1691 return res; 1692} 1693 1694INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 1695 void *ctx; 1696 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 1697 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 1698 if (res) write_hostent(ctx, res); 1699 return res; 1700} 1701 1702INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1703 void *ctx; 1704 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1705 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1706 if (res) write_hostent(ctx, res); 1707 return res; 1708} 1709#define INIT_GETHOSTBYNAME \ 1710 COMMON_INTERCEPT_FUNCTION(gethostent); \ 1711 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ 1712 COMMON_INTERCEPT_FUNCTION(gethostbyname); \ 1713 COMMON_INTERCEPT_FUNCTION(gethostbyname2); 1714#else 1715#define INIT_GETHOSTBYNAME 1716#endif 1717 1718#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1719INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1720 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1721 void *ctx; 1722 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1723 h_errnop); 1724 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1725 if (result) { 1726 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1727 if (res == 0 && *result) write_hostent(ctx, *result); 1728 } 1729 if (h_errnop) 1730 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1731 return res; 1732} 1733 1734INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1735 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1736 __sanitizer_hostent **result, int *h_errnop) { 1737 void *ctx; 1738 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1739 buflen, result, h_errnop); 1740 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1741 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1742 h_errnop); 1743 if (result) { 1744 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1745 if (res == 0 && *result) write_hostent(ctx, *result); 1746 } 1747 if (h_errnop) 1748 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1749 return res; 1750} 1751 1752INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1753 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1754 int *h_errnop) { 1755 void *ctx; 1756 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1757 h_errnop); 1758 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1759 if (result) { 1760 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1761 if (res == 0 && *result) write_hostent(ctx, *result); 1762 } 1763 if (h_errnop) 1764 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1765 return res; 1766} 1767 1768INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1769 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1770 __sanitizer_hostent **result, int *h_errnop) { 1771 void *ctx; 1772 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1773 result, h_errnop); 1774 int res = 1775 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1776 if (result) { 1777 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1778 if (res == 0 && *result) write_hostent(ctx, *result); 1779 } 1780 if (h_errnop) 1781 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1782 return res; 1783} 1784#define INIT_GETHOSTBYNAME_R \ 1785 COMMON_INTERCEPT_FUNCTION(gethostent_r); \ 1786 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1787 COMMON_INTERCEPT_FUNCTION(gethostbyname_r); \ 1788 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r); 1789#else 1790#define INIT_GETHOSTBYNAME_R 1791#endif 1792 1793#if SANITIZER_INTERCEPT_GETSOCKOPT 1794INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1795 int *optlen) { 1796 void *ctx; 1797 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1798 optlen); 1799 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1800 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1801 if (res == 0) 1802 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1803 return res; 1804} 1805#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt); 1806#else 1807#define INIT_GETSOCKOPT 1808#endif 1809 1810#if SANITIZER_INTERCEPT_ACCEPT 1811INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1812 void *ctx; 1813 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1814 unsigned addrlen0; 1815 if (addrlen) { 1816 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1817 addrlen0 = *addrlen; 1818 } 1819 int fd2 = REAL(accept)(fd, addr, addrlen); 1820 if (fd2 >= 0) { 1821 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1822 if (addr && addrlen) 1823 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1824 } 1825 return fd2; 1826} 1827#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept); 1828#else 1829#define INIT_ACCEPT 1830#endif 1831 1832#if SANITIZER_INTERCEPT_ACCEPT4 1833INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1834 void *ctx; 1835 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1836 unsigned addrlen0; 1837 if (addrlen) { 1838 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1839 addrlen0 = *addrlen; 1840 } 1841 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1842 if (fd2 >= 0) { 1843 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1844 if (addr && addrlen) 1845 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1846 } 1847 return fd2; 1848} 1849#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4); 1850#else 1851#define INIT_ACCEPT4 1852#endif 1853 1854#if SANITIZER_INTERCEPT_MODF 1855INTERCEPTOR(double, modf, double x, double *iptr) { 1856 void *ctx; 1857 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1858 double res = REAL(modf)(x, iptr); 1859 if (iptr) { 1860 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1861 } 1862 return res; 1863} 1864INTERCEPTOR(float, modff, float x, float *iptr) { 1865 void *ctx; 1866 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1867 float res = REAL(modff)(x, iptr); 1868 if (iptr) { 1869 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1870 } 1871 return res; 1872} 1873INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1874 void *ctx; 1875 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1876 long double res = REAL(modfl)(x, iptr); 1877 if (iptr) { 1878 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1879 } 1880 return res; 1881} 1882#define INIT_MODF \ 1883 COMMON_INTERCEPT_FUNCTION(modf); \ 1884 COMMON_INTERCEPT_FUNCTION(modff); \ 1885 COMMON_INTERCEPT_FUNCTION(modfl); 1886#else 1887#define INIT_MODF 1888#endif 1889 1890#if SANITIZER_INTERCEPT_RECVMSG 1891static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1892 SSIZE_T maxlen) { 1893 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1894 if (msg->msg_name && msg->msg_namelen) 1895 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 1896 if (msg->msg_iov && msg->msg_iovlen) 1897 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1898 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1899 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1900 if (msg->msg_control && msg->msg_controllen) 1901 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1902} 1903 1904INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1905 int flags) { 1906 void *ctx; 1907 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1908 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1909 if (res >= 0) { 1910 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1911 if (msg) { 1912 write_msghdr(ctx, msg, res); 1913 COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg); 1914 } 1915 } 1916 return res; 1917} 1918#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg); 1919#else 1920#define INIT_RECVMSG 1921#endif 1922 1923#if SANITIZER_INTERCEPT_GETPEERNAME 1924INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1925 void *ctx; 1926 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1927 unsigned addr_sz; 1928 if (addrlen) addr_sz = *addrlen; 1929 int res = REAL(getpeername)(sockfd, addr, addrlen); 1930 if (!res && addr && addrlen) 1931 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1932 return res; 1933} 1934#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername); 1935#else 1936#define INIT_GETPEERNAME 1937#endif 1938 1939#if SANITIZER_INTERCEPT_SYSINFO 1940INTERCEPTOR(int, sysinfo, void *info) { 1941 void *ctx; 1942 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1943 int res = REAL(sysinfo)(info); 1944 if (!res && info) 1945 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1946 return res; 1947} 1948#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo); 1949#else 1950#define INIT_SYSINFO 1951#endif 1952 1953#if SANITIZER_INTERCEPT_READDIR 1954INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1955 void *ctx; 1956 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1957 __sanitizer_dirent *res = REAL(readdir)(dirp); 1958 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1959 return res; 1960} 1961 1962INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1963 __sanitizer_dirent **result) { 1964 void *ctx; 1965 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1966 int res = REAL(readdir_r)(dirp, entry, result); 1967 if (!res) { 1968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1969 if (*result) 1970 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1971 } 1972 return res; 1973} 1974 1975#define INIT_READDIR \ 1976 COMMON_INTERCEPT_FUNCTION(readdir); \ 1977 COMMON_INTERCEPT_FUNCTION(readdir_r); 1978#else 1979#define INIT_READDIR 1980#endif 1981 1982#if SANITIZER_INTERCEPT_READDIR64 1983INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1984 void *ctx; 1985 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1986 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1987 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1988 return res; 1989} 1990 1991INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1992 __sanitizer_dirent64 **result) { 1993 void *ctx; 1994 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1995 int res = REAL(readdir64_r)(dirp, entry, result); 1996 if (!res) { 1997 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1998 if (*result) 1999 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 2000 } 2001 return res; 2002} 2003#define INIT_READDIR64 \ 2004 COMMON_INTERCEPT_FUNCTION(readdir64); \ 2005 COMMON_INTERCEPT_FUNCTION(readdir64_r); 2006#else 2007#define INIT_READDIR64 2008#endif 2009 2010#if SANITIZER_INTERCEPT_PTRACE 2011INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 2012 void *ctx; 2013 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 2014 2015 if (data) { 2016 if (request == ptrace_setregs) 2017 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 2018 else if (request == ptrace_setfpregs) 2019 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 2020 else if (request == ptrace_setfpxregs) 2021 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 2022 else if (request == ptrace_setsiginfo) 2023 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 2024 else if (request == ptrace_setregset) { 2025 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 2026 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 2027 } 2028 } 2029 2030 uptr res = REAL(ptrace)(request, pid, addr, data); 2031 2032 if (!res && data) { 2033 // Note that PEEK* requests assing different meaning to the return value. 2034 // This function does not handle them (nor does it need to). 2035 if (request == ptrace_getregs) 2036 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 2037 else if (request == ptrace_getfpregs) 2038 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 2039 else if (request == ptrace_getfpxregs) 2040 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 2041 else if (request == ptrace_getsiginfo) 2042 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 2043 else if (request == ptrace_getregset) { 2044 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 2045 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 2046 } 2047 } 2048 return res; 2049} 2050 2051#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace); 2052#else 2053#define INIT_PTRACE 2054#endif 2055 2056#if SANITIZER_INTERCEPT_SETLOCALE 2057INTERCEPTOR(char *, setlocale, int category, char *locale) { 2058 void *ctx; 2059 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 2060 if (locale) 2061 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 2062 char *res = REAL(setlocale)(category, locale); 2063 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2064 return res; 2065} 2066 2067#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale); 2068#else 2069#define INIT_SETLOCALE 2070#endif 2071 2072#if SANITIZER_INTERCEPT_GETCWD 2073INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 2074 void *ctx; 2075 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 2076 char *res = REAL(getcwd)(buf, size); 2077 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2078 return res; 2079} 2080#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); 2081#else 2082#define INIT_GETCWD 2083#endif 2084 2085#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 2086INTERCEPTOR(char *, get_current_dir_name, int fake) { 2087 void *ctx; 2088 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 2089 char *res = REAL(get_current_dir_name)(fake); 2090 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2091 return res; 2092} 2093 2094#define INIT_GET_CURRENT_DIR_NAME \ 2095 COMMON_INTERCEPT_FUNCTION(get_current_dir_name); 2096#else 2097#define INIT_GET_CURRENT_DIR_NAME 2098#endif 2099 2100#if SANITIZER_INTERCEPT_STRTOIMAX 2101INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 2102 void *ctx; 2103 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 2104 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 2105 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 2106 return res; 2107} 2108 2109INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 2110 void *ctx; 2111 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 2112 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 2113 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 2114 return res; 2115} 2116 2117#define INIT_STRTOIMAX \ 2118 COMMON_INTERCEPT_FUNCTION(strtoimax); \ 2119 COMMON_INTERCEPT_FUNCTION(strtoumax); 2120#else 2121#define INIT_STRTOIMAX 2122#endif 2123 2124#if SANITIZER_INTERCEPT_MBSTOWCS 2125INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 2126 void *ctx; 2127 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 2128 SIZE_T res = REAL(mbstowcs)(dest, src, len); 2129 if (res != (SIZE_T) - 1 && dest) { 2130 SIZE_T write_cnt = res + (res < len); 2131 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 2132 } 2133 return res; 2134} 2135 2136INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 2137 void *ps) { 2138 void *ctx; 2139 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 2140 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 2141 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 2142 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 2143 if (res != (SIZE_T)(-1) && dest && src) { 2144 // This function, and several others, may or may not write the terminating 2145 // \0 character. They write it iff they clear *src. 2146 SIZE_T write_cnt = res + !*src; 2147 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 2148 } 2149 return res; 2150} 2151 2152#define INIT_MBSTOWCS \ 2153 COMMON_INTERCEPT_FUNCTION(mbstowcs); \ 2154 COMMON_INTERCEPT_FUNCTION(mbsrtowcs); 2155#else 2156#define INIT_MBSTOWCS 2157#endif 2158 2159#if SANITIZER_INTERCEPT_MBSNRTOWCS 2160INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 2161 SIZE_T len, void *ps) { 2162 void *ctx; 2163 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 2164 if (src) { 2165 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 2166 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 2167 } 2168 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 2169 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 2170 if (res != (SIZE_T)(-1) && dest && src) { 2171 SIZE_T write_cnt = res + !*src; 2172 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 2173 } 2174 return res; 2175} 2176 2177#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs); 2178#else 2179#define INIT_MBSNRTOWCS 2180#endif 2181 2182#if SANITIZER_INTERCEPT_WCSTOMBS 2183INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 2184 void *ctx; 2185 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 2186 SIZE_T res = REAL(wcstombs)(dest, src, len); 2187 if (res != (SIZE_T) - 1 && dest) { 2188 SIZE_T write_cnt = res + (res < len); 2189 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 2190 } 2191 return res; 2192} 2193 2194INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 2195 void *ps) { 2196 void *ctx; 2197 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 2198 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 2199 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 2200 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 2201 if (res != (SIZE_T) - 1 && dest && src) { 2202 SIZE_T write_cnt = res + !*src; 2203 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 2204 } 2205 return res; 2206} 2207 2208#define INIT_WCSTOMBS \ 2209 COMMON_INTERCEPT_FUNCTION(wcstombs); \ 2210 COMMON_INTERCEPT_FUNCTION(wcsrtombs); 2211#else 2212#define INIT_WCSTOMBS 2213#endif 2214 2215#if SANITIZER_INTERCEPT_WCSNRTOMBS 2216INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 2217 SIZE_T len, void *ps) { 2218 void *ctx; 2219 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 2220 if (src) { 2221 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 2222 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 2223 } 2224 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 2225 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 2226 if (res != (SIZE_T) - 1 && dest && src) { 2227 SIZE_T write_cnt = res + !*src; 2228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 2229 } 2230 return res; 2231} 2232 2233#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs); 2234#else 2235#define INIT_WCSNRTOMBS 2236#endif 2237 2238#if SANITIZER_INTERCEPT_TCGETATTR 2239INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 2240 void *ctx; 2241 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 2242 int res = REAL(tcgetattr)(fd, termios_p); 2243 if (!res && termios_p) 2244 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 2245 return res; 2246} 2247 2248#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr); 2249#else 2250#define INIT_TCGETATTR 2251#endif 2252 2253#if SANITIZER_INTERCEPT_REALPATH 2254INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 2255 void *ctx; 2256 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 2257 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2258 2259 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 2260 // version of a versioned symbol. For realpath(), this gives us something 2261 // (called __old_realpath) that does not handle NULL in the second argument. 2262 // Handle it as part of the interceptor. 2263 char *allocated_path = 0; 2264 if (!resolved_path) 2265 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 2266 2267 char *res = REAL(realpath)(path, resolved_path); 2268 if (allocated_path && !res) WRAP(free)(allocated_path); 2269 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2270 return res; 2271} 2272#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); 2273#else 2274#define INIT_REALPATH 2275#endif 2276 2277#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 2278INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 2279 void *ctx; 2280 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 2281 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2282 char *res = REAL(canonicalize_file_name)(path); 2283 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2284 return res; 2285} 2286#define INIT_CANONICALIZE_FILE_NAME \ 2287 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name); 2288#else 2289#define INIT_CANONICALIZE_FILE_NAME 2290#endif 2291 2292#if SANITIZER_INTERCEPT_CONFSTR 2293INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 2294 void *ctx; 2295 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 2296 SIZE_T res = REAL(confstr)(name, buf, len); 2297 if (buf && res) 2298 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 2299 return res; 2300} 2301#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr); 2302#else 2303#define INIT_CONFSTR 2304#endif 2305 2306#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 2307INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 2308 void *ctx; 2309 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 2310 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 2311 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 2312 return res; 2313} 2314#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity); 2315#else 2316#define INIT_SCHED_GETAFFINITY 2317#endif 2318 2319#if SANITIZER_INTERCEPT_STRERROR 2320INTERCEPTOR(char *, strerror, int errnum) { 2321 void *ctx; 2322 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 2323 char *res = REAL(strerror)(errnum); 2324 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 2325 return res; 2326} 2327#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); 2328#else 2329#define INIT_STRERROR 2330#endif 2331 2332#if SANITIZER_INTERCEPT_STRERROR_R 2333INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 2334 void *ctx; 2335 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 2336 char *res = REAL(strerror_r)(errnum, buf, buflen); 2337 // There are 2 versions of strerror_r: 2338 // * POSIX version returns 0 on success, negative error code on failure, 2339 // writes message to buf. 2340 // * GNU version returns message pointer, which points to either buf or some 2341 // static storage. 2342 SIZE_T posix_res = (SIZE_T)res; 2343 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 2344 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 2345 // At least on OSX, buf contents are valid even when the call fails. 2346 SIZE_T sz = internal_strnlen(buf, buflen); 2347 if (sz < buflen) ++sz; 2348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 2349 } else { 2350 // GNU version. 2351 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2352 } 2353 return res; 2354} 2355#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); 2356#else 2357#define INIT_STRERROR_R 2358#endif 2359 2360#if SANITIZER_INTERCEPT_XPG_STRERROR_R 2361INTERCEPTOR(int, __xpg_strerror_r, int errnum, char *buf, SIZE_T buflen) { 2362 void *ctx; 2363 COMMON_INTERCEPTOR_ENTER(ctx, __xpg_strerror_r, errnum, buf, buflen); 2364 int res = REAL(__xpg_strerror_r)(errnum, buf, buflen); 2365 // This version always returns a null-terminated string. 2366 if (buf && buflen) 2367 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2368 return res; 2369} 2370#define INIT_XPG_STRERROR_R COMMON_INTERCEPT_FUNCTION(__xpg_strerror_r); 2371#else 2372#define INIT_XPG_STRERROR_R 2373#endif 2374 2375#if SANITIZER_INTERCEPT_SCANDIR 2376typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 2377typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 2378 const struct __sanitizer_dirent **); 2379 2380static THREADLOCAL scandir_filter_f scandir_filter; 2381static THREADLOCAL scandir_compar_f scandir_compar; 2382 2383static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 2384 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2385 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 2386 return IndirectExternCall(scandir_filter)(dir); 2387} 2388 2389static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 2390 const struct __sanitizer_dirent **b) { 2391 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2392 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 2393 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 2394 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 2395 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 2396 return IndirectExternCall(scandir_compar)(a, b); 2397} 2398 2399INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 2400 scandir_filter_f filter, scandir_compar_f compar) { 2401 void *ctx; 2402 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 2403 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 2404 scandir_filter = filter; 2405 scandir_compar = compar; 2406 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 2407 compar ? wrapped_scandir_compar : 0); 2408 scandir_filter = 0; 2409 scandir_compar = 0; 2410 if (namelist && res > 0) { 2411 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 2412 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 2413 for (int i = 0; i < res; ++i) 2414 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 2415 (*namelist)[i]->d_reclen); 2416 } 2417 return res; 2418} 2419#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir); 2420#else 2421#define INIT_SCANDIR 2422#endif 2423 2424#if SANITIZER_INTERCEPT_SCANDIR64 2425typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 2426typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 2427 const struct __sanitizer_dirent64 **); 2428 2429static THREADLOCAL scandir64_filter_f scandir64_filter; 2430static THREADLOCAL scandir64_compar_f scandir64_compar; 2431 2432static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 2433 COMMON_INTERCEPTOR_UNPOISON_PARAM(1); 2434 COMMON_INTERCEPTOR_INITIALIZE_RANGE(dir, dir->d_reclen); 2435 return IndirectExternCall(scandir64_filter)(dir); 2436} 2437 2438static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 2439 const struct __sanitizer_dirent64 **b) { 2440 COMMON_INTERCEPTOR_UNPOISON_PARAM(2); 2441 COMMON_INTERCEPTOR_INITIALIZE_RANGE(a, sizeof(*a)); 2442 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*a, (*a)->d_reclen); 2443 COMMON_INTERCEPTOR_INITIALIZE_RANGE(b, sizeof(*b)); 2444 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*b, (*b)->d_reclen); 2445 return IndirectExternCall(scandir64_compar)(a, b); 2446} 2447 2448INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 2449 scandir64_filter_f filter, scandir64_compar_f compar) { 2450 void *ctx; 2451 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 2452 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 2453 scandir64_filter = filter; 2454 scandir64_compar = compar; 2455 int res = 2456 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 2457 compar ? wrapped_scandir64_compar : 0); 2458 scandir64_filter = 0; 2459 scandir64_compar = 0; 2460 if (namelist && res > 0) { 2461 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 2462 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 2463 for (int i = 0; i < res; ++i) 2464 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 2465 (*namelist)[i]->d_reclen); 2466 } 2467 return res; 2468} 2469#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64); 2470#else 2471#define INIT_SCANDIR64 2472#endif 2473 2474#if SANITIZER_INTERCEPT_GETGROUPS 2475INTERCEPTOR(int, getgroups, int size, u32 *lst) { 2476 void *ctx; 2477 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 2478 int res = REAL(getgroups)(size, lst); 2479 if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 2480 return res; 2481} 2482#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups); 2483#else 2484#define INIT_GETGROUPS 2485#endif 2486 2487#if SANITIZER_INTERCEPT_POLL 2488static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 2489 __sanitizer_nfds_t nfds) { 2490 for (unsigned i = 0; i < nfds; ++i) { 2491 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 2492 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 2493 } 2494} 2495 2496static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 2497 __sanitizer_nfds_t nfds) { 2498 for (unsigned i = 0; i < nfds; ++i) 2499 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 2500 sizeof(fds[i].revents)); 2501} 2502 2503INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2504 int timeout) { 2505 void *ctx; 2506 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 2507 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2508 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 2509 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2510 return res; 2511} 2512#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll); 2513#else 2514#define INIT_POLL 2515#endif 2516 2517#if SANITIZER_INTERCEPT_PPOLL 2518INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2519 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 2520 void *ctx; 2521 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 2522 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2523 if (timeout_ts) 2524 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2525 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2526 int res = 2527 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2528 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2529 return res; 2530} 2531#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll); 2532#else 2533#define INIT_PPOLL 2534#endif 2535 2536#if SANITIZER_INTERCEPT_WORDEXP 2537INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2538 void *ctx; 2539 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2540 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2541 int res = REAL(wordexp)(s, p, flags); 2542 if (!res && p) { 2543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2544 if (p->we_wordc) 2545 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2546 sizeof(*p->we_wordv) * p->we_wordc); 2547 for (uptr i = 0; i < p->we_wordc; ++i) { 2548 char *w = p->we_wordv[i]; 2549 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2550 } 2551 } 2552 return res; 2553} 2554#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp); 2555#else 2556#define INIT_WORDEXP 2557#endif 2558 2559#if SANITIZER_INTERCEPT_SIGWAIT 2560INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2561 void *ctx; 2562 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2563 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2564 int res = REAL(sigwait)(set, sig); 2565 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2566 return res; 2567} 2568#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait); 2569#else 2570#define INIT_SIGWAIT 2571#endif 2572 2573#if SANITIZER_INTERCEPT_SIGWAITINFO 2574INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2575 void *ctx; 2576 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2577 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2578 int res = REAL(sigwaitinfo)(set, info); 2579 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2580 return res; 2581} 2582#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo); 2583#else 2584#define INIT_SIGWAITINFO 2585#endif 2586 2587#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2588INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2589 void *timeout) { 2590 void *ctx; 2591 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2592 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2593 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2594 int res = REAL(sigtimedwait)(set, info, timeout); 2595 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2596 return res; 2597} 2598#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait); 2599#else 2600#define INIT_SIGTIMEDWAIT 2601#endif 2602 2603#if SANITIZER_INTERCEPT_SIGSETOPS 2604INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2605 void *ctx; 2606 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2607 int res = REAL(sigemptyset)(set); 2608 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2609 return res; 2610} 2611 2612INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2613 void *ctx; 2614 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2615 int res = REAL(sigfillset)(set); 2616 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2617 return res; 2618} 2619#define INIT_SIGSETOPS \ 2620 COMMON_INTERCEPT_FUNCTION(sigemptyset); \ 2621 COMMON_INTERCEPT_FUNCTION(sigfillset); 2622#else 2623#define INIT_SIGSETOPS 2624#endif 2625 2626#if SANITIZER_INTERCEPT_SIGPENDING 2627INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2628 void *ctx; 2629 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2630 int res = REAL(sigpending)(set); 2631 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2632 return res; 2633} 2634#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending); 2635#else 2636#define INIT_SIGPENDING 2637#endif 2638 2639#if SANITIZER_INTERCEPT_SIGPROCMASK 2640INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2641 __sanitizer_sigset_t *oldset) { 2642 void *ctx; 2643 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2644 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2645 int res = REAL(sigprocmask)(how, set, oldset); 2646 if (!res && oldset) 2647 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2648 return res; 2649} 2650#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask); 2651#else 2652#define INIT_SIGPROCMASK 2653#endif 2654 2655#if SANITIZER_INTERCEPT_BACKTRACE 2656INTERCEPTOR(int, backtrace, void **buffer, int size) { 2657 void *ctx; 2658 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2659 int res = REAL(backtrace)(buffer, size); 2660 if (res && buffer) 2661 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2662 return res; 2663} 2664 2665INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2666 void *ctx; 2667 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2668 if (buffer && size) 2669 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2670 char **res = REAL(backtrace_symbols)(buffer, size); 2671 if (res && size) { 2672 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2673 for (int i = 0; i < size; ++i) 2674 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2675 } 2676 return res; 2677} 2678#define INIT_BACKTRACE \ 2679 COMMON_INTERCEPT_FUNCTION(backtrace); \ 2680 COMMON_INTERCEPT_FUNCTION(backtrace_symbols); 2681#else 2682#define INIT_BACKTRACE 2683#endif 2684 2685#if SANITIZER_INTERCEPT__EXIT 2686INTERCEPTOR(void, _exit, int status) { 2687 void *ctx; 2688 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 2689 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 2690 if (status == 0) status = status1; 2691 REAL(_exit)(status); 2692} 2693#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit); 2694#else 2695#define INIT__EXIT 2696#endif 2697 2698#if SANITIZER_INTERCEPT_PHTREAD_MUTEX 2699INTERCEPTOR(int, pthread_mutex_lock, void *m) { 2700 void *ctx; 2701 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 2702 int res = REAL(pthread_mutex_lock)(m); 2703 if (res == errno_EOWNERDEAD) 2704 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 2705 if (res == 0 || res == errno_EOWNERDEAD) 2706 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2707 return res; 2708} 2709 2710INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 2711 void *ctx; 2712 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 2713 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2714 return REAL(pthread_mutex_unlock)(m); 2715} 2716 2717#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) 2718#define INIT_PTHREAD_MUTEX_UNLOCK \ 2719 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) 2720#else 2721#define INIT_PTHREAD_MUTEX_LOCK 2722#define INIT_PTHREAD_MUTEX_UNLOCK 2723#endif 2724 2725#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 2726static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 2727 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 2728 if (mnt->mnt_fsname) 2729 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 2730 REAL(strlen)(mnt->mnt_fsname) + 1); 2731 if (mnt->mnt_dir) 2732 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 2733 REAL(strlen)(mnt->mnt_dir) + 1); 2734 if (mnt->mnt_type) 2735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 2736 REAL(strlen)(mnt->mnt_type) + 1); 2737 if (mnt->mnt_opts) 2738 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 2739 REAL(strlen)(mnt->mnt_opts) + 1); 2740} 2741#endif 2742 2743#if SANITIZER_INTERCEPT_GETMNTENT 2744INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 2745 void *ctx; 2746 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 2747 __sanitizer_mntent *res = REAL(getmntent)(fp); 2748 if (res) write_mntent(ctx, res); 2749 return res; 2750} 2751#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent); 2752#else 2753#define INIT_GETMNTENT 2754#endif 2755 2756#if SANITIZER_INTERCEPT_GETMNTENT_R 2757INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 2758 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 2759 void *ctx; 2760 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 2761 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 2762 if (res) write_mntent(ctx, res); 2763 return res; 2764} 2765#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r); 2766#else 2767#define INIT_GETMNTENT_R 2768#endif 2769 2770#if SANITIZER_INTERCEPT_STATFS 2771INTERCEPTOR(int, statfs, char *path, void *buf) { 2772 void *ctx; 2773 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 2774 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2775 int res = REAL(statfs)(path, buf); 2776 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2777 return res; 2778} 2779INTERCEPTOR(int, fstatfs, int fd, void *buf) { 2780 void *ctx; 2781 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 2782 int res = REAL(fstatfs)(fd, buf); 2783 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2784 return res; 2785} 2786#define INIT_STATFS \ 2787 COMMON_INTERCEPT_FUNCTION(statfs); \ 2788 COMMON_INTERCEPT_FUNCTION(fstatfs); 2789#else 2790#define INIT_STATFS 2791#endif 2792 2793#if SANITIZER_INTERCEPT_STATFS64 2794INTERCEPTOR(int, statfs64, char *path, void *buf) { 2795 void *ctx; 2796 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 2797 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2798 int res = REAL(statfs64)(path, buf); 2799 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2800 return res; 2801} 2802INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 2803 void *ctx; 2804 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 2805 int res = REAL(fstatfs64)(fd, buf); 2806 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2807 return res; 2808} 2809#define INIT_STATFS64 \ 2810 COMMON_INTERCEPT_FUNCTION(statfs64); \ 2811 COMMON_INTERCEPT_FUNCTION(fstatfs64); 2812#else 2813#define INIT_STATFS64 2814#endif 2815 2816#if SANITIZER_INTERCEPT_STATVFS 2817INTERCEPTOR(int, statvfs, char *path, void *buf) { 2818 void *ctx; 2819 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 2820 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2821 int res = REAL(statvfs)(path, buf); 2822 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2823 return res; 2824} 2825INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 2826 void *ctx; 2827 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 2828 int res = REAL(fstatvfs)(fd, buf); 2829 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2830 return res; 2831} 2832#define INIT_STATVFS \ 2833 COMMON_INTERCEPT_FUNCTION(statvfs); \ 2834 COMMON_INTERCEPT_FUNCTION(fstatvfs); 2835#else 2836#define INIT_STATVFS 2837#endif 2838 2839#if SANITIZER_INTERCEPT_STATVFS64 2840INTERCEPTOR(int, statvfs64, char *path, void *buf) { 2841 void *ctx; 2842 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 2843 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2844 int res = REAL(statvfs64)(path, buf); 2845 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2846 return res; 2847} 2848INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 2849 void *ctx; 2850 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 2851 int res = REAL(fstatvfs64)(fd, buf); 2852 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2853 return res; 2854} 2855#define INIT_STATVFS64 \ 2856 COMMON_INTERCEPT_FUNCTION(statvfs64); \ 2857 COMMON_INTERCEPT_FUNCTION(fstatvfs64); 2858#else 2859#define INIT_STATVFS64 2860#endif 2861 2862#if SANITIZER_INTERCEPT_INITGROUPS 2863INTERCEPTOR(int, initgroups, char *user, u32 group) { 2864 void *ctx; 2865 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 2866 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 2867 int res = REAL(initgroups)(user, group); 2868 return res; 2869} 2870#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups); 2871#else 2872#define INIT_INITGROUPS 2873#endif 2874 2875#if SANITIZER_INTERCEPT_ETHER 2876INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 2877 void *ctx; 2878 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 2879 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2880 char *res = REAL(ether_ntoa)(addr); 2881 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 2882 return res; 2883} 2884INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 2885 void *ctx; 2886 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 2887 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2888 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 2889 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, sizeof(*res)); 2890 return res; 2891} 2892INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 2893 void *ctx; 2894 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 2895 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2896 int res = REAL(ether_ntohost)(hostname, addr); 2897 if (!res && hostname) 2898 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2899 return res; 2900} 2901INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 2902 void *ctx; 2903 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 2904 if (hostname) 2905 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2906 int res = REAL(ether_hostton)(hostname, addr); 2907 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2908 return res; 2909} 2910INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 2911 char *hostname) { 2912 void *ctx; 2913 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 2914 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 2915 int res = REAL(ether_line)(line, addr, hostname); 2916 if (!res) { 2917 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2918 if (hostname) 2919 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2920 } 2921 return res; 2922} 2923#define INIT_ETHER \ 2924 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \ 2925 COMMON_INTERCEPT_FUNCTION(ether_aton); \ 2926 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \ 2927 COMMON_INTERCEPT_FUNCTION(ether_hostton); \ 2928 COMMON_INTERCEPT_FUNCTION(ether_line); 2929#else 2930#define INIT_ETHER 2931#endif 2932 2933#if SANITIZER_INTERCEPT_ETHER_R 2934INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 2935 void *ctx; 2936 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 2937 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2938 char *res = REAL(ether_ntoa_r)(addr, buf); 2939 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2940 return res; 2941} 2942INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 2943 __sanitizer_ether_addr *addr) { 2944 void *ctx; 2945 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 2946 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2947 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 2948 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 2949 return res; 2950} 2951#define INIT_ETHER_R \ 2952 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \ 2953 COMMON_INTERCEPT_FUNCTION(ether_aton_r); 2954#else 2955#define INIT_ETHER_R 2956#endif 2957 2958#if SANITIZER_INTERCEPT_SHMCTL 2959INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 2960 void *ctx; 2961 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 2962 int res = REAL(shmctl)(shmid, cmd, buf); 2963 if (res >= 0) { 2964 unsigned sz = 0; 2965 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 2966 sz = sizeof(__sanitizer_shmid_ds); 2967 else if (cmd == shmctl_ipc_info) 2968 sz = struct_shminfo_sz; 2969 else if (cmd == shmctl_shm_info) 2970 sz = struct_shm_info_sz; 2971 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 2972 } 2973 return res; 2974} 2975#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); 2976#else 2977#define INIT_SHMCTL 2978#endif 2979 2980#if SANITIZER_INTERCEPT_RANDOM_R 2981INTERCEPTOR(int, random_r, void *buf, u32 *result) { 2982 void *ctx; 2983 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 2984 int res = REAL(random_r)(buf, result); 2985 if (!res && result) 2986 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2987 return res; 2988} 2989#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r); 2990#else 2991#define INIT_RANDOM_R 2992#endif 2993 2994#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 2995 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED 2996#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 2997 INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \ 2998 void *ctx; \ 2999 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \ 3000 int res = REAL(pthread_attr_get##what)(attr, r); \ 3001 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 3002 return res; \ 3003 } 3004#endif 3005 3006#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 3007INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 3008INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 3009INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 3010INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 3011INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 3012INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 3013INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 3014 void *ctx; 3015 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 3016 int res = REAL(pthread_attr_getstack)(attr, addr, size); 3017 if (!res) { 3018 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 3019 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 3020 } 3021 return res; 3022} 3023 3024// We may need to call the real pthread_attr_getstack from the run-time 3025// in sanitizer_common, but we don't want to include the interception headers 3026// there. So, just define this function here. 3027namespace __sanitizer { 3028extern "C" { 3029int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { 3030 return REAL(pthread_attr_getstack)(attr, addr, size); 3031} 3032} // extern "C" 3033} // namespace __sanitizer 3034 3035#define INIT_PTHREAD_ATTR_GET \ 3036 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 3037 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 3038 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 3039 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ 3040 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ 3041 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 3042 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); 3043#else 3044#define INIT_PTHREAD_ATTR_GET 3045#endif 3046 3047#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 3048INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 3049 3050#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 3051 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 3052#else 3053#define INIT_PTHREAD_ATTR_GETINHERITSCHED 3054#endif 3055 3056#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 3057INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 3058 void *cpuset) { 3059 void *ctx; 3060 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 3061 cpuset); 3062 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 3063 if (!res && cpusetsize && cpuset) 3064 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 3065 return res; 3066} 3067 3068#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 3069 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 3070#else 3071#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 3072#endif 3073 3074#if SANITIZER_INTERCEPT_TMPNAM 3075INTERCEPTOR(char *, tmpnam, char *s) { 3076 void *ctx; 3077 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 3078 char *res = REAL(tmpnam)(s); 3079 if (res) { 3080 if (s) 3081 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 3082 else 3083 COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3084 } 3085 return res; 3086} 3087#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam); 3088#else 3089#define INIT_TMPNAM 3090#endif 3091 3092#if SANITIZER_INTERCEPT_TMPNAM_R 3093INTERCEPTOR(char *, tmpnam_r, char *s) { 3094 void *ctx; 3095 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 3096 char *res = REAL(tmpnam_r)(s); 3097 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 3098 return res; 3099} 3100#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); 3101#else 3102#define INIT_TMPNAM_R 3103#endif 3104 3105#if SANITIZER_INTERCEPT_TEMPNAM 3106INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 3107 void *ctx; 3108 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 3109 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 3110 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 3111 char *res = REAL(tempnam)(dir, pfx); 3112 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); 3113 return res; 3114} 3115#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); 3116#else 3117#define INIT_TEMPNAM 3118#endif 3119 3120#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP 3121INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 3122 void *ctx; 3123 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 3124 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 3125 return REAL(pthread_setname_np)(thread, name); 3126} 3127#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 3128#else 3129#define INIT_PTHREAD_SETNAME_NP 3130#endif 3131 3132#if SANITIZER_INTERCEPT_SINCOS 3133INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 3134 void *ctx; 3135 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 3136 REAL(sincos)(x, sin, cos); 3137 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 3138 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 3139} 3140INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 3141 void *ctx; 3142 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 3143 REAL(sincosf)(x, sin, cos); 3144 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 3145 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 3146} 3147INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 3148 void *ctx; 3149 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 3150 REAL(sincosl)(x, sin, cos); 3151 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 3152 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 3153} 3154#define INIT_SINCOS \ 3155 COMMON_INTERCEPT_FUNCTION(sincos); \ 3156 COMMON_INTERCEPT_FUNCTION(sincosf); \ 3157 COMMON_INTERCEPT_FUNCTION(sincosl); 3158#else 3159#define INIT_SINCOS 3160#endif 3161 3162#if SANITIZER_INTERCEPT_REMQUO 3163INTERCEPTOR(double, remquo, double x, double y, int *quo) { 3164 void *ctx; 3165 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 3166 double res = REAL(remquo)(x, y, quo); 3167 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 3168 return res; 3169} 3170INTERCEPTOR(float, remquof, float x, float y, int *quo) { 3171 void *ctx; 3172 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 3173 float res = REAL(remquof)(x, y, quo); 3174 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 3175 return res; 3176} 3177INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 3178 void *ctx; 3179 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 3180 long double res = REAL(remquol)(x, y, quo); 3181 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 3182 return res; 3183} 3184#define INIT_REMQUO \ 3185 COMMON_INTERCEPT_FUNCTION(remquo); \ 3186 COMMON_INTERCEPT_FUNCTION(remquof); \ 3187 COMMON_INTERCEPT_FUNCTION(remquol); 3188#else 3189#define INIT_REMQUO 3190#endif 3191 3192#if SANITIZER_INTERCEPT_LGAMMA 3193extern int signgam; 3194INTERCEPTOR(double, lgamma, double x) { 3195 void *ctx; 3196 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 3197 double res = REAL(lgamma)(x); 3198 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 3199 return res; 3200} 3201INTERCEPTOR(float, lgammaf, float x) { 3202 void *ctx; 3203 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 3204 float res = REAL(lgammaf)(x); 3205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 3206 return res; 3207} 3208INTERCEPTOR(long double, lgammal, long double x) { 3209 void *ctx; 3210 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 3211 long double res = REAL(lgammal)(x); 3212 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 3213 return res; 3214} 3215#define INIT_LGAMMA \ 3216 COMMON_INTERCEPT_FUNCTION(lgamma); \ 3217 COMMON_INTERCEPT_FUNCTION(lgammaf); \ 3218 COMMON_INTERCEPT_FUNCTION(lgammal); 3219#else 3220#define INIT_LGAMMA 3221#endif 3222 3223#if SANITIZER_INTERCEPT_LGAMMA_R 3224INTERCEPTOR(double, lgamma_r, double x, int *signp) { 3225 void *ctx; 3226 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 3227 double res = REAL(lgamma_r)(x, signp); 3228 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 3229 return res; 3230} 3231INTERCEPTOR(float, lgammaf_r, float x, int *signp) { 3232 void *ctx; 3233 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 3234 float res = REAL(lgammaf_r)(x, signp); 3235 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 3236 return res; 3237} 3238INTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 3239 void *ctx; 3240 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 3241 long double res = REAL(lgammal_r)(x, signp); 3242 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 3243 return res; 3244} 3245#define INIT_LGAMMA_R \ 3246 COMMON_INTERCEPT_FUNCTION(lgamma_r); \ 3247 COMMON_INTERCEPT_FUNCTION(lgammaf_r); \ 3248 COMMON_INTERCEPT_FUNCTION(lgammal_r); 3249#else 3250#define INIT_LGAMMA_R 3251#endif 3252 3253#if SANITIZER_INTERCEPT_DRAND48_R 3254INTERCEPTOR(int, drand48_r, void *buffer, double *result) { 3255 void *ctx; 3256 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 3257 int res = REAL(drand48_r)(buffer, result); 3258 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3259 return res; 3260} 3261INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 3262 void *ctx; 3263 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 3264 int res = REAL(lrand48_r)(buffer, result); 3265 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 3266 return res; 3267} 3268#define INIT_DRAND48_R \ 3269 COMMON_INTERCEPT_FUNCTION(drand48_r); \ 3270 COMMON_INTERCEPT_FUNCTION(lrand48_r); 3271#else 3272#define INIT_DRAND48_R 3273#endif 3274 3275#if SANITIZER_INTERCEPT_RAND_R 3276INTERCEPTOR(int, rand_r, unsigned *seedp) { 3277 void *ctx; 3278 COMMON_INTERCEPTOR_ENTER(ctx, rand_r, seedp); 3279 COMMON_INTERCEPTOR_READ_RANGE(ctx, seedp, sizeof(*seedp)); 3280 return REAL(rand_r)(seedp); 3281} 3282#define INIT_RAND_R COMMON_INTERCEPT_FUNCTION(rand_r); 3283#else 3284#define INIT_RAND_R 3285#endif 3286 3287#if SANITIZER_INTERCEPT_GETLINE 3288INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { 3289 void *ctx; 3290 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); 3291 SSIZE_T res = REAL(getline)(lineptr, n, stream); 3292 if (res > 0) { 3293 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 3294 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 3295 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 3296 } 3297 return res; 3298} 3299INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, 3300 void *stream) { 3301 void *ctx; 3302 COMMON_INTERCEPTOR_ENTER(ctx, getdelim, lineptr, n, delim, stream); 3303 SSIZE_T res = REAL(getdelim)(lineptr, n, delim, stream); 3304 if (res > 0) { 3305 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 3306 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 3307 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 3308 } 3309 return res; 3310} 3311#define INIT_GETLINE \ 3312 COMMON_INTERCEPT_FUNCTION(getline); \ 3313 COMMON_INTERCEPT_FUNCTION(getdelim); 3314#else 3315#define INIT_GETLINE 3316#endif 3317 3318#if SANITIZER_INTERCEPT_ICONV 3319INTERCEPTOR(SIZE_T, iconv, void *cd, char **inbuf, SIZE_T *inbytesleft, 3320 char **outbuf, SIZE_T *outbytesleft) { 3321 void *ctx; 3322 COMMON_INTERCEPTOR_ENTER(ctx, iconv, cd, inbuf, inbytesleft, outbuf, 3323 outbytesleft); 3324 if (inbytesleft) 3325 COMMON_INTERCEPTOR_READ_RANGE(ctx, inbytesleft, sizeof(*inbytesleft)); 3326 if (inbuf && inbytesleft) 3327 COMMON_INTERCEPTOR_READ_RANGE(ctx, *inbuf, *inbytesleft); 3328 if (outbytesleft) 3329 COMMON_INTERCEPTOR_READ_RANGE(ctx, outbytesleft, sizeof(*outbytesleft)); 3330 void *outbuf_orig = outbuf ? *outbuf : 0; 3331 SIZE_T res = REAL(iconv)(cd, inbuf, inbytesleft, outbuf, outbytesleft); 3332 if (res != (SIZE_T) - 1 && outbuf && *outbuf > outbuf_orig) { 3333 SIZE_T sz = (char *)*outbuf - (char *)outbuf_orig; 3334 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, outbuf_orig, sz); 3335 } 3336 return res; 3337} 3338#define INIT_ICONV COMMON_INTERCEPT_FUNCTION(iconv); 3339#else 3340#define INIT_ICONV 3341#endif 3342 3343#if SANITIZER_INTERCEPT_TIMES 3344INTERCEPTOR(__sanitizer_clock_t, times, void *tms) { 3345 void *ctx; 3346 COMMON_INTERCEPTOR_ENTER(ctx, times, tms); 3347 __sanitizer_clock_t res = REAL(times)(tms); 3348 if (res != (__sanitizer_clock_t)-1 && tms) 3349 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tms, struct_tms_sz); 3350 return res; 3351} 3352#define INIT_TIMES COMMON_INTERCEPT_FUNCTION(times); 3353#else 3354#define INIT_TIMES 3355#endif 3356 3357#if SANITIZER_INTERCEPT_TLS_GET_ADDR 3358#define INIT_TLS_GET_ADDR COMMON_INTERCEPT_FUNCTION(__tls_get_addr) 3359INTERCEPTOR(void *, __tls_get_addr, void *arg) { 3360 void *ctx; 3361 COMMON_INTERCEPTOR_ENTER(ctx, __tls_get_addr, arg); 3362 void *res = REAL(__tls_get_addr)(arg); 3363 DTLS_on_tls_get_addr(arg, res); 3364 return res; 3365} 3366#else 3367#define INIT_TLS_GET_ADDR 3368#endif 3369 3370#if SANITIZER_INTERCEPT_LISTXATTR 3371INTERCEPTOR(SSIZE_T, listxattr, const char *path, char *list, SIZE_T size) { 3372 void *ctx; 3373 COMMON_INTERCEPTOR_ENTER(ctx, listxattr, path, list, size); 3374 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3375 SSIZE_T res = REAL(listxattr)(path, list, size); 3376 // Here and below, size == 0 is a special case where nothing is written to the 3377 // buffer, and res contains the desired buffer size. 3378 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 3379 return res; 3380} 3381INTERCEPTOR(SSIZE_T, llistxattr, const char *path, char *list, SIZE_T size) { 3382 void *ctx; 3383 COMMON_INTERCEPTOR_ENTER(ctx, llistxattr, path, list, size); 3384 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3385 SSIZE_T res = REAL(llistxattr)(path, list, size); 3386 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 3387 return res; 3388} 3389INTERCEPTOR(SSIZE_T, flistxattr, int fd, char *list, SIZE_T size) { 3390 void *ctx; 3391 COMMON_INTERCEPTOR_ENTER(ctx, flistxattr, fd, list, size); 3392 SSIZE_T res = REAL(flistxattr)(fd, list, size); 3393 if (size && res > 0 && list) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, list, res); 3394 return res; 3395} 3396#define INIT_LISTXATTR \ 3397 COMMON_INTERCEPT_FUNCTION(listxattr); \ 3398 COMMON_INTERCEPT_FUNCTION(llistxattr); \ 3399 COMMON_INTERCEPT_FUNCTION(flistxattr); 3400#else 3401#define INIT_LISTXATTR 3402#endif 3403 3404#if SANITIZER_INTERCEPT_GETXATTR 3405INTERCEPTOR(SSIZE_T, getxattr, const char *path, const char *name, char *value, 3406 SIZE_T size) { 3407 void *ctx; 3408 COMMON_INTERCEPTOR_ENTER(ctx, getxattr, path, name, value, size); 3409 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3410 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 3411 SSIZE_T res = REAL(getxattr)(path, name, value, size); 3412 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 3413 return res; 3414} 3415INTERCEPTOR(SSIZE_T, lgetxattr, const char *path, const char *name, char *value, 3416 SIZE_T size) { 3417 void *ctx; 3418 COMMON_INTERCEPTOR_ENTER(ctx, lgetxattr, path, name, value, size); 3419 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3420 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 3421 SSIZE_T res = REAL(lgetxattr)(path, name, value, size); 3422 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 3423 return res; 3424} 3425INTERCEPTOR(SSIZE_T, fgetxattr, int fd, const char *name, char *value, 3426 SIZE_T size) { 3427 void *ctx; 3428 COMMON_INTERCEPTOR_ENTER(ctx, fgetxattr, fd, name, value, size); 3429 if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 3430 SSIZE_T res = REAL(fgetxattr)(fd, name, value, size); 3431 if (size && res > 0 && value) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, value, res); 3432 return res; 3433} 3434#define INIT_GETXATTR \ 3435 COMMON_INTERCEPT_FUNCTION(getxattr); \ 3436 COMMON_INTERCEPT_FUNCTION(lgetxattr); \ 3437 COMMON_INTERCEPT_FUNCTION(fgetxattr); 3438#else 3439#define INIT_GETXATTR 3440#endif 3441 3442#if SANITIZER_INTERCEPT_GETRESID 3443INTERCEPTOR(int, getresuid, void *ruid, void *euid, void *suid) { 3444 void *ctx; 3445 COMMON_INTERCEPTOR_ENTER(ctx, getresuid, ruid, euid, suid); 3446 int res = REAL(getresuid)(ruid, euid, suid); 3447 if (res >= 0) { 3448 if (ruid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ruid, uid_t_sz); 3449 if (euid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, euid, uid_t_sz); 3450 if (suid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, suid, uid_t_sz); 3451 } 3452 return res; 3453} 3454INTERCEPTOR(int, getresgid, void *rgid, void *egid, void *sgid) { 3455 void *ctx; 3456 COMMON_INTERCEPTOR_ENTER(ctx, getresgid, rgid, egid, sgid); 3457 int res = REAL(getresgid)(rgid, egid, sgid); 3458 if (res >= 0) { 3459 if (rgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rgid, gid_t_sz); 3460 if (egid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, egid, gid_t_sz); 3461 if (sgid) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sgid, gid_t_sz); 3462 } 3463 return res; 3464} 3465#define INIT_GETRESID \ 3466 COMMON_INTERCEPT_FUNCTION(getresuid); \ 3467 COMMON_INTERCEPT_FUNCTION(getresgid); 3468#else 3469#define INIT_GETRESID 3470#endif 3471 3472#if SANITIZER_INTERCEPT_GETIFADDRS 3473// As long as getifaddrs()/freeifaddrs() use calloc()/free(), we don't need to 3474// intercept freeifaddrs(). If that ceases to be the case, we might need to 3475// intercept it to poison the memory again. 3476INTERCEPTOR(int, getifaddrs, __sanitizer_ifaddrs **ifap) { 3477 void *ctx; 3478 COMMON_INTERCEPTOR_ENTER(ctx, getifaddrs, ifap); 3479 int res = REAL(getifaddrs)(ifap); 3480 if (res == 0 && ifap) { 3481 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifap, sizeof(void *)); 3482 __sanitizer_ifaddrs *p = *ifap; 3483 while (p) { 3484 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(__sanitizer_ifaddrs)); 3485 if (p->ifa_name) 3486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_name, 3487 REAL(strlen)(p->ifa_name) + 1); 3488 if (p->ifa_addr) 3489 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_addr, struct_sockaddr_sz); 3490 if (p->ifa_netmask) 3491 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_netmask, struct_sockaddr_sz); 3492 // On Linux this is a union, but the other member also points to a 3493 // struct sockaddr, so the following is sufficient. 3494 if (p->ifa_dstaddr) 3495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ifa_dstaddr, struct_sockaddr_sz); 3496 // FIXME(smatveev): Unpoison p->ifa_data as well. 3497 p = p->ifa_next; 3498 } 3499 } 3500 return res; 3501} 3502#define INIT_GETIFADDRS \ 3503 COMMON_INTERCEPT_FUNCTION(getifaddrs); 3504#else 3505#define INIT_GETIFADDRS 3506#endif 3507 3508#if SANITIZER_INTERCEPT_IF_INDEXTONAME 3509INTERCEPTOR(char *, if_indextoname, unsigned int ifindex, char* ifname) { 3510 void *ctx; 3511 COMMON_INTERCEPTOR_ENTER(ctx, if_indextoname, ifindex, ifname); 3512 char *res = REAL(if_indextoname)(ifindex, ifname); 3513 if (res && ifname) 3514 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 3515 return res; 3516} 3517INTERCEPTOR(unsigned int, if_nametoindex, const char* ifname) { 3518 void *ctx; 3519 COMMON_INTERCEPTOR_ENTER(ctx, if_nametoindex, ifname); 3520 if (ifname) 3521 COMMON_INTERCEPTOR_READ_RANGE(ctx, ifname, REAL(strlen)(ifname) + 1); 3522 return REAL(if_nametoindex)(ifname); 3523} 3524#define INIT_IF_INDEXTONAME \ 3525 COMMON_INTERCEPT_FUNCTION(if_indextoname); \ 3526 COMMON_INTERCEPT_FUNCTION(if_nametoindex); 3527#else 3528#define INIT_IF_INDEXTONAME 3529#endif 3530 3531#if SANITIZER_INTERCEPT_CAPGET 3532INTERCEPTOR(int, capget, void *hdrp, void *datap) { 3533 void *ctx; 3534 COMMON_INTERCEPTOR_ENTER(ctx, capget, hdrp, datap); 3535 if (hdrp) 3536 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 3537 int res = REAL(capget)(hdrp, datap); 3538 if (res == 0 && datap) 3539 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datap, __user_cap_data_struct_sz); 3540 // We can also return -1 and write to hdrp->version if the version passed in 3541 // hdrp->version is unsupported. But that's not a trivial condition to check, 3542 // and anyway COMMON_INTERCEPTOR_READ_RANGE protects us to some extent. 3543 return res; 3544} 3545INTERCEPTOR(int, capset, void *hdrp, const void *datap) { 3546 void *ctx; 3547 COMMON_INTERCEPTOR_ENTER(ctx, capset, hdrp, datap); 3548 if (hdrp) 3549 COMMON_INTERCEPTOR_READ_RANGE(ctx, hdrp, __user_cap_header_struct_sz); 3550 if (datap) 3551 COMMON_INTERCEPTOR_READ_RANGE(ctx, datap, __user_cap_data_struct_sz); 3552 return REAL(capset)(hdrp, datap); 3553} 3554#define INIT_CAPGET \ 3555 COMMON_INTERCEPT_FUNCTION(capget); \ 3556 COMMON_INTERCEPT_FUNCTION(capset); 3557#else 3558#define INIT_CAPGET 3559#endif 3560 3561#if SANITIZER_INTERCEPT_AEABI_MEM 3562DECLARE_REAL_AND_INTERCEPTOR(void *, memmove, void *, const void *, uptr); 3563DECLARE_REAL_AND_INTERCEPTOR(void *, memcpy, void *, const void *, uptr); 3564DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr); 3565 3566INTERCEPTOR(void *, __aeabi_memmove, void *to, const void *from, uptr size) { 3567 return WRAP(memmove)(to, from, size); 3568} 3569INTERCEPTOR(void *, __aeabi_memmove4, void *to, const void *from, uptr size) { 3570 return WRAP(memmove)(to, from, size); 3571} 3572INTERCEPTOR(void *, __aeabi_memmove8, void *to, const void *from, uptr size) { 3573 return WRAP(memmove)(to, from, size); 3574} 3575INTERCEPTOR(void *, __aeabi_memcpy, void *to, const void *from, uptr size) { 3576 return WRAP(memcpy)(to, from, size); 3577} 3578INTERCEPTOR(void *, __aeabi_memcpy4, void *to, const void *from, uptr size) { 3579 return WRAP(memcpy)(to, from, size); 3580} 3581INTERCEPTOR(void *, __aeabi_memcpy8, void *to, const void *from, uptr size) { 3582 return WRAP(memcpy)(to, from, size); 3583} 3584// Note the argument order. 3585INTERCEPTOR(void *, __aeabi_memset, void *block, uptr size, int c) { 3586 return WRAP(memset)(block, c, size); 3587} 3588INTERCEPTOR(void *, __aeabi_memset4, void *block, uptr size, int c) { 3589 return WRAP(memset)(block, c, size); 3590} 3591INTERCEPTOR(void *, __aeabi_memset8, void *block, uptr size, int c) { 3592 return WRAP(memset)(block, c, size); 3593} 3594INTERCEPTOR(void *, __aeabi_memclr, void *block, uptr size) { 3595 return WRAP(memset)(block, 0, size); 3596} 3597INTERCEPTOR(void *, __aeabi_memclr4, void *block, uptr size) { 3598 return WRAP(memset)(block, 0, size); 3599} 3600INTERCEPTOR(void *, __aeabi_memclr8, void *block, uptr size) { 3601 return WRAP(memset)(block, 0, size); 3602} 3603#define INIT_AEABI_MEM \ 3604 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove); \ 3605 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove4); \ 3606 COMMON_INTERCEPT_FUNCTION(__aeabi_memmove8); \ 3607 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy); \ 3608 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy4); \ 3609 COMMON_INTERCEPT_FUNCTION(__aeabi_memcpy8); \ 3610 COMMON_INTERCEPT_FUNCTION(__aeabi_memset); \ 3611 COMMON_INTERCEPT_FUNCTION(__aeabi_memset4); \ 3612 COMMON_INTERCEPT_FUNCTION(__aeabi_memset8); \ 3613 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr); \ 3614 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr4); \ 3615 COMMON_INTERCEPT_FUNCTION(__aeabi_memclr8); 3616#else 3617#define INIT_AEABI_MEM 3618#endif // SANITIZER_INTERCEPT_AEABI_MEM 3619 3620#if SANITIZER_INTERCEPT___BZERO 3621DECLARE_REAL_AND_INTERCEPTOR(void *, memset, void *, int, uptr); 3622 3623INTERCEPTOR(void *, __bzero, void *block, uptr size) { 3624 return WRAP(memset)(block, 0, size); 3625} 3626#define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); 3627#else 3628#define INIT___BZERO 3629#endif // SANITIZER_INTERCEPT___BZERO 3630 3631#if SANITIZER_INTERCEPT_FTIME 3632INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { 3633 void *ctx; 3634 COMMON_INTERCEPTOR_ENTER(ctx, ftime, tp); 3635 int res = REAL(ftime)(tp); 3636 if (tp) 3637 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, sizeof(*tp)); 3638 return res; 3639} 3640#define INIT_FTIME COMMON_INTERCEPT_FUNCTION(ftime); 3641#else 3642#define INIT_FTIME 3643#endif // SANITIZER_INTERCEPT_FTIME 3644 3645#if SANITIZER_INTERCEPT_XDR 3646INTERCEPTOR(void, xdrmem_create, __sanitizer_XDR *xdrs, uptr addr, 3647 unsigned size, int op) { 3648 void *ctx; 3649 COMMON_INTERCEPTOR_ENTER(ctx, xdrmem_create, xdrs, addr, size, op); 3650 REAL(xdrmem_create)(xdrs, addr, size, op); 3651 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 3652 if (op == __sanitizer_XDR_ENCODE) { 3653 // It's not obvious how much data individual xdr_ routines write. 3654 // Simply unpoison the entire target buffer in advance. 3655 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (void *)addr, size); 3656 } 3657} 3658 3659INTERCEPTOR(void, xdrstdio_create, __sanitizer_XDR *xdrs, void *file, int op) { 3660 void *ctx; 3661 COMMON_INTERCEPTOR_ENTER(ctx, xdrstdio_create, xdrs, file, op); 3662 REAL(xdrstdio_create)(xdrs, file, op); 3663 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, xdrs, sizeof(*xdrs)); 3664} 3665 3666#define XDR_INTERCEPTOR(F, T) \ 3667 INTERCEPTOR(int, F, __sanitizer_XDR *xdrs, T *p) { \ 3668 void *ctx; \ 3669 COMMON_INTERCEPTOR_ENTER(ctx, F, xdrs, p); \ 3670 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) \ 3671 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); \ 3672 int res = REAL(F)(xdrs, p); \ 3673 if (res && p && xdrs->x_op == __sanitizer_XDR_DECODE) \ 3674 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); \ 3675 return res; \ 3676 } 3677 3678XDR_INTERCEPTOR(xdr_short, short) 3679XDR_INTERCEPTOR(xdr_u_short, unsigned short) 3680XDR_INTERCEPTOR(xdr_int, int) 3681XDR_INTERCEPTOR(xdr_u_int, unsigned) 3682XDR_INTERCEPTOR(xdr_long, long) 3683XDR_INTERCEPTOR(xdr_u_long, unsigned long) 3684XDR_INTERCEPTOR(xdr_hyper, long long) 3685XDR_INTERCEPTOR(xdr_u_hyper, unsigned long long) 3686XDR_INTERCEPTOR(xdr_longlong_t, long long) 3687XDR_INTERCEPTOR(xdr_u_longlong_t, unsigned long long) 3688XDR_INTERCEPTOR(xdr_int8_t, u8) 3689XDR_INTERCEPTOR(xdr_uint8_t, u8) 3690XDR_INTERCEPTOR(xdr_int16_t, u16) 3691XDR_INTERCEPTOR(xdr_uint16_t, u16) 3692XDR_INTERCEPTOR(xdr_int32_t, u32) 3693XDR_INTERCEPTOR(xdr_uint32_t, u32) 3694XDR_INTERCEPTOR(xdr_int64_t, u64) 3695XDR_INTERCEPTOR(xdr_uint64_t, u64) 3696XDR_INTERCEPTOR(xdr_quad_t, long long) 3697XDR_INTERCEPTOR(xdr_u_quad_t, unsigned long long) 3698XDR_INTERCEPTOR(xdr_bool, bool) 3699XDR_INTERCEPTOR(xdr_enum, int) 3700XDR_INTERCEPTOR(xdr_char, char) 3701XDR_INTERCEPTOR(xdr_u_char, unsigned char) 3702XDR_INTERCEPTOR(xdr_float, float) 3703XDR_INTERCEPTOR(xdr_double, double) 3704 3705// FIXME: intercept xdr_array, opaque, union, vector, reference, pointer, 3706// wrapstring, sizeof 3707 3708INTERCEPTOR(int, xdr_bytes, __sanitizer_XDR *xdrs, char **p, unsigned *sizep, 3709 unsigned maxsize) { 3710 void *ctx; 3711 COMMON_INTERCEPTOR_ENTER(ctx, xdr_bytes, xdrs, p, sizep, maxsize); 3712 if (p && sizep && xdrs->x_op == __sanitizer_XDR_ENCODE) { 3713 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 3714 COMMON_INTERCEPTOR_READ_RANGE(ctx, sizep, sizeof(*sizep)); 3715 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, *sizep); 3716 } 3717 int res = REAL(xdr_bytes)(xdrs, p, sizep, maxsize); 3718 if (p && sizep && xdrs->x_op == __sanitizer_XDR_DECODE) { 3719 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 3720 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizep, sizeof(*sizep)); 3721 if (res && *p && *sizep) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, *sizep); 3722 } 3723 return res; 3724} 3725 3726INTERCEPTOR(int, xdr_string, __sanitizer_XDR *xdrs, char **p, 3727 unsigned maxsize) { 3728 void *ctx; 3729 COMMON_INTERCEPTOR_ENTER(ctx, xdr_string, xdrs, p, maxsize); 3730 if (p && xdrs->x_op == __sanitizer_XDR_ENCODE) { 3731 COMMON_INTERCEPTOR_READ_RANGE(ctx, p, sizeof(*p)); 3732 COMMON_INTERCEPTOR_READ_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 3733 } 3734 int res = REAL(xdr_string)(xdrs, p, maxsize); 3735 if (p && xdrs->x_op == __sanitizer_XDR_DECODE) { 3736 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 3737 if (res && *p) 3738 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 3739 } 3740 return res; 3741} 3742 3743#define INIT_XDR \ 3744 COMMON_INTERCEPT_FUNCTION(xdrmem_create); \ 3745 COMMON_INTERCEPT_FUNCTION(xdrstdio_create); \ 3746 COMMON_INTERCEPT_FUNCTION(xdr_short); \ 3747 COMMON_INTERCEPT_FUNCTION(xdr_u_short); \ 3748 COMMON_INTERCEPT_FUNCTION(xdr_int); \ 3749 COMMON_INTERCEPT_FUNCTION(xdr_u_int); \ 3750 COMMON_INTERCEPT_FUNCTION(xdr_long); \ 3751 COMMON_INTERCEPT_FUNCTION(xdr_u_long); \ 3752 COMMON_INTERCEPT_FUNCTION(xdr_hyper); \ 3753 COMMON_INTERCEPT_FUNCTION(xdr_u_hyper); \ 3754 COMMON_INTERCEPT_FUNCTION(xdr_longlong_t); \ 3755 COMMON_INTERCEPT_FUNCTION(xdr_u_longlong_t); \ 3756 COMMON_INTERCEPT_FUNCTION(xdr_int8_t); \ 3757 COMMON_INTERCEPT_FUNCTION(xdr_uint8_t); \ 3758 COMMON_INTERCEPT_FUNCTION(xdr_int16_t); \ 3759 COMMON_INTERCEPT_FUNCTION(xdr_uint16_t); \ 3760 COMMON_INTERCEPT_FUNCTION(xdr_int32_t); \ 3761 COMMON_INTERCEPT_FUNCTION(xdr_uint32_t); \ 3762 COMMON_INTERCEPT_FUNCTION(xdr_int64_t); \ 3763 COMMON_INTERCEPT_FUNCTION(xdr_uint64_t); \ 3764 COMMON_INTERCEPT_FUNCTION(xdr_quad_t); \ 3765 COMMON_INTERCEPT_FUNCTION(xdr_u_quad_t); \ 3766 COMMON_INTERCEPT_FUNCTION(xdr_bool); \ 3767 COMMON_INTERCEPT_FUNCTION(xdr_enum); \ 3768 COMMON_INTERCEPT_FUNCTION(xdr_char); \ 3769 COMMON_INTERCEPT_FUNCTION(xdr_u_char); \ 3770 COMMON_INTERCEPT_FUNCTION(xdr_float); \ 3771 COMMON_INTERCEPT_FUNCTION(xdr_double); \ 3772 COMMON_INTERCEPT_FUNCTION(xdr_bytes); \ 3773 COMMON_INTERCEPT_FUNCTION(xdr_string); 3774#else 3775#define INIT_XDR 3776#endif // SANITIZER_INTERCEPT_XDR 3777 3778#if SANITIZER_INTERCEPT_TSEARCH 3779INTERCEPTOR(void *, tsearch, void *key, void **rootp, 3780 int (*compar)(const void *, const void *)) { 3781 void *ctx; 3782 COMMON_INTERCEPTOR_ENTER(ctx, tsearch, key, rootp, compar); 3783 void *res = REAL(tsearch)(key, rootp, compar); 3784 if (res && *(void **)res == key) 3785 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(void *)); 3786 return res; 3787} 3788#define INIT_TSEARCH COMMON_INTERCEPT_FUNCTION(tsearch); 3789#else 3790#define INIT_TSEARCH 3791#endif 3792 3793#if SANITIZER_INTERCEPT_LIBIO_INTERNALS || SANITIZER_INTERCEPT_FOPEN || \ 3794 SANITIZER_INTERCEPT_OPEN_MEMSTREAM 3795void unpoison_file(__sanitizer_FILE *fp) { 3796#if SANITIZER_HAS_STRUCT_FILE 3797 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp)); 3798 if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) 3799 COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, 3800 fp->_IO_read_end - fp->_IO_read_base); 3801#endif // SANITIZER_HAS_STRUCT_FILE 3802} 3803#endif 3804 3805#if SANITIZER_INTERCEPT_LIBIO_INTERNALS 3806// These guys are called when a .c source is built with -O2. 3807INTERCEPTOR(int, __uflow, __sanitizer_FILE *fp) { 3808 void *ctx; 3809 COMMON_INTERCEPTOR_ENTER(ctx, __uflow, fp); 3810 int res = REAL(__uflow)(fp); 3811 unpoison_file(fp); 3812 return res; 3813} 3814INTERCEPTOR(int, __underflow, __sanitizer_FILE *fp) { 3815 void *ctx; 3816 COMMON_INTERCEPTOR_ENTER(ctx, __underflow, fp); 3817 int res = REAL(__underflow)(fp); 3818 unpoison_file(fp); 3819 return res; 3820} 3821INTERCEPTOR(int, __overflow, __sanitizer_FILE *fp, int ch) { 3822 void *ctx; 3823 COMMON_INTERCEPTOR_ENTER(ctx, __overflow, fp, ch); 3824 int res = REAL(__overflow)(fp, ch); 3825 unpoison_file(fp); 3826 return res; 3827} 3828INTERCEPTOR(int, __wuflow, __sanitizer_FILE *fp) { 3829 void *ctx; 3830 COMMON_INTERCEPTOR_ENTER(ctx, __wuflow, fp); 3831 int res = REAL(__wuflow)(fp); 3832 unpoison_file(fp); 3833 return res; 3834} 3835INTERCEPTOR(int, __wunderflow, __sanitizer_FILE *fp) { 3836 void *ctx; 3837 COMMON_INTERCEPTOR_ENTER(ctx, __wunderflow, fp); 3838 int res = REAL(__wunderflow)(fp); 3839 unpoison_file(fp); 3840 return res; 3841} 3842INTERCEPTOR(int, __woverflow, __sanitizer_FILE *fp, int ch) { 3843 void *ctx; 3844 COMMON_INTERCEPTOR_ENTER(ctx, __woverflow, fp, ch); 3845 int res = REAL(__woverflow)(fp, ch); 3846 unpoison_file(fp); 3847 return res; 3848} 3849#define INIT_LIBIO_INTERNALS \ 3850 COMMON_INTERCEPT_FUNCTION(__uflow); \ 3851 COMMON_INTERCEPT_FUNCTION(__underflow); \ 3852 COMMON_INTERCEPT_FUNCTION(__overflow); \ 3853 COMMON_INTERCEPT_FUNCTION(__wuflow); \ 3854 COMMON_INTERCEPT_FUNCTION(__wunderflow); \ 3855 COMMON_INTERCEPT_FUNCTION(__woverflow); 3856#else 3857#define INIT_LIBIO_INTERNALS 3858#endif 3859 3860#if SANITIZER_INTERCEPT_FOPEN 3861INTERCEPTOR(__sanitizer_FILE *, fopen, const char *path, const char *mode) { 3862 void *ctx; 3863 COMMON_INTERCEPTOR_ENTER(ctx, fopen, path, mode); 3864 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3865 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 3866 __sanitizer_FILE *res = REAL(fopen)(path, mode); 3867 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 3868 if (res) unpoison_file(res); 3869 return res; 3870} 3871INTERCEPTOR(__sanitizer_FILE *, fdopen, int fd, const char *mode) { 3872 void *ctx; 3873 COMMON_INTERCEPTOR_ENTER(ctx, fdopen, fd, mode); 3874 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 3875 __sanitizer_FILE *res = REAL(fdopen)(fd, mode); 3876 if (res) unpoison_file(res); 3877 return res; 3878} 3879INTERCEPTOR(__sanitizer_FILE *, freopen, const char *path, const char *mode, 3880 __sanitizer_FILE *fp) { 3881 void *ctx; 3882 COMMON_INTERCEPTOR_ENTER(ctx, freopen, path, mode, fp); 3883 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3884 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 3885 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 3886 __sanitizer_FILE *res = REAL(freopen)(path, mode, fp); 3887 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 3888 if (res) unpoison_file(res); 3889 return res; 3890} 3891#define INIT_FOPEN \ 3892 COMMON_INTERCEPT_FUNCTION(fopen); \ 3893 COMMON_INTERCEPT_FUNCTION(fdopen); \ 3894 COMMON_INTERCEPT_FUNCTION(freopen); 3895#else 3896#define INIT_FOPEN 3897#endif 3898 3899#if SANITIZER_INTERCEPT_FOPEN64 3900INTERCEPTOR(__sanitizer_FILE *, fopen64, const char *path, const char *mode) { 3901 void *ctx; 3902 COMMON_INTERCEPTOR_ENTER(ctx, fopen64, path, mode); 3903 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3904 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 3905 __sanitizer_FILE *res = REAL(fopen64)(path, mode); 3906 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 3907 if (res) unpoison_file(res); 3908 return res; 3909} 3910INTERCEPTOR(__sanitizer_FILE *, freopen64, const char *path, const char *mode, 3911 __sanitizer_FILE *fp) { 3912 void *ctx; 3913 COMMON_INTERCEPTOR_ENTER(ctx, freopen64, path, mode, fp); 3914 COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 3915 COMMON_INTERCEPTOR_READ_RANGE(ctx, mode, REAL(strlen)(mode) + 1); 3916 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 3917 __sanitizer_FILE *res = REAL(freopen64)(path, mode, fp); 3918 COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, path); 3919 if (res) unpoison_file(res); 3920 return res; 3921} 3922#define INIT_FOPEN64 \ 3923 COMMON_INTERCEPT_FUNCTION(fopen64); \ 3924 COMMON_INTERCEPT_FUNCTION(freopen64); 3925#else 3926#define INIT_FOPEN64 3927#endif 3928 3929#if SANITIZER_INTERCEPT_OPEN_MEMSTREAM 3930INTERCEPTOR(__sanitizer_FILE *, open_memstream, char **ptr, SIZE_T *sizeloc) { 3931 void *ctx; 3932 COMMON_INTERCEPTOR_ENTER(ctx, open_memstream, ptr, sizeloc); 3933 __sanitizer_FILE *res = REAL(open_memstream)(ptr, sizeloc); 3934 if (res) { 3935 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 3936 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 3937 unpoison_file(res); 3938 FileMetadata file = {ptr, sizeloc}; 3939 SetInterceptorMetadata(res, file); 3940 } 3941 return res; 3942} 3943INTERCEPTOR(__sanitizer_FILE *, open_wmemstream, wchar_t **ptr, 3944 SIZE_T *sizeloc) { 3945 void *ctx; 3946 COMMON_INTERCEPTOR_ENTER(ctx, open_wmemstream, ptr, sizeloc); 3947 __sanitizer_FILE *res = REAL(open_wmemstream)(ptr, sizeloc); 3948 if (res) { 3949 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sizeof(*ptr)); 3950 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sizeloc, sizeof(*sizeloc)); 3951 unpoison_file(res); 3952 FileMetadata file = {(char **)ptr, sizeloc}; 3953 SetInterceptorMetadata(res, file); 3954 } 3955 return res; 3956} 3957INTERCEPTOR(__sanitizer_FILE *, fmemopen, void *buf, SIZE_T size, 3958 const char *mode) { 3959 void *ctx; 3960 COMMON_INTERCEPTOR_ENTER(ctx, fmemopen, buf, size, mode); 3961 __sanitizer_FILE *res = REAL(fmemopen)(buf, size, mode); 3962 if (res) unpoison_file(res); 3963 return res; 3964} 3965#define INIT_OPEN_MEMSTREAM \ 3966 COMMON_INTERCEPT_FUNCTION(open_memstream); \ 3967 COMMON_INTERCEPT_FUNCTION(open_wmemstream); \ 3968 COMMON_INTERCEPT_FUNCTION(fmemopen); 3969#else 3970#define INIT_OPEN_MEMSTREAM 3971#endif 3972 3973#if SANITIZER_INTERCEPT_OBSTACK 3974static void initialize_obstack(__sanitizer_obstack *obstack) { 3975 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack, sizeof(*obstack)); 3976 if (obstack->chunk) 3977 COMMON_INTERCEPTOR_INITIALIZE_RANGE(obstack->chunk, 3978 sizeof(*obstack->chunk)); 3979} 3980 3981INTERCEPTOR(int, _obstack_begin_1, __sanitizer_obstack *obstack, int sz, 3982 int align, void *(*alloc_fn)(uptr arg, uptr sz), 3983 void (*free_fn)(uptr arg, void *p)) { 3984 void *ctx; 3985 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin_1, obstack, sz, align, alloc_fn, 3986 free_fn); 3987 int res = REAL(_obstack_begin_1)(obstack, sz, align, alloc_fn, free_fn); 3988 if (res) initialize_obstack(obstack); 3989 return res; 3990} 3991INTERCEPTOR(int, _obstack_begin, __sanitizer_obstack *obstack, int sz, 3992 int align, void *(*alloc_fn)(uptr sz), void (*free_fn)(void *p)) { 3993 void *ctx; 3994 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_begin, obstack, sz, align, alloc_fn, 3995 free_fn); 3996 int res = REAL(_obstack_begin)(obstack, sz, align, alloc_fn, free_fn); 3997 if (res) initialize_obstack(obstack); 3998 return res; 3999} 4000INTERCEPTOR(void, _obstack_newchunk, __sanitizer_obstack *obstack, int length) { 4001 void *ctx; 4002 COMMON_INTERCEPTOR_ENTER(ctx, _obstack_newchunk, obstack, length); 4003 REAL(_obstack_newchunk)(obstack, length); 4004 if (obstack->chunk) 4005 COMMON_INTERCEPTOR_INITIALIZE_RANGE( 4006 obstack->chunk, obstack->next_free - (char *)obstack->chunk); 4007} 4008#define INIT_OBSTACK \ 4009 COMMON_INTERCEPT_FUNCTION(_obstack_begin_1); \ 4010 COMMON_INTERCEPT_FUNCTION(_obstack_begin); \ 4011 COMMON_INTERCEPT_FUNCTION(_obstack_newchunk); 4012#else 4013#define INIT_OBSTACK 4014#endif 4015 4016#if SANITIZER_INTERCEPT_FFLUSH 4017INTERCEPTOR(int, fflush, __sanitizer_FILE *fp) { 4018 void *ctx; 4019 COMMON_INTERCEPTOR_ENTER(ctx, fflush, fp); 4020 int res = REAL(fflush)(fp); 4021 // FIXME: handle fp == NULL 4022 if (fp) { 4023 const FileMetadata *m = GetInterceptorMetadata(fp); 4024 if (m) COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 4025 } 4026 return res; 4027} 4028#define INIT_FFLUSH COMMON_INTERCEPT_FUNCTION(fflush); 4029#else 4030#define INIT_FFLUSH 4031#endif 4032 4033#if SANITIZER_INTERCEPT_FCLOSE 4034INTERCEPTOR(int, fclose, __sanitizer_FILE *fp) { 4035 void *ctx; 4036 COMMON_INTERCEPTOR_ENTER(ctx, fclose, fp); 4037 if (fp) { 4038 COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); 4039 const FileMetadata *m = GetInterceptorMetadata(fp); 4040 if (m) { 4041 COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); 4042 DeleteInterceptorMetadata(fp); 4043 } 4044 } 4045 return REAL(fclose)(fp); 4046} 4047#define INIT_FCLOSE COMMON_INTERCEPT_FUNCTION(fclose); 4048#else 4049#define INIT_FCLOSE 4050#endif 4051 4052#if SANITIZER_INTERCEPT_DLOPEN_DLCLOSE 4053INTERCEPTOR(void*, dlopen, const char *filename, int flag) { 4054 void *ctx; 4055 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlopen, filename, flag); 4056 void *res = REAL(dlopen)(filename, flag); 4057 COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, res); 4058 return res; 4059} 4060 4061INTERCEPTOR(int, dlclose, void *handle) { 4062 void *ctx; 4063 COMMON_INTERCEPTOR_ENTER_NOIGNORE(ctx, dlclose, handle); 4064 int res = REAL(dlclose)(handle); 4065 COMMON_INTERCEPTOR_LIBRARY_UNLOADED(); 4066 return res; 4067} 4068#define INIT_DLOPEN_DLCLOSE \ 4069 COMMON_INTERCEPT_FUNCTION(dlopen); \ 4070 COMMON_INTERCEPT_FUNCTION(dlclose); 4071#else 4072#define INIT_DLOPEN_DLCLOSE 4073#endif 4074 4075static void InitializeCommonInterceptors() { 4076 static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; 4077 interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); 4078 4079 INIT_TEXTDOMAIN; 4080 INIT_STRCMP; 4081 INIT_STRNCMP; 4082 INIT_STRCASECMP; 4083 INIT_STRNCASECMP; 4084 INIT_MEMCHR; 4085 INIT_MEMRCHR; 4086 INIT_READ; 4087 INIT_PREAD; 4088 INIT_PREAD64; 4089 INIT_READV; 4090 INIT_PREADV; 4091 INIT_PREADV64; 4092 INIT_WRITE; 4093 INIT_PWRITE; 4094 INIT_PWRITE64; 4095 INIT_WRITEV; 4096 INIT_PWRITEV; 4097 INIT_PWRITEV64; 4098 INIT_PRCTL; 4099 INIT_LOCALTIME_AND_FRIENDS; 4100 INIT_STRPTIME; 4101 INIT_SCANF; 4102 INIT_ISOC99_SCANF; 4103 INIT_PRINTF; 4104 INIT_ISOC99_PRINTF; 4105 INIT_FREXP; 4106 INIT_FREXPF_FREXPL; 4107 INIT_GETPWNAM_AND_FRIENDS; 4108 INIT_GETPWNAM_R_AND_FRIENDS; 4109 INIT_GETPWENT; 4110 INIT_FGETPWENT; 4111 INIT_GETPWENT_R; 4112 INIT_SETPWENT; 4113 INIT_CLOCK_GETTIME; 4114 INIT_GETITIMER; 4115 INIT_TIME; 4116 INIT_GLOB; 4117 INIT_WAIT; 4118 INIT_WAIT4; 4119 INIT_INET; 4120 INIT_PTHREAD_GETSCHEDPARAM; 4121 INIT_GETADDRINFO; 4122 INIT_GETNAMEINFO; 4123 INIT_GETSOCKNAME; 4124 INIT_GETHOSTBYNAME; 4125 INIT_GETHOSTBYNAME_R; 4126 INIT_GETSOCKOPT; 4127 INIT_ACCEPT; 4128 INIT_ACCEPT4; 4129 INIT_MODF; 4130 INIT_RECVMSG; 4131 INIT_GETPEERNAME; 4132 INIT_IOCTL; 4133 INIT_INET_ATON; 4134 INIT_SYSINFO; 4135 INIT_READDIR; 4136 INIT_READDIR64; 4137 INIT_PTRACE; 4138 INIT_SETLOCALE; 4139 INIT_GETCWD; 4140 INIT_GET_CURRENT_DIR_NAME; 4141 INIT_STRTOIMAX; 4142 INIT_MBSTOWCS; 4143 INIT_MBSNRTOWCS; 4144 INIT_WCSTOMBS; 4145 INIT_WCSNRTOMBS; 4146 INIT_TCGETATTR; 4147 INIT_REALPATH; 4148 INIT_CANONICALIZE_FILE_NAME; 4149 INIT_CONFSTR; 4150 INIT_SCHED_GETAFFINITY; 4151 INIT_STRERROR; 4152 INIT_STRERROR_R; 4153 INIT_XPG_STRERROR_R; 4154 INIT_SCANDIR; 4155 INIT_SCANDIR64; 4156 INIT_GETGROUPS; 4157 INIT_POLL; 4158 INIT_PPOLL; 4159 INIT_WORDEXP; 4160 INIT_SIGWAIT; 4161 INIT_SIGWAITINFO; 4162 INIT_SIGTIMEDWAIT; 4163 INIT_SIGSETOPS; 4164 INIT_SIGPENDING; 4165 INIT_SIGPROCMASK; 4166 INIT_BACKTRACE; 4167 INIT__EXIT; 4168 INIT_PTHREAD_MUTEX_LOCK; 4169 INIT_PTHREAD_MUTEX_UNLOCK; 4170 INIT_GETMNTENT; 4171 INIT_GETMNTENT_R; 4172 INIT_STATFS; 4173 INIT_STATFS64; 4174 INIT_STATVFS; 4175 INIT_STATVFS64; 4176 INIT_INITGROUPS; 4177 INIT_ETHER; 4178 INIT_ETHER_R; 4179 INIT_SHMCTL; 4180 INIT_RANDOM_R; 4181 INIT_PTHREAD_ATTR_GET; 4182 INIT_PTHREAD_ATTR_GETINHERITSCHED; 4183 INIT_PTHREAD_ATTR_GETAFFINITY_NP; 4184 INIT_TMPNAM; 4185 INIT_TMPNAM_R; 4186 INIT_TEMPNAM; 4187 INIT_PTHREAD_SETNAME_NP; 4188 INIT_SINCOS; 4189 INIT_REMQUO; 4190 INIT_LGAMMA; 4191 INIT_LGAMMA_R; 4192 INIT_DRAND48_R; 4193 INIT_RAND_R; 4194 INIT_GETLINE; 4195 INIT_ICONV; 4196 INIT_TIMES; 4197 INIT_TLS_GET_ADDR; 4198 INIT_LISTXATTR; 4199 INIT_GETXATTR; 4200 INIT_GETRESID; 4201 INIT_GETIFADDRS; 4202 INIT_IF_INDEXTONAME; 4203 INIT_CAPGET; 4204 INIT_AEABI_MEM; 4205 INIT___BZERO; 4206 INIT_FTIME; 4207 INIT_XDR; 4208 INIT_TSEARCH; 4209 INIT_LIBIO_INTERNALS; 4210 INIT_FOPEN; 4211 INIT_FOPEN64; 4212 INIT_OPEN_MEMSTREAM; 4213 INIT_OBSTACK; 4214 INIT_FFLUSH; 4215 INIT_FCLOSE; 4216 INIT_DLOPEN_DLCLOSE; 4217} 4218