sanitizer_common_interceptors.inc revision 5e2d3776a314629680921abd1d55d89d95a2da90
15d71de26cedae3dafc17449fe0182045c0bd20e8Stephen Hines//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 22d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 32d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// The LLVM Compiler Infrastructure 42d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 52d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file is distributed under the University of Illinois Open Source 62d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// License. See LICENSE.TXT for details. 72d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 82d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines//===----------------------------------------------------------------------===// 92d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 102d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// Common function interceptors for tools like AddressSanitizer, 112d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// ThreadSanitizer, MemorySanitizer, etc. 122d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 132d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// This file should be included into the tool's interceptor file, 142d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// which has to define it's own macros: 152d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// COMMON_INTERCEPTOR_ENTER 162d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// COMMON_INTERCEPTOR_READ_RANGE 172d1fdb26e458c4ddc04155c1d421bced3ba90cd0Stephen Hines// 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//===----------------------------------------------------------------------===// 27#include "interception/interception.h" 28#include "sanitizer_platform_interceptors.h" 29 30#include <stdarg.h> 31 32#if SANITIZER_WINDOWS 33#define va_copy(dst, src) ((dst) = (src)) 34#endif // _WIN32 35 36#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 37#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) 38#endif 39 40#ifndef COMMON_INTERCEPTOR_FD_ACCESS 41#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) 42#endif 43 44#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK 45#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) 46#endif 47 48#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 49#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) 50#endif 51 52#if SANITIZER_INTERCEPT_STRCMP 53static inline int CharCmpX(unsigned char c1, unsigned char c2) { 54 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 55} 56 57INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 58 void *ctx; 59 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 60 unsigned char c1, c2; 61 uptr i; 62 for (i = 0; ; i++) { 63 c1 = (unsigned char)s1[i]; 64 c2 = (unsigned char)s2[i]; 65 if (c1 != c2 || c1 == '\0') break; 66 } 67 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 68 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 69 return CharCmpX(c1, c2); 70} 71 72INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 73 void *ctx; 74 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 75 unsigned char c1 = 0, c2 = 0; 76 uptr i; 77 for (i = 0; i < size; i++) { 78 c1 = (unsigned char)s1[i]; 79 c2 = (unsigned char)s2[i]; 80 if (c1 != c2 || c1 == '\0') break; 81 } 82 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 83 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 84 return CharCmpX(c1, c2); 85} 86 87#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp) 88#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp) 89#else 90#define INIT_STRCMP 91#define INIT_STRNCMP 92#endif 93 94#if SANITIZER_INTERCEPT_STRCASECMP 95static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 96 int c1_low = ToLower(c1); 97 int c2_low = ToLower(c2); 98 return c1_low - c2_low; 99} 100 101INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 102 void *ctx; 103 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 104 unsigned char c1 = 0, c2 = 0; 105 uptr i; 106 for (i = 0; ; i++) { 107 c1 = (unsigned char)s1[i]; 108 c2 = (unsigned char)s2[i]; 109 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 110 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') 126 break; 127 } 128 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 129 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 130 return CharCaseCmp(c1, c2); 131} 132 133#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 134#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 135#else 136#define INIT_STRCASECMP 137#define INIT_STRNCASECMP 138#endif 139 140#if SANITIZER_INTERCEPT_FREXP 141INTERCEPTOR(double, frexp, double x, int *exp) { 142 void *ctx; 143 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 144 double res = REAL(frexp)(x, exp); 145 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 146 return res; 147} 148 149#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 150#else 151#define INIT_FREXP 152#endif // SANITIZER_INTERCEPT_FREXP 153 154#if SANITIZER_INTERCEPT_FREXPF_FREXPL 155INTERCEPTOR(float, frexpf, float x, int *exp) { 156 void *ctx; 157 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 158 float res = REAL(frexpf)(x, exp); 159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 160 return res; 161} 162 163INTERCEPTOR(long double, frexpl, long double x, int *exp) { 164 void *ctx; 165 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 166 long double res = REAL(frexpl)(x, exp); 167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 168 return res; 169} 170 171#define INIT_FREXPF_FREXPL \ 172 INTERCEPT_FUNCTION(frexpf); \ 173 INTERCEPT_FUNCTION(frexpl) 174#else 175#define INIT_FREXPF_FREXPL 176#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 177 178#if SI_NOT_WINDOWS 179static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 180 SIZE_T iovlen, SIZE_T maxlen) { 181 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 182 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 183 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 184 maxlen -= sz; 185 } 186} 187 188static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 189 SIZE_T iovlen, SIZE_T maxlen) { 190 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 191 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 192 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 193 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 194 maxlen -= sz; 195 } 196} 197#endif 198 199#if SANITIZER_INTERCEPT_READ 200INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 201 void *ctx; 202 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 203 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 204 SSIZE_T res = REAL(read)(fd, ptr, count); 205 if (res > 0) 206 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 207 if (res >= 0 && fd >= 0) 208 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 209 return res; 210} 211#define INIT_READ INTERCEPT_FUNCTION(read) 212#else 213#define INIT_READ 214#endif 215 216#if SANITIZER_INTERCEPT_PREAD 217INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 218 void *ctx; 219 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 220 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 221 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 222 if (res > 0) 223 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 224 if (res >= 0 && fd >= 0) 225 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 226 return res; 227} 228#define INIT_PREAD INTERCEPT_FUNCTION(pread) 229#else 230#define INIT_PREAD 231#endif 232 233#if SANITIZER_INTERCEPT_PREAD64 234INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 235 void *ctx; 236 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 237 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 238 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 239 if (res > 0) 240 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 241 if (res >= 0 && fd >= 0) 242 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 243 return res; 244} 245#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 246#else 247#define INIT_PREAD64 248#endif 249 250#if SANITIZER_INTERCEPT_READV 251INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 252 int iovcnt) { 253 void *ctx; 254 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 255 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 256 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 257 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 258 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 259 return res; 260} 261#define INIT_READV INTERCEPT_FUNCTION(readv) 262#else 263#define INIT_READV 264#endif 265 266#if SANITIZER_INTERCEPT_PREADV 267INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 268 OFF_T offset) { 269 void *ctx; 270 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 271 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 272 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 273 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 274 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 275 return res; 276} 277#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 278#else 279#define INIT_PREADV 280#endif 281 282#if SANITIZER_INTERCEPT_PREADV64 283INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 284 OFF64_T offset) { 285 void *ctx; 286 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 287 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 288 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 289 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 290 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 291 return res; 292} 293#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 294#else 295#define INIT_PREADV64 296#endif 297 298#if SANITIZER_INTERCEPT_WRITE 299INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 300 void *ctx; 301 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 302 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 303 if (fd >= 0) 304 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 305 SSIZE_T res = REAL(write)(fd, ptr, count); 306 // FIXME: this check should be _before_ the call to REAL(write), not after 307 if (res > 0) 308 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 309 return res; 310} 311#define INIT_WRITE INTERCEPT_FUNCTION(write) 312#else 313#define INIT_WRITE 314#endif 315 316#if SANITIZER_INTERCEPT_PWRITE 317INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 318 void *ctx; 319 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 320 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 321 if (fd >= 0) 322 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 323 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 324 if (res > 0) 325 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 326 return res; 327} 328#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 329#else 330#define INIT_PWRITE 331#endif 332 333#if SANITIZER_INTERCEPT_PWRITE64 334INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 335 OFF64_T offset) { 336 void *ctx; 337 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 338 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 339 if (fd >= 0) 340 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 341 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 342 if (res > 0) 343 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 344 return res; 345} 346#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 347#else 348#define INIT_PWRITE64 349#endif 350 351#if SANITIZER_INTERCEPT_WRITEV 352INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 353 int iovcnt) { 354 void *ctx; 355 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 356 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 357 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 358 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 359 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 360 return res; 361} 362#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 363#else 364#define INIT_WRITEV 365#endif 366 367#if SANITIZER_INTERCEPT_PWRITEV 368INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 369 OFF_T offset) { 370 void *ctx; 371 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 372 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 373 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 374 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 375 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 376 return res; 377} 378#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 379#else 380#define INIT_PWRITEV 381#endif 382 383#if SANITIZER_INTERCEPT_PWRITEV64 384INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 385 OFF64_T offset) { 386 void *ctx; 387 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 388 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 389 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 390 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 391 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 392 return res; 393} 394#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 395#else 396#define INIT_PWRITEV64 397#endif 398 399#if SANITIZER_INTERCEPT_PRCTL 400INTERCEPTOR(int, prctl, int option, 401 unsigned long arg2, unsigned long arg3, // NOLINT 402 unsigned long arg4, unsigned long arg5) { // NOLINT 403 void *ctx; 404 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 405 static const int PR_SET_NAME = 15; 406 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 407 if (option == PR_SET_NAME) { 408 char buff[16]; 409 internal_strncpy(buff, (char *)arg2, 15); 410 buff[15] = 0; 411 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 412 } 413 return res; 414} 415#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 416#else 417#define INIT_PRCTL 418#endif // SANITIZER_INTERCEPT_PRCTL 419 420 421#if SANITIZER_INTERCEPT_TIME 422INTERCEPTOR(unsigned long, time, unsigned long *t) { 423 void *ctx; 424 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 425 unsigned long res = REAL(time)(t); 426 if (t && res != (unsigned long)-1) { 427 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 428 } 429 return res; 430} 431#define INIT_TIME \ 432 INTERCEPT_FUNCTION(time); 433#else 434#define INIT_TIME 435#endif // SANITIZER_INTERCEPT_TIME 436 437 438#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 439static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 441 if (tm->tm_zone) { 442 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 443 // can point to shared memory and tsan would report a data race. 444 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone, 445 REAL(strlen(tm->tm_zone)) + 1); 446 } 447} 448 449INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 450 void *ctx; 451 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 452 __sanitizer_tm *res = REAL(localtime)(timep); 453 if (res) { 454 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 455 unpoison_tm(ctx, res); 456 } 457 return res; 458} 459INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 460 void *ctx; 461 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 462 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 463 if (res) { 464 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 465 unpoison_tm(ctx, res); 466 } 467 return res; 468} 469INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 470 void *ctx; 471 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 472 __sanitizer_tm *res = REAL(gmtime)(timep); 473 if (res) { 474 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 475 unpoison_tm(ctx, res); 476 } 477 return res; 478} 479INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 480 void *ctx; 481 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 482 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 483 if (res) { 484 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 485 unpoison_tm(ctx, res); 486 } 487 return res; 488} 489INTERCEPTOR(char *, ctime, unsigned long *timep) { 490 void *ctx; 491 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 492 char *res = REAL(ctime)(timep); 493 if (res) { 494 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 496 } 497 return res; 498} 499INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 500 void *ctx; 501 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 502 char *res = REAL(ctime_r)(timep, result); 503 if (res) { 504 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 505 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 506 } 507 return res; 508} 509INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 510 void *ctx; 511 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 512 char *res = REAL(asctime)(tm); 513 if (res) { 514 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 516 } 517 return res; 518} 519INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 520 void *ctx; 521 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 522 char *res = REAL(asctime_r)(tm, result); 523 if (res) { 524 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 526 } 527 return res; 528} 529#define INIT_LOCALTIME_AND_FRIENDS \ 530 INTERCEPT_FUNCTION(localtime); \ 531 INTERCEPT_FUNCTION(localtime_r); \ 532 INTERCEPT_FUNCTION(gmtime); \ 533 INTERCEPT_FUNCTION(gmtime_r); \ 534 INTERCEPT_FUNCTION(ctime); \ 535 INTERCEPT_FUNCTION(ctime_r); \ 536 INTERCEPT_FUNCTION(asctime); \ 537 INTERCEPT_FUNCTION(asctime_r); 538#else 539#define INIT_LOCALTIME_AND_FRIENDS 540#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 541 542#if SANITIZER_INTERCEPT_SCANF 543 544#include "sanitizer_common_interceptors_scanf.inc" 545 546#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 547 { \ 548 void *ctx; \ 549 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 550 va_list aq; \ 551 va_copy(aq, ap); \ 552 int res = REAL(vname)(__VA_ARGS__); \ 553 if (res > 0) \ 554 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 555 va_end(aq); \ 556 return res; \ 557 } 558 559INTERCEPTOR(int, vscanf, const char *format, va_list ap) 560VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 561 562INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 563VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 564 565INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 566VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 567 568#if SANITIZER_INTERCEPT_ISOC99_SCANF 569INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 570VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 571 572INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 573 va_list ap) 574VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 575 576INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 577VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 578#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 579 580#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 581 { \ 582 void *ctx; \ 583 va_list ap; \ 584 va_start(ap, format); \ 585 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 586 int res = vname(__VA_ARGS__, ap); \ 587 va_end(ap); \ 588 return res; \ 589 } 590 591INTERCEPTOR(int, scanf, const char *format, ...) 592SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 593 594INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 595SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 596 597INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 598SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 599 600#if SANITIZER_INTERCEPT_ISOC99_SCANF 601INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 602SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 603 604INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 605SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 606 607INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 608SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 609#endif 610 611#endif 612 613#if SANITIZER_INTERCEPT_SCANF 614#define INIT_SCANF \ 615 INTERCEPT_FUNCTION(scanf); \ 616 INTERCEPT_FUNCTION(sscanf); \ 617 INTERCEPT_FUNCTION(fscanf); \ 618 INTERCEPT_FUNCTION(vscanf); \ 619 INTERCEPT_FUNCTION(vsscanf); \ 620 INTERCEPT_FUNCTION(vfscanf); 621#else 622#define INIT_SCANF 623#endif 624 625#if SANITIZER_INTERCEPT_ISOC99_SCANF 626#define INIT_ISOC99_SCANF \ 627 INTERCEPT_FUNCTION(__isoc99_scanf); \ 628 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 629 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 630 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 631 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 632 INTERCEPT_FUNCTION(__isoc99_vfscanf); 633#else 634#define INIT_ISOC99_SCANF 635#endif 636 637#if SANITIZER_INTERCEPT_IOCTL 638#include "sanitizer_common_interceptors_ioctl.inc" 639INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 640 void *ctx; 641 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 642 643 CHECK(ioctl_initialized); 644 645 // Note: TSan does not use common flags, and they are zero-initialized. 646 // This effectively disables ioctl handling in TSan. 647 if (!common_flags()->handle_ioctl) 648 return REAL(ioctl)(d, request, arg); 649 650 const ioctl_desc *desc = ioctl_lookup(request); 651 if (!desc) 652 Printf("WARNING: unknown ioctl %x\n", request); 653 654 if (desc) 655 ioctl_common_pre(ctx, desc, d, request, arg); 656 int res = REAL(ioctl)(d, request, arg); 657 // FIXME: some ioctls have different return values for success and failure. 658 if (desc && res != -1) 659 ioctl_common_post(ctx, desc, res, d, request, arg); 660 return res; 661} 662#define INIT_IOCTL \ 663 ioctl_init(); \ 664 INTERCEPT_FUNCTION(ioctl); 665#else 666#define INIT_IOCTL 667#endif 668 669 670#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 671INTERCEPTOR(void *, getpwnam, const char *name) { 672 void *ctx; 673 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 674 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 675 void *res = REAL(getpwnam)(name); 676 if (res != 0) 677 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 678 return res; 679} 680INTERCEPTOR(void *, getpwuid, u32 uid) { 681 void *ctx; 682 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 683 void *res = REAL(getpwuid)(uid); 684 if (res != 0) 685 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 686 return res; 687} 688INTERCEPTOR(void *, getgrnam, const char *name) { 689 void *ctx; 690 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 691 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 692 void *res = REAL(getgrnam)(name); 693 if (res != 0) 694 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 695 return res; 696} 697INTERCEPTOR(void *, getgrgid, u32 gid) { 698 void *ctx; 699 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 700 void *res = REAL(getgrgid)(gid); 701 if (res != 0) 702 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 703 return res; 704} 705#define INIT_GETPWNAM_AND_FRIENDS \ 706 INTERCEPT_FUNCTION(getpwnam); \ 707 INTERCEPT_FUNCTION(getpwuid); \ 708 INTERCEPT_FUNCTION(getgrnam); \ 709 INTERCEPT_FUNCTION(getgrgid); 710#else 711#define INIT_GETPWNAM_AND_FRIENDS 712#endif 713 714 715#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 716INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 717 char *buf, SIZE_T buflen, void **result) { 718 void *ctx; 719 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 720 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 721 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 722 if (!res) { 723 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 725 } 726 return res; 727} 728INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 729 char *buf, SIZE_T buflen, void **result) { 730 void *ctx; 731 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 732 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 733 if (!res) { 734 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 736 } 737 return res; 738} 739INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 740 char *buf, SIZE_T buflen, void **result) { 741 void *ctx; 742 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 743 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 744 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 745 if (!res) { 746 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 747 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 748 } 749 return res; 750} 751INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 752 char *buf, SIZE_T buflen, void **result) { 753 void *ctx; 754 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 755 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 756 if (!res) { 757 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 758 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 759 } 760 return res; 761} 762#define INIT_GETPWNAM_R_AND_FRIENDS \ 763 INTERCEPT_FUNCTION(getpwnam_r); \ 764 INTERCEPT_FUNCTION(getpwuid_r); \ 765 INTERCEPT_FUNCTION(getgrnam_r); \ 766 INTERCEPT_FUNCTION(getgrgid_r); 767#else 768#define INIT_GETPWNAM_R_AND_FRIENDS 769#endif 770 771 772#if SANITIZER_INTERCEPT_CLOCK_GETTIME 773INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 774 void *ctx; 775 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 776 int res = REAL(clock_getres)(clk_id, tp); 777 if (!res && tp) { 778 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 779 } 780 return res; 781} 782INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 783 void *ctx; 784 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 785 int res = REAL(clock_gettime)(clk_id, tp); 786 if (!res) { 787 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 788 } 789 return res; 790} 791INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 792 void *ctx; 793 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 794 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 795 return REAL(clock_settime)(clk_id, tp); 796} 797#define INIT_CLOCK_GETTIME \ 798 INTERCEPT_FUNCTION(clock_getres); \ 799 INTERCEPT_FUNCTION(clock_gettime); \ 800 INTERCEPT_FUNCTION(clock_settime); 801#else 802#define INIT_CLOCK_GETTIME 803#endif 804 805 806#if SANITIZER_INTERCEPT_GETITIMER 807INTERCEPTOR(int, getitimer, int which, void *curr_value) { 808 void *ctx; 809 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 810 int res = REAL(getitimer)(which, curr_value); 811 if (!res && curr_value) { 812 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 813 } 814 return res; 815} 816INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 817 void *ctx; 818 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 819 if (new_value) 820 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 821 int res = REAL(setitimer)(which, new_value, old_value); 822 if (!res && old_value) { 823 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 824 } 825 return res; 826} 827#define INIT_GETITIMER \ 828 INTERCEPT_FUNCTION(getitimer); \ 829 INTERCEPT_FUNCTION(setitimer); 830#else 831#define INIT_GETITIMER 832#endif 833 834#if SANITIZER_INTERCEPT_GLOB 835static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 836 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 837 // +1 for NULL pointer at the end. 838 if (pglob->gl_pathv) 839 COMMON_INTERCEPTOR_WRITE_RANGE( 840 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 841 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 842 char *p = pglob->gl_pathv[i]; 843 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 844 } 845} 846 847static THREADLOCAL __sanitizer_glob_t* pglob_copy; 848static THREADLOCAL void* glob_ctx; 849 850static void wrapped_gl_closedir(void *dir) { 851 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 852 pglob_copy->gl_closedir(dir); 853} 854 855static void *wrapped_gl_readdir(void *dir) { 856 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 857 return pglob_copy->gl_readdir(dir); 858} 859 860static void *wrapped_gl_opendir(const char *s) { 861 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 862 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 863 return pglob_copy->gl_opendir(s); 864} 865 866static int wrapped_gl_lstat(const char *s, void *st) { 867 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 868 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 869 return pglob_copy->gl_lstat(s, st); 870} 871 872static int wrapped_gl_stat(const char *s, void *st) { 873 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 874 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 875 return pglob_copy->gl_stat(s, st); 876} 877 878INTERCEPTOR(int, glob, const char *pattern, int flags, 879 int (*errfunc)(const char *epath, int eerrno), 880 __sanitizer_glob_t *pglob) { 881 void *ctx; 882 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 883 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 884 wrapped_gl_readdir, wrapped_gl_opendir, 885 wrapped_gl_lstat, wrapped_gl_stat}; 886 if (flags & glob_altdirfunc) { 887 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 888 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 889 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 890 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 891 Swap(pglob->gl_stat, glob_copy.gl_stat); 892 pglob_copy = &glob_copy; 893 glob_ctx = ctx; 894 } 895 int res = REAL(glob)(pattern, flags, errfunc, pglob); 896 if (flags & glob_altdirfunc) { 897 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 898 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 899 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 900 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 901 Swap(pglob->gl_stat, glob_copy.gl_stat); 902 } 903 pglob_copy = 0; 904 glob_ctx = 0; 905 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 906 return res; 907} 908 909INTERCEPTOR(int, glob64, const char *pattern, int flags, 910 int (*errfunc)(const char *epath, int eerrno), 911 __sanitizer_glob_t *pglob) { 912 void *ctx; 913 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 914 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 915 wrapped_gl_readdir, wrapped_gl_opendir, 916 wrapped_gl_lstat, wrapped_gl_stat}; 917 if (flags & glob_altdirfunc) { 918 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 919 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 920 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 921 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 922 Swap(pglob->gl_stat, glob_copy.gl_stat); 923 pglob_copy = &glob_copy; 924 glob_ctx = ctx; 925 } 926 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 927 if (flags & glob_altdirfunc) { 928 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 929 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 930 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 931 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 932 Swap(pglob->gl_stat, glob_copy.gl_stat); 933 } 934 pglob_copy = 0; 935 glob_ctx = 0; 936 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 937 return res; 938} 939#define INIT_GLOB \ 940 INTERCEPT_FUNCTION(glob); \ 941 INTERCEPT_FUNCTION(glob64); 942#else // SANITIZER_INTERCEPT_GLOB 943#define INIT_GLOB 944#endif // SANITIZER_INTERCEPT_GLOB 945 946#if SANITIZER_INTERCEPT_WAIT 947// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 948// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 949// details. 950INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 951 void *ctx; 952 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 953 int res = REAL(wait)(status); 954 if (res != -1 && status) 955 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 956 return res; 957} 958INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 959 int options) { 960 void *ctx; 961 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 962 int res = REAL(waitid)(idtype, id, infop, options); 963 if (res != -1 && infop) 964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 965 return res; 966} 967INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 968 void *ctx; 969 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 970 int res = REAL(waitpid)(pid, status, options); 971 if (res != -1 && status) 972 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 973 return res; 974} 975INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 976 void *ctx; 977 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 978 int res = REAL(wait3)(status, options, rusage); 979 if (res != -1) { 980 if (status) 981 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 982 if (rusage) 983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 984 } 985 return res; 986} 987INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 988 void *ctx; 989 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 990 int res = REAL(wait4)(pid, status, options, rusage); 991 if (res != -1) { 992 if (status) 993 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 994 if (rusage) 995 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 996 } 997 return res; 998} 999#define INIT_WAIT \ 1000 INTERCEPT_FUNCTION(wait); \ 1001 INTERCEPT_FUNCTION(waitid); \ 1002 INTERCEPT_FUNCTION(waitpid); \ 1003 INTERCEPT_FUNCTION(wait3); \ 1004 INTERCEPT_FUNCTION(wait4); 1005#else 1006#define INIT_WAIT 1007#endif 1008 1009#if SANITIZER_INTERCEPT_INET 1010INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 1011 void *ctx; 1012 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 1013 uptr sz = __sanitizer_in_addr_sz(af); 1014 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 1015 // FIXME: figure out read size based on the address family. 1016 char *res = REAL(inet_ntop)(af, src, dst, size); 1017 if (res) 1018 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1019 return res; 1020} 1021INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 1022 void *ctx; 1023 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 1024 // FIXME: figure out read size based on the address family. 1025 int res = REAL(inet_pton)(af, src, dst); 1026 if (res == 1) { 1027 uptr sz = __sanitizer_in_addr_sz(af); 1028 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1029 } 1030 return res; 1031} 1032#define INIT_INET \ 1033 INTERCEPT_FUNCTION(inet_ntop); \ 1034 INTERCEPT_FUNCTION(inet_pton); 1035#else 1036#define INIT_INET 1037#endif 1038 1039#if SANITIZER_INTERCEPT_INET 1040INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 1041 void *ctx; 1042 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1043 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1044 int res = REAL(inet_aton)(cp, dst); 1045 if (res != 0) { 1046 uptr sz = __sanitizer_in_addr_sz(af_inet); 1047 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1048 } 1049 return res; 1050} 1051#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 1052#else 1053#define INIT_INET_ATON 1054#endif 1055 1056#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1057INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1058 void *ctx; 1059 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1060 int res = REAL(pthread_getschedparam)(thread, policy, param); 1061 if (res == 0) { 1062 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1063 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1064 } 1065 return res; 1066} 1067#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 1068#else 1069#define INIT_PTHREAD_GETSCHEDPARAM 1070#endif 1071 1072#if SANITIZER_INTERCEPT_GETADDRINFO 1073INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1074 struct __sanitizer_addrinfo *hints, 1075 struct __sanitizer_addrinfo **out) { 1076 void *ctx; 1077 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1078 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1079 if (service) 1080 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1081 if (hints) 1082 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1083 int res = REAL(getaddrinfo)(node, service, hints, out); 1084 if (res == 0 && out) { 1085 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1086 struct __sanitizer_addrinfo *p = *out; 1087 while (p) { 1088 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1089 if (p->ai_addr) 1090 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1091 if (p->ai_canonname) 1092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1093 REAL(strlen)(p->ai_canonname) + 1); 1094 p = p->ai_next; 1095 } 1096 } 1097 return res; 1098} 1099#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 1100#else 1101#define INIT_GETADDRINFO 1102#endif 1103 1104#if SANITIZER_INTERCEPT_GETNAMEINFO 1105INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1106 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1107 void *ctx; 1108 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1109 serv, servlen, flags); 1110 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1111 // There is padding in in_addr that may make this too noisy 1112 int res = 1113 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1114 if (res == 0) { 1115 if (host && hostlen) 1116 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1117 if (serv && servlen) 1118 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1119 } 1120 return res; 1121} 1122#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1123#else 1124#define INIT_GETNAMEINFO 1125#endif 1126 1127#if SANITIZER_INTERCEPT_GETSOCKNAME 1128INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1129 void *ctx; 1130 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1131 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1132 int addrlen_in = *addrlen; 1133 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1134 if (res == 0) { 1135 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1136 } 1137 return res; 1138} 1139#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1140#else 1141#define INIT_GETSOCKNAME 1142#endif 1143 1144#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1145static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1147 if (h->h_name) 1148 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1149 char **p = h->h_aliases; 1150 while (*p) { 1151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1152 ++p; 1153 } 1154 COMMON_INTERCEPTOR_WRITE_RANGE( 1155 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1156 p = h->h_addr_list; 1157 while (*p) { 1158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1159 ++p; 1160 } 1161 COMMON_INTERCEPTOR_WRITE_RANGE( 1162 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1163} 1164#endif 1165 1166#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1167INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1168 void *ctx; 1169 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1170 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1171 if (res) write_hostent(ctx, res); 1172 return res; 1173} 1174 1175INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1176 int type) { 1177 void *ctx; 1178 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1179 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1180 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1181 if (res) write_hostent(ctx, res); 1182 return res; 1183} 1184 1185INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 1186 void *ctx; 1187 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 1188 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 1189 if (res) write_hostent(ctx, res); 1190 return res; 1191} 1192 1193INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1194 void *ctx; 1195 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1196 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1197 if (res) write_hostent(ctx, res); 1198 return res; 1199} 1200#define INIT_GETHOSTBYNAME \ 1201 INTERCEPT_FUNCTION(gethostent); \ 1202 INTERCEPT_FUNCTION(gethostbyaddr); \ 1203 INTERCEPT_FUNCTION(gethostbyname); \ 1204 INTERCEPT_FUNCTION(gethostbyname2); 1205#else 1206#define INIT_GETHOSTBYNAME 1207#endif 1208 1209#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1210INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1211 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1212 void *ctx; 1213 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1214 h_errnop); 1215 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1216 if (res == 0) { 1217 if (result) { 1218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1219 if (*result) write_hostent(ctx, *result); 1220 } 1221 if (h_errnop) 1222 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1223 } 1224 return res; 1225} 1226 1227INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1228 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1229 __sanitizer_hostent **result, int *h_errnop) { 1230 void *ctx; 1231 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1232 buflen, result, h_errnop); 1233 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1234 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1235 h_errnop); 1236 if (res == 0) { 1237 if (result) { 1238 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1239 if (*result) write_hostent(ctx, *result); 1240 } 1241 if (h_errnop) 1242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1243 } 1244 return res; 1245} 1246 1247INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1248 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1249 int *h_errnop) { 1250 void *ctx; 1251 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1252 h_errnop); 1253 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1254 if (res == 0) { 1255 if (result) { 1256 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1257 if (*result) write_hostent(ctx, *result); 1258 } 1259 if (h_errnop) 1260 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1261 } 1262 return res; 1263} 1264 1265INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1266 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1267 __sanitizer_hostent **result, int *h_errnop) { 1268 void *ctx; 1269 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1270 result, h_errnop); 1271 int res = 1272 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1273 if (res == 0) { 1274 if (result) { 1275 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1276 if (*result) write_hostent(ctx, *result); 1277 } 1278 if (h_errnop) 1279 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1280 } 1281 return res; 1282} 1283#define INIT_GETHOSTBYNAME_R \ 1284 INTERCEPT_FUNCTION(gethostent_r); \ 1285 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1286 INTERCEPT_FUNCTION(gethostbyname_r); \ 1287 INTERCEPT_FUNCTION(gethostbyname2_r); 1288#else 1289#define INIT_GETHOSTBYNAME_R 1290#endif 1291 1292#if SANITIZER_INTERCEPT_GETSOCKOPT 1293INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1294 int *optlen) { 1295 void *ctx; 1296 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1297 optlen); 1298 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1299 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1300 if (res == 0) 1301 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1302 return res; 1303} 1304#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1305#else 1306#define INIT_GETSOCKOPT 1307#endif 1308 1309#if SANITIZER_INTERCEPT_ACCEPT 1310INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1311 void *ctx; 1312 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1313 unsigned addrlen0; 1314 if (addrlen) { 1315 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1316 addrlen0 = *addrlen; 1317 } 1318 int fd2 = REAL(accept)(fd, addr, addrlen); 1319 if (fd2 >= 0) { 1320 if (fd >= 0) 1321 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1322 if (addr && addrlen) 1323 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1324 } 1325 return fd2; 1326} 1327#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1328#else 1329#define INIT_ACCEPT 1330#endif 1331 1332#if SANITIZER_INTERCEPT_ACCEPT4 1333INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1334 void *ctx; 1335 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1336 unsigned addrlen0; 1337 if (addrlen) { 1338 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1339 addrlen0 = *addrlen; 1340 } 1341 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1342 if (fd2 >= 0) { 1343 if (fd >= 0) 1344 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1345 if (addr && addrlen) 1346 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1347 } 1348 return fd2; 1349} 1350#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1351#else 1352#define INIT_ACCEPT4 1353#endif 1354 1355#if SANITIZER_INTERCEPT_MODF 1356INTERCEPTOR(double, modf, double x, double *iptr) { 1357 void *ctx; 1358 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1359 double res = REAL(modf)(x, iptr); 1360 if (iptr) { 1361 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1362 } 1363 return res; 1364} 1365INTERCEPTOR(float, modff, float x, float *iptr) { 1366 void *ctx; 1367 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1368 float res = REAL(modff)(x, iptr); 1369 if (iptr) { 1370 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1371 } 1372 return res; 1373} 1374INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1375 void *ctx; 1376 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1377 long double res = REAL(modfl)(x, iptr); 1378 if (iptr) { 1379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1380 } 1381 return res; 1382} 1383#define INIT_MODF \ 1384 INTERCEPT_FUNCTION(modf); \ 1385 INTERCEPT_FUNCTION(modff); \ 1386 INTERCEPT_FUNCTION(modfl); 1387#else 1388#define INIT_MODF 1389#endif 1390 1391#if SANITIZER_INTERCEPT_RECVMSG 1392static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1393 SSIZE_T maxlen) { 1394 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1395 if (msg->msg_name) 1396 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1397 REAL(strlen)((char *)msg->msg_name) + 1); 1398 if (msg->msg_iov) 1399 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1400 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1401 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1402 if (msg->msg_control) 1403 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1404} 1405 1406INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1407 int flags) { 1408 void *ctx; 1409 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1410 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1411 if (res >= 0) { 1412 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1413 if (msg) write_msghdr(ctx, msg, res); 1414 } 1415 return res; 1416} 1417#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1418#else 1419#define INIT_RECVMSG 1420#endif 1421 1422#if SANITIZER_INTERCEPT_GETPEERNAME 1423INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1424 void *ctx; 1425 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1426 unsigned addr_sz; 1427 if (addrlen) addr_sz = *addrlen; 1428 int res = REAL(getpeername)(sockfd, addr, addrlen); 1429 if (!res && addr && addrlen) 1430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1431 return res; 1432} 1433#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1434#else 1435#define INIT_GETPEERNAME 1436#endif 1437 1438#if SANITIZER_INTERCEPT_SYSINFO 1439INTERCEPTOR(int, sysinfo, void *info) { 1440 void *ctx; 1441 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1442 int res = REAL(sysinfo)(info); 1443 if (!res && info) 1444 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1445 return res; 1446} 1447#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1448#else 1449#define INIT_SYSINFO 1450#endif 1451 1452#if SANITIZER_INTERCEPT_READDIR 1453INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1454 void *ctx; 1455 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1456 __sanitizer_dirent *res = REAL(readdir)(dirp); 1457 if (res) 1458 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1459 return res; 1460} 1461 1462INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1463 __sanitizer_dirent **result) { 1464 void *ctx; 1465 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1466 int res = REAL(readdir_r)(dirp, entry, result); 1467 if (!res) { 1468 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1469 if (*result) 1470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1471 } 1472 return res; 1473} 1474 1475#define INIT_READDIR \ 1476 INTERCEPT_FUNCTION(readdir); \ 1477 INTERCEPT_FUNCTION(readdir_r); 1478#else 1479#define INIT_READDIR 1480#endif 1481 1482#if SANITIZER_INTERCEPT_READDIR64 1483INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1484 void *ctx; 1485 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1486 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1487 if (res) 1488 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1489 return res; 1490} 1491 1492INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1493 __sanitizer_dirent64 **result) { 1494 void *ctx; 1495 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1496 int res = REAL(readdir64_r)(dirp, entry, result); 1497 if (!res) { 1498 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1499 if (*result) 1500 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1501 } 1502 return res; 1503} 1504#define INIT_READDIR64 \ 1505 INTERCEPT_FUNCTION(readdir64); \ 1506 INTERCEPT_FUNCTION(readdir64_r); 1507#else 1508#define INIT_READDIR64 1509#endif 1510 1511#if SANITIZER_INTERCEPT_PTRACE 1512INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1513 void *ctx; 1514 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1515 1516 if (data) { 1517 if (request == ptrace_setregs) 1518 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1519 else if (request == ptrace_setfpregs) 1520 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1521 else if (request == ptrace_setfpxregs) 1522 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1523 else if (request == ptrace_setsiginfo) 1524 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1525 else if (request == ptrace_setregset) { 1526 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1527 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1528 } 1529 } 1530 1531 uptr res = REAL(ptrace)(request, pid, addr, data); 1532 1533 if (!res && data) { 1534 // Note that PEEK* requests assing different meaning to the return value. 1535 // This function does not handle them (nor does it need to). 1536 if (request == ptrace_getregs) 1537 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1538 else if (request == ptrace_getfpregs) 1539 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1540 else if (request == ptrace_getfpxregs) 1541 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1542 else if (request == ptrace_getsiginfo) 1543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1544 else if (request == ptrace_getregset) { 1545 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1547 } 1548 } 1549 return res; 1550} 1551 1552#define INIT_PTRACE \ 1553 INTERCEPT_FUNCTION(ptrace); 1554#else 1555#define INIT_PTRACE 1556#endif 1557 1558#if SANITIZER_INTERCEPT_SETLOCALE 1559INTERCEPTOR(char *, setlocale, int category, char *locale) { 1560 void *ctx; 1561 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1562 if (locale) 1563 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1564 char *res = REAL(setlocale)(category, locale); 1565 if (res) 1566 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1567 return res; 1568} 1569 1570#define INIT_SETLOCALE \ 1571 INTERCEPT_FUNCTION(setlocale); 1572#else 1573#define INIT_SETLOCALE 1574#endif 1575 1576#if SANITIZER_INTERCEPT_GETCWD 1577INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1578 void *ctx; 1579 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1580 char *res = REAL(getcwd)(buf, size); 1581 if (res) 1582 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1583 return res; 1584} 1585#define INIT_GETCWD \ 1586 INTERCEPT_FUNCTION(getcwd); 1587#else 1588#define INIT_GETCWD 1589#endif 1590 1591#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1592INTERCEPTOR(char *, get_current_dir_name, int fake) { 1593 void *ctx; 1594 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 1595 char *res = REAL(get_current_dir_name)(fake); 1596 if (res) 1597 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1598 return res; 1599} 1600 1601#define INIT_GET_CURRENT_DIR_NAME \ 1602 INTERCEPT_FUNCTION(get_current_dir_name); 1603#else 1604#define INIT_GET_CURRENT_DIR_NAME 1605#endif 1606 1607#if SANITIZER_INTERCEPT_STRTOIMAX 1608INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1609 void *ctx; 1610 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1611 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1612 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1613 return res; 1614} 1615 1616INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1617 void *ctx; 1618 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1619 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1620 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1621 return res; 1622} 1623 1624#define INIT_STRTOIMAX \ 1625 INTERCEPT_FUNCTION(strtoimax); \ 1626 INTERCEPT_FUNCTION(strtoumax); 1627#else 1628#define INIT_STRTOIMAX 1629#endif 1630 1631#if SANITIZER_INTERCEPT_MBSTOWCS 1632INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1633 void *ctx; 1634 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1635 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1636 if (res != (SIZE_T) - 1 && dest) { 1637 SIZE_T write_cnt = res + (res < len); 1638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1639 } 1640 return res; 1641} 1642 1643INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1644 void *ps) { 1645 void *ctx; 1646 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1647 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1648 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1649 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1650 if (res != (SIZE_T)(-1) && dest && src) { 1651 // This function, and several others, may or may not write the terminating 1652 // \0 character. They write it iff they clear *src. 1653 SIZE_T write_cnt = res + !*src; 1654 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1655 } 1656 return res; 1657} 1658 1659#define INIT_MBSTOWCS \ 1660 INTERCEPT_FUNCTION(mbstowcs); \ 1661 INTERCEPT_FUNCTION(mbsrtowcs); 1662#else 1663#define INIT_MBSTOWCS 1664#endif 1665 1666#if SANITIZER_INTERCEPT_MBSNRTOWCS 1667INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1668 SIZE_T len, void *ps) { 1669 void *ctx; 1670 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1671 if (src) { 1672 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1673 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1674 } 1675 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1676 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1677 if (res != (SIZE_T)(-1) && dest && src) { 1678 SIZE_T write_cnt = res + !*src; 1679 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1680 } 1681 return res; 1682} 1683 1684#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1685#else 1686#define INIT_MBSNRTOWCS 1687#endif 1688 1689#if SANITIZER_INTERCEPT_WCSTOMBS 1690INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1691 void *ctx; 1692 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1693 SIZE_T res = REAL(wcstombs)(dest, src, len); 1694 if (res != (SIZE_T) - 1 && dest) { 1695 SIZE_T write_cnt = res + (res < len); 1696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1697 } 1698 return res; 1699} 1700 1701INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1702 void *ps) { 1703 void *ctx; 1704 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1705 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1706 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1707 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1708 if (res != (SIZE_T) - 1 && dest && src) { 1709 SIZE_T write_cnt = res + !*src; 1710 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1711 } 1712 return res; 1713} 1714 1715#define INIT_WCSTOMBS \ 1716 INTERCEPT_FUNCTION(wcstombs); \ 1717 INTERCEPT_FUNCTION(wcsrtombs); 1718#else 1719#define INIT_WCSTOMBS 1720#endif 1721 1722#if SANITIZER_INTERCEPT_WCSNRTOMBS 1723INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1724 SIZE_T len, void *ps) { 1725 void *ctx; 1726 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1727 if (src) { 1728 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1729 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1730 } 1731 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1732 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1733 if (res != (SIZE_T) - 1 && dest && src) { 1734 SIZE_T write_cnt = res + !*src; 1735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1736 } 1737 return res; 1738} 1739 1740#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1741#else 1742#define INIT_WCSNRTOMBS 1743#endif 1744 1745 1746#if SANITIZER_INTERCEPT_TCGETATTR 1747INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1748 void *ctx; 1749 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1750 int res = REAL(tcgetattr)(fd, termios_p); 1751 if (!res && termios_p) 1752 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1753 return res; 1754} 1755 1756#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1757#else 1758#define INIT_TCGETATTR 1759#endif 1760 1761 1762#if SANITIZER_INTERCEPT_REALPATH 1763INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1764 void *ctx; 1765 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1766 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1767 1768 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1769 // version of a versioned symbol. For realpath(), this gives us something 1770 // (called __old_realpath) that does not handle NULL in the second argument. 1771 // Handle it as part of the interceptor. 1772 char *allocated_path = 0; 1773 if (!resolved_path) 1774 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1775 1776 char *res = REAL(realpath)(path, resolved_path); 1777 if (allocated_path && !res) 1778 WRAP(free)(allocated_path); 1779 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1780 return res; 1781} 1782#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1783#else 1784#define INIT_REALPATH 1785#endif 1786 1787#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1788INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1789 void *ctx; 1790 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1791 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1792 char *res = REAL(canonicalize_file_name)(path); 1793 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1794 return res; 1795} 1796#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1797#else 1798#define INIT_CANONICALIZE_FILE_NAME 1799#endif 1800 1801#if SANITIZER_INTERCEPT_CONFSTR 1802INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1803 void *ctx; 1804 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1805 SIZE_T res = REAL(confstr)(name, buf, len); 1806 if (buf && res) 1807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1808 return res; 1809} 1810#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1811#else 1812#define INIT_CONFSTR 1813#endif 1814 1815#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1816INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1817 void *ctx; 1818 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1819 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1820 if (mask && !res) 1821 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1822 return res; 1823} 1824#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1825#else 1826#define INIT_SCHED_GETAFFINITY 1827#endif 1828 1829#if SANITIZER_INTERCEPT_STRERROR 1830INTERCEPTOR(char *, strerror, int errnum) { 1831 void *ctx; 1832 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1833 char *res = REAL(strerror)(errnum); 1834 if (res) 1835 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1836 return res; 1837} 1838#define INIT_STRERROR INTERCEPT_FUNCTION(strerror); 1839#else 1840#define INIT_STRERROR 1841#endif 1842 1843#if SANITIZER_INTERCEPT_STRERROR_R 1844INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1845 void *ctx; 1846 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1847 char *res = REAL(strerror_r)(errnum, buf, buflen); 1848 // There are 2 versions of strerror_r: 1849 // * POSIX version returns 0 on success, negative error code on failure, 1850 // writes message to buf. 1851 // * GNU version returns message pointer, which points to either buf or some 1852 // static storage. 1853 SIZE_T posix_res = (SIZE_T)res; 1854 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 1855 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1856 // At least on OSX, buf contents are valid even when the call fails. 1857 SIZE_T sz = internal_strnlen(buf, buflen); 1858 if (sz < buflen) ++sz; 1859 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1860 } else { 1861 // GNU version. 1862 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1863 } 1864 return res; 1865} 1866#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); 1867#else 1868#define INIT_STRERROR_R 1869#endif 1870 1871#if SANITIZER_INTERCEPT_SCANDIR 1872typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1873typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1874 const struct __sanitizer_dirent **); 1875 1876static THREADLOCAL void *scandir_ctx; 1877static THREADLOCAL scandir_filter_f scandir_filter; 1878static THREADLOCAL scandir_compar_f scandir_compar; 1879 1880static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1881 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1882 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1883 return scandir_filter(dir); 1884} 1885 1886static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1887 const struct __sanitizer_dirent **b) { 1888 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1889 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1890 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1891 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1892 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1893 return scandir_compar(a, b); 1894} 1895 1896INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1897 scandir_filter_f filter, scandir_compar_f compar) { 1898 void *ctx; 1899 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1900 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1901 CHECK_EQ(0, scandir_ctx); 1902 scandir_ctx = ctx; 1903 scandir_filter = filter; 1904 scandir_compar = compar; 1905 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1906 compar ? wrapped_scandir_compar : 0); 1907 scandir_ctx = 0; 1908 scandir_filter = 0; 1909 scandir_compar = 0; 1910 if (namelist && res > 0) { 1911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1912 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1913 for (int i = 0; i < res; ++i) 1914 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1915 (*namelist)[i]->d_reclen); 1916 } 1917 return res; 1918} 1919#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); 1920#else 1921#define INIT_SCANDIR 1922#endif 1923 1924#if SANITIZER_INTERCEPT_SCANDIR64 1925typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1926typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1927 const struct __sanitizer_dirent64 **); 1928 1929static THREADLOCAL void *scandir64_ctx; 1930static THREADLOCAL scandir64_filter_f scandir64_filter; 1931static THREADLOCAL scandir64_compar_f scandir64_compar; 1932 1933static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1934 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1935 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1936 return scandir64_filter(dir); 1937} 1938 1939static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1940 const struct __sanitizer_dirent64 **b) { 1941 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1942 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1943 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1944 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1945 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1946 return scandir64_compar(a, b); 1947} 1948 1949INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1950 scandir64_filter_f filter, scandir64_compar_f compar) { 1951 void *ctx; 1952 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1953 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1954 CHECK_EQ(0, scandir64_ctx); 1955 scandir64_ctx = ctx; 1956 scandir64_filter = filter; 1957 scandir64_compar = compar; 1958 int res = 1959 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1960 compar ? wrapped_scandir64_compar : 0); 1961 scandir64_ctx = 0; 1962 scandir64_filter = 0; 1963 scandir64_compar = 0; 1964 if (namelist && res > 0) { 1965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1966 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1967 for (int i = 0; i < res; ++i) 1968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1969 (*namelist)[i]->d_reclen); 1970 } 1971 return res; 1972} 1973#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); 1974#else 1975#define INIT_SCANDIR64 1976#endif 1977 1978#if SANITIZER_INTERCEPT_GETGROUPS 1979INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1980 void *ctx; 1981 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1982 int res = REAL(getgroups)(size, lst); 1983 if (res && lst) 1984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1985 return res; 1986} 1987#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); 1988#else 1989#define INIT_GETGROUPS 1990#endif 1991 1992#if SANITIZER_INTERCEPT_POLL 1993static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1994 __sanitizer_nfds_t nfds) { 1995 for (unsigned i = 0; i < nfds; ++i) { 1996 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1997 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1998 } 1999} 2000 2001static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 2002 __sanitizer_nfds_t nfds) { 2003 for (unsigned i = 0; i < nfds; ++i) 2004 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 2005 sizeof(fds[i].revents)); 2006} 2007 2008INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2009 int timeout) { 2010 void *ctx; 2011 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 2012 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2013 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 2014 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2015 return res; 2016} 2017#define INIT_POLL INTERCEPT_FUNCTION(poll); 2018#else 2019#define INIT_POLL 2020#endif 2021 2022#if SANITIZER_INTERCEPT_PPOLL 2023INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2024 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 2025 void *ctx; 2026 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 2027 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2028 if (timeout_ts) 2029 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2030 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2031 int res = 2032 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2033 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2034 return res; 2035} 2036#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); 2037#else 2038#define INIT_PPOLL 2039#endif 2040 2041#if SANITIZER_INTERCEPT_WORDEXP 2042INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2043 void *ctx; 2044 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2045 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2046 int res = REAL(wordexp)(s, p, flags); 2047 if (!res && p) { 2048 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2049 if (p->we_wordc) 2050 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2051 sizeof(*p->we_wordv) * p->we_wordc); 2052 for (uptr i = 0; i < p->we_wordc; ++i) { 2053 char *w = p->we_wordv[i]; 2054 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2055 } 2056 } 2057 return res; 2058} 2059#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp); 2060#else 2061#define INIT_WORDEXP 2062#endif 2063 2064#if SANITIZER_INTERCEPT_SIGWAIT 2065INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2066 void *ctx; 2067 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2068 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2069 int res = REAL(sigwait)(set, sig); 2070 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2071 return res; 2072} 2073#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait); 2074#else 2075#define INIT_SIGWAIT 2076#endif 2077 2078#if SANITIZER_INTERCEPT_SIGWAITINFO 2079INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2080 void *ctx; 2081 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2082 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2083 int res = REAL(sigwaitinfo)(set, info); 2084 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2085 return res; 2086} 2087#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo); 2088#else 2089#define INIT_SIGWAITINFO 2090#endif 2091 2092#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2093INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2094 void *timeout) { 2095 void *ctx; 2096 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2097 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2098 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2099 int res = REAL(sigtimedwait)(set, info, timeout); 2100 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2101 return res; 2102} 2103#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait); 2104#else 2105#define INIT_SIGTIMEDWAIT 2106#endif 2107 2108#if SANITIZER_INTERCEPT_SIGSETOPS 2109INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2110 void *ctx; 2111 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2112 int res = REAL(sigemptyset)(set); 2113 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2114 return res; 2115} 2116 2117INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2118 void *ctx; 2119 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2120 int res = REAL(sigfillset)(set); 2121 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2122 return res; 2123} 2124#define INIT_SIGSETOPS \ 2125 INTERCEPT_FUNCTION(sigemptyset); \ 2126 INTERCEPT_FUNCTION(sigfillset); 2127#else 2128#define INIT_SIGSETOPS 2129#endif 2130 2131#if SANITIZER_INTERCEPT_SIGPENDING 2132INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2133 void *ctx; 2134 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2135 int res = REAL(sigpending)(set); 2136 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2137 return res; 2138} 2139#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending); 2140#else 2141#define INIT_SIGPENDING 2142#endif 2143 2144#if SANITIZER_INTERCEPT_SIGPROCMASK 2145INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2146 __sanitizer_sigset_t *oldset) { 2147 void *ctx; 2148 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2149 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2150 int res = REAL(sigprocmask)(how, set, oldset); 2151 if (!res && oldset) 2152 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2153 return res; 2154} 2155#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask); 2156#else 2157#define INIT_SIGPROCMASK 2158#endif 2159 2160#if SANITIZER_INTERCEPT_BACKTRACE 2161INTERCEPTOR(int, backtrace, void **buffer, int size) { 2162 void *ctx; 2163 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2164 int res = REAL(backtrace)(buffer, size); 2165 if (res && buffer) 2166 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2167 return res; 2168} 2169 2170INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2171 void *ctx; 2172 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2173 if (buffer && size) 2174 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2175 char ** res = REAL(backtrace_symbols)(buffer, size); 2176 if (res && size) { 2177 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2178 for (int i = 0; i < size; ++i) 2179 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2180 } 2181 return res; 2182} 2183#define INIT_BACKTRACE \ 2184 INTERCEPT_FUNCTION(backtrace); \ 2185 INTERCEPT_FUNCTION(backtrace_symbols); 2186#else 2187#define INIT_BACKTRACE 2188#endif 2189 2190#if SANITIZER_INTERCEPT__EXIT 2191INTERCEPTOR(void, _exit, int status) { 2192 void *ctx; 2193 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 2194 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 2195 if (status == 0) 2196 status = status1; 2197 REAL(_exit)(status); 2198} 2199#define INIT__EXIT INTERCEPT_FUNCTION(_exit); 2200#else 2201#define INIT__EXIT 2202#endif 2203 2204#if SANITIZER_INTERCEPT_PHTREAD_MUTEX 2205INTERCEPTOR(int, pthread_mutex_lock, void *m) { 2206 void *ctx; 2207 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 2208 int res = REAL(pthread_mutex_lock)(m); 2209 if (res == 0) 2210 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2211 return res; 2212} 2213 2214INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 2215 void *ctx; 2216 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 2217 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2218 return REAL(pthread_mutex_unlock)(m); 2219} 2220 2221#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock) 2222#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock) 2223#else 2224#define INIT_PTHREAD_MUTEX_LOCK 2225#define INIT_PTHREAD_MUTEX_UNLOCK 2226#endif 2227 2228#if SANITIZER_INTERCEPT_PTHREAD_COND 2229INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 2230 void *ctx; 2231 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); 2232 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2233 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2234 int res = REAL(pthread_cond_wait)(c, m); 2235 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2236 return res; 2237} 2238 2239INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 2240 void *ctx; 2241 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); 2242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); 2243 return REAL(pthread_cond_init)(c, a); 2244} 2245 2246#define INIT_PTHREAD_COND_WAIT \ 2247 INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2) 2248#define INIT_PTHREAD_COND_INIT \ 2249 INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2) 2250#else 2251#define INIT_PTHREAD_COND_WAIT 2252#define INIT_PTHREAD_COND_INIT 2253#endif 2254 2255#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 2256 INIT_STRCMP; \ 2257 INIT_STRNCMP; \ 2258 INIT_STRCASECMP; \ 2259 INIT_STRNCASECMP; \ 2260 INIT_READ; \ 2261 INIT_PREAD; \ 2262 INIT_PREAD64; \ 2263 INIT_READV; \ 2264 INIT_PREADV; \ 2265 INIT_PREADV64; \ 2266 INIT_WRITE; \ 2267 INIT_PWRITE; \ 2268 INIT_PWRITE64; \ 2269 INIT_WRITEV; \ 2270 INIT_PWRITEV; \ 2271 INIT_PWRITEV64; \ 2272 INIT_PRCTL; \ 2273 INIT_LOCALTIME_AND_FRIENDS; \ 2274 INIT_SCANF; \ 2275 INIT_ISOC99_SCANF; \ 2276 INIT_FREXP; \ 2277 INIT_FREXPF_FREXPL; \ 2278 INIT_GETPWNAM_AND_FRIENDS; \ 2279 INIT_GETPWNAM_R_AND_FRIENDS; \ 2280 INIT_CLOCK_GETTIME; \ 2281 INIT_GETITIMER; \ 2282 INIT_TIME; \ 2283 INIT_GLOB; \ 2284 INIT_WAIT; \ 2285 INIT_INET; \ 2286 INIT_PTHREAD_GETSCHEDPARAM; \ 2287 INIT_GETADDRINFO; \ 2288 INIT_GETNAMEINFO; \ 2289 INIT_GETSOCKNAME; \ 2290 INIT_GETHOSTBYNAME; \ 2291 INIT_GETHOSTBYNAME_R; \ 2292 INIT_GETSOCKOPT; \ 2293 INIT_ACCEPT; \ 2294 INIT_ACCEPT4; \ 2295 INIT_MODF; \ 2296 INIT_RECVMSG; \ 2297 INIT_GETPEERNAME; \ 2298 INIT_IOCTL; \ 2299 INIT_INET_ATON; \ 2300 INIT_SYSINFO; \ 2301 INIT_READDIR; \ 2302 INIT_READDIR64; \ 2303 INIT_PTRACE; \ 2304 INIT_SETLOCALE; \ 2305 INIT_GETCWD; \ 2306 INIT_GET_CURRENT_DIR_NAME; \ 2307 INIT_STRTOIMAX; \ 2308 INIT_MBSTOWCS; \ 2309 INIT_MBSNRTOWCS; \ 2310 INIT_WCSTOMBS; \ 2311 INIT_WCSNRTOMBS; \ 2312 INIT_TCGETATTR; \ 2313 INIT_REALPATH; \ 2314 INIT_CANONICALIZE_FILE_NAME; \ 2315 INIT_CONFSTR; \ 2316 INIT_SCHED_GETAFFINITY; \ 2317 INIT_STRERROR; \ 2318 INIT_STRERROR_R; \ 2319 INIT_SCANDIR; \ 2320 INIT_SCANDIR64; \ 2321 INIT_GETGROUPS; \ 2322 INIT_POLL; \ 2323 INIT_PPOLL; \ 2324 INIT_WORDEXP; \ 2325 INIT_SIGWAIT; \ 2326 INIT_SIGWAITINFO; \ 2327 INIT_SIGTIMEDWAIT; \ 2328 INIT_SIGSETOPS; \ 2329 INIT_SIGPENDING; \ 2330 INIT_SIGPROCMASK; \ 2331 INIT_BACKTRACE; \ 2332 INIT__EXIT; \ 2333 INIT_PTHREAD_MUTEX_LOCK; \ 2334 INIT_PTHREAD_MUTEX_UNLOCK; \ 2335 INIT_PTHREAD_COND_WAIT; \ 2336 INIT_PTHREAD_COND_INIT; \ 2337/**/ 2338