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