sanitizer_common_interceptors.inc revision e236dbb5e558b174609d2d13e80685d488c129d8
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//===----------------------------------------------------------------------===// 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 && msg->msg_namelen) 1396 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 1397 if (msg->msg_iov && msg->msg_iovlen) 1398 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1399 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1400 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1401 if (msg->msg_control && msg->msg_controllen) 1402 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1403} 1404 1405INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1406 int flags) { 1407 void *ctx; 1408 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1409 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1410 if (res >= 0) { 1411 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1412 if (msg) write_msghdr(ctx, msg, res); 1413 } 1414 return res; 1415} 1416#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1417#else 1418#define INIT_RECVMSG 1419#endif 1420 1421#if SANITIZER_INTERCEPT_GETPEERNAME 1422INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1423 void *ctx; 1424 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1425 unsigned addr_sz; 1426 if (addrlen) addr_sz = *addrlen; 1427 int res = REAL(getpeername)(sockfd, addr, addrlen); 1428 if (!res && addr && addrlen) 1429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1430 return res; 1431} 1432#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1433#else 1434#define INIT_GETPEERNAME 1435#endif 1436 1437#if SANITIZER_INTERCEPT_SYSINFO 1438INTERCEPTOR(int, sysinfo, void *info) { 1439 void *ctx; 1440 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1441 int res = REAL(sysinfo)(info); 1442 if (!res && info) 1443 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1444 return res; 1445} 1446#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1447#else 1448#define INIT_SYSINFO 1449#endif 1450 1451#if SANITIZER_INTERCEPT_READDIR 1452INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1453 void *ctx; 1454 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1455 __sanitizer_dirent *res = REAL(readdir)(dirp); 1456 if (res) 1457 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1458 return res; 1459} 1460 1461INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1462 __sanitizer_dirent **result) { 1463 void *ctx; 1464 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1465 int res = REAL(readdir_r)(dirp, entry, result); 1466 if (!res) { 1467 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1468 if (*result) 1469 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1470 } 1471 return res; 1472} 1473 1474#define INIT_READDIR \ 1475 INTERCEPT_FUNCTION(readdir); \ 1476 INTERCEPT_FUNCTION(readdir_r); 1477#else 1478#define INIT_READDIR 1479#endif 1480 1481#if SANITIZER_INTERCEPT_READDIR64 1482INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1483 void *ctx; 1484 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1485 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1486 if (res) 1487 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1488 return res; 1489} 1490 1491INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1492 __sanitizer_dirent64 **result) { 1493 void *ctx; 1494 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1495 int res = REAL(readdir64_r)(dirp, entry, result); 1496 if (!res) { 1497 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1498 if (*result) 1499 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1500 } 1501 return res; 1502} 1503#define INIT_READDIR64 \ 1504 INTERCEPT_FUNCTION(readdir64); \ 1505 INTERCEPT_FUNCTION(readdir64_r); 1506#else 1507#define INIT_READDIR64 1508#endif 1509 1510#if SANITIZER_INTERCEPT_PTRACE 1511INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1512 void *ctx; 1513 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1514 1515 if (data) { 1516 if (request == ptrace_setregs) 1517 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1518 else if (request == ptrace_setfpregs) 1519 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1520 else if (request == ptrace_setfpxregs) 1521 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1522 else if (request == ptrace_setsiginfo) 1523 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1524 else if (request == ptrace_setregset) { 1525 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1526 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1527 } 1528 } 1529 1530 uptr res = REAL(ptrace)(request, pid, addr, data); 1531 1532 if (!res && data) { 1533 // Note that PEEK* requests assing different meaning to the return value. 1534 // This function does not handle them (nor does it need to). 1535 if (request == ptrace_getregs) 1536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1537 else if (request == ptrace_getfpregs) 1538 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1539 else if (request == ptrace_getfpxregs) 1540 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1541 else if (request == ptrace_getsiginfo) 1542 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1543 else if (request == ptrace_getregset) { 1544 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1545 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1546 } 1547 } 1548 return res; 1549} 1550 1551#define INIT_PTRACE \ 1552 INTERCEPT_FUNCTION(ptrace); 1553#else 1554#define INIT_PTRACE 1555#endif 1556 1557#if SANITIZER_INTERCEPT_SETLOCALE 1558INTERCEPTOR(char *, setlocale, int category, char *locale) { 1559 void *ctx; 1560 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1561 if (locale) 1562 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1563 char *res = REAL(setlocale)(category, locale); 1564 if (res) 1565 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1566 return res; 1567} 1568 1569#define INIT_SETLOCALE \ 1570 INTERCEPT_FUNCTION(setlocale); 1571#else 1572#define INIT_SETLOCALE 1573#endif 1574 1575#if SANITIZER_INTERCEPT_GETCWD 1576INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1577 void *ctx; 1578 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1579 char *res = REAL(getcwd)(buf, size); 1580 if (res) 1581 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1582 return res; 1583} 1584#define INIT_GETCWD \ 1585 INTERCEPT_FUNCTION(getcwd); 1586#else 1587#define INIT_GETCWD 1588#endif 1589 1590#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1591INTERCEPTOR(char *, get_current_dir_name, int fake) { 1592 void *ctx; 1593 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 1594 char *res = REAL(get_current_dir_name)(fake); 1595 if (res) 1596 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1597 return res; 1598} 1599 1600#define INIT_GET_CURRENT_DIR_NAME \ 1601 INTERCEPT_FUNCTION(get_current_dir_name); 1602#else 1603#define INIT_GET_CURRENT_DIR_NAME 1604#endif 1605 1606#if SANITIZER_INTERCEPT_STRTOIMAX 1607INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1608 void *ctx; 1609 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1610 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1611 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1612 return res; 1613} 1614 1615INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1616 void *ctx; 1617 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1618 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1619 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1620 return res; 1621} 1622 1623#define INIT_STRTOIMAX \ 1624 INTERCEPT_FUNCTION(strtoimax); \ 1625 INTERCEPT_FUNCTION(strtoumax); 1626#else 1627#define INIT_STRTOIMAX 1628#endif 1629 1630#if SANITIZER_INTERCEPT_MBSTOWCS 1631INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1632 void *ctx; 1633 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1634 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1635 if (res != (SIZE_T) - 1 && dest) { 1636 SIZE_T write_cnt = res + (res < len); 1637 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1638 } 1639 return res; 1640} 1641 1642INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1643 void *ps) { 1644 void *ctx; 1645 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1646 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1647 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1648 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1649 if (res != (SIZE_T)(-1) && dest && src) { 1650 // This function, and several others, may or may not write the terminating 1651 // \0 character. They write it iff they clear *src. 1652 SIZE_T write_cnt = res + !*src; 1653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1654 } 1655 return res; 1656} 1657 1658#define INIT_MBSTOWCS \ 1659 INTERCEPT_FUNCTION(mbstowcs); \ 1660 INTERCEPT_FUNCTION(mbsrtowcs); 1661#else 1662#define INIT_MBSTOWCS 1663#endif 1664 1665#if SANITIZER_INTERCEPT_MBSNRTOWCS 1666INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1667 SIZE_T len, void *ps) { 1668 void *ctx; 1669 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1670 if (src) { 1671 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1672 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1673 } 1674 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1675 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1676 if (res != (SIZE_T)(-1) && dest && src) { 1677 SIZE_T write_cnt = res + !*src; 1678 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1679 } 1680 return res; 1681} 1682 1683#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1684#else 1685#define INIT_MBSNRTOWCS 1686#endif 1687 1688#if SANITIZER_INTERCEPT_WCSTOMBS 1689INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1690 void *ctx; 1691 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1692 SIZE_T res = REAL(wcstombs)(dest, src, len); 1693 if (res != (SIZE_T) - 1 && dest) { 1694 SIZE_T write_cnt = res + (res < len); 1695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1696 } 1697 return res; 1698} 1699 1700INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1701 void *ps) { 1702 void *ctx; 1703 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1704 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1705 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1706 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1707 if (res != (SIZE_T) - 1 && dest && src) { 1708 SIZE_T write_cnt = res + !*src; 1709 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1710 } 1711 return res; 1712} 1713 1714#define INIT_WCSTOMBS \ 1715 INTERCEPT_FUNCTION(wcstombs); \ 1716 INTERCEPT_FUNCTION(wcsrtombs); 1717#else 1718#define INIT_WCSTOMBS 1719#endif 1720 1721#if SANITIZER_INTERCEPT_WCSNRTOMBS 1722INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1723 SIZE_T len, void *ps) { 1724 void *ctx; 1725 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1726 if (src) { 1727 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1728 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1729 } 1730 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1731 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1732 if (res != (SIZE_T) - 1 && dest && src) { 1733 SIZE_T write_cnt = res + !*src; 1734 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1735 } 1736 return res; 1737} 1738 1739#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1740#else 1741#define INIT_WCSNRTOMBS 1742#endif 1743 1744 1745#if SANITIZER_INTERCEPT_TCGETATTR 1746INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1747 void *ctx; 1748 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1749 int res = REAL(tcgetattr)(fd, termios_p); 1750 if (!res && termios_p) 1751 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1752 return res; 1753} 1754 1755#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1756#else 1757#define INIT_TCGETATTR 1758#endif 1759 1760 1761#if SANITIZER_INTERCEPT_REALPATH 1762INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1763 void *ctx; 1764 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1765 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1766 1767 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1768 // version of a versioned symbol. For realpath(), this gives us something 1769 // (called __old_realpath) that does not handle NULL in the second argument. 1770 // Handle it as part of the interceptor. 1771 char *allocated_path = 0; 1772 if (!resolved_path) 1773 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1774 1775 char *res = REAL(realpath)(path, resolved_path); 1776 if (allocated_path && !res) 1777 WRAP(free)(allocated_path); 1778 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1779 return res; 1780} 1781#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1782#else 1783#define INIT_REALPATH 1784#endif 1785 1786#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1787INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1788 void *ctx; 1789 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1790 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1791 char *res = REAL(canonicalize_file_name)(path); 1792 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1793 return res; 1794} 1795#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1796#else 1797#define INIT_CANONICALIZE_FILE_NAME 1798#endif 1799 1800#if SANITIZER_INTERCEPT_CONFSTR 1801INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1802 void *ctx; 1803 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1804 SIZE_T res = REAL(confstr)(name, buf, len); 1805 if (buf && res) 1806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1807 return res; 1808} 1809#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1810#else 1811#define INIT_CONFSTR 1812#endif 1813 1814#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1815INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1816 void *ctx; 1817 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1818 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1819 if (mask && !res) 1820 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1821 return res; 1822} 1823#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1824#else 1825#define INIT_SCHED_GETAFFINITY 1826#endif 1827 1828#if SANITIZER_INTERCEPT_STRERROR 1829INTERCEPTOR(char *, strerror, int errnum) { 1830 void *ctx; 1831 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1832 char *res = REAL(strerror)(errnum); 1833 if (res) 1834 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1835 return res; 1836} 1837#define INIT_STRERROR INTERCEPT_FUNCTION(strerror); 1838#else 1839#define INIT_STRERROR 1840#endif 1841 1842#if SANITIZER_INTERCEPT_STRERROR_R 1843INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1844 void *ctx; 1845 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1846 char *res = REAL(strerror_r)(errnum, buf, buflen); 1847 // There are 2 versions of strerror_r: 1848 // * POSIX version returns 0 on success, negative error code on failure, 1849 // writes message to buf. 1850 // * GNU version returns message pointer, which points to either buf or some 1851 // static storage. 1852 SIZE_T posix_res = (SIZE_T)res; 1853 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 1854 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1855 // At least on OSX, buf contents are valid even when the call fails. 1856 SIZE_T sz = internal_strnlen(buf, buflen); 1857 if (sz < buflen) ++sz; 1858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1859 } else { 1860 // GNU version. 1861 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1862 } 1863 return res; 1864} 1865#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); 1866#else 1867#define INIT_STRERROR_R 1868#endif 1869 1870#if SANITIZER_INTERCEPT_SCANDIR 1871typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1872typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1873 const struct __sanitizer_dirent **); 1874 1875static THREADLOCAL void *scandir_ctx; 1876static THREADLOCAL scandir_filter_f scandir_filter; 1877static THREADLOCAL scandir_compar_f scandir_compar; 1878 1879static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1880 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1881 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1882 return scandir_filter(dir); 1883} 1884 1885static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1886 const struct __sanitizer_dirent **b) { 1887 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1888 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1889 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1890 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1891 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1892 return scandir_compar(a, b); 1893} 1894 1895INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1896 scandir_filter_f filter, scandir_compar_f compar) { 1897 void *ctx; 1898 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1899 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1900 CHECK_EQ(0, scandir_ctx); 1901 scandir_ctx = ctx; 1902 scandir_filter = filter; 1903 scandir_compar = compar; 1904 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1905 compar ? wrapped_scandir_compar : 0); 1906 scandir_ctx = 0; 1907 scandir_filter = 0; 1908 scandir_compar = 0; 1909 if (namelist && res > 0) { 1910 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1912 for (int i = 0; i < res; ++i) 1913 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1914 (*namelist)[i]->d_reclen); 1915 } 1916 return res; 1917} 1918#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); 1919#else 1920#define INIT_SCANDIR 1921#endif 1922 1923#if SANITIZER_INTERCEPT_SCANDIR64 1924typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1925typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1926 const struct __sanitizer_dirent64 **); 1927 1928static THREADLOCAL void *scandir64_ctx; 1929static THREADLOCAL scandir64_filter_f scandir64_filter; 1930static THREADLOCAL scandir64_compar_f scandir64_compar; 1931 1932static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1933 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1934 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1935 return scandir64_filter(dir); 1936} 1937 1938static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1939 const struct __sanitizer_dirent64 **b) { 1940 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1941 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1942 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1943 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1944 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1945 return scandir64_compar(a, b); 1946} 1947 1948INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1949 scandir64_filter_f filter, scandir64_compar_f compar) { 1950 void *ctx; 1951 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1952 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1953 CHECK_EQ(0, scandir64_ctx); 1954 scandir64_ctx = ctx; 1955 scandir64_filter = filter; 1956 scandir64_compar = compar; 1957 int res = 1958 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1959 compar ? wrapped_scandir64_compar : 0); 1960 scandir64_ctx = 0; 1961 scandir64_filter = 0; 1962 scandir64_compar = 0; 1963 if (namelist && res > 0) { 1964 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1966 for (int i = 0; i < res; ++i) 1967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1968 (*namelist)[i]->d_reclen); 1969 } 1970 return res; 1971} 1972#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); 1973#else 1974#define INIT_SCANDIR64 1975#endif 1976 1977#if SANITIZER_INTERCEPT_GETGROUPS 1978INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1979 void *ctx; 1980 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1981 int res = REAL(getgroups)(size, lst); 1982 if (res && lst) 1983 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1984 return res; 1985} 1986#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); 1987#else 1988#define INIT_GETGROUPS 1989#endif 1990 1991#if SANITIZER_INTERCEPT_POLL 1992static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1993 __sanitizer_nfds_t nfds) { 1994 for (unsigned i = 0; i < nfds; ++i) { 1995 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1996 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1997 } 1998} 1999 2000static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 2001 __sanitizer_nfds_t nfds) { 2002 for (unsigned i = 0; i < nfds; ++i) 2003 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 2004 sizeof(fds[i].revents)); 2005} 2006 2007INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2008 int timeout) { 2009 void *ctx; 2010 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 2011 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2012 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 2013 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2014 return res; 2015} 2016#define INIT_POLL INTERCEPT_FUNCTION(poll); 2017#else 2018#define INIT_POLL 2019#endif 2020 2021#if SANITIZER_INTERCEPT_PPOLL 2022INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2023 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 2024 void *ctx; 2025 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 2026 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2027 if (timeout_ts) 2028 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2029 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2030 int res = 2031 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2032 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2033 return res; 2034} 2035#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); 2036#else 2037#define INIT_PPOLL 2038#endif 2039 2040#if SANITIZER_INTERCEPT_WORDEXP 2041INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2042 void *ctx; 2043 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2044 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2045 int res = REAL(wordexp)(s, p, flags); 2046 if (!res && p) { 2047 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2048 if (p->we_wordc) 2049 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2050 sizeof(*p->we_wordv) * p->we_wordc); 2051 for (uptr i = 0; i < p->we_wordc; ++i) { 2052 char *w = p->we_wordv[i]; 2053 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2054 } 2055 } 2056 return res; 2057} 2058#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp); 2059#else 2060#define INIT_WORDEXP 2061#endif 2062 2063#if SANITIZER_INTERCEPT_SIGWAIT 2064INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2065 void *ctx; 2066 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2067 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2068 int res = REAL(sigwait)(set, sig); 2069 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2070 return res; 2071} 2072#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait); 2073#else 2074#define INIT_SIGWAIT 2075#endif 2076 2077#if SANITIZER_INTERCEPT_SIGWAITINFO 2078INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2079 void *ctx; 2080 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2081 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2082 int res = REAL(sigwaitinfo)(set, info); 2083 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2084 return res; 2085} 2086#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo); 2087#else 2088#define INIT_SIGWAITINFO 2089#endif 2090 2091#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2092INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2093 void *timeout) { 2094 void *ctx; 2095 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2096 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2097 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2098 int res = REAL(sigtimedwait)(set, info, timeout); 2099 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2100 return res; 2101} 2102#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait); 2103#else 2104#define INIT_SIGTIMEDWAIT 2105#endif 2106 2107#if SANITIZER_INTERCEPT_SIGSETOPS 2108INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2109 void *ctx; 2110 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2111 int res = REAL(sigemptyset)(set); 2112 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2113 return res; 2114} 2115 2116INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2117 void *ctx; 2118 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2119 int res = REAL(sigfillset)(set); 2120 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2121 return res; 2122} 2123#define INIT_SIGSETOPS \ 2124 INTERCEPT_FUNCTION(sigemptyset); \ 2125 INTERCEPT_FUNCTION(sigfillset); 2126#else 2127#define INIT_SIGSETOPS 2128#endif 2129 2130#if SANITIZER_INTERCEPT_SIGPENDING 2131INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2132 void *ctx; 2133 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2134 int res = REAL(sigpending)(set); 2135 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2136 return res; 2137} 2138#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending); 2139#else 2140#define INIT_SIGPENDING 2141#endif 2142 2143#if SANITIZER_INTERCEPT_SIGPROCMASK 2144INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2145 __sanitizer_sigset_t *oldset) { 2146 void *ctx; 2147 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2148 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2149 int res = REAL(sigprocmask)(how, set, oldset); 2150 if (!res && oldset) 2151 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2152 return res; 2153} 2154#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask); 2155#else 2156#define INIT_SIGPROCMASK 2157#endif 2158 2159#if SANITIZER_INTERCEPT_BACKTRACE 2160INTERCEPTOR(int, backtrace, void **buffer, int size) { 2161 void *ctx; 2162 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2163 int res = REAL(backtrace)(buffer, size); 2164 if (res && buffer) 2165 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2166 return res; 2167} 2168 2169INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2170 void *ctx; 2171 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2172 if (buffer && size) 2173 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2174 char ** res = REAL(backtrace_symbols)(buffer, size); 2175 if (res && size) { 2176 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2177 for (int i = 0; i < size; ++i) 2178 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2179 } 2180 return res; 2181} 2182#define INIT_BACKTRACE \ 2183 INTERCEPT_FUNCTION(backtrace); \ 2184 INTERCEPT_FUNCTION(backtrace_symbols); 2185#else 2186#define INIT_BACKTRACE 2187#endif 2188 2189#if SANITIZER_INTERCEPT__EXIT 2190INTERCEPTOR(void, _exit, int status) { 2191 void *ctx; 2192 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 2193 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 2194 if (status == 0) 2195 status = status1; 2196 REAL(_exit)(status); 2197} 2198#define INIT__EXIT INTERCEPT_FUNCTION(_exit); 2199#else 2200#define INIT__EXIT 2201#endif 2202 2203#if SANITIZER_INTERCEPT_PHTREAD_MUTEX 2204INTERCEPTOR(int, pthread_mutex_lock, void *m) { 2205 void *ctx; 2206 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 2207 int res = REAL(pthread_mutex_lock)(m); 2208 if (res == 0) 2209 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2210 return res; 2211} 2212 2213INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 2214 void *ctx; 2215 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 2216 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2217 return REAL(pthread_mutex_unlock)(m); 2218} 2219 2220#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock) 2221#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock) 2222#else 2223#define INIT_PTHREAD_MUTEX_LOCK 2224#define INIT_PTHREAD_MUTEX_UNLOCK 2225#endif 2226 2227#if SANITIZER_INTERCEPT_PTHREAD_COND 2228INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 2229 void *ctx; 2230 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); 2231 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2232 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2233 int res = REAL(pthread_cond_wait)(c, m); 2234 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2235 return res; 2236} 2237 2238INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 2239 void *ctx; 2240 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); 2241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); 2242 return REAL(pthread_cond_init)(c, a); 2243} 2244 2245INTERCEPTOR(int, pthread_cond_signal, void *c) { 2246 void *ctx; 2247 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c); 2248 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2249 return REAL(pthread_cond_signal)(c); 2250} 2251 2252INTERCEPTOR(int, pthread_cond_broadcast, void *c) { 2253 void *ctx; 2254 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c); 2255 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2256 return REAL(pthread_cond_broadcast)(c); 2257} 2258 2259#define INIT_PTHREAD_COND_WAIT \ 2260 INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2) 2261#define INIT_PTHREAD_COND_INIT \ 2262 INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2) 2263#define INIT_PTHREAD_COND_SIGNAL \ 2264 INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2) 2265#define INIT_PTHREAD_COND_BROADCAST \ 2266 INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2) 2267#else 2268#define INIT_PTHREAD_COND_WAIT 2269#define INIT_PTHREAD_COND_INIT 2270#define INIT_PTHREAD_COND_SIGNAL 2271#define INIT_PTHREAD_COND_BROADCAST 2272#endif 2273 2274#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 2275static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 2276 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 2277 if (mnt->mnt_fsname) 2278 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 2279 REAL(strlen)(mnt->mnt_fsname) + 1); 2280 if (mnt->mnt_dir) 2281 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 2282 REAL(strlen)(mnt->mnt_dir) + 1); 2283 if (mnt->mnt_type) 2284 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 2285 REAL(strlen)(mnt->mnt_type) + 1); 2286 if (mnt->mnt_opts) 2287 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 2288 REAL(strlen)(mnt->mnt_opts) + 1); 2289} 2290#endif 2291 2292#if SANITIZER_INTERCEPT_GETMNTENT 2293INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 2294 void *ctx; 2295 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 2296 __sanitizer_mntent *res = REAL(getmntent)(fp); 2297 if (res) write_mntent(ctx, res); 2298 return res; 2299} 2300#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent); 2301#else 2302#define INIT_GETMNTENT 2303#endif 2304 2305#if SANITIZER_INTERCEPT_GETMNTENT_R 2306INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 2307 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 2308 void *ctx; 2309 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 2310 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 2311 if (res) write_mntent(ctx, res); 2312 return res; 2313} 2314#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r); 2315#else 2316#define INIT_GETMNTENT_R 2317#endif 2318 2319#if SANITIZER_INTERCEPT_STATFS 2320INTERCEPTOR(int, statfs, char *path, void *buf) { 2321 void *ctx; 2322 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 2323 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2324 int res = REAL(statfs)(path, buf); 2325 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2326 return res; 2327} 2328INTERCEPTOR(int, fstatfs, int fd, void *buf) { 2329 void *ctx; 2330 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 2331 int res = REAL(fstatfs)(fd, buf); 2332 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2333 return res; 2334} 2335#define INIT_STATFS \ 2336 INTERCEPT_FUNCTION(statfs); \ 2337 INTERCEPT_FUNCTION(fstatfs); 2338#else 2339#define INIT_STATFS 2340#endif 2341 2342#if SANITIZER_INTERCEPT_STATFS64 2343INTERCEPTOR(int, statfs64, char *path, void *buf) { 2344 void *ctx; 2345 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 2346 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2347 int res = REAL(statfs64)(path, buf); 2348 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2349 return res; 2350} 2351INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 2352 void *ctx; 2353 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 2354 int res = REAL(fstatfs64)(fd, buf); 2355 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2356 return res; 2357} 2358#define INIT_STATFS64 \ 2359 INTERCEPT_FUNCTION(statfs64); \ 2360 INTERCEPT_FUNCTION(fstatfs64); 2361#else 2362#define INIT_STATFS64 2363#endif 2364 2365#if SANITIZER_INTERCEPT_STATVFS 2366INTERCEPTOR(int, statvfs, char *path, void *buf) { 2367 void *ctx; 2368 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 2369 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2370 int res = REAL(statvfs)(path, buf); 2371 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2372 return res; 2373} 2374INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 2375 void *ctx; 2376 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 2377 int res = REAL(fstatvfs)(fd, buf); 2378 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2379 return res; 2380} 2381#define INIT_STATVFS \ 2382 INTERCEPT_FUNCTION(statvfs); \ 2383 INTERCEPT_FUNCTION(fstatvfs); 2384#else 2385#define INIT_STATVFS 2386#endif 2387 2388#if SANITIZER_INTERCEPT_STATVFS64 2389INTERCEPTOR(int, statvfs64, char *path, void *buf) { 2390 void *ctx; 2391 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 2392 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2393 int res = REAL(statvfs64)(path, buf); 2394 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2395 return res; 2396} 2397INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 2398 void *ctx; 2399 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 2400 int res = REAL(fstatvfs64)(fd, buf); 2401 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2402 return res; 2403} 2404#define INIT_STATVFS64 \ 2405 INTERCEPT_FUNCTION(statvfs64); \ 2406 INTERCEPT_FUNCTION(fstatvfs64); 2407#else 2408#define INIT_STATVFS64 2409#endif 2410 2411#if SANITIZER_INTERCEPT_INITGROUPS 2412INTERCEPTOR(int, initgroups, char *user, u32 group) { 2413 void *ctx; 2414 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 2415 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 2416 int res = REAL(initgroups)(user, group); 2417 return res; 2418} 2419#define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups); 2420#else 2421#define INIT_INITGROUPS 2422#endif 2423 2424#if SANITIZER_INTERCEPT_ETHER 2425INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 2426 void *ctx; 2427 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 2428 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2429 char *res = REAL(ether_ntoa)(addr); 2430 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2431 return res; 2432} 2433INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 2434 void *ctx; 2435 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 2436 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2437 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 2438 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res)); 2439 return res; 2440} 2441INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 2442 void *ctx; 2443 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 2444 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2445 int res = REAL(ether_ntohost)(hostname, addr); 2446 if (!res && hostname) 2447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2448 return res; 2449} 2450INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 2451 void *ctx; 2452 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 2453 if (hostname) 2454 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2455 int res = REAL(ether_hostton)(hostname, addr); 2456 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2457 return res; 2458} 2459INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 2460 char *hostname) { 2461 void *ctx; 2462 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 2463 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 2464 int res = REAL(ether_line)(line, addr, hostname); 2465 if (!res) { 2466 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2467 if (hostname) 2468 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2469 } 2470 return res; 2471} 2472#define INIT_ETHER \ 2473 INTERCEPT_FUNCTION(ether_ntoa); \ 2474 INTERCEPT_FUNCTION(ether_aton); \ 2475 INTERCEPT_FUNCTION(ether_ntohost); \ 2476 INTERCEPT_FUNCTION(ether_hostton); \ 2477 INTERCEPT_FUNCTION(ether_line); 2478#else 2479#define INIT_ETHER 2480#endif 2481 2482#if SANITIZER_INTERCEPT_ETHER_R 2483INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 2484 void *ctx; 2485 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 2486 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2487 char *res = REAL(ether_ntoa_r)(addr, buf); 2488 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2489 return res; 2490} 2491INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 2492 __sanitizer_ether_addr *addr) { 2493 void *ctx; 2494 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 2495 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2496 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 2497 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 2498 return res; 2499} 2500#define INIT_ETHER_R \ 2501 INTERCEPT_FUNCTION(ether_ntoa_r); \ 2502 INTERCEPT_FUNCTION(ether_aton_r); 2503#else 2504#define INIT_ETHER_R 2505#endif 2506 2507#if SANITIZER_INTERCEPT_SHMCTL 2508INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 2509 void *ctx; 2510 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 2511 int res = REAL(shmctl)(shmid, cmd, buf); 2512 if (res >= 0) { 2513 unsigned sz = 0; 2514 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 2515 sz = struct_shmid_ds_sz; 2516 else if (cmd == shmctl_ipc_info) 2517 sz = struct_shminfo_sz; 2518 else if (cmd == shmctl_shm_info) 2519 sz = struct_shm_info_sz; 2520 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 2521 } 2522 return res; 2523} 2524#define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl); 2525#else 2526#define INIT_SHMCTL 2527#endif 2528 2529#if SANITIZER_INTERCEPT_RANDOM_R 2530INTERCEPTOR(int, random_r, void *buf, u32 *result) { 2531 void *ctx; 2532 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 2533 int res = REAL(random_r)(buf, result); 2534 if (!res && result) 2535 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2536 return res; 2537} 2538#define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r); 2539#else 2540#define INIT_RANDOM_R 2541#endif 2542 2543#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 2544 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED 2545#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 2546 INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \ 2547 void *ctx; \ 2548 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \ 2549 int res = REAL(pthread_attr_get##what)(attr, r); \ 2550 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 2551 return res; \ 2552 } 2553#endif 2554 2555#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 2556INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 2557INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 2558INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 2559INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 2560INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 2561INTERCEPTOR_PTHREAD_ATTR_GET(stackaddr, sizeof(void *)) 2562INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 2563INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 2564 void *ctx; 2565 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 2566 int res = REAL(pthread_attr_getstack)(attr, addr, size); 2567 if (!res) { 2568 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2569 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 2570 } 2571 return res; 2572} 2573 2574#define INIT_PTHREAD_ATTR_GET \ 2575 INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 2576 INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 2577 INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 2578 INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ 2579 INTERCEPT_FUNCTION(pthread_attr_getinheritsched); \ 2580 INTERCEPT_FUNCTION(pthread_attr_getscope); \ 2581 INTERCEPT_FUNCTION(pthread_attr_getstackaddr); \ 2582 INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 2583 INTERCEPT_FUNCTION(pthread_attr_getstack); \ 2584 INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 2585#else 2586#define INIT_PTHREAD_ATTR_GET 2587#endif 2588 2589#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 2590INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 2591 2592#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 2593 INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 2594#else 2595#define INIT_PTHREAD_ATTR_GETINHERITSCHED 2596#endif 2597 2598#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 2599INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 2600 void *cpuset) { 2601 void *ctx; 2602 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 2603 cpuset); 2604 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 2605 if (!res && cpusetsize && cpuset) 2606 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 2607 return res; 2608} 2609 2610#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 2611 INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 2612#else 2613#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 2614#endif 2615 2616#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 2617 INIT_STRCMP; \ 2618 INIT_STRNCMP; \ 2619 INIT_STRCASECMP; \ 2620 INIT_STRNCASECMP; \ 2621 INIT_READ; \ 2622 INIT_PREAD; \ 2623 INIT_PREAD64; \ 2624 INIT_READV; \ 2625 INIT_PREADV; \ 2626 INIT_PREADV64; \ 2627 INIT_WRITE; \ 2628 INIT_PWRITE; \ 2629 INIT_PWRITE64; \ 2630 INIT_WRITEV; \ 2631 INIT_PWRITEV; \ 2632 INIT_PWRITEV64; \ 2633 INIT_PRCTL; \ 2634 INIT_LOCALTIME_AND_FRIENDS; \ 2635 INIT_SCANF; \ 2636 INIT_ISOC99_SCANF; \ 2637 INIT_FREXP; \ 2638 INIT_FREXPF_FREXPL; \ 2639 INIT_GETPWNAM_AND_FRIENDS; \ 2640 INIT_GETPWNAM_R_AND_FRIENDS; \ 2641 INIT_CLOCK_GETTIME; \ 2642 INIT_GETITIMER; \ 2643 INIT_TIME; \ 2644 INIT_GLOB; \ 2645 INIT_WAIT; \ 2646 INIT_INET; \ 2647 INIT_PTHREAD_GETSCHEDPARAM; \ 2648 INIT_GETADDRINFO; \ 2649 INIT_GETNAMEINFO; \ 2650 INIT_GETSOCKNAME; \ 2651 INIT_GETHOSTBYNAME; \ 2652 INIT_GETHOSTBYNAME_R; \ 2653 INIT_GETSOCKOPT; \ 2654 INIT_ACCEPT; \ 2655 INIT_ACCEPT4; \ 2656 INIT_MODF; \ 2657 INIT_RECVMSG; \ 2658 INIT_GETPEERNAME; \ 2659 INIT_IOCTL; \ 2660 INIT_INET_ATON; \ 2661 INIT_SYSINFO; \ 2662 INIT_READDIR; \ 2663 INIT_READDIR64; \ 2664 INIT_PTRACE; \ 2665 INIT_SETLOCALE; \ 2666 INIT_GETCWD; \ 2667 INIT_GET_CURRENT_DIR_NAME; \ 2668 INIT_STRTOIMAX; \ 2669 INIT_MBSTOWCS; \ 2670 INIT_MBSNRTOWCS; \ 2671 INIT_WCSTOMBS; \ 2672 INIT_WCSNRTOMBS; \ 2673 INIT_TCGETATTR; \ 2674 INIT_REALPATH; \ 2675 INIT_CANONICALIZE_FILE_NAME; \ 2676 INIT_CONFSTR; \ 2677 INIT_SCHED_GETAFFINITY; \ 2678 INIT_STRERROR; \ 2679 INIT_STRERROR_R; \ 2680 INIT_SCANDIR; \ 2681 INIT_SCANDIR64; \ 2682 INIT_GETGROUPS; \ 2683 INIT_POLL; \ 2684 INIT_PPOLL; \ 2685 INIT_WORDEXP; \ 2686 INIT_SIGWAIT; \ 2687 INIT_SIGWAITINFO; \ 2688 INIT_SIGTIMEDWAIT; \ 2689 INIT_SIGSETOPS; \ 2690 INIT_SIGPENDING; \ 2691 INIT_SIGPROCMASK; \ 2692 INIT_BACKTRACE; \ 2693 INIT__EXIT; \ 2694 INIT_PTHREAD_MUTEX_LOCK; \ 2695 INIT_PTHREAD_MUTEX_UNLOCK; \ 2696 INIT_PTHREAD_COND_WAIT; \ 2697 INIT_PTHREAD_COND_INIT; \ 2698 INIT_PTHREAD_COND_SIGNAL; \ 2699 INIT_PTHREAD_COND_BROADCAST; \ 2700 INIT_GETMNTENT; \ 2701 INIT_GETMNTENT_R; \ 2702 INIT_STATFS; \ 2703 INIT_STATFS64; \ 2704 INIT_STATVFS; \ 2705 INIT_STATVFS64; \ 2706 INIT_INITGROUPS; \ 2707 INIT_ETHER; \ 2708 INIT_ETHER_R; \ 2709 INIT_SHMCTL; \ 2710 INIT_RANDOM_R; \ 2711 INIT_PTHREAD_ATTR_GET; \ 2712 INIT_PTHREAD_ATTR_GETINHERITSCHED; \ 2713 INIT_PTHREAD_ATTR_GETAFFINITY_NP; \ 2714/**/ 2715