sanitizer_common_interceptors.inc revision 5bd2174c1385ec10b172cc9a32bc33b1967d60b5
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 406INTERCEPTOR(void *, localtime, unsigned long *timep) { 407 void *ctx; 408 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 409 void *res = REAL(localtime)(timep); 410 if (res) { 411 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 412 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 413 } 414 return res; 415} 416INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 417 void *ctx; 418 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 419 void *res = REAL(localtime_r)(timep, result); 420 if (res) { 421 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 422 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 423 } 424 return res; 425} 426INTERCEPTOR(void *, gmtime, unsigned long *timep) { 427 void *ctx; 428 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 429 void *res = REAL(gmtime)(timep); 430 if (res) { 431 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 432 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 433 } 434 return res; 435} 436INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 437 void *ctx; 438 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 439 void *res = REAL(gmtime_r)(timep, result); 440 if (res) { 441 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 442 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 443 } 444 return res; 445} 446INTERCEPTOR(char *, ctime, unsigned long *timep) { 447 void *ctx; 448 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 449 char *res = REAL(ctime)(timep); 450 if (res) { 451 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 453 } 454 return res; 455} 456INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 457 void *ctx; 458 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 459 char *res = REAL(ctime_r)(timep, result); 460 if (res) { 461 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 462 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 463 } 464 return res; 465} 466INTERCEPTOR(char *, asctime, void *tm) { 467 void *ctx; 468 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 469 char *res = REAL(asctime)(tm); 470 if (res) { 471 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 473 } 474 return res; 475} 476INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 477 void *ctx; 478 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 479 char *res = REAL(asctime_r)(tm, result); 480 if (res) { 481 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 482 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 483 } 484 return res; 485} 486#define INIT_LOCALTIME_AND_FRIENDS \ 487 INTERCEPT_FUNCTION(localtime); \ 488 INTERCEPT_FUNCTION(localtime_r); \ 489 INTERCEPT_FUNCTION(gmtime); \ 490 INTERCEPT_FUNCTION(gmtime_r); \ 491 INTERCEPT_FUNCTION(ctime); \ 492 INTERCEPT_FUNCTION(ctime_r); \ 493 INTERCEPT_FUNCTION(asctime); \ 494 INTERCEPT_FUNCTION(asctime_r); 495#else 496#define INIT_LOCALTIME_AND_FRIENDS 497#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 498 499#if SANITIZER_INTERCEPT_SCANF 500 501#include "sanitizer_common_interceptors_scanf.inc" 502 503#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 504 { \ 505 void *ctx; \ 506 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 507 va_list aq; \ 508 va_copy(aq, ap); \ 509 int res = REAL(vname)(__VA_ARGS__); \ 510 if (res > 0) \ 511 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 512 va_end(aq); \ 513 return res; \ 514 } 515 516INTERCEPTOR(int, vscanf, const char *format, va_list ap) 517VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 518 519INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 520VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 521 522INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 523VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 524 525#if SANITIZER_INTERCEPT_ISOC99_SCANF 526INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 527VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 528 529INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 530 va_list ap) 531VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 532 533INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 534VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 535#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 536 537#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 538 { \ 539 void *ctx; \ 540 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 541 va_list ap; \ 542 va_start(ap, format); \ 543 int res = vname(__VA_ARGS__, ap); \ 544 va_end(ap); \ 545 return res; \ 546 } 547 548INTERCEPTOR(int, scanf, const char *format, ...) 549SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 550 551INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 552SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 553 554INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 555SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 556 557#if SANITIZER_INTERCEPT_ISOC99_SCANF 558INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 559SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 560 561INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 562SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 563 564INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 565SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 566#endif 567 568#endif 569 570#if SANITIZER_INTERCEPT_SCANF 571#define INIT_SCANF \ 572 INTERCEPT_FUNCTION(scanf); \ 573 INTERCEPT_FUNCTION(sscanf); \ 574 INTERCEPT_FUNCTION(fscanf); \ 575 INTERCEPT_FUNCTION(vscanf); \ 576 INTERCEPT_FUNCTION(vsscanf); \ 577 INTERCEPT_FUNCTION(vfscanf); 578#else 579#define INIT_SCANF 580#endif 581 582#if SANITIZER_INTERCEPT_ISOC99_SCANF 583#define INIT_ISOC99_SCANF \ 584 INTERCEPT_FUNCTION(__isoc99_scanf); \ 585 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 586 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 587 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 588 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 589 INTERCEPT_FUNCTION(__isoc99_vfscanf); 590#else 591#define INIT_ISOC99_SCANF 592#endif 593 594#if SANITIZER_INTERCEPT_IOCTL 595#include "sanitizer_common_interceptors_ioctl.inc" 596INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 597 void *ctx; 598 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 599 600 CHECK(ioctl_initialized); 601 602 // Note: TSan does not use common flags, and they are zero-initialized. 603 // This effectively disables ioctl handling in TSan. 604 if (!common_flags()->handle_ioctl) 605 return REAL(ioctl)(d, request, arg); 606 607 const ioctl_desc *desc = ioctl_lookup(request); 608 if (!desc) 609 Printf("WARNING: unknown ioctl %x\n", request); 610 611 if (desc) 612 ioctl_common_pre(ctx, desc, d, request, arg); 613 int res = REAL(ioctl)(d, request, arg); 614 // FIXME: some ioctls have different return values for success and failure. 615 if (desc && res != -1) 616 ioctl_common_post(ctx, desc, res, d, request, arg); 617 return res; 618} 619#define INIT_IOCTL \ 620 ioctl_init(); \ 621 INTERCEPT_FUNCTION(ioctl); 622#else 623#define INIT_IOCTL 624#endif 625 626 627#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 628INTERCEPTOR(void *, getpwnam, const char *name) { 629 void *ctx; 630 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 631 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 632 void *res = REAL(getpwnam)(name); 633 if (res != 0) 634 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 635 return res; 636} 637INTERCEPTOR(void *, getpwuid, u32 uid) { 638 void *ctx; 639 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 640 void *res = REAL(getpwuid)(uid); 641 if (res != 0) 642 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 643 return res; 644} 645INTERCEPTOR(void *, getgrnam, const char *name) { 646 void *ctx; 647 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 648 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 649 void *res = REAL(getgrnam)(name); 650 if (res != 0) 651 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 652 return res; 653} 654INTERCEPTOR(void *, getgrgid, u32 gid) { 655 void *ctx; 656 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 657 void *res = REAL(getgrgid)(gid); 658 if (res != 0) 659 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 660 return res; 661} 662#define INIT_GETPWNAM_AND_FRIENDS \ 663 INTERCEPT_FUNCTION(getpwnam); \ 664 INTERCEPT_FUNCTION(getpwuid); \ 665 INTERCEPT_FUNCTION(getgrnam); \ 666 INTERCEPT_FUNCTION(getgrgid); 667#else 668#define INIT_GETPWNAM_AND_FRIENDS 669#endif 670 671 672#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 673INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 674 char *buf, SIZE_T buflen, void **result) { 675 void *ctx; 676 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 677 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 678 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 679 if (!res) { 680 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 681 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 682 } 683 return res; 684} 685INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 686 char *buf, SIZE_T buflen, void **result) { 687 void *ctx; 688 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 689 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 690 if (!res) { 691 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 692 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 693 } 694 return res; 695} 696INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 697 char *buf, SIZE_T buflen, void **result) { 698 void *ctx; 699 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 700 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 701 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 702 if (!res) { 703 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 704 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 705 } 706 return res; 707} 708INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 709 char *buf, SIZE_T buflen, void **result) { 710 void *ctx; 711 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 712 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 713 if (!res) { 714 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 715 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 716 } 717 return res; 718} 719#define INIT_GETPWNAM_R_AND_FRIENDS \ 720 INTERCEPT_FUNCTION(getpwnam_r); \ 721 INTERCEPT_FUNCTION(getpwuid_r); \ 722 INTERCEPT_FUNCTION(getgrnam_r); \ 723 INTERCEPT_FUNCTION(getgrgid_r); 724#else 725#define INIT_GETPWNAM_R_AND_FRIENDS 726#endif 727 728 729#if SANITIZER_INTERCEPT_CLOCK_GETTIME 730INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 731 void *ctx; 732 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 733 int res = REAL(clock_getres)(clk_id, tp); 734 if (!res && tp) { 735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 736 } 737 return res; 738} 739INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 740 void *ctx; 741 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 742 int res = REAL(clock_gettime)(clk_id, tp); 743 if (!res) { 744 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 745 } 746 return res; 747} 748INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 749 void *ctx; 750 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 751 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 752 return REAL(clock_settime)(clk_id, tp); 753} 754#define INIT_CLOCK_GETTIME \ 755 INTERCEPT_FUNCTION(clock_getres); \ 756 INTERCEPT_FUNCTION(clock_gettime); \ 757 INTERCEPT_FUNCTION(clock_settime); 758#else 759#define INIT_CLOCK_GETTIME 760#endif 761 762 763#if SANITIZER_INTERCEPT_GETITIMER 764INTERCEPTOR(int, getitimer, int which, void *curr_value) { 765 void *ctx; 766 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 767 int res = REAL(getitimer)(which, curr_value); 768 if (!res && curr_value) { 769 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 770 } 771 return res; 772} 773INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 774 void *ctx; 775 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 776 if (new_value) 777 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 778 int res = REAL(setitimer)(which, new_value, old_value); 779 if (!res && old_value) { 780 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 781 } 782 return res; 783} 784#define INIT_GETITIMER \ 785 INTERCEPT_FUNCTION(getitimer); \ 786 INTERCEPT_FUNCTION(setitimer); 787#else 788#define INIT_GETITIMER 789#endif 790 791#if SANITIZER_INTERCEPT_GLOB 792static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 793 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 794 // +1 for NULL pointer at the end. 795 if (pglob->gl_pathv) 796 COMMON_INTERCEPTOR_WRITE_RANGE( 797 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 798 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 799 char *p = pglob->gl_pathv[i]; 800 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 801 } 802} 803 804static THREADLOCAL __sanitizer_glob_t* pglob_copy; 805static THREADLOCAL void* glob_ctx; 806 807static void wrapped_gl_closedir(void *dir) { 808 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 809 pglob_copy->gl_closedir(dir); 810} 811 812static void *wrapped_gl_readdir(void *dir) { 813 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 814 return pglob_copy->gl_readdir(dir); 815} 816 817static void *wrapped_gl_opendir(const char *s) { 818 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 819 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 820 return pglob_copy->gl_opendir(s); 821} 822 823static int wrapped_gl_lstat(const char *s, void *st) { 824 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 825 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 826 return pglob_copy->gl_lstat(s, st); 827} 828 829static int wrapped_gl_stat(const char *s, void *st) { 830 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 831 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 832 return pglob_copy->gl_stat(s, st); 833} 834 835INTERCEPTOR(int, glob, const char *pattern, int flags, 836 int (*errfunc)(const char *epath, int eerrno), 837 __sanitizer_glob_t *pglob) { 838 void *ctx; 839 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 840 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 841 wrapped_gl_readdir, wrapped_gl_opendir, 842 wrapped_gl_lstat, wrapped_gl_stat}; 843 if (flags & glob_altdirfunc) { 844 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 845 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 846 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 847 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 848 Swap(pglob->gl_stat, glob_copy.gl_stat); 849 pglob_copy = &glob_copy; 850 glob_ctx = ctx; 851 } 852 int res = REAL(glob)(pattern, flags, errfunc, pglob); 853 if (flags & glob_altdirfunc) { 854 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 855 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 856 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 857 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 858 Swap(pglob->gl_stat, glob_copy.gl_stat); 859 } 860 pglob_copy = 0; 861 glob_ctx = 0; 862 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 863 return res; 864} 865 866INTERCEPTOR(int, glob64, const char *pattern, int flags, 867 int (*errfunc)(const char *epath, int eerrno), 868 __sanitizer_glob_t *pglob) { 869 void *ctx; 870 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 871 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 872 wrapped_gl_readdir, wrapped_gl_opendir, 873 wrapped_gl_lstat, wrapped_gl_stat}; 874 if (flags & glob_altdirfunc) { 875 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 876 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 877 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 878 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 879 Swap(pglob->gl_stat, glob_copy.gl_stat); 880 pglob_copy = &glob_copy; 881 glob_ctx = ctx; 882 } 883 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 884 if (flags & glob_altdirfunc) { 885 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 886 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 887 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 888 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 889 Swap(pglob->gl_stat, glob_copy.gl_stat); 890 } 891 pglob_copy = 0; 892 glob_ctx = 0; 893 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 894 return res; 895} 896#define INIT_GLOB \ 897 INTERCEPT_FUNCTION(glob); \ 898 INTERCEPT_FUNCTION(glob64); 899#else // SANITIZER_INTERCEPT_GLOB 900#define INIT_GLOB 901#endif // SANITIZER_INTERCEPT_GLOB 902 903#if SANITIZER_INTERCEPT_WAIT 904// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 905// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 906// details. 907INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 908 void *ctx; 909 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 910 int res = REAL(wait)(status); 911 if (res != -1 && status) 912 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 913 return res; 914} 915INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 916 int options) { 917 void *ctx; 918 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 919 int res = REAL(waitid)(idtype, id, infop, options); 920 if (res != -1 && infop) 921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 922 return res; 923} 924INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 925 void *ctx; 926 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 927 int res = REAL(waitpid)(pid, status, options); 928 if (res != -1 && status) 929 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 930 return res; 931} 932INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 933 void *ctx; 934 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 935 int res = REAL(wait3)(status, options, rusage); 936 if (res != -1) { 937 if (status) 938 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 939 if (rusage) 940 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 941 } 942 return res; 943} 944INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 945 void *ctx; 946 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 947 int res = REAL(wait4)(pid, status, options, rusage); 948 if (res != -1) { 949 if (status) 950 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 951 if (rusage) 952 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 953 } 954 return res; 955} 956#define INIT_WAIT \ 957 INTERCEPT_FUNCTION(wait); \ 958 INTERCEPT_FUNCTION(waitid); \ 959 INTERCEPT_FUNCTION(waitpid); \ 960 INTERCEPT_FUNCTION(wait3); \ 961 INTERCEPT_FUNCTION(wait4); 962#else 963#define INIT_WAIT 964#endif 965 966#if SANITIZER_INTERCEPT_INET 967INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 968 void *ctx; 969 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 970 uptr sz = __sanitizer_in_addr_sz(af); 971 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 972 // FIXME: figure out read size based on the address family. 973 char *res = REAL(inet_ntop)(af, src, dst, size); 974 if (res) 975 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 976 return res; 977} 978INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 979 void *ctx; 980 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 981 // FIXME: figure out read size based on the address family. 982 int res = REAL(inet_pton)(af, src, dst); 983 if (res == 1) { 984 uptr sz = __sanitizer_in_addr_sz(af); 985 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 986 } 987 return res; 988} 989#define INIT_INET \ 990 INTERCEPT_FUNCTION(inet_ntop); \ 991 INTERCEPT_FUNCTION(inet_pton); 992#else 993#define INIT_INET 994#endif 995 996#if SANITIZER_INTERCEPT_INET 997INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 998 void *ctx; 999 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1000 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1001 int res = REAL(inet_aton)(cp, dst); 1002 if (res != 0) { 1003 uptr sz = __sanitizer_in_addr_sz(af_inet); 1004 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1005 } 1006 return res; 1007} 1008#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 1009#else 1010#define INIT_INET_ATON 1011#endif 1012 1013#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1014INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1015 void *ctx; 1016 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1017 int res = REAL(pthread_getschedparam)(thread, policy, param); 1018 if (res == 0) { 1019 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1020 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1021 } 1022 return res; 1023} 1024#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 1025#else 1026#define INIT_PTHREAD_GETSCHEDPARAM 1027#endif 1028 1029#if SANITIZER_INTERCEPT_GETADDRINFO 1030INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1031 struct __sanitizer_addrinfo *hints, 1032 struct __sanitizer_addrinfo **out) { 1033 void *ctx; 1034 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1035 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1036 if (service) 1037 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1038 if (hints) 1039 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1040 int res = REAL(getaddrinfo)(node, service, hints, out); 1041 if (res == 0 && out) { 1042 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1043 struct __sanitizer_addrinfo *p = *out; 1044 while (p) { 1045 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1046 if (p->ai_addr) 1047 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1048 if (p->ai_canonname) 1049 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1050 REAL(strlen)(p->ai_canonname) + 1); 1051 p = p->ai_next; 1052 } 1053 } 1054 return res; 1055} 1056#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 1057#else 1058#define INIT_GETADDRINFO 1059#endif 1060 1061#if SANITIZER_INTERCEPT_GETNAMEINFO 1062INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1063 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1064 void *ctx; 1065 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1066 serv, servlen, flags); 1067 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1068 // There is padding in in_addr that may make this too noisy 1069 int res = 1070 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1071 if (res == 0) { 1072 if (host && hostlen) 1073 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1074 if (serv && servlen) 1075 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1076 } 1077 return res; 1078} 1079#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1080#else 1081#define INIT_GETNAMEINFO 1082#endif 1083 1084#if SANITIZER_INTERCEPT_GETSOCKNAME 1085INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1086 void *ctx; 1087 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1088 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1089 int addrlen_in = *addrlen; 1090 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1091 if (res == 0) { 1092 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1093 } 1094 return res; 1095} 1096#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1097#else 1098#define INIT_GETSOCKNAME 1099#endif 1100 1101#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1102static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1103 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1104 if (h->h_name) 1105 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1106 char **p = h->h_aliases; 1107 while (*p) { 1108 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1109 ++p; 1110 } 1111 COMMON_INTERCEPTOR_WRITE_RANGE( 1112 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1113 p = h->h_addr_list; 1114 while (*p) { 1115 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1116 ++p; 1117 } 1118 COMMON_INTERCEPTOR_WRITE_RANGE( 1119 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1120} 1121#endif 1122 1123#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1124INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1125 void *ctx; 1126 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1127 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1128 if (res) write_hostent(ctx, res); 1129 return res; 1130} 1131 1132INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1133 int type) { 1134 void *ctx; 1135 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1136 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1137 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1138 if (res) write_hostent(ctx, res); 1139 return res; 1140} 1141 1142INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 1143 void *ctx; 1144 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 1145 struct __sanitizer_hostent *res = REAL(gethostent)(); 1146 if (res) write_hostent(ctx, res); 1147 return res; 1148} 1149 1150INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1151 void *ctx; 1152 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1153 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1154 if (res) write_hostent(ctx, res); 1155 return res; 1156} 1157#define INIT_GETHOSTBYNAME \ 1158 INTERCEPT_FUNCTION(gethostent); \ 1159 INTERCEPT_FUNCTION(gethostbyaddr); \ 1160 INTERCEPT_FUNCTION(gethostbyname); \ 1161 INTERCEPT_FUNCTION(gethostbyname2); 1162#else 1163#define INIT_GETHOSTBYNAME 1164#endif 1165 1166#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1167INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1168 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1169 void *ctx; 1170 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1171 h_errnop); 1172 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1173 if (res == 0) { 1174 if (result) { 1175 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1176 if (*result) write_hostent(ctx, *result); 1177 } 1178 if (h_errnop) 1179 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1180 } 1181 return res; 1182} 1183 1184INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1185 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1186 __sanitizer_hostent **result, int *h_errnop) { 1187 void *ctx; 1188 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1189 buflen, result, h_errnop); 1190 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1191 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1192 h_errnop); 1193 if (res == 0) { 1194 if (result) { 1195 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1196 if (*result) write_hostent(ctx, *result); 1197 } 1198 if (h_errnop) 1199 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1200 } 1201 return res; 1202} 1203 1204INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1205 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1206 int *h_errnop) { 1207 void *ctx; 1208 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1209 h_errnop); 1210 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1211 if (res == 0) { 1212 if (result) { 1213 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1214 if (*result) write_hostent(ctx, *result); 1215 } 1216 if (h_errnop) 1217 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1218 } 1219 return res; 1220} 1221 1222INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1223 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1224 __sanitizer_hostent **result, int *h_errnop) { 1225 void *ctx; 1226 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1227 result, h_errnop); 1228 int res = 1229 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1230 if (res == 0) { 1231 if (result) { 1232 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1233 if (*result) write_hostent(ctx, *result); 1234 } 1235 if (h_errnop) 1236 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1237 } 1238 return res; 1239} 1240#define INIT_GETHOSTBYNAME_R \ 1241 INTERCEPT_FUNCTION(gethostent_r); \ 1242 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1243 INTERCEPT_FUNCTION(gethostbyname_r); \ 1244 INTERCEPT_FUNCTION(gethostbyname2_r); 1245#else 1246#define INIT_GETHOSTBYNAME_R 1247#endif 1248 1249#if SANITIZER_INTERCEPT_GETSOCKOPT 1250INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1251 int *optlen) { 1252 void *ctx; 1253 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1254 optlen); 1255 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1256 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1257 if (res == 0) 1258 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1259 return res; 1260} 1261#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1262#else 1263#define INIT_GETSOCKOPT 1264#endif 1265 1266#if SANITIZER_INTERCEPT_ACCEPT 1267INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1268 void *ctx; 1269 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1270 unsigned addrlen0; 1271 if (addrlen) { 1272 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1273 addrlen0 = *addrlen; 1274 } 1275 int fd2 = REAL(accept)(fd, addr, addrlen); 1276 if (fd2 >= 0) { 1277 if (fd >= 0) 1278 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1279 if (addr && addrlen) 1280 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1281 } 1282 return fd2; 1283} 1284#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1285#else 1286#define INIT_ACCEPT 1287#endif 1288 1289#if SANITIZER_INTERCEPT_ACCEPT4 1290INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1291 void *ctx; 1292 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1293 unsigned addrlen0; 1294 if (addrlen) { 1295 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1296 addrlen0 = *addrlen; 1297 } 1298 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1299 if (fd2 >= 0) { 1300 if (fd >= 0) 1301 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1302 if (addr && addrlen) 1303 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1304 } 1305 return fd2; 1306} 1307#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1308#else 1309#define INIT_ACCEPT4 1310#endif 1311 1312#if SANITIZER_INTERCEPT_MODF 1313INTERCEPTOR(double, modf, double x, double *iptr) { 1314 void *ctx; 1315 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1316 double res = REAL(modf)(x, iptr); 1317 if (iptr) { 1318 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1319 } 1320 return res; 1321} 1322INTERCEPTOR(float, modff, float x, float *iptr) { 1323 void *ctx; 1324 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1325 float res = REAL(modff)(x, iptr); 1326 if (iptr) { 1327 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1328 } 1329 return res; 1330} 1331INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1332 void *ctx; 1333 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1334 long double res = REAL(modfl)(x, iptr); 1335 if (iptr) { 1336 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1337 } 1338 return res; 1339} 1340#define INIT_MODF \ 1341 INTERCEPT_FUNCTION(modf); \ 1342 INTERCEPT_FUNCTION(modff); \ 1343 INTERCEPT_FUNCTION(modfl); 1344#else 1345#define INIT_MODF 1346#endif 1347 1348#if SANITIZER_INTERCEPT_RECVMSG 1349static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1350 SSIZE_T maxlen) { 1351 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1352 if (msg->msg_name) 1353 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1354 REAL(strlen)((char *)msg->msg_name) + 1); 1355 if (msg->msg_iov) 1356 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1357 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1358 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1359 if (msg->msg_control) 1360 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1361} 1362 1363INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1364 int flags) { 1365 void *ctx; 1366 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1367 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1368 if (res >= 0) { 1369 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1370 if (msg) write_msghdr(ctx, msg, res); 1371 } 1372 return res; 1373} 1374#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1375#else 1376#define INIT_RECVMSG 1377#endif 1378 1379#if SANITIZER_INTERCEPT_GETPEERNAME 1380INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1381 void *ctx; 1382 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1383 unsigned addr_sz; 1384 if (addrlen) addr_sz = *addrlen; 1385 int res = REAL(getpeername)(sockfd, addr, addrlen); 1386 if (!res && addr && addrlen) 1387 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1388 return res; 1389} 1390#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1391#else 1392#define INIT_GETPEERNAME 1393#endif 1394 1395#if SANITIZER_INTERCEPT_SYSINFO 1396INTERCEPTOR(int, sysinfo, void *info) { 1397 void *ctx; 1398 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1399 int res = REAL(sysinfo)(info); 1400 if (!res && info) 1401 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1402 return res; 1403} 1404#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1405#else 1406#define INIT_SYSINFO 1407#endif 1408 1409#if SANITIZER_INTERCEPT_READDIR 1410INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1411 void *ctx; 1412 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1413 __sanitizer_dirent *res = REAL(readdir)(dirp); 1414 if (res) 1415 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1416 return res; 1417} 1418 1419INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1420 __sanitizer_dirent **result) { 1421 void *ctx; 1422 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1423 int res = REAL(readdir_r)(dirp, entry, result); 1424 if (!res) { 1425 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1426 if (*result) 1427 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1428 } 1429 return res; 1430} 1431 1432#define INIT_READDIR \ 1433 INTERCEPT_FUNCTION(readdir); \ 1434 INTERCEPT_FUNCTION(readdir_r); 1435#else 1436#define INIT_READDIR 1437#endif 1438 1439#if SANITIZER_INTERCEPT_READDIR64 1440INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1441 void *ctx; 1442 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1443 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1444 if (res) 1445 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1446 return res; 1447} 1448 1449INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1450 __sanitizer_dirent64 **result) { 1451 void *ctx; 1452 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1453 int res = REAL(readdir64_r)(dirp, entry, result); 1454 if (!res) { 1455 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1456 if (*result) 1457 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1458 } 1459 return res; 1460} 1461#define INIT_READDIR64 \ 1462 INTERCEPT_FUNCTION(readdir64); \ 1463 INTERCEPT_FUNCTION(readdir64_r); 1464#else 1465#define INIT_READDIR64 1466#endif 1467 1468#if SANITIZER_INTERCEPT_PTRACE 1469INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1470 void *ctx; 1471 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1472 1473 if (data) { 1474 if (request == ptrace_setregs) 1475 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1476 else if (request == ptrace_setfpregs) 1477 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1478 else if (request == ptrace_setfpxregs) 1479 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1480 else if (request == ptrace_setsiginfo) 1481 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1482 else if (request == ptrace_setregset) { 1483 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1484 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1485 } 1486 } 1487 1488 uptr res = REAL(ptrace)(request, pid, addr, data); 1489 1490 if (!res && data) { 1491 // Note that PEEK* requests assing different meaning to the return value. 1492 // This function does not handle them (nor does it need to). 1493 if (request == ptrace_getregs) 1494 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1495 else if (request == ptrace_getfpregs) 1496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1497 else if (request == ptrace_getfpxregs) 1498 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1499 else if (request == ptrace_getsiginfo) 1500 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1501 else if (request == ptrace_getregset) { 1502 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1503 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1504 } 1505 } 1506 return res; 1507} 1508 1509#define INIT_PTRACE \ 1510 INTERCEPT_FUNCTION(ptrace); 1511#else 1512#define INIT_PTRACE 1513#endif 1514 1515#if SANITIZER_INTERCEPT_SETLOCALE 1516INTERCEPTOR(char *, setlocale, int category, char *locale) { 1517 void *ctx; 1518 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1519 if (locale) 1520 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1521 char *res = REAL(setlocale)(category, locale); 1522 if (res) 1523 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1524 return res; 1525} 1526 1527#define INIT_SETLOCALE \ 1528 INTERCEPT_FUNCTION(setlocale); 1529#else 1530#define INIT_SETLOCALE 1531#endif 1532 1533#if SANITIZER_INTERCEPT_GETCWD 1534INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1535 void *ctx; 1536 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1537 char *res = REAL(getcwd)(buf, size); 1538 if (res) 1539 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1540 return res; 1541} 1542#define INIT_GETCWD \ 1543 INTERCEPT_FUNCTION(getcwd); 1544#else 1545#define INIT_GETCWD 1546#endif 1547 1548#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1549INTERCEPTOR(char *, get_current_dir_name) { 1550 void *ctx; 1551 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name); 1552 char *res = REAL(get_current_dir_name)(); 1553 if (res) 1554 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1555 return res; 1556} 1557 1558#define INIT_GET_CURRENT_DIR_NAME \ 1559 INTERCEPT_FUNCTION(get_current_dir_name); 1560#else 1561#define INIT_GET_CURRENT_DIR_NAME 1562#endif 1563 1564#if SANITIZER_INTERCEPT_STRTOIMAX 1565INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1566 void *ctx; 1567 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1568 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1569 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1570 return res; 1571} 1572 1573INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1574 void *ctx; 1575 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1576 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1577 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1578 return res; 1579} 1580 1581#define INIT_STRTOIMAX \ 1582 INTERCEPT_FUNCTION(strtoimax); \ 1583 INTERCEPT_FUNCTION(strtoumax); 1584#else 1585#define INIT_STRTOIMAX 1586#endif 1587 1588#if SANITIZER_INTERCEPT_MBSTOWCS 1589INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1590 void *ctx; 1591 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1592 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1593 if (res != (SIZE_T) - 1 && dest) { 1594 SIZE_T write_cnt = res + (res < len); 1595 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1596 } 1597 return res; 1598} 1599 1600INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1601 void *ps) { 1602 void *ctx; 1603 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1604 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1605 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1606 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1607 if (res != (SIZE_T)(-1) && dest && src) { 1608 // This function, and several others, may or may not write the terminating 1609 // \0 character. They write it iff they clear *src. 1610 SIZE_T write_cnt = res + !*src; 1611 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1612 } 1613 return res; 1614} 1615 1616#define INIT_MBSTOWCS \ 1617 INTERCEPT_FUNCTION(mbstowcs); \ 1618 INTERCEPT_FUNCTION(mbsrtowcs); 1619#else 1620#define INIT_MBSTOWCS 1621#endif 1622 1623#if SANITIZER_INTERCEPT_MBSNRTOWCS 1624INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1625 SIZE_T len, void *ps) { 1626 void *ctx; 1627 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1628 if (src) { 1629 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1630 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1631 } 1632 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1633 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1634 if (res != (SIZE_T)(-1) && dest && src) { 1635 SIZE_T write_cnt = res + !*src; 1636 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1637 } 1638 return res; 1639} 1640 1641#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1642#else 1643#define INIT_MBSNRTOWCS 1644#endif 1645 1646#if SANITIZER_INTERCEPT_WCSTOMBS 1647INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1648 void *ctx; 1649 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1650 SIZE_T res = REAL(wcstombs)(dest, src, len); 1651 if (res != (SIZE_T) - 1 && dest) { 1652 SIZE_T write_cnt = res + (res < len); 1653 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1654 } 1655 return res; 1656} 1657 1658INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1659 void *ps) { 1660 void *ctx; 1661 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1662 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1663 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1664 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1665 if (res != (SIZE_T) - 1 && dest && src) { 1666 SIZE_T write_cnt = res + !*src; 1667 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1668 } 1669 return res; 1670} 1671 1672#define INIT_WCSTOMBS \ 1673 INTERCEPT_FUNCTION(wcstombs); \ 1674 INTERCEPT_FUNCTION(wcsrtombs); 1675#else 1676#define INIT_WCSTOMBS 1677#endif 1678 1679#if SANITIZER_INTERCEPT_WCSNRTOMBS 1680INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1681 SIZE_T len, void *ps) { 1682 void *ctx; 1683 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1684 if (src) { 1685 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1686 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1687 } 1688 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1689 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1690 if (res != (SIZE_T) - 1 && dest && src) { 1691 SIZE_T write_cnt = res + !*src; 1692 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1693 } 1694 return res; 1695} 1696 1697#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1698#else 1699#define INIT_WCSNRTOMBS 1700#endif 1701 1702 1703#if SANITIZER_INTERCEPT_TCGETATTR 1704INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1705 void *ctx; 1706 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1707 int res = REAL(tcgetattr)(fd, termios_p); 1708 if (!res && termios_p) 1709 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1710 return res; 1711} 1712 1713#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1714#else 1715#define INIT_TCGETATTR 1716#endif 1717 1718 1719#if SANITIZER_INTERCEPT_REALPATH 1720INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1721 void *ctx; 1722 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1723 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1724 1725 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1726 // version of a versioned symbol. For realpath(), this gives us something 1727 // (called __old_realpath) that does not handle NULL in the second argument. 1728 // Handle it as part of the interceptor. 1729 char *allocated_path = 0; 1730 if (!resolved_path) 1731 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1732 1733 char *res = REAL(realpath)(path, resolved_path); 1734 if (allocated_path && !res) 1735 WRAP(free)(allocated_path); 1736 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1737 return res; 1738} 1739#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1740#else 1741#define INIT_REALPATH 1742#endif 1743 1744#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1745INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1746 void *ctx; 1747 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1748 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1749 char *res = REAL(canonicalize_file_name)(path); 1750 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1751 return res; 1752} 1753#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1754#else 1755#define INIT_CANONICALIZE_FILE_NAME 1756#endif 1757 1758#if SANITIZER_INTERCEPT_CONFSTR 1759INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1760 void *ctx; 1761 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1762 SIZE_T res = REAL(confstr)(name, buf, len); 1763 if (buf && res) 1764 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1765 return res; 1766} 1767#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1768#else 1769#define INIT_CONFSTR 1770#endif 1771 1772#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1773INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1774 void *ctx; 1775 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1776 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1777 if (mask && !res) 1778 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1779 return res; 1780} 1781#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1782#else 1783#define INIT_SCHED_GETAFFINITY 1784#endif 1785 1786#if SANITIZER_INTERCEPT_STRERROR 1787INTERCEPTOR(char *, strerror, int errnum) { 1788 void *ctx; 1789 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1790 char *res = REAL(strerror)(errnum); 1791 if (res) 1792 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1793 return res; 1794} 1795#define INIT_STRERROR INTERCEPT_FUNCTION(strerror); 1796#else 1797#define INIT_STRERROR 1798#endif 1799 1800#if SANITIZER_INTERCEPT_STRERROR_R 1801INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1802 void *ctx; 1803 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1804 char *res = REAL(strerror_r)(errnum, buf, buflen); 1805 // There are 2 versions of strerror_r: 1806 // * POSIX version returns 0 on success, negative error code on failure, 1807 // writes message to buf. 1808 // * GNU version returns message pointer, which points to either buf or some 1809 // static storage. 1810 if (!res) { 1811 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1812 SIZE_T sz = internal_strnlen(buf, buflen); 1813 if (sz < buflen) ++sz; 1814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1815 } else if ((SIZE_T)res < (SIZE_T) - 1024) { 1816 // GNU version. 1817 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1818 } 1819 return res; 1820} 1821#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); 1822#else 1823#define INIT_STRERROR_R 1824#endif 1825 1826#if SANITIZER_INTERCEPT_SCANDIR 1827typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1828typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1829 const struct __sanitizer_dirent **); 1830 1831static THREADLOCAL void *scandir_ctx; 1832static THREADLOCAL scandir_filter_f scandir_filter; 1833static THREADLOCAL scandir_compar_f scandir_compar; 1834 1835static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1836 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1837 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1838 return scandir_filter(dir); 1839} 1840 1841static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1842 const struct __sanitizer_dirent **b) { 1843 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1844 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1845 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1846 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1847 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1848 return scandir_compar(a, b); 1849} 1850 1851INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1852 scandir_filter_f filter, scandir_compar_f compar) { 1853 void *ctx; 1854 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1855 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1856 CHECK_EQ(0, scandir_ctx); 1857 scandir_ctx = ctx; 1858 scandir_filter = filter; 1859 scandir_compar = compar; 1860 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1861 compar ? wrapped_scandir_compar : 0); 1862 scandir_ctx = 0; 1863 scandir_filter = 0; 1864 scandir_compar = 0; 1865 if (namelist && res > 0) { 1866 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1867 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1868 for (int i = 0; i < res; ++i) 1869 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1870 (*namelist)[i]->d_reclen); 1871 } 1872 return res; 1873} 1874#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); 1875#else 1876#define INIT_SCANDIR 1877#endif 1878 1879#if SANITIZER_INTERCEPT_SCANDIR64 1880typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1881typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1882 const struct __sanitizer_dirent64 **); 1883 1884static THREADLOCAL void *scandir64_ctx; 1885static THREADLOCAL scandir64_filter_f scandir64_filter; 1886static THREADLOCAL scandir64_compar_f scandir64_compar; 1887 1888static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1889 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1890 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1891 return scandir64_filter(dir); 1892} 1893 1894static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1895 const struct __sanitizer_dirent64 **b) { 1896 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1897 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1898 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1899 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1900 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1901 return scandir64_compar(a, b); 1902} 1903 1904INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1905 scandir64_filter_f filter, scandir64_compar_f compar) { 1906 void *ctx; 1907 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1908 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1909 CHECK_EQ(0, scandir64_ctx); 1910 scandir64_ctx = ctx; 1911 scandir64_filter = filter; 1912 scandir64_compar = compar; 1913 int res = 1914 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1915 compar ? wrapped_scandir64_compar : 0); 1916 scandir64_ctx = 0; 1917 scandir64_filter = 0; 1918 scandir64_compar = 0; 1919 if (namelist && res > 0) { 1920 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1922 for (int i = 0; i < res; ++i) 1923 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1924 (*namelist)[i]->d_reclen); 1925 } 1926 return res; 1927} 1928#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); 1929#else 1930#define INIT_SCANDIR64 1931#endif 1932 1933#if SANITIZER_INTERCEPT_GETGROUPS 1934INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1935 void *ctx; 1936 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1937 int res = REAL(getgroups)(size, lst); 1938 if (res && lst) 1939 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1940 return res; 1941} 1942#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); 1943#else 1944#define INIT_GETGROUPS 1945#endif 1946 1947#if SANITIZER_INTERCEPT_POLL 1948static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1949 __sanitizer_nfds_t nfds) { 1950 for (unsigned i = 0; i < nfds; ++i) { 1951 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1952 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1953 } 1954} 1955 1956static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 1957 __sanitizer_nfds_t nfds) { 1958 for (unsigned i = 0; i < nfds; ++i) 1959 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 1960 sizeof(fds[i].revents)); 1961} 1962 1963INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 1964 int timeout) { 1965 void *ctx; 1966 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 1967 if (fds && nfds) read_pollfd(ctx, fds, nfds); 1968 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 1969 if (fds && nfds) write_pollfd(ctx, fds, nfds); 1970 return res; 1971} 1972#define INIT_POLL INTERCEPT_FUNCTION(poll); 1973#else 1974#define INIT_POLL 1975#endif 1976 1977#if SANITIZER_INTERCEPT_PPOLL 1978INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 1979 void *timeout_ts, void *sigmask) { 1980 void *ctx; 1981 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 1982 if (fds && nfds) read_pollfd(ctx, fds, nfds); 1983 if (timeout_ts) 1984 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 1985 if (sigmask) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, sigset_t_sz); 1986 int res = 1987 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 1988 if (fds && nfds) write_pollfd(ctx, fds, nfds); 1989 return res; 1990} 1991#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); 1992#else 1993#define INIT_PPOLL 1994#endif 1995 1996#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 1997 INIT_STRCMP; \ 1998 INIT_STRNCMP; \ 1999 INIT_STRCASECMP; \ 2000 INIT_STRNCASECMP; \ 2001 INIT_READ; \ 2002 INIT_PREAD; \ 2003 INIT_PREAD64; \ 2004 INIT_READV; \ 2005 INIT_PREADV; \ 2006 INIT_PREADV64; \ 2007 INIT_WRITE; \ 2008 INIT_PWRITE; \ 2009 INIT_PWRITE64; \ 2010 INIT_WRITEV; \ 2011 INIT_PWRITEV; \ 2012 INIT_PWRITEV64; \ 2013 INIT_PRCTL; \ 2014 INIT_LOCALTIME_AND_FRIENDS; \ 2015 INIT_SCANF; \ 2016 INIT_ISOC99_SCANF; \ 2017 INIT_FREXP; \ 2018 INIT_FREXPF_FREXPL; \ 2019 INIT_GETPWNAM_AND_FRIENDS; \ 2020 INIT_GETPWNAM_R_AND_FRIENDS; \ 2021 INIT_CLOCK_GETTIME; \ 2022 INIT_GETITIMER; \ 2023 INIT_TIME; \ 2024 INIT_GLOB; \ 2025 INIT_WAIT; \ 2026 INIT_INET; \ 2027 INIT_PTHREAD_GETSCHEDPARAM; \ 2028 INIT_GETADDRINFO; \ 2029 INIT_GETNAMEINFO; \ 2030 INIT_GETSOCKNAME; \ 2031 INIT_GETHOSTBYNAME; \ 2032 INIT_GETHOSTBYNAME_R; \ 2033 INIT_GETSOCKOPT; \ 2034 INIT_ACCEPT; \ 2035 INIT_ACCEPT4; \ 2036 INIT_MODF; \ 2037 INIT_RECVMSG; \ 2038 INIT_GETPEERNAME; \ 2039 INIT_IOCTL; \ 2040 INIT_INET_ATON; \ 2041 INIT_SYSINFO; \ 2042 INIT_READDIR; \ 2043 INIT_READDIR64; \ 2044 INIT_PTRACE; \ 2045 INIT_SETLOCALE; \ 2046 INIT_GETCWD; \ 2047 INIT_GET_CURRENT_DIR_NAME; \ 2048 INIT_STRTOIMAX; \ 2049 INIT_MBSTOWCS; \ 2050 INIT_MBSNRTOWCS; \ 2051 INIT_WCSTOMBS; \ 2052 INIT_WCSNRTOMBS; \ 2053 INIT_TCGETATTR; \ 2054 INIT_REALPATH; \ 2055 INIT_CANONICALIZE_FILE_NAME; \ 2056 INIT_CONFSTR; \ 2057 INIT_SCHED_GETAFFINITY; \ 2058 INIT_STRERROR; \ 2059 INIT_STRERROR_R; \ 2060 INIT_SCANDIR; \ 2061 INIT_SCANDIR64; \ 2062 INIT_GETGROUPS; \ 2063 INIT_POLL; \ 2064 INIT_PPOLL; 2065