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