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