sanitizer_common_interceptors.inc revision 11f5309ec1bf13430c8a3a16f177d9e8e1190e38
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//===----------------------------------------------------------------------===// 29#include "interception/interception.h" 30#include "sanitizer_platform_interceptors.h" 31 32#include <stdarg.h> 33 34#if SANITIZER_WINDOWS 35#define va_copy(dst, src) ((dst) = (src)) 36#endif // _WIN32 37 38#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 39#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {} 40#endif 41 42#ifndef COMMON_INTERCEPTOR_FD_ACCESS 43#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 44#endif 45 46#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK 47#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {} 48#endif 49 50#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 51#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 52#endif 53 54#ifndef COMMON_INTERCEPTOR_MUTEX_REPAIR 55#define COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m) {} 56#endif 57 58#if SANITIZER_INTERCEPT_STRCMP 59static inline int CharCmpX(unsigned char c1, unsigned char c2) { 60 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 61} 62 63INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 64 void *ctx; 65 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 66 unsigned char c1, c2; 67 uptr i; 68 for (i = 0;; i++) { 69 c1 = (unsigned char)s1[i]; 70 c2 = (unsigned char)s2[i]; 71 if (c1 != c2 || c1 == '\0') break; 72 } 73 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 74 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 75 return CharCmpX(c1, c2); 76} 77 78INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 79 void *ctx; 80 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 81 unsigned char c1 = 0, c2 = 0; 82 uptr i; 83 for (i = 0; i < size; i++) { 84 c1 = (unsigned char)s1[i]; 85 c2 = (unsigned char)s2[i]; 86 if (c1 != c2 || c1 == '\0') break; 87 } 88 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 89 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 90 return CharCmpX(c1, c2); 91} 92 93#define INIT_STRCMP COMMON_INTERCEPT_FUNCTION(strcmp) 94#define INIT_STRNCMP COMMON_INTERCEPT_FUNCTION(strncmp) 95#else 96#define INIT_STRCMP 97#define INIT_STRNCMP 98#endif 99 100#if SANITIZER_INTERCEPT_STRCASECMP 101static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 102 int c1_low = ToLower(c1); 103 int c2_low = ToLower(c2); 104 return c1_low - c2_low; 105} 106 107INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 108 void *ctx; 109 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 110 unsigned char c1 = 0, c2 = 0; 111 uptr i; 112 for (i = 0;; i++) { 113 c1 = (unsigned char)s1[i]; 114 c2 = (unsigned char)s2[i]; 115 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 116 } 117 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 118 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 119 return CharCaseCmp(c1, c2); 120} 121 122INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 123 void *ctx; 124 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 125 unsigned char c1 = 0, c2 = 0; 126 uptr i; 127 for (i = 0; i < n; i++) { 128 c1 = (unsigned char)s1[i]; 129 c2 = (unsigned char)s2[i]; 130 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') break; 131 } 132 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 133 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 134 return CharCaseCmp(c1, c2); 135} 136 137#define INIT_STRCASECMP COMMON_INTERCEPT_FUNCTION(strcasecmp) 138#define INIT_STRNCASECMP COMMON_INTERCEPT_FUNCTION(strncasecmp) 139#else 140#define INIT_STRCASECMP 141#define INIT_STRNCASECMP 142#endif 143 144#if SANITIZER_INTERCEPT_FREXP 145INTERCEPTOR(double, frexp, double x, int *exp) { 146 void *ctx; 147 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 148 double res = REAL(frexp)(x, exp); 149 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 150 return res; 151} 152 153#define INIT_FREXP COMMON_INTERCEPT_FUNCTION(frexp); 154#else 155#define INIT_FREXP 156#endif // SANITIZER_INTERCEPT_FREXP 157 158#if SANITIZER_INTERCEPT_FREXPF_FREXPL 159INTERCEPTOR(float, frexpf, float x, int *exp) { 160 void *ctx; 161 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 162 float res = REAL(frexpf)(x, exp); 163 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 164 return res; 165} 166 167INTERCEPTOR(long double, frexpl, long double x, int *exp) { 168 void *ctx; 169 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 170 long double res = REAL(frexpl)(x, exp); 171 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 172 return res; 173} 174 175#define INIT_FREXPF_FREXPL \ 176 COMMON_INTERCEPT_FUNCTION(frexpf); \ 177 COMMON_INTERCEPT_FUNCTION(frexpl) 178#else 179#define INIT_FREXPF_FREXPL 180#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 181 182#if SI_NOT_WINDOWS 183static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 184 SIZE_T iovlen, SIZE_T maxlen) { 185 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 186 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 187 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 188 maxlen -= sz; 189 } 190} 191 192static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 193 SIZE_T iovlen, SIZE_T maxlen) { 194 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 195 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 196 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 197 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 198 maxlen -= sz; 199 } 200} 201#endif 202 203#if SANITIZER_INTERCEPT_READ 204INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 205 void *ctx; 206 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 207 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 208 SSIZE_T res = REAL(read)(fd, ptr, count); 209 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 210 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 211 return res; 212} 213#define INIT_READ COMMON_INTERCEPT_FUNCTION(read) 214#else 215#define INIT_READ 216#endif 217 218#if SANITIZER_INTERCEPT_PREAD 219INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 220 void *ctx; 221 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 222 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 223 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 224 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 225 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 226 return res; 227} 228#define INIT_PREAD COMMON_INTERCEPT_FUNCTION(pread) 229#else 230#define INIT_PREAD 231#endif 232 233#if SANITIZER_INTERCEPT_PREAD64 234INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 235 void *ctx; 236 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 237 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 238 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 239 if (res > 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 240 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 241 return res; 242} 243#define INIT_PREAD64 COMMON_INTERCEPT_FUNCTION(pread64) 244#else 245#define INIT_PREAD64 246#endif 247 248#if SANITIZER_INTERCEPT_READV 249INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 250 int iovcnt) { 251 void *ctx; 252 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 253 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 254 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 255 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 256 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 257 return res; 258} 259#define INIT_READV COMMON_INTERCEPT_FUNCTION(readv) 260#else 261#define INIT_READV 262#endif 263 264#if SANITIZER_INTERCEPT_PREADV 265INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 266 OFF_T offset) { 267 void *ctx; 268 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 269 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 270 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 271 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 272 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 273 return res; 274} 275#define INIT_PREADV COMMON_INTERCEPT_FUNCTION(preadv) 276#else 277#define INIT_PREADV 278#endif 279 280#if SANITIZER_INTERCEPT_PREADV64 281INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 282 OFF64_T offset) { 283 void *ctx; 284 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 285 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 286 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 287 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 288 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 289 return res; 290} 291#define INIT_PREADV64 COMMON_INTERCEPT_FUNCTION(preadv64) 292#else 293#define INIT_PREADV64 294#endif 295 296#if SANITIZER_INTERCEPT_WRITE 297INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 298 void *ctx; 299 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 300 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 301 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 302 SSIZE_T res = REAL(write)(fd, ptr, count); 303 // FIXME: this check should be _before_ the call to REAL(write), not after 304 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 305 return res; 306} 307#define INIT_WRITE COMMON_INTERCEPT_FUNCTION(write) 308#else 309#define INIT_WRITE 310#endif 311 312#if SANITIZER_INTERCEPT_PWRITE 313INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 314 void *ctx; 315 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 316 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 317 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 318 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 319 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 320 return res; 321} 322#define INIT_PWRITE COMMON_INTERCEPT_FUNCTION(pwrite) 323#else 324#define INIT_PWRITE 325#endif 326 327#if SANITIZER_INTERCEPT_PWRITE64 328INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 329 OFF64_T offset) { 330 void *ctx; 331 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 332 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 333 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 334 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 335 if (res > 0) COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 336 return res; 337} 338#define INIT_PWRITE64 COMMON_INTERCEPT_FUNCTION(pwrite64) 339#else 340#define INIT_PWRITE64 341#endif 342 343#if SANITIZER_INTERCEPT_WRITEV 344INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 345 int iovcnt) { 346 void *ctx; 347 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 348 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 349 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 350 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 351 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 352 return res; 353} 354#define INIT_WRITEV COMMON_INTERCEPT_FUNCTION(writev) 355#else 356#define INIT_WRITEV 357#endif 358 359#if SANITIZER_INTERCEPT_PWRITEV 360INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 361 OFF_T offset) { 362 void *ctx; 363 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 364 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 365 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 366 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 367 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 368 return res; 369} 370#define INIT_PWRITEV COMMON_INTERCEPT_FUNCTION(pwritev) 371#else 372#define INIT_PWRITEV 373#endif 374 375#if SANITIZER_INTERCEPT_PWRITEV64 376INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 377 OFF64_T offset) { 378 void *ctx; 379 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 380 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 381 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 382 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 383 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 384 return res; 385} 386#define INIT_PWRITEV64 COMMON_INTERCEPT_FUNCTION(pwritev64) 387#else 388#define INIT_PWRITEV64 389#endif 390 391#if SANITIZER_INTERCEPT_PRCTL 392INTERCEPTOR(int, prctl, int option, unsigned long arg2, 393 unsigned long arg3, // NOLINT 394 unsigned long arg4, unsigned long arg5) { // NOLINT 395 void *ctx; 396 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 397 static const int PR_SET_NAME = 15; 398 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 399 if (option == PR_SET_NAME) { 400 char buff[16]; 401 internal_strncpy(buff, (char *)arg2, 15); 402 buff[15] = 0; 403 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 404 } 405 return res; 406} 407#define INIT_PRCTL COMMON_INTERCEPT_FUNCTION(prctl) 408#else 409#define INIT_PRCTL 410#endif // SANITIZER_INTERCEPT_PRCTL 411 412#if SANITIZER_INTERCEPT_TIME 413INTERCEPTOR(unsigned long, time, unsigned long *t) { 414 void *ctx; 415 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 416 unsigned long res = REAL(time)(t); 417 if (t && res != (unsigned long)-1) { 418 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 419 } 420 return res; 421} 422#define INIT_TIME COMMON_INTERCEPT_FUNCTION(time); 423#else 424#define INIT_TIME 425#endif // SANITIZER_INTERCEPT_TIME 426 427#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 428static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 430 if (tm->tm_zone) { 431 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 432 // can point to shared memory and tsan would report a data race. 433 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone, 434 REAL(strlen(tm->tm_zone)) + 1); 435 } 436} 437INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 438 void *ctx; 439 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 440 __sanitizer_tm *res = REAL(localtime)(timep); 441 if (res) { 442 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 443 unpoison_tm(ctx, res); 444 } 445 return res; 446} 447INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 448 void *ctx; 449 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 450 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 451 if (res) { 452 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 453 unpoison_tm(ctx, res); 454 } 455 return res; 456} 457INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 458 void *ctx; 459 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 460 __sanitizer_tm *res = REAL(gmtime)(timep); 461 if (res) { 462 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 463 unpoison_tm(ctx, res); 464 } 465 return res; 466} 467INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 468 void *ctx; 469 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 470 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 471 if (res) { 472 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 473 unpoison_tm(ctx, res); 474 } 475 return res; 476} 477INTERCEPTOR(char *, ctime, unsigned long *timep) { 478 void *ctx; 479 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 480 char *res = REAL(ctime)(timep); 481 if (res) { 482 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 483 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 484 } 485 return res; 486} 487INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 488 void *ctx; 489 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 490 char *res = REAL(ctime_r)(timep, result); 491 if (res) { 492 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 493 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 494 } 495 return res; 496} 497INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 498 void *ctx; 499 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 500 char *res = REAL(asctime)(tm); 501 if (res) { 502 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 503 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 504 } 505 return res; 506} 507INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 508 void *ctx; 509 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 510 char *res = REAL(asctime_r)(tm, result); 511 if (res) { 512 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 513 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 514 } 515 return res; 516} 517#define INIT_LOCALTIME_AND_FRIENDS \ 518 COMMON_INTERCEPT_FUNCTION(localtime); \ 519 COMMON_INTERCEPT_FUNCTION(localtime_r); \ 520 COMMON_INTERCEPT_FUNCTION(gmtime); \ 521 COMMON_INTERCEPT_FUNCTION(gmtime_r); \ 522 COMMON_INTERCEPT_FUNCTION(ctime); \ 523 COMMON_INTERCEPT_FUNCTION(ctime_r); \ 524 COMMON_INTERCEPT_FUNCTION(asctime); \ 525 COMMON_INTERCEPT_FUNCTION(asctime_r); 526#else 527#define INIT_LOCALTIME_AND_FRIENDS 528#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 529 530#if SANITIZER_INTERCEPT_STRPTIME 531INTERCEPTOR(char *, strptime, char *s, char *format, __sanitizer_tm *tm) { 532 void *ctx; 533 COMMON_INTERCEPTOR_ENTER(ctx, strptime, s, format, tm); 534 if (format) 535 COMMON_INTERCEPTOR_READ_RANGE(ctx, format, REAL(strlen)(format) + 1); 536 char *res = REAL(strptime)(s, format, tm); 537 if (res) { 538 COMMON_INTERCEPTOR_READ_RANGE(ctx, s, res - s); 539 // Do not call unpoison_tm here, because strptime does not, in fact, 540 // initialize the entire struct tm. For example, tm_zone pointer is left 541 // uninitialized. 542 if (tm) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 543 } 544 return res; 545} 546#define INIT_STRPTIME COMMON_INTERCEPT_FUNCTION(strptime); 547#else 548#define INIT_STRPTIME 549#endif 550 551#if SANITIZER_INTERCEPT_SCANF 552 553#include "sanitizer_common_interceptors_scanf.inc" 554 555#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 556 { \ 557 void *ctx; \ 558 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 559 va_list aq; \ 560 va_copy(aq, ap); \ 561 int res = REAL(vname)(__VA_ARGS__); \ 562 if (res > 0) \ 563 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 564 va_end(aq); \ 565 return res; \ 566 } 567 568INTERCEPTOR(int, vscanf, const char *format, va_list ap) 569VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 570 571INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 572VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 573 574INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 575VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 576 577#if SANITIZER_INTERCEPT_ISOC99_SCANF 578INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 579VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 580 581INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 582 va_list ap) 583VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 584 585INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 586VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 587#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 588 589#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 590 { \ 591 void *ctx; \ 592 va_list ap; \ 593 va_start(ap, format); \ 594 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 595 int res = vname(__VA_ARGS__, ap); \ 596 va_end(ap); \ 597 return res; \ 598 } 599 600INTERCEPTOR(int, scanf, const char *format, ...) 601SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 602 603INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 604SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 605 606INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 607SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 608 609#if SANITIZER_INTERCEPT_ISOC99_SCANF 610INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 611SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 612 613INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 614SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 615 616INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 617SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 618#endif 619 620#endif 621 622#if SANITIZER_INTERCEPT_SCANF 623#define INIT_SCANF \ 624 COMMON_INTERCEPT_FUNCTION(scanf); \ 625 COMMON_INTERCEPT_FUNCTION(sscanf); \ 626 COMMON_INTERCEPT_FUNCTION(fscanf); \ 627 COMMON_INTERCEPT_FUNCTION(vscanf); \ 628 COMMON_INTERCEPT_FUNCTION(vsscanf); \ 629 COMMON_INTERCEPT_FUNCTION(vfscanf); 630#else 631#define INIT_SCANF 632#endif 633 634#if SANITIZER_INTERCEPT_ISOC99_SCANF 635#define INIT_ISOC99_SCANF \ 636 COMMON_INTERCEPT_FUNCTION(__isoc99_scanf); \ 637 COMMON_INTERCEPT_FUNCTION(__isoc99_sscanf); \ 638 COMMON_INTERCEPT_FUNCTION(__isoc99_fscanf); \ 639 COMMON_INTERCEPT_FUNCTION(__isoc99_vscanf); \ 640 COMMON_INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 641 COMMON_INTERCEPT_FUNCTION(__isoc99_vfscanf); 642#else 643#define INIT_ISOC99_SCANF 644#endif 645 646#if SANITIZER_INTERCEPT_IOCTL 647#include "sanitizer_common_interceptors_ioctl.inc" 648INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 649 void *ctx; 650 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 651 652 CHECK(ioctl_initialized); 653 654 // Note: TSan does not use common flags, and they are zero-initialized. 655 // This effectively disables ioctl handling in TSan. 656 if (!common_flags()->handle_ioctl) return REAL(ioctl)(d, request, arg); 657 658 const ioctl_desc *desc = ioctl_lookup(request); 659 if (!desc) Printf("WARNING: unknown ioctl %x\n", request); 660 661 if (desc) ioctl_common_pre(ctx, desc, d, request, arg); 662 int res = REAL(ioctl)(d, request, arg); 663 // FIXME: some ioctls have different return values for success and failure. 664 if (desc && res != -1) ioctl_common_post(ctx, desc, res, d, request, arg); 665 return res; 666} 667#define INIT_IOCTL \ 668 ioctl_init(); \ 669 COMMON_INTERCEPT_FUNCTION(ioctl); 670#else 671#define INIT_IOCTL 672#endif 673 674#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 675INTERCEPTOR(void *, getpwnam, const char *name) { 676 void *ctx; 677 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 678 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 679 void *res = REAL(getpwnam)(name); 680 if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 681 return res; 682} 683INTERCEPTOR(void *, getpwuid, u32 uid) { 684 void *ctx; 685 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 686 void *res = REAL(getpwuid)(uid); 687 if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 688 return res; 689} 690INTERCEPTOR(void *, getgrnam, const char *name) { 691 void *ctx; 692 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 693 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 694 void *res = REAL(getgrnam)(name); 695 if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 696 return res; 697} 698INTERCEPTOR(void *, getgrgid, u32 gid) { 699 void *ctx; 700 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 701 void *res = REAL(getgrgid)(gid); 702 if (res != 0) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 703 return res; 704} 705#define INIT_GETPWNAM_AND_FRIENDS \ 706 COMMON_INTERCEPT_FUNCTION(getpwnam); \ 707 COMMON_INTERCEPT_FUNCTION(getpwuid); \ 708 COMMON_INTERCEPT_FUNCTION(getgrnam); \ 709 COMMON_INTERCEPT_FUNCTION(getgrgid); 710#else 711#define INIT_GETPWNAM_AND_FRIENDS 712#endif 713 714#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 715INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, char *buf, 716 SIZE_T buflen, void **result) { 717 void *ctx; 718 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 719 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 720 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 721 if (!res) { 722 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 723 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 724 } 725 return res; 726} 727INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, char *buf, SIZE_T buflen, 728 void **result) { 729 void *ctx; 730 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 731 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 732 if (!res) { 733 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 734 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 735 } 736 return res; 737} 738INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, char *buf, 739 SIZE_T buflen, void **result) { 740 void *ctx; 741 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 742 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 743 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 744 if (!res) { 745 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 747 } 748 return res; 749} 750INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, char *buf, SIZE_T buflen, 751 void **result) { 752 void *ctx; 753 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 754 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 755 if (!res) { 756 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 757 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 758 } 759 return res; 760} 761#define INIT_GETPWNAM_R_AND_FRIENDS \ 762 COMMON_INTERCEPT_FUNCTION(getpwnam_r); \ 763 COMMON_INTERCEPT_FUNCTION(getpwuid_r); \ 764 COMMON_INTERCEPT_FUNCTION(getgrnam_r); \ 765 COMMON_INTERCEPT_FUNCTION(getgrgid_r); 766#else 767#define INIT_GETPWNAM_R_AND_FRIENDS 768#endif 769 770#if SANITIZER_INTERCEPT_CLOCK_GETTIME 771INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 772 void *ctx; 773 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 774 int res = REAL(clock_getres)(clk_id, tp); 775 if (!res && tp) { 776 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 777 } 778 return res; 779} 780INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 781 void *ctx; 782 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 783 int res = REAL(clock_gettime)(clk_id, tp); 784 if (!res) { 785 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 786 } 787 return res; 788} 789INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 790 void *ctx; 791 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 792 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 793 return REAL(clock_settime)(clk_id, tp); 794} 795#define INIT_CLOCK_GETTIME \ 796 COMMON_INTERCEPT_FUNCTION(clock_getres); \ 797 COMMON_INTERCEPT_FUNCTION(clock_gettime); \ 798 COMMON_INTERCEPT_FUNCTION(clock_settime); 799#else 800#define INIT_CLOCK_GETTIME 801#endif 802 803#if SANITIZER_INTERCEPT_GETITIMER 804INTERCEPTOR(int, getitimer, int which, void *curr_value) { 805 void *ctx; 806 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 807 int res = REAL(getitimer)(which, curr_value); 808 if (!res && curr_value) { 809 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 810 } 811 return res; 812} 813INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 814 void *ctx; 815 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 816 if (new_value) 817 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 818 int res = REAL(setitimer)(which, new_value, old_value); 819 if (!res && old_value) { 820 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 821 } 822 return res; 823} 824#define INIT_GETITIMER \ 825 COMMON_INTERCEPT_FUNCTION(getitimer); \ 826 COMMON_INTERCEPT_FUNCTION(setitimer); 827#else 828#define INIT_GETITIMER 829#endif 830 831#if SANITIZER_INTERCEPT_GLOB 832static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 833 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 834 // +1 for NULL pointer at the end. 835 if (pglob->gl_pathv) 836 COMMON_INTERCEPTOR_WRITE_RANGE( 837 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 838 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 839 char *p = pglob->gl_pathv[i]; 840 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 841 } 842} 843 844static THREADLOCAL __sanitizer_glob_t *pglob_copy; 845static THREADLOCAL void *glob_ctx; 846 847static void wrapped_gl_closedir(void *dir) { 848 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 849 pglob_copy->gl_closedir(dir); 850} 851 852static void *wrapped_gl_readdir(void *dir) { 853 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 854 return pglob_copy->gl_readdir(dir); 855} 856 857static void *wrapped_gl_opendir(const char *s) { 858 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 859 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 860 return pglob_copy->gl_opendir(s); 861} 862 863static int wrapped_gl_lstat(const char *s, void *st) { 864 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 865 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 866 return pglob_copy->gl_lstat(s, st); 867} 868 869static int wrapped_gl_stat(const char *s, void *st) { 870 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 871 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 872 return pglob_copy->gl_stat(s, st); 873} 874 875INTERCEPTOR(int, glob, const char *pattern, int flags, 876 int (*errfunc)(const char *epath, int eerrno), 877 __sanitizer_glob_t *pglob) { 878 void *ctx; 879 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 880 __sanitizer_glob_t glob_copy = { 881 0, 0, 0, 882 0, wrapped_gl_closedir, wrapped_gl_readdir, 883 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 884 if (flags & glob_altdirfunc) { 885 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 886 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 887 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 888 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 889 Swap(pglob->gl_stat, glob_copy.gl_stat); 890 pglob_copy = &glob_copy; 891 glob_ctx = ctx; 892 } 893 int res = REAL(glob)(pattern, flags, errfunc, pglob); 894 if (flags & glob_altdirfunc) { 895 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 896 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 897 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 898 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 899 Swap(pglob->gl_stat, glob_copy.gl_stat); 900 } 901 pglob_copy = 0; 902 glob_ctx = 0; 903 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 904 return res; 905} 906 907INTERCEPTOR(int, glob64, const char *pattern, int flags, 908 int (*errfunc)(const char *epath, int eerrno), 909 __sanitizer_glob_t *pglob) { 910 void *ctx; 911 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 912 __sanitizer_glob_t glob_copy = { 913 0, 0, 0, 914 0, wrapped_gl_closedir, wrapped_gl_readdir, 915 wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; 916 if (flags & glob_altdirfunc) { 917 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 918 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 919 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 920 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 921 Swap(pglob->gl_stat, glob_copy.gl_stat); 922 pglob_copy = &glob_copy; 923 glob_ctx = ctx; 924 } 925 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 926 if (flags & glob_altdirfunc) { 927 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 928 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 929 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 930 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 931 Swap(pglob->gl_stat, glob_copy.gl_stat); 932 } 933 pglob_copy = 0; 934 glob_ctx = 0; 935 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 936 return res; 937} 938#define INIT_GLOB \ 939 COMMON_INTERCEPT_FUNCTION(glob); \ 940 COMMON_INTERCEPT_FUNCTION(glob64); 941#else // SANITIZER_INTERCEPT_GLOB 942#define INIT_GLOB 943#endif // SANITIZER_INTERCEPT_GLOB 944 945#if SANITIZER_INTERCEPT_WAIT 946// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 947// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 948// details. 949INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 950 void *ctx; 951 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 952 int res = REAL(wait)(status); 953 if (res != -1 && status) 954 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 955 return res; 956} 957INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 958 int options) { 959 void *ctx; 960 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 961 int res = REAL(waitid)(idtype, id, infop, options); 962 if (res != -1 && infop) 963 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 964 return res; 965} 966INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 967 void *ctx; 968 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 969 int res = REAL(waitpid)(pid, status, options); 970 if (res != -1 && status) 971 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 972 return res; 973} 974INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 975 void *ctx; 976 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 977 int res = REAL(wait3)(status, options, rusage); 978 if (res != -1) { 979 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 980 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 981 } 982 return res; 983} 984INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 985 void *ctx; 986 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 987 int res = REAL(wait4)(pid, status, options, rusage); 988 if (res != -1) { 989 if (status) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 990 if (rusage) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 991 } 992 return res; 993} 994#define INIT_WAIT \ 995 COMMON_INTERCEPT_FUNCTION(wait); \ 996 COMMON_INTERCEPT_FUNCTION(waitid); \ 997 COMMON_INTERCEPT_FUNCTION(waitpid); \ 998 COMMON_INTERCEPT_FUNCTION(wait3); \ 999 COMMON_INTERCEPT_FUNCTION(wait4); 1000#else 1001#define INIT_WAIT 1002#endif 1003 1004#if SANITIZER_INTERCEPT_INET 1005INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 1006 void *ctx; 1007 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 1008 uptr sz = __sanitizer_in_addr_sz(af); 1009 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 1010 // FIXME: figure out read size based on the address family. 1011 char *res = REAL(inet_ntop)(af, src, dst, size); 1012 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1013 return res; 1014} 1015INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 1016 void *ctx; 1017 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 1018 // FIXME: figure out read size based on the address family. 1019 int res = REAL(inet_pton)(af, src, dst); 1020 if (res == 1) { 1021 uptr sz = __sanitizer_in_addr_sz(af); 1022 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1023 } 1024 return res; 1025} 1026#define INIT_INET \ 1027 COMMON_INTERCEPT_FUNCTION(inet_ntop); \ 1028 COMMON_INTERCEPT_FUNCTION(inet_pton); 1029#else 1030#define INIT_INET 1031#endif 1032 1033#if SANITIZER_INTERCEPT_INET 1034INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 1035 void *ctx; 1036 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1037 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1038 int res = REAL(inet_aton)(cp, dst); 1039 if (res != 0) { 1040 uptr sz = __sanitizer_in_addr_sz(af_inet); 1041 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1042 } 1043 return res; 1044} 1045#define INIT_INET_ATON COMMON_INTERCEPT_FUNCTION(inet_aton); 1046#else 1047#define INIT_INET_ATON 1048#endif 1049 1050#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1051INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1052 void *ctx; 1053 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1054 int res = REAL(pthread_getschedparam)(thread, policy, param); 1055 if (res == 0) { 1056 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1057 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1058 } 1059 return res; 1060} 1061#define INIT_PTHREAD_GETSCHEDPARAM \ 1062 COMMON_INTERCEPT_FUNCTION(pthread_getschedparam); 1063#else 1064#define INIT_PTHREAD_GETSCHEDPARAM 1065#endif 1066 1067#if SANITIZER_INTERCEPT_GETADDRINFO 1068INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1069 struct __sanitizer_addrinfo *hints, 1070 struct __sanitizer_addrinfo **out) { 1071 void *ctx; 1072 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1073 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1074 if (service) 1075 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1076 if (hints) 1077 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1078 int res = REAL(getaddrinfo)(node, service, hints, out); 1079 if (res == 0 && out) { 1080 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1081 struct __sanitizer_addrinfo *p = *out; 1082 while (p) { 1083 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1084 if (p->ai_addr) 1085 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1086 if (p->ai_canonname) 1087 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1088 REAL(strlen)(p->ai_canonname) + 1); 1089 p = p->ai_next; 1090 } 1091 } 1092 return res; 1093} 1094#define INIT_GETADDRINFO COMMON_INTERCEPT_FUNCTION(getaddrinfo); 1095#else 1096#define INIT_GETADDRINFO 1097#endif 1098 1099#if SANITIZER_INTERCEPT_GETNAMEINFO 1100INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1101 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1102 void *ctx; 1103 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1104 serv, servlen, flags); 1105 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1106 // There is padding in in_addr that may make this too noisy 1107 int res = 1108 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1109 if (res == 0) { 1110 if (host && hostlen) 1111 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1112 if (serv && servlen) 1113 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1114 } 1115 return res; 1116} 1117#define INIT_GETNAMEINFO COMMON_INTERCEPT_FUNCTION(getnameinfo); 1118#else 1119#define INIT_GETNAMEINFO 1120#endif 1121 1122#if SANITIZER_INTERCEPT_GETSOCKNAME 1123INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1124 void *ctx; 1125 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1126 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1127 int addrlen_in = *addrlen; 1128 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1129 if (res == 0) { 1130 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1131 } 1132 return res; 1133} 1134#define INIT_GETSOCKNAME COMMON_INTERCEPT_FUNCTION(getsockname); 1135#else 1136#define INIT_GETSOCKNAME 1137#endif 1138 1139#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1140static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1141 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1142 if (h->h_name) 1143 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1144 char **p = h->h_aliases; 1145 while (*p) { 1146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1147 ++p; 1148 } 1149 COMMON_INTERCEPTOR_WRITE_RANGE( 1150 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1151 p = h->h_addr_list; 1152 while (*p) { 1153 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1154 ++p; 1155 } 1156 COMMON_INTERCEPTOR_WRITE_RANGE( 1157 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1158} 1159#endif 1160 1161#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1162INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1163 void *ctx; 1164 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1165 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1166 if (res) write_hostent(ctx, res); 1167 return res; 1168} 1169 1170INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1171 int type) { 1172 void *ctx; 1173 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1174 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1175 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1176 if (res) write_hostent(ctx, res); 1177 return res; 1178} 1179 1180INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 1181 void *ctx; 1182 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 1183 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 1184 if (res) write_hostent(ctx, res); 1185 return res; 1186} 1187 1188INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1189 void *ctx; 1190 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1191 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1192 if (res) write_hostent(ctx, res); 1193 return res; 1194} 1195#define INIT_GETHOSTBYNAME \ 1196 COMMON_INTERCEPT_FUNCTION(gethostent); \ 1197 COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ 1198 COMMON_INTERCEPT_FUNCTION(gethostbyname); \ 1199 COMMON_INTERCEPT_FUNCTION(gethostbyname2); 1200#else 1201#define INIT_GETHOSTBYNAME 1202#endif 1203 1204#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1205INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1206 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1207 void *ctx; 1208 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1209 h_errnop); 1210 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1211 if (res == 0) { 1212 if (result) { 1213 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1214 if (*result) write_hostent(ctx, *result); 1215 } 1216 if (h_errnop) 1217 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1218 } 1219 return res; 1220} 1221 1222INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1223 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1224 __sanitizer_hostent **result, int *h_errnop) { 1225 void *ctx; 1226 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1227 buflen, result, h_errnop); 1228 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1229 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1230 h_errnop); 1231 if (res == 0) { 1232 if (result) { 1233 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1234 if (*result) write_hostent(ctx, *result); 1235 } 1236 if (h_errnop) 1237 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1238 } 1239 return res; 1240} 1241 1242INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1243 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1244 int *h_errnop) { 1245 void *ctx; 1246 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1247 h_errnop); 1248 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1249 if (res == 0) { 1250 if (result) { 1251 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1252 if (*result) write_hostent(ctx, *result); 1253 } 1254 if (h_errnop) 1255 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1256 } 1257 return res; 1258} 1259 1260INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1261 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1262 __sanitizer_hostent **result, int *h_errnop) { 1263 void *ctx; 1264 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1265 result, h_errnop); 1266 int res = 1267 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1268 if (res == 0) { 1269 if (result) { 1270 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1271 if (*result) write_hostent(ctx, *result); 1272 } 1273 if (h_errnop) 1274 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1275 } 1276 return res; 1277} 1278#define INIT_GETHOSTBYNAME_R \ 1279 COMMON_INTERCEPT_FUNCTION(gethostent_r); \ 1280 COMMON_INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1281 COMMON_INTERCEPT_FUNCTION(gethostbyname_r); \ 1282 COMMON_INTERCEPT_FUNCTION(gethostbyname2_r); 1283#else 1284#define INIT_GETHOSTBYNAME_R 1285#endif 1286 1287#if SANITIZER_INTERCEPT_GETSOCKOPT 1288INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1289 int *optlen) { 1290 void *ctx; 1291 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1292 optlen); 1293 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1294 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1295 if (res == 0) 1296 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1297 return res; 1298} 1299#define INIT_GETSOCKOPT COMMON_INTERCEPT_FUNCTION(getsockopt); 1300#else 1301#define INIT_GETSOCKOPT 1302#endif 1303 1304#if SANITIZER_INTERCEPT_ACCEPT 1305INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1306 void *ctx; 1307 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1308 unsigned addrlen0; 1309 if (addrlen) { 1310 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1311 addrlen0 = *addrlen; 1312 } 1313 int fd2 = REAL(accept)(fd, addr, addrlen); 1314 if (fd2 >= 0) { 1315 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1316 if (addr && addrlen) 1317 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1318 } 1319 return fd2; 1320} 1321#define INIT_ACCEPT COMMON_INTERCEPT_FUNCTION(accept); 1322#else 1323#define INIT_ACCEPT 1324#endif 1325 1326#if SANITIZER_INTERCEPT_ACCEPT4 1327INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1328 void *ctx; 1329 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1330 unsigned addrlen0; 1331 if (addrlen) { 1332 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1333 addrlen0 = *addrlen; 1334 } 1335 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1336 if (fd2 >= 0) { 1337 if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1338 if (addr && addrlen) 1339 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1340 } 1341 return fd2; 1342} 1343#define INIT_ACCEPT4 COMMON_INTERCEPT_FUNCTION(accept4); 1344#else 1345#define INIT_ACCEPT4 1346#endif 1347 1348#if SANITIZER_INTERCEPT_MODF 1349INTERCEPTOR(double, modf, double x, double *iptr) { 1350 void *ctx; 1351 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1352 double res = REAL(modf)(x, iptr); 1353 if (iptr) { 1354 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1355 } 1356 return res; 1357} 1358INTERCEPTOR(float, modff, float x, float *iptr) { 1359 void *ctx; 1360 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1361 float res = REAL(modff)(x, iptr); 1362 if (iptr) { 1363 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1364 } 1365 return res; 1366} 1367INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1368 void *ctx; 1369 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1370 long double res = REAL(modfl)(x, iptr); 1371 if (iptr) { 1372 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1373 } 1374 return res; 1375} 1376#define INIT_MODF \ 1377 COMMON_INTERCEPT_FUNCTION(modf); \ 1378 COMMON_INTERCEPT_FUNCTION(modff); \ 1379 COMMON_INTERCEPT_FUNCTION(modfl); 1380#else 1381#define INIT_MODF 1382#endif 1383 1384#if SANITIZER_INTERCEPT_RECVMSG 1385static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1386 SSIZE_T maxlen) { 1387 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1388 if (msg->msg_name && msg->msg_namelen) 1389 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 1390 if (msg->msg_iov && msg->msg_iovlen) 1391 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1392 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1393 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1394 if (msg->msg_control && msg->msg_controllen) 1395 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1396} 1397 1398INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1399 int flags) { 1400 void *ctx; 1401 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1402 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1403 if (res >= 0) { 1404 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1405 if (msg) write_msghdr(ctx, msg, res); 1406 } 1407 return res; 1408} 1409#define INIT_RECVMSG COMMON_INTERCEPT_FUNCTION(recvmsg); 1410#else 1411#define INIT_RECVMSG 1412#endif 1413 1414#if SANITIZER_INTERCEPT_GETPEERNAME 1415INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1416 void *ctx; 1417 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1418 unsigned addr_sz; 1419 if (addrlen) addr_sz = *addrlen; 1420 int res = REAL(getpeername)(sockfd, addr, addrlen); 1421 if (!res && addr && addrlen) 1422 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1423 return res; 1424} 1425#define INIT_GETPEERNAME COMMON_INTERCEPT_FUNCTION(getpeername); 1426#else 1427#define INIT_GETPEERNAME 1428#endif 1429 1430#if SANITIZER_INTERCEPT_SYSINFO 1431INTERCEPTOR(int, sysinfo, void *info) { 1432 void *ctx; 1433 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1434 int res = REAL(sysinfo)(info); 1435 if (!res && info) 1436 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1437 return res; 1438} 1439#define INIT_SYSINFO COMMON_INTERCEPT_FUNCTION(sysinfo); 1440#else 1441#define INIT_SYSINFO 1442#endif 1443 1444#if SANITIZER_INTERCEPT_READDIR 1445INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1446 void *ctx; 1447 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1448 __sanitizer_dirent *res = REAL(readdir)(dirp); 1449 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1450 return res; 1451} 1452 1453INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1454 __sanitizer_dirent **result) { 1455 void *ctx; 1456 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1457 int res = REAL(readdir_r)(dirp, entry, result); 1458 if (!res) { 1459 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1460 if (*result) 1461 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1462 } 1463 return res; 1464} 1465 1466#define INIT_READDIR \ 1467 COMMON_INTERCEPT_FUNCTION(readdir); \ 1468 COMMON_INTERCEPT_FUNCTION(readdir_r); 1469#else 1470#define INIT_READDIR 1471#endif 1472 1473#if SANITIZER_INTERCEPT_READDIR64 1474INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1475 void *ctx; 1476 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1477 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1478 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1479 return res; 1480} 1481 1482INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1483 __sanitizer_dirent64 **result) { 1484 void *ctx; 1485 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1486 int res = REAL(readdir64_r)(dirp, entry, result); 1487 if (!res) { 1488 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1489 if (*result) 1490 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1491 } 1492 return res; 1493} 1494#define INIT_READDIR64 \ 1495 COMMON_INTERCEPT_FUNCTION(readdir64); \ 1496 COMMON_INTERCEPT_FUNCTION(readdir64_r); 1497#else 1498#define INIT_READDIR64 1499#endif 1500 1501#if SANITIZER_INTERCEPT_PTRACE 1502INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1503 void *ctx; 1504 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1505 1506 if (data) { 1507 if (request == ptrace_setregs) 1508 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1509 else if (request == ptrace_setfpregs) 1510 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1511 else if (request == ptrace_setfpxregs) 1512 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1513 else if (request == ptrace_setsiginfo) 1514 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1515 else if (request == ptrace_setregset) { 1516 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1517 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1518 } 1519 } 1520 1521 uptr res = REAL(ptrace)(request, pid, addr, data); 1522 1523 if (!res && data) { 1524 // Note that PEEK* requests assing different meaning to the return value. 1525 // This function does not handle them (nor does it need to). 1526 if (request == ptrace_getregs) 1527 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1528 else if (request == ptrace_getfpregs) 1529 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1530 else if (request == ptrace_getfpxregs) 1531 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1532 else if (request == ptrace_getsiginfo) 1533 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1534 else if (request == ptrace_getregset) { 1535 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1537 } 1538 } 1539 return res; 1540} 1541 1542#define INIT_PTRACE COMMON_INTERCEPT_FUNCTION(ptrace); 1543#else 1544#define INIT_PTRACE 1545#endif 1546 1547#if SANITIZER_INTERCEPT_SETLOCALE 1548INTERCEPTOR(char *, setlocale, int category, char *locale) { 1549 void *ctx; 1550 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1551 if (locale) 1552 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1553 char *res = REAL(setlocale)(category, locale); 1554 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1555 return res; 1556} 1557 1558#define INIT_SETLOCALE COMMON_INTERCEPT_FUNCTION(setlocale); 1559#else 1560#define INIT_SETLOCALE 1561#endif 1562 1563#if SANITIZER_INTERCEPT_GETCWD 1564INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1565 void *ctx; 1566 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1567 char *res = REAL(getcwd)(buf, size); 1568 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1569 return res; 1570} 1571#define INIT_GETCWD COMMON_INTERCEPT_FUNCTION(getcwd); 1572#else 1573#define INIT_GETCWD 1574#endif 1575 1576#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1577INTERCEPTOR(char *, get_current_dir_name, int fake) { 1578 void *ctx; 1579 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 1580 char *res = REAL(get_current_dir_name)(fake); 1581 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1582 return res; 1583} 1584 1585#define INIT_GET_CURRENT_DIR_NAME \ 1586 COMMON_INTERCEPT_FUNCTION(get_current_dir_name); 1587#else 1588#define INIT_GET_CURRENT_DIR_NAME 1589#endif 1590 1591#if SANITIZER_INTERCEPT_STRTOIMAX 1592INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1593 void *ctx; 1594 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1595 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1596 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1597 return res; 1598} 1599 1600INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1601 void *ctx; 1602 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1603 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1604 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1605 return res; 1606} 1607 1608#define INIT_STRTOIMAX \ 1609 COMMON_INTERCEPT_FUNCTION(strtoimax); \ 1610 COMMON_INTERCEPT_FUNCTION(strtoumax); 1611#else 1612#define INIT_STRTOIMAX 1613#endif 1614 1615#if SANITIZER_INTERCEPT_MBSTOWCS 1616INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1617 void *ctx; 1618 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1619 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1620 if (res != (SIZE_T) - 1 && dest) { 1621 SIZE_T write_cnt = res + (res < len); 1622 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1623 } 1624 return res; 1625} 1626 1627INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1628 void *ps) { 1629 void *ctx; 1630 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1631 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1632 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1633 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1634 if (res != (SIZE_T)(-1) && dest && src) { 1635 // This function, and several others, may or may not write the terminating 1636 // \0 character. They write it iff they clear *src. 1637 SIZE_T write_cnt = res + !*src; 1638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1639 } 1640 return res; 1641} 1642 1643#define INIT_MBSTOWCS \ 1644 COMMON_INTERCEPT_FUNCTION(mbstowcs); \ 1645 COMMON_INTERCEPT_FUNCTION(mbsrtowcs); 1646#else 1647#define INIT_MBSTOWCS 1648#endif 1649 1650#if SANITIZER_INTERCEPT_MBSNRTOWCS 1651INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1652 SIZE_T len, void *ps) { 1653 void *ctx; 1654 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1655 if (src) { 1656 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1657 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1658 } 1659 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1660 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1661 if (res != (SIZE_T)(-1) && dest && src) { 1662 SIZE_T write_cnt = res + !*src; 1663 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1664 } 1665 return res; 1666} 1667 1668#define INIT_MBSNRTOWCS COMMON_INTERCEPT_FUNCTION(mbsnrtowcs); 1669#else 1670#define INIT_MBSNRTOWCS 1671#endif 1672 1673#if SANITIZER_INTERCEPT_WCSTOMBS 1674INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1675 void *ctx; 1676 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1677 SIZE_T res = REAL(wcstombs)(dest, src, len); 1678 if (res != (SIZE_T) - 1 && dest) { 1679 SIZE_T write_cnt = res + (res < len); 1680 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1681 } 1682 return res; 1683} 1684 1685INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1686 void *ps) { 1687 void *ctx; 1688 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1689 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1690 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1691 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1692 if (res != (SIZE_T) - 1 && dest && src) { 1693 SIZE_T write_cnt = res + !*src; 1694 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1695 } 1696 return res; 1697} 1698 1699#define INIT_WCSTOMBS \ 1700 COMMON_INTERCEPT_FUNCTION(wcstombs); \ 1701 COMMON_INTERCEPT_FUNCTION(wcsrtombs); 1702#else 1703#define INIT_WCSTOMBS 1704#endif 1705 1706#if SANITIZER_INTERCEPT_WCSNRTOMBS 1707INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1708 SIZE_T len, void *ps) { 1709 void *ctx; 1710 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1711 if (src) { 1712 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1713 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1714 } 1715 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1716 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1717 if (res != (SIZE_T) - 1 && dest && src) { 1718 SIZE_T write_cnt = res + !*src; 1719 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1720 } 1721 return res; 1722} 1723 1724#define INIT_WCSNRTOMBS COMMON_INTERCEPT_FUNCTION(wcsnrtombs); 1725#else 1726#define INIT_WCSNRTOMBS 1727#endif 1728 1729#if SANITIZER_INTERCEPT_TCGETATTR 1730INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1731 void *ctx; 1732 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1733 int res = REAL(tcgetattr)(fd, termios_p); 1734 if (!res && termios_p) 1735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1736 return res; 1737} 1738 1739#define INIT_TCGETATTR COMMON_INTERCEPT_FUNCTION(tcgetattr); 1740#else 1741#define INIT_TCGETATTR 1742#endif 1743 1744#if SANITIZER_INTERCEPT_REALPATH 1745INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1746 void *ctx; 1747 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1748 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1749 1750 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1751 // version of a versioned symbol. For realpath(), this gives us something 1752 // (called __old_realpath) that does not handle NULL in the second argument. 1753 // Handle it as part of the interceptor. 1754 char *allocated_path = 0; 1755 if (!resolved_path) 1756 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1757 1758 char *res = REAL(realpath)(path, resolved_path); 1759 if (allocated_path && !res) WRAP(free)(allocated_path); 1760 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1761 return res; 1762} 1763#define INIT_REALPATH COMMON_INTERCEPT_FUNCTION(realpath); 1764#else 1765#define INIT_REALPATH 1766#endif 1767 1768#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1769INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1770 void *ctx; 1771 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1772 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1773 char *res = REAL(canonicalize_file_name)(path); 1774 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1775 return res; 1776} 1777#define INIT_CANONICALIZE_FILE_NAME \ 1778 COMMON_INTERCEPT_FUNCTION(canonicalize_file_name); 1779#else 1780#define INIT_CANONICALIZE_FILE_NAME 1781#endif 1782 1783#if SANITIZER_INTERCEPT_CONFSTR 1784INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1785 void *ctx; 1786 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1787 SIZE_T res = REAL(confstr)(name, buf, len); 1788 if (buf && res) 1789 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1790 return res; 1791} 1792#define INIT_CONFSTR COMMON_INTERCEPT_FUNCTION(confstr); 1793#else 1794#define INIT_CONFSTR 1795#endif 1796 1797#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1798INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1799 void *ctx; 1800 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1801 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1802 if (mask && !res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1803 return res; 1804} 1805#define INIT_SCHED_GETAFFINITY COMMON_INTERCEPT_FUNCTION(sched_getaffinity); 1806#else 1807#define INIT_SCHED_GETAFFINITY 1808#endif 1809 1810#if SANITIZER_INTERCEPT_STRERROR 1811INTERCEPTOR(char *, strerror, int errnum) { 1812 void *ctx; 1813 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1814 char *res = REAL(strerror)(errnum); 1815 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1816 return res; 1817} 1818#define INIT_STRERROR COMMON_INTERCEPT_FUNCTION(strerror); 1819#else 1820#define INIT_STRERROR 1821#endif 1822 1823#if SANITIZER_INTERCEPT_STRERROR_R 1824INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1825 void *ctx; 1826 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1827 char *res = REAL(strerror_r)(errnum, buf, buflen); 1828 // There are 2 versions of strerror_r: 1829 // * POSIX version returns 0 on success, negative error code on failure, 1830 // writes message to buf. 1831 // * GNU version returns message pointer, which points to either buf or some 1832 // static storage. 1833 SIZE_T posix_res = (SIZE_T)res; 1834 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 1835 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1836 // At least on OSX, buf contents are valid even when the call fails. 1837 SIZE_T sz = internal_strnlen(buf, buflen); 1838 if (sz < buflen) ++sz; 1839 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1840 } else { 1841 // GNU version. 1842 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1843 } 1844 return res; 1845} 1846#define INIT_STRERROR_R COMMON_INTERCEPT_FUNCTION(strerror_r); 1847#else 1848#define INIT_STRERROR_R 1849#endif 1850 1851#if SANITIZER_INTERCEPT_SCANDIR 1852typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1853typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1854 const struct __sanitizer_dirent **); 1855 1856static THREADLOCAL void *scandir_ctx; 1857static THREADLOCAL scandir_filter_f scandir_filter; 1858static THREADLOCAL scandir_compar_f scandir_compar; 1859 1860static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1861 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1862 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1863 return scandir_filter(dir); 1864} 1865 1866static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1867 const struct __sanitizer_dirent **b) { 1868 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1869 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1870 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1871 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1872 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1873 return scandir_compar(a, b); 1874} 1875 1876INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1877 scandir_filter_f filter, scandir_compar_f compar) { 1878 void *ctx; 1879 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1880 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1881 CHECK_EQ(0, scandir_ctx); 1882 scandir_ctx = ctx; 1883 scandir_filter = filter; 1884 scandir_compar = compar; 1885 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1886 compar ? wrapped_scandir_compar : 0); 1887 scandir_ctx = 0; 1888 scandir_filter = 0; 1889 scandir_compar = 0; 1890 if (namelist && res > 0) { 1891 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1892 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1893 for (int i = 0; i < res; ++i) 1894 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1895 (*namelist)[i]->d_reclen); 1896 } 1897 return res; 1898} 1899#define INIT_SCANDIR COMMON_INTERCEPT_FUNCTION(scandir); 1900#else 1901#define INIT_SCANDIR 1902#endif 1903 1904#if SANITIZER_INTERCEPT_SCANDIR64 1905typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1906typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1907 const struct __sanitizer_dirent64 **); 1908 1909static THREADLOCAL void *scandir64_ctx; 1910static THREADLOCAL scandir64_filter_f scandir64_filter; 1911static THREADLOCAL scandir64_compar_f scandir64_compar; 1912 1913static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1914 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1915 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1916 return scandir64_filter(dir); 1917} 1918 1919static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1920 const struct __sanitizer_dirent64 **b) { 1921 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1922 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1923 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1924 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1925 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1926 return scandir64_compar(a, b); 1927} 1928 1929INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1930 scandir64_filter_f filter, scandir64_compar_f compar) { 1931 void *ctx; 1932 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1933 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1934 CHECK_EQ(0, scandir64_ctx); 1935 scandir64_ctx = ctx; 1936 scandir64_filter = filter; 1937 scandir64_compar = compar; 1938 int res = 1939 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1940 compar ? wrapped_scandir64_compar : 0); 1941 scandir64_ctx = 0; 1942 scandir64_filter = 0; 1943 scandir64_compar = 0; 1944 if (namelist && res > 0) { 1945 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1946 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1947 for (int i = 0; i < res; ++i) 1948 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1949 (*namelist)[i]->d_reclen); 1950 } 1951 return res; 1952} 1953#define INIT_SCANDIR64 COMMON_INTERCEPT_FUNCTION(scandir64); 1954#else 1955#define INIT_SCANDIR64 1956#endif 1957 1958#if SANITIZER_INTERCEPT_GETGROUPS 1959INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1960 void *ctx; 1961 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1962 int res = REAL(getgroups)(size, lst); 1963 if (res && lst) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1964 return res; 1965} 1966#define INIT_GETGROUPS COMMON_INTERCEPT_FUNCTION(getgroups); 1967#else 1968#define INIT_GETGROUPS 1969#endif 1970 1971#if SANITIZER_INTERCEPT_POLL 1972static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1973 __sanitizer_nfds_t nfds) { 1974 for (unsigned i = 0; i < nfds; ++i) { 1975 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1976 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1977 } 1978} 1979 1980static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 1981 __sanitizer_nfds_t nfds) { 1982 for (unsigned i = 0; i < nfds; ++i) 1983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 1984 sizeof(fds[i].revents)); 1985} 1986 1987INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 1988 int timeout) { 1989 void *ctx; 1990 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 1991 if (fds && nfds) read_pollfd(ctx, fds, nfds); 1992 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 1993 if (fds && nfds) write_pollfd(ctx, fds, nfds); 1994 return res; 1995} 1996#define INIT_POLL COMMON_INTERCEPT_FUNCTION(poll); 1997#else 1998#define INIT_POLL 1999#endif 2000 2001#if SANITIZER_INTERCEPT_PPOLL 2002INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2003 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 2004 void *ctx; 2005 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 2006 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2007 if (timeout_ts) 2008 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2009 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2010 int res = 2011 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2012 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2013 return res; 2014} 2015#define INIT_PPOLL COMMON_INTERCEPT_FUNCTION(ppoll); 2016#else 2017#define INIT_PPOLL 2018#endif 2019 2020#if SANITIZER_INTERCEPT_WORDEXP 2021INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2022 void *ctx; 2023 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2024 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2025 int res = REAL(wordexp)(s, p, flags); 2026 if (!res && p) { 2027 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2028 if (p->we_wordc) 2029 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2030 sizeof(*p->we_wordv) * p->we_wordc); 2031 for (uptr i = 0; i < p->we_wordc; ++i) { 2032 char *w = p->we_wordv[i]; 2033 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2034 } 2035 } 2036 return res; 2037} 2038#define INIT_WORDEXP COMMON_INTERCEPT_FUNCTION(wordexp); 2039#else 2040#define INIT_WORDEXP 2041#endif 2042 2043#if SANITIZER_INTERCEPT_SIGWAIT 2044INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2045 void *ctx; 2046 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2047 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2048 int res = REAL(sigwait)(set, sig); 2049 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2050 return res; 2051} 2052#define INIT_SIGWAIT COMMON_INTERCEPT_FUNCTION(sigwait); 2053#else 2054#define INIT_SIGWAIT 2055#endif 2056 2057#if SANITIZER_INTERCEPT_SIGWAITINFO 2058INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2059 void *ctx; 2060 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2061 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2062 int res = REAL(sigwaitinfo)(set, info); 2063 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2064 return res; 2065} 2066#define INIT_SIGWAITINFO COMMON_INTERCEPT_FUNCTION(sigwaitinfo); 2067#else 2068#define INIT_SIGWAITINFO 2069#endif 2070 2071#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2072INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2073 void *timeout) { 2074 void *ctx; 2075 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2076 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2077 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2078 int res = REAL(sigtimedwait)(set, info, timeout); 2079 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2080 return res; 2081} 2082#define INIT_SIGTIMEDWAIT COMMON_INTERCEPT_FUNCTION(sigtimedwait); 2083#else 2084#define INIT_SIGTIMEDWAIT 2085#endif 2086 2087#if SANITIZER_INTERCEPT_SIGSETOPS 2088INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2089 void *ctx; 2090 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2091 int res = REAL(sigemptyset)(set); 2092 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2093 return res; 2094} 2095 2096INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2097 void *ctx; 2098 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2099 int res = REAL(sigfillset)(set); 2100 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2101 return res; 2102} 2103#define INIT_SIGSETOPS \ 2104 COMMON_INTERCEPT_FUNCTION(sigemptyset); \ 2105 COMMON_INTERCEPT_FUNCTION(sigfillset); 2106#else 2107#define INIT_SIGSETOPS 2108#endif 2109 2110#if SANITIZER_INTERCEPT_SIGPENDING 2111INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2112 void *ctx; 2113 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2114 int res = REAL(sigpending)(set); 2115 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2116 return res; 2117} 2118#define INIT_SIGPENDING COMMON_INTERCEPT_FUNCTION(sigpending); 2119#else 2120#define INIT_SIGPENDING 2121#endif 2122 2123#if SANITIZER_INTERCEPT_SIGPROCMASK 2124INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2125 __sanitizer_sigset_t *oldset) { 2126 void *ctx; 2127 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2128 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2129 int res = REAL(sigprocmask)(how, set, oldset); 2130 if (!res && oldset) 2131 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2132 return res; 2133} 2134#define INIT_SIGPROCMASK COMMON_INTERCEPT_FUNCTION(sigprocmask); 2135#else 2136#define INIT_SIGPROCMASK 2137#endif 2138 2139#if SANITIZER_INTERCEPT_BACKTRACE 2140INTERCEPTOR(int, backtrace, void **buffer, int size) { 2141 void *ctx; 2142 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2143 int res = REAL(backtrace)(buffer, size); 2144 if (res && buffer) 2145 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2146 return res; 2147} 2148 2149INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2150 void *ctx; 2151 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2152 if (buffer && size) 2153 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2154 char **res = REAL(backtrace_symbols)(buffer, size); 2155 if (res && size) { 2156 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2157 for (int i = 0; i < size; ++i) 2158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2159 } 2160 return res; 2161} 2162#define INIT_BACKTRACE \ 2163 COMMON_INTERCEPT_FUNCTION(backtrace); \ 2164 COMMON_INTERCEPT_FUNCTION(backtrace_symbols); 2165#else 2166#define INIT_BACKTRACE 2167#endif 2168 2169#if SANITIZER_INTERCEPT__EXIT 2170INTERCEPTOR(void, _exit, int status) { 2171 void *ctx; 2172 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 2173 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 2174 if (status == 0) status = status1; 2175 REAL(_exit)(status); 2176} 2177#define INIT__EXIT COMMON_INTERCEPT_FUNCTION(_exit); 2178#else 2179#define INIT__EXIT 2180#endif 2181 2182#if SANITIZER_INTERCEPT_PHTREAD_MUTEX 2183INTERCEPTOR(int, pthread_mutex_lock, void *m) { 2184 void *ctx; 2185 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 2186 int res = REAL(pthread_mutex_lock)(m); 2187 if (res == errno_EOWNERDEAD) 2188 COMMON_INTERCEPTOR_MUTEX_REPAIR(ctx, m); 2189 if (res == 0 || res == errno_EOWNERDEAD) 2190 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2191 return res; 2192} 2193 2194INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 2195 void *ctx; 2196 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 2197 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2198 return REAL(pthread_mutex_unlock)(m); 2199} 2200 2201#define INIT_PTHREAD_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(pthread_mutex_lock) 2202#define INIT_PTHREAD_MUTEX_UNLOCK \ 2203 COMMON_INTERCEPT_FUNCTION(pthread_mutex_unlock) 2204#else 2205#define INIT_PTHREAD_MUTEX_LOCK 2206#define INIT_PTHREAD_MUTEX_UNLOCK 2207#endif 2208 2209#if SANITIZER_INTERCEPT_PTHREAD_COND 2210INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 2211 void *ctx; 2212 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); 2213 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2214 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2215 int res = REAL(pthread_cond_wait)(c, m); 2216 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2217 return res; 2218} 2219 2220INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 2221 void *ctx; 2222 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); 2223 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); 2224 return REAL(pthread_cond_init)(c, a); 2225} 2226 2227INTERCEPTOR(int, pthread_cond_signal, void *c) { 2228 void *ctx; 2229 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c); 2230 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2231 return REAL(pthread_cond_signal)(c); 2232} 2233 2234INTERCEPTOR(int, pthread_cond_broadcast, void *c) { 2235 void *ctx; 2236 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c); 2237 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2238 return REAL(pthread_cond_broadcast)(c); 2239} 2240 2241#define INIT_PTHREAD_COND_WAIT \ 2242 INTERCEPT_FUNCTION_VER(pthread_cond_wait, "GLIBC_2.3.2") 2243#define INIT_PTHREAD_COND_INIT \ 2244 INTERCEPT_FUNCTION_VER(pthread_cond_init, "GLIBC_2.3.2") 2245#define INIT_PTHREAD_COND_SIGNAL \ 2246 INTERCEPT_FUNCTION_VER(pthread_cond_signal, "GLIBC_2.3.2") 2247#define INIT_PTHREAD_COND_BROADCAST \ 2248 INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, "GLIBC_2.3.2") 2249#else 2250#define INIT_PTHREAD_COND_WAIT 2251#define INIT_PTHREAD_COND_INIT 2252#define INIT_PTHREAD_COND_SIGNAL 2253#define INIT_PTHREAD_COND_BROADCAST 2254#endif 2255 2256#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 2257static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 2258 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 2259 if (mnt->mnt_fsname) 2260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 2261 REAL(strlen)(mnt->mnt_fsname) + 1); 2262 if (mnt->mnt_dir) 2263 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 2264 REAL(strlen)(mnt->mnt_dir) + 1); 2265 if (mnt->mnt_type) 2266 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 2267 REAL(strlen)(mnt->mnt_type) + 1); 2268 if (mnt->mnt_opts) 2269 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 2270 REAL(strlen)(mnt->mnt_opts) + 1); 2271} 2272#endif 2273 2274#if SANITIZER_INTERCEPT_GETMNTENT 2275INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 2276 void *ctx; 2277 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 2278 __sanitizer_mntent *res = REAL(getmntent)(fp); 2279 if (res) write_mntent(ctx, res); 2280 return res; 2281} 2282#define INIT_GETMNTENT COMMON_INTERCEPT_FUNCTION(getmntent); 2283#else 2284#define INIT_GETMNTENT 2285#endif 2286 2287#if SANITIZER_INTERCEPT_GETMNTENT_R 2288INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 2289 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 2290 void *ctx; 2291 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 2292 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 2293 if (res) write_mntent(ctx, res); 2294 return res; 2295} 2296#define INIT_GETMNTENT_R COMMON_INTERCEPT_FUNCTION(getmntent_r); 2297#else 2298#define INIT_GETMNTENT_R 2299#endif 2300 2301#if SANITIZER_INTERCEPT_STATFS 2302INTERCEPTOR(int, statfs, char *path, void *buf) { 2303 void *ctx; 2304 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 2305 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2306 int res = REAL(statfs)(path, buf); 2307 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2308 return res; 2309} 2310INTERCEPTOR(int, fstatfs, int fd, void *buf) { 2311 void *ctx; 2312 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 2313 int res = REAL(fstatfs)(fd, buf); 2314 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2315 return res; 2316} 2317#define INIT_STATFS \ 2318 COMMON_INTERCEPT_FUNCTION(statfs); \ 2319 COMMON_INTERCEPT_FUNCTION(fstatfs); 2320#else 2321#define INIT_STATFS 2322#endif 2323 2324#if SANITIZER_INTERCEPT_STATFS64 2325INTERCEPTOR(int, statfs64, char *path, void *buf) { 2326 void *ctx; 2327 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 2328 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2329 int res = REAL(statfs64)(path, buf); 2330 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2331 return res; 2332} 2333INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 2334 void *ctx; 2335 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 2336 int res = REAL(fstatfs64)(fd, buf); 2337 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2338 return res; 2339} 2340#define INIT_STATFS64 \ 2341 COMMON_INTERCEPT_FUNCTION(statfs64); \ 2342 COMMON_INTERCEPT_FUNCTION(fstatfs64); 2343#else 2344#define INIT_STATFS64 2345#endif 2346 2347#if SANITIZER_INTERCEPT_STATVFS 2348INTERCEPTOR(int, statvfs, char *path, void *buf) { 2349 void *ctx; 2350 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 2351 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2352 int res = REAL(statvfs)(path, buf); 2353 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2354 return res; 2355} 2356INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 2357 void *ctx; 2358 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 2359 int res = REAL(fstatvfs)(fd, buf); 2360 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2361 return res; 2362} 2363#define INIT_STATVFS \ 2364 COMMON_INTERCEPT_FUNCTION(statvfs); \ 2365 COMMON_INTERCEPT_FUNCTION(fstatvfs); 2366#else 2367#define INIT_STATVFS 2368#endif 2369 2370#if SANITIZER_INTERCEPT_STATVFS64 2371INTERCEPTOR(int, statvfs64, char *path, void *buf) { 2372 void *ctx; 2373 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 2374 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2375 int res = REAL(statvfs64)(path, buf); 2376 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2377 return res; 2378} 2379INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 2380 void *ctx; 2381 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 2382 int res = REAL(fstatvfs64)(fd, buf); 2383 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2384 return res; 2385} 2386#define INIT_STATVFS64 \ 2387 COMMON_INTERCEPT_FUNCTION(statvfs64); \ 2388 COMMON_INTERCEPT_FUNCTION(fstatvfs64); 2389#else 2390#define INIT_STATVFS64 2391#endif 2392 2393#if SANITIZER_INTERCEPT_INITGROUPS 2394INTERCEPTOR(int, initgroups, char *user, u32 group) { 2395 void *ctx; 2396 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 2397 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 2398 int res = REAL(initgroups)(user, group); 2399 return res; 2400} 2401#define INIT_INITGROUPS COMMON_INTERCEPT_FUNCTION(initgroups); 2402#else 2403#define INIT_INITGROUPS 2404#endif 2405 2406#if SANITIZER_INTERCEPT_ETHER 2407INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 2408 void *ctx; 2409 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 2410 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2411 char *res = REAL(ether_ntoa)(addr); 2412 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2413 return res; 2414} 2415INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 2416 void *ctx; 2417 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 2418 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2419 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 2420 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res)); 2421 return res; 2422} 2423INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 2424 void *ctx; 2425 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 2426 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2427 int res = REAL(ether_ntohost)(hostname, addr); 2428 if (!res && hostname) 2429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2430 return res; 2431} 2432INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 2433 void *ctx; 2434 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 2435 if (hostname) 2436 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2437 int res = REAL(ether_hostton)(hostname, addr); 2438 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2439 return res; 2440} 2441INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 2442 char *hostname) { 2443 void *ctx; 2444 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 2445 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 2446 int res = REAL(ether_line)(line, addr, hostname); 2447 if (!res) { 2448 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2449 if (hostname) 2450 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2451 } 2452 return res; 2453} 2454#define INIT_ETHER \ 2455 COMMON_INTERCEPT_FUNCTION(ether_ntoa); \ 2456 COMMON_INTERCEPT_FUNCTION(ether_aton); \ 2457 COMMON_INTERCEPT_FUNCTION(ether_ntohost); \ 2458 COMMON_INTERCEPT_FUNCTION(ether_hostton); \ 2459 COMMON_INTERCEPT_FUNCTION(ether_line); 2460#else 2461#define INIT_ETHER 2462#endif 2463 2464#if SANITIZER_INTERCEPT_ETHER_R 2465INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 2466 void *ctx; 2467 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 2468 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2469 char *res = REAL(ether_ntoa_r)(addr, buf); 2470 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2471 return res; 2472} 2473INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 2474 __sanitizer_ether_addr *addr) { 2475 void *ctx; 2476 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 2477 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2478 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 2479 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 2480 return res; 2481} 2482#define INIT_ETHER_R \ 2483 COMMON_INTERCEPT_FUNCTION(ether_ntoa_r); \ 2484 COMMON_INTERCEPT_FUNCTION(ether_aton_r); 2485#else 2486#define INIT_ETHER_R 2487#endif 2488 2489#if SANITIZER_INTERCEPT_SHMCTL 2490INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 2491 void *ctx; 2492 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 2493 int res = REAL(shmctl)(shmid, cmd, buf); 2494 if (res >= 0) { 2495 unsigned sz = 0; 2496 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 2497 sz = sizeof(__sanitizer_shmid_ds); 2498 else if (cmd == shmctl_ipc_info) 2499 sz = struct_shminfo_sz; 2500 else if (cmd == shmctl_shm_info) 2501 sz = struct_shm_info_sz; 2502 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 2503 } 2504 return res; 2505} 2506#define INIT_SHMCTL COMMON_INTERCEPT_FUNCTION(shmctl); 2507#else 2508#define INIT_SHMCTL 2509#endif 2510 2511#if SANITIZER_INTERCEPT_RANDOM_R 2512INTERCEPTOR(int, random_r, void *buf, u32 *result) { 2513 void *ctx; 2514 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 2515 int res = REAL(random_r)(buf, result); 2516 if (!res && result) 2517 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2518 return res; 2519} 2520#define INIT_RANDOM_R COMMON_INTERCEPT_FUNCTION(random_r); 2521#else 2522#define INIT_RANDOM_R 2523#endif 2524 2525#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 2526 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED 2527#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 2528 INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \ 2529 void *ctx; \ 2530 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \ 2531 int res = REAL(pthread_attr_get##what)(attr, r); \ 2532 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 2533 return res; \ 2534 } 2535#endif 2536 2537#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 2538INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 2539INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 2540INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 2541INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 2542INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 2543INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 2544INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 2545 void *ctx; 2546 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 2547 int res = REAL(pthread_attr_getstack)(attr, addr, size); 2548 if (!res) { 2549 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2550 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 2551 } 2552 return res; 2553} 2554 2555#define INIT_PTHREAD_ATTR_GET \ 2556 COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 2557 COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 2558 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 2559 COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ 2560 COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ 2561 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 2562 COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); 2563#else 2564#define INIT_PTHREAD_ATTR_GET 2565#endif 2566 2567#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 2568INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 2569 2570#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 2571 COMMON_INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 2572#else 2573#define INIT_PTHREAD_ATTR_GETINHERITSCHED 2574#endif 2575 2576#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 2577INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 2578 void *cpuset) { 2579 void *ctx; 2580 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 2581 cpuset); 2582 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 2583 if (!res && cpusetsize && cpuset) 2584 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 2585 return res; 2586} 2587 2588#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 2589 COMMON_INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 2590#else 2591#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 2592#endif 2593 2594#if SANITIZER_INTERCEPT_TMPNAM 2595INTERCEPTOR(char *, tmpnam, char *s) { 2596 void *ctx; 2597 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 2598 char *res = REAL(tmpnam)(s); 2599 if (res) { 2600 if (s) 2601 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 2602 else 2603 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2604 } 2605 return res; 2606} 2607#define INIT_TMPNAM COMMON_INTERCEPT_FUNCTION(tmpnam); 2608#else 2609#define INIT_TMPNAM 2610#endif 2611 2612#if SANITIZER_INTERCEPT_TMPNAM_R 2613INTERCEPTOR(char *, tmpnam_r, char *s) { 2614 void *ctx; 2615 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 2616 char *res = REAL(tmpnam_r)(s); 2617 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 2618 return res; 2619} 2620#define INIT_TMPNAM_R COMMON_INTERCEPT_FUNCTION(tmpnam_r); 2621#else 2622#define INIT_TMPNAM_R 2623#endif 2624 2625#if SANITIZER_INTERCEPT_TEMPNAM 2626INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 2627 void *ctx; 2628 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 2629 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 2630 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 2631 char *res = REAL(tempnam)(dir, pfx); 2632 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2633 return res; 2634} 2635#define INIT_TEMPNAM COMMON_INTERCEPT_FUNCTION(tempnam); 2636#else 2637#define INIT_TEMPNAM 2638#endif 2639 2640#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP 2641INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 2642 void *ctx; 2643 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 2644 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 2645 return REAL(pthread_setname_np)(thread, name); 2646} 2647#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); 2648#else 2649#define INIT_PTHREAD_SETNAME_NP 2650#endif 2651 2652#if SANITIZER_INTERCEPT_SINCOS 2653INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 2654 void *ctx; 2655 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 2656 REAL(sincos)(x, sin, cos); 2657 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2658 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2659} 2660INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 2661 void *ctx; 2662 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 2663 REAL(sincosf)(x, sin, cos); 2664 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2665 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2666} 2667INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 2668 void *ctx; 2669 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 2670 REAL(sincosl)(x, sin, cos); 2671 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2672 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2673} 2674#define INIT_SINCOS \ 2675 COMMON_INTERCEPT_FUNCTION(sincos); \ 2676 COMMON_INTERCEPT_FUNCTION(sincosf); \ 2677 COMMON_INTERCEPT_FUNCTION(sincosl); 2678#else 2679#define INIT_SINCOS 2680#endif 2681 2682#if SANITIZER_INTERCEPT_REMQUO 2683INTERCEPTOR(double, remquo, double x, double y, int *quo) { 2684 void *ctx; 2685 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 2686 double res = REAL(remquo)(x, y, quo); 2687 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2688 return res; 2689} 2690INTERCEPTOR(float, remquof, float x, float y, int *quo) { 2691 void *ctx; 2692 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 2693 float res = REAL(remquof)(x, y, quo); 2694 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2695 return res; 2696} 2697INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 2698 void *ctx; 2699 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 2700 long double res = REAL(remquol)(x, y, quo); 2701 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2702 return res; 2703} 2704#define INIT_REMQUO \ 2705 COMMON_INTERCEPT_FUNCTION(remquo); \ 2706 COMMON_INTERCEPT_FUNCTION(remquof); \ 2707 COMMON_INTERCEPT_FUNCTION(remquol); 2708#else 2709#define INIT_REMQUO 2710#endif 2711 2712#if SANITIZER_INTERCEPT_LGAMMA 2713extern int signgam; 2714INTERCEPTOR(double, lgamma, double x) { 2715 void *ctx; 2716 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 2717 double res = REAL(lgamma)(x); 2718 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2719 return res; 2720} 2721INTERCEPTOR(float, lgammaf, float x) { 2722 void *ctx; 2723 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 2724 float res = REAL(lgammaf)(x); 2725 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2726 return res; 2727} 2728INTERCEPTOR(long double, lgammal, long double x) { 2729 void *ctx; 2730 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 2731 long double res = REAL(lgammal)(x); 2732 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2733 return res; 2734} 2735#define INIT_LGAMMA \ 2736 COMMON_INTERCEPT_FUNCTION(lgamma); \ 2737 COMMON_INTERCEPT_FUNCTION(lgammaf); \ 2738 COMMON_INTERCEPT_FUNCTION(lgammal); 2739#else 2740#define INIT_LGAMMA 2741#endif 2742 2743#if SANITIZER_INTERCEPT_LGAMMA_R 2744INTERCEPTOR(double, lgamma_r, double x, int *signp) { 2745 void *ctx; 2746 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 2747 double res = REAL(lgamma_r)(x, signp); 2748 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2749 return res; 2750} 2751INTERCEPTOR(float, lgammaf_r, float x, int *signp) { 2752 void *ctx; 2753 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 2754 float res = REAL(lgammaf_r)(x, signp); 2755 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2756 return res; 2757} 2758INTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 2759 void *ctx; 2760 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 2761 long double res = REAL(lgammal_r)(x, signp); 2762 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2763 return res; 2764} 2765#define INIT_LGAMMA_R \ 2766 COMMON_INTERCEPT_FUNCTION(lgamma_r); \ 2767 COMMON_INTERCEPT_FUNCTION(lgammaf_r); \ 2768 COMMON_INTERCEPT_FUNCTION(lgammal_r); 2769#else 2770#define INIT_LGAMMA_R 2771#endif 2772 2773#if SANITIZER_INTERCEPT_DRAND48_R 2774INTERCEPTOR(int, drand48_r, void *buffer, double *result) { 2775 void *ctx; 2776 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 2777 int res = REAL(drand48_r)(buffer, result); 2778 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2779 return res; 2780} 2781INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 2782 void *ctx; 2783 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 2784 int res = REAL(lrand48_r)(buffer, result); 2785 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2786 return res; 2787} 2788#define INIT_DRAND48_R \ 2789 COMMON_INTERCEPT_FUNCTION(drand48_r); \ 2790 COMMON_INTERCEPT_FUNCTION(lrand48_r); 2791#else 2792#define INIT_DRAND48_R 2793#endif 2794 2795#if SANITIZER_INTERCEPT_GETLINE 2796INTERCEPTOR(SSIZE_T, getline, char **lineptr, SIZE_T *n, void *stream) { 2797 void *ctx; 2798 COMMON_INTERCEPTOR_ENTER(ctx, getline, lineptr, n, stream); 2799 SSIZE_T res = REAL(getline)(lineptr, n, stream); 2800 if (res > 0) { 2801 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 2802 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 2803 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 2804 } 2805 return res; 2806} 2807INTERCEPTOR(SSIZE_T, getdelim, char **lineptr, SIZE_T *n, int delim, 2808 void *stream) { 2809 void *ctx; 2810 COMMON_INTERCEPTOR_ENTER(ctx, getdelim, lineptr, n, delim, stream); 2811 SSIZE_T res = REAL(getdelim)(lineptr, n, delim, stream); 2812 if (res > 0) { 2813 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineptr, sizeof(*lineptr)); 2814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); 2815 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *lineptr, res + 1); 2816 } 2817 return res; 2818} 2819#define INIT_GETLINE \ 2820 COMMON_INTERCEPT_FUNCTION(getline); \ 2821 COMMON_INTERCEPT_FUNCTION(getdelim); 2822#else 2823#define INIT_GETLINE 2824#endif 2825 2826#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 2827 INIT_STRCMP; \ 2828 INIT_STRNCMP; \ 2829 INIT_STRCASECMP; \ 2830 INIT_STRNCASECMP; \ 2831 INIT_READ; \ 2832 INIT_PREAD; \ 2833 INIT_PREAD64; \ 2834 INIT_READV; \ 2835 INIT_PREADV; \ 2836 INIT_PREADV64; \ 2837 INIT_WRITE; \ 2838 INIT_PWRITE; \ 2839 INIT_PWRITE64; \ 2840 INIT_WRITEV; \ 2841 INIT_PWRITEV; \ 2842 INIT_PWRITEV64; \ 2843 INIT_PRCTL; \ 2844 INIT_LOCALTIME_AND_FRIENDS; \ 2845 INIT_STRPTIME; \ 2846 INIT_SCANF; \ 2847 INIT_ISOC99_SCANF; \ 2848 INIT_FREXP; \ 2849 INIT_FREXPF_FREXPL; \ 2850 INIT_GETPWNAM_AND_FRIENDS; \ 2851 INIT_GETPWNAM_R_AND_FRIENDS; \ 2852 INIT_CLOCK_GETTIME; \ 2853 INIT_GETITIMER; \ 2854 INIT_TIME; \ 2855 INIT_GLOB; \ 2856 INIT_WAIT; \ 2857 INIT_INET; \ 2858 INIT_PTHREAD_GETSCHEDPARAM; \ 2859 INIT_GETADDRINFO; \ 2860 INIT_GETNAMEINFO; \ 2861 INIT_GETSOCKNAME; \ 2862 INIT_GETHOSTBYNAME; \ 2863 INIT_GETHOSTBYNAME_R; \ 2864 INIT_GETSOCKOPT; \ 2865 INIT_ACCEPT; \ 2866 INIT_ACCEPT4; \ 2867 INIT_MODF; \ 2868 INIT_RECVMSG; \ 2869 INIT_GETPEERNAME; \ 2870 INIT_IOCTL; \ 2871 INIT_INET_ATON; \ 2872 INIT_SYSINFO; \ 2873 INIT_READDIR; \ 2874 INIT_READDIR64; \ 2875 INIT_PTRACE; \ 2876 INIT_SETLOCALE; \ 2877 INIT_GETCWD; \ 2878 INIT_GET_CURRENT_DIR_NAME; \ 2879 INIT_STRTOIMAX; \ 2880 INIT_MBSTOWCS; \ 2881 INIT_MBSNRTOWCS; \ 2882 INIT_WCSTOMBS; \ 2883 INIT_WCSNRTOMBS; \ 2884 INIT_TCGETATTR; \ 2885 INIT_REALPATH; \ 2886 INIT_CANONICALIZE_FILE_NAME; \ 2887 INIT_CONFSTR; \ 2888 INIT_SCHED_GETAFFINITY; \ 2889 INIT_STRERROR; \ 2890 INIT_STRERROR_R; \ 2891 INIT_SCANDIR; \ 2892 INIT_SCANDIR64; \ 2893 INIT_GETGROUPS; \ 2894 INIT_POLL; \ 2895 INIT_PPOLL; \ 2896 INIT_WORDEXP; \ 2897 INIT_SIGWAIT; \ 2898 INIT_SIGWAITINFO; \ 2899 INIT_SIGTIMEDWAIT; \ 2900 INIT_SIGSETOPS; \ 2901 INIT_SIGPENDING; \ 2902 INIT_SIGPROCMASK; \ 2903 INIT_BACKTRACE; \ 2904 INIT__EXIT; \ 2905 INIT_PTHREAD_MUTEX_LOCK; \ 2906 INIT_PTHREAD_MUTEX_UNLOCK; \ 2907 INIT_PTHREAD_COND_WAIT; \ 2908 INIT_PTHREAD_COND_INIT; \ 2909 INIT_PTHREAD_COND_SIGNAL; \ 2910 INIT_PTHREAD_COND_BROADCAST; \ 2911 INIT_GETMNTENT; \ 2912 INIT_GETMNTENT_R; \ 2913 INIT_STATFS; \ 2914 INIT_STATFS64; \ 2915 INIT_STATVFS; \ 2916 INIT_STATVFS64; \ 2917 INIT_INITGROUPS; \ 2918 INIT_ETHER; \ 2919 INIT_ETHER_R; \ 2920 INIT_SHMCTL; \ 2921 INIT_RANDOM_R; \ 2922 INIT_PTHREAD_ATTR_GET; \ 2923 INIT_PTHREAD_ATTR_GETINHERITSCHED; \ 2924 INIT_PTHREAD_ATTR_GETAFFINITY_NP; \ 2925 INIT_TMPNAM; \ 2926 INIT_TMPNAM_R; \ 2927 INIT_TEMPNAM; \ 2928 INIT_PTHREAD_SETNAME_NP; \ 2929 INIT_SINCOS; \ 2930 INIT_REMQUO; \ 2931 INIT_LGAMMA; \ 2932 INIT_LGAMMA_R; \ 2933 INIT_DRAND48_R; \ 2934 INIT_GETLINE; \ 2935/**/ 2936