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