sanitizer_common_interceptors.inc revision 52d08d8412bfa4ccfa38384d781b51e8774807a7
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_STRCASECMP 32static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 33 int c1_low = ToLower(c1); 34 int c2_low = ToLower(c2); 35 return c1_low - c2_low; 36} 37 38INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 39 void *ctx; 40 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 41 unsigned char c1 = 0, c2 = 0; 42 uptr i; 43 for (i = 0; ; i++) { 44 c1 = (unsigned char)s1[i]; 45 c2 = (unsigned char)s2[i]; 46 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 47 break; 48 } 49 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 50 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 51 return CharCaseCmp(c1, c2); 52} 53 54INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 55 void *ctx; 56 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 57 unsigned char c1 = 0, c2 = 0; 58 uptr i; 59 for (i = 0; i < n; i++) { 60 c1 = (unsigned char)s1[i]; 61 c2 = (unsigned char)s2[i]; 62 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 63 break; 64 } 65 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 66 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 67 return CharCaseCmp(c1, c2); 68} 69 70#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 71#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 72#else 73#define INIT_STRCASECMP 74#define INIT_STRNCASECMP 75#endif 76 77#if SANITIZER_INTERCEPT_FREXP 78INTERCEPTOR(double, frexp, double x, int *exp) { 79 void *ctx; 80 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 81 double res = REAL(frexp)(x, exp); 82 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 83 return res; 84} 85 86#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 87#else 88#define INIT_FREXP 89#endif // SANITIZER_INTERCEPT_FREXP 90 91#if SANITIZER_INTERCEPT_FREXPF_FREXPL 92INTERCEPTOR(float, frexpf, float x, int *exp) { 93 void *ctx; 94 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 95 float res = REAL(frexpf)(x, exp); 96 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 97 return res; 98} 99 100INTERCEPTOR(long double, frexpl, long double x, int *exp) { 101 void *ctx; 102 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 103 long double res = REAL(frexpl)(x, exp); 104 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 105 return res; 106} 107 108#define INIT_FREXPF_FREXPL \ 109 INTERCEPT_FUNCTION(frexpf); \ 110 INTERCEPT_FUNCTION(frexpl) 111#else 112#define INIT_FREXPF_FREXPL 113#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 114 115#if SI_NOT_WINDOWS 116static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 117 SIZE_T iovlen, SIZE_T maxlen) { 118 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 119 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 120 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 121 maxlen -= sz; 122 } 123} 124 125static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 126 SIZE_T iovlen, SIZE_T maxlen) { 127 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 128 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 129 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 130 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 131 maxlen -= sz; 132 } 133} 134#endif 135 136#if SANITIZER_INTERCEPT_READ 137INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 138 void *ctx; 139 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 140 SSIZE_T res = REAL(read)(fd, ptr, count); 141 if (res > 0) 142 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 143 if (res >= 0 && fd >= 0) 144 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 145 return res; 146} 147#define INIT_READ INTERCEPT_FUNCTION(read) 148#else 149#define INIT_READ 150#endif 151 152#if SANITIZER_INTERCEPT_PREAD 153INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 154 void *ctx; 155 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 156 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 157 if (res > 0) 158 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 159 if (res >= 0 && fd >= 0) 160 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 161 return res; 162} 163#define INIT_PREAD INTERCEPT_FUNCTION(pread) 164#else 165#define INIT_PREAD 166#endif 167 168#if SANITIZER_INTERCEPT_PREAD64 169INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 170 void *ctx; 171 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 172 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 173 if (res > 0) 174 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 175 if (res >= 0 && fd >= 0) 176 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 177 return res; 178} 179#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 180#else 181#define INIT_PREAD64 182#endif 183 184#if SANITIZER_INTERCEPT_READV 185INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 186 int iovcnt) { 187 void *ctx; 188 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 189 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 190 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 191 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 192 return res; 193} 194#define INIT_READV INTERCEPT_FUNCTION(readv) 195#else 196#define INIT_READV 197#endif 198 199#if SANITIZER_INTERCEPT_PREADV 200INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 201 OFF_T offset) { 202 void *ctx; 203 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 204 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 205 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 206 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 207 return res; 208} 209#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 210#else 211#define INIT_PREADV 212#endif 213 214#if SANITIZER_INTERCEPT_PREADV64 215INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 216 OFF64_T offset) { 217 void *ctx; 218 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 219 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 220 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 221 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 222 return res; 223} 224#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 225#else 226#define INIT_PREADV64 227#endif 228 229#if SANITIZER_INTERCEPT_WRITE 230INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 231 void *ctx; 232 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 233 if (fd >= 0) 234 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 235 SSIZE_T res = REAL(write)(fd, ptr, count); 236 // FIXME: this check should be _before_ the call to REAL(write), not after 237 if (res > 0) 238 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 239 return res; 240} 241#define INIT_WRITE INTERCEPT_FUNCTION(write) 242#else 243#define INIT_WRITE 244#endif 245 246#if SANITIZER_INTERCEPT_PWRITE 247INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 248 void *ctx; 249 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 250 if (fd >= 0) 251 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 252 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 253 if (res > 0) 254 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 255 return res; 256} 257#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 258#else 259#define INIT_PWRITE 260#endif 261 262#if SANITIZER_INTERCEPT_PWRITE64 263INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 264 OFF64_T offset) { 265 void *ctx; 266 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 267 if (fd >= 0) 268 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 269 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 270 if (res > 0) 271 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 272 return res; 273} 274#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 275#else 276#define INIT_PWRITE64 277#endif 278 279#if SANITIZER_INTERCEPT_WRITEV 280INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 281 int iovcnt) { 282 void *ctx; 283 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 284 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 285 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 286 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 287 return res; 288} 289#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 290#else 291#define INIT_WRITEV 292#endif 293 294#if SANITIZER_INTERCEPT_PWRITEV 295INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 296 OFF_T offset) { 297 void *ctx; 298 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 299 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 300 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 301 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 302 return res; 303} 304#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 305#else 306#define INIT_PWRITEV 307#endif 308 309#if SANITIZER_INTERCEPT_PWRITEV64 310INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 311 OFF64_T offset) { 312 void *ctx; 313 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 314 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 315 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 316 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 317 return res; 318} 319#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 320#else 321#define INIT_PWRITEV64 322#endif 323 324#if SANITIZER_INTERCEPT_PRCTL 325INTERCEPTOR(int, prctl, int option, 326 unsigned long arg2, unsigned long arg3, // NOLINT 327 unsigned long arg4, unsigned long arg5) { // NOLINT 328 void *ctx; 329 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 330 static const int PR_SET_NAME = 15; 331 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 332 if (option == PR_SET_NAME) { 333 char buff[16]; 334 internal_strncpy(buff, (char *)arg2, 15); 335 buff[15] = 0; 336 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 337 } 338 return res; 339} 340#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 341#else 342#define INIT_PRCTL 343#endif // SANITIZER_INTERCEPT_PRCTL 344 345 346#if SANITIZER_INTERCEPT_TIME 347INTERCEPTOR(unsigned long, time, unsigned long *t) { 348 void *ctx; 349 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 350 unsigned long res = REAL(time)(t); 351 if (t && res != (unsigned long)-1) { 352 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 353 } 354 return res; 355} 356#define INIT_TIME \ 357 INTERCEPT_FUNCTION(time); 358#else 359#define INIT_TIME 360#endif // SANITIZER_INTERCEPT_TIME 361 362 363#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 364INTERCEPTOR(void *, localtime, unsigned long *timep) { 365 void *ctx; 366 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 367 void *res = REAL(localtime)(timep); 368 if (res) { 369 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 370 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 371 } 372 return res; 373} 374INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 375 void *ctx; 376 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 377 void *res = REAL(localtime_r)(timep, result); 378 if (res) { 379 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 380 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 381 } 382 return res; 383} 384INTERCEPTOR(void *, gmtime, unsigned long *timep) { 385 void *ctx; 386 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 387 void *res = REAL(gmtime)(timep); 388 if (res) { 389 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 390 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 391 } 392 return res; 393} 394INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 395 void *ctx; 396 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 397 void *res = REAL(gmtime_r)(timep, result); 398 if (res) { 399 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 400 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 401 } 402 return res; 403} 404INTERCEPTOR(char *, ctime, unsigned long *timep) { 405 void *ctx; 406 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 407 char *res = REAL(ctime)(timep); 408 if (res) { 409 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 410 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 411 } 412 return res; 413} 414INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 415 void *ctx; 416 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 417 char *res = REAL(ctime_r)(timep, result); 418 if (res) { 419 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 420 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 421 } 422 return res; 423} 424INTERCEPTOR(char *, asctime, void *tm) { 425 void *ctx; 426 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 427 char *res = REAL(asctime)(tm); 428 if (res) { 429 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 431 } 432 return res; 433} 434INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 435 void *ctx; 436 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 437 char *res = REAL(asctime_r)(tm, result); 438 if (res) { 439 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 440 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 441 } 442 return res; 443} 444#define INIT_LOCALTIME_AND_FRIENDS \ 445 INTERCEPT_FUNCTION(localtime); \ 446 INTERCEPT_FUNCTION(localtime_r); \ 447 INTERCEPT_FUNCTION(gmtime); \ 448 INTERCEPT_FUNCTION(gmtime_r); \ 449 INTERCEPT_FUNCTION(ctime); \ 450 INTERCEPT_FUNCTION(ctime_r); \ 451 INTERCEPT_FUNCTION(asctime); \ 452 INTERCEPT_FUNCTION(asctime_r); 453#else 454#define INIT_LOCALTIME_AND_FRIENDS 455#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 456 457#if SANITIZER_INTERCEPT_SCANF 458 459#include "sanitizer_common_interceptors_scanf.inc" 460 461#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 462 { \ 463 void *ctx; \ 464 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 465 va_list aq; \ 466 va_copy(aq, ap); \ 467 int res = REAL(vname)(__VA_ARGS__); \ 468 if (res > 0) \ 469 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 470 va_end(aq); \ 471 return res; \ 472 } 473 474INTERCEPTOR(int, vscanf, const char *format, va_list ap) 475VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 476 477INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 478VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 479 480INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 481VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 482 483#if SANITIZER_INTERCEPT_ISOC99_SCANF 484INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 485VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 486 487INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 488 va_list ap) 489VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 490 491INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 492VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 493#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 494 495#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 496 { \ 497 void *ctx; \ 498 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 499 va_list ap; \ 500 va_start(ap, format); \ 501 int res = vname(__VA_ARGS__, ap); \ 502 va_end(ap); \ 503 return res; \ 504 } 505 506INTERCEPTOR(int, scanf, const char *format, ...) 507SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 508 509INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 510SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 511 512INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 513SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 514 515#if SANITIZER_INTERCEPT_ISOC99_SCANF 516INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 517SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 518 519INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 520SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 521 522INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 523SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 524#endif 525 526#define INIT_SCANF \ 527 INTERCEPT_FUNCTION(scanf); \ 528 INTERCEPT_FUNCTION(sscanf); \ 529 INTERCEPT_FUNCTION(fscanf); \ 530 INTERCEPT_FUNCTION(vscanf); \ 531 INTERCEPT_FUNCTION(vsscanf); \ 532 INTERCEPT_FUNCTION(vfscanf); \ 533 INTERCEPT_FUNCTION(__isoc99_scanf); \ 534 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 535 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 536 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 537 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 538 INTERCEPT_FUNCTION(__isoc99_vfscanf); 539 540#else 541#define INIT_SCANF 542#endif 543 544 545#if SANITIZER_INTERCEPT_IOCTL 546#include "sanitizer_common_interceptors_ioctl.inc" 547INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 548 void *ctx; 549 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 550 551 CHECK(ioctl_initialized); 552 553 // Note: TSan does not use common flags, and they are zero-initialized. 554 // This effectively disables ioctl handling in TSan. 555 if (!common_flags()->handle_ioctl) 556 return REAL(ioctl)(d, request, arg); 557 558 const ioctl_desc *desc = ioctl_lookup(request); 559 if (!desc) 560 Printf("WARNING: unknown ioctl %x\n", request); 561 562 if (desc) 563 ioctl_common_pre(ctx, desc, d, request, arg); 564 int res = REAL(ioctl)(d, request, arg); 565 // FIXME: some ioctls have different return values for success and failure. 566 if (desc && res != -1) 567 ioctl_common_post(ctx, desc, res, d, request, arg); 568 return res; 569} 570#define INIT_IOCTL \ 571 ioctl_init(); \ 572 INTERCEPT_FUNCTION(ioctl); 573#else 574#define INIT_IOCTL 575#endif 576 577 578#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 579INTERCEPTOR(void *, getpwnam, const char *name) { 580 void *ctx; 581 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 582 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 583 void *res = REAL(getpwnam)(name); 584 if (res != 0) 585 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 586 return res; 587} 588INTERCEPTOR(void *, getpwuid, u32 uid) { 589 void *ctx; 590 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 591 void *res = REAL(getpwuid)(uid); 592 if (res != 0) 593 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 594 return res; 595} 596INTERCEPTOR(void *, getgrnam, const char *name) { 597 void *ctx; 598 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 599 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 600 void *res = REAL(getgrnam)(name); 601 if (res != 0) 602 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 603 return res; 604} 605INTERCEPTOR(void *, getgrgid, u32 gid) { 606 void *ctx; 607 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 608 void *res = REAL(getgrgid)(gid); 609 if (res != 0) 610 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 611 return res; 612} 613#define INIT_GETPWNAM_AND_FRIENDS \ 614 INTERCEPT_FUNCTION(getpwnam); \ 615 INTERCEPT_FUNCTION(getpwuid); \ 616 INTERCEPT_FUNCTION(getgrnam); \ 617 INTERCEPT_FUNCTION(getgrgid); 618#else 619#define INIT_GETPWNAM_AND_FRIENDS 620#endif 621 622 623#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 624INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 625 char *buf, SIZE_T buflen, void **result) { 626 void *ctx; 627 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 628 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 629 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 630 if (!res) { 631 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 632 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 633 } 634 return res; 635} 636INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 637 char *buf, SIZE_T buflen, void **result) { 638 void *ctx; 639 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 640 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 641 if (!res) { 642 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 643 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 644 } 645 return res; 646} 647INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 648 char *buf, SIZE_T buflen, void **result) { 649 void *ctx; 650 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 651 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 652 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 653 if (!res) { 654 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 655 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 656 } 657 return res; 658} 659INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 660 char *buf, SIZE_T buflen, void **result) { 661 void *ctx; 662 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 663 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 664 if (!res) { 665 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 666 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 667 } 668 return res; 669} 670#define INIT_GETPWNAM_R_AND_FRIENDS \ 671 INTERCEPT_FUNCTION(getpwnam_r); \ 672 INTERCEPT_FUNCTION(getpwuid_r); \ 673 INTERCEPT_FUNCTION(getgrnam_r); \ 674 INTERCEPT_FUNCTION(getgrgid_r); 675#else 676#define INIT_GETPWNAM_R_AND_FRIENDS 677#endif 678 679 680#if SANITIZER_INTERCEPT_CLOCK_GETTIME 681INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 682 void *ctx; 683 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 684 int res = REAL(clock_getres)(clk_id, tp); 685 if (!res && tp) { 686 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 687 } 688 return res; 689} 690INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 691 void *ctx; 692 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 693 int res = REAL(clock_gettime)(clk_id, tp); 694 if (!res) { 695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 696 } 697 return res; 698} 699INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 700 void *ctx; 701 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 702 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 703 return REAL(clock_settime)(clk_id, tp); 704} 705#define INIT_CLOCK_GETTIME \ 706 INTERCEPT_FUNCTION(clock_getres); \ 707 INTERCEPT_FUNCTION(clock_gettime); \ 708 INTERCEPT_FUNCTION(clock_settime); 709#else 710#define INIT_CLOCK_GETTIME 711#endif 712 713 714#if SANITIZER_INTERCEPT_GETITIMER 715INTERCEPTOR(int, getitimer, int which, void *curr_value) { 716 void *ctx; 717 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 718 int res = REAL(getitimer)(which, curr_value); 719 if (!res) { 720 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 721 } 722 return res; 723} 724INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 725 void *ctx; 726 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 727 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 728 int res = REAL(setitimer)(which, new_value, old_value); 729 if (!res && old_value) { 730 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 731 } 732 return res; 733} 734#define INIT_GETITIMER \ 735 INTERCEPT_FUNCTION(getitimer); \ 736 INTERCEPT_FUNCTION(setitimer); 737#else 738#define INIT_GETITIMER 739#endif 740 741 742#if SANITIZER_INTERCEPT_GLOB 743struct sanitizer_glob_t { 744 SIZE_T gl_pathc; 745 char **gl_pathv; 746}; 747 748static void unpoison_glob_t(void *ctx, sanitizer_glob_t *pglob) { 749 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 750 // +1 for NULL pointer at the end. 751 COMMON_INTERCEPTOR_WRITE_RANGE( 752 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 753 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 754 char *p = pglob->gl_pathv[i]; 755 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 756 } 757} 758 759INTERCEPTOR(int, glob, const char *pattern, int flags, 760 int (*errfunc)(const char *epath, int eerrno), 761 sanitizer_glob_t *pglob) { 762 void *ctx; 763 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 764 int res = REAL(glob)(pattern, flags, errfunc, pglob); 765 if (res == 0) 766 unpoison_glob_t(ctx, pglob); 767 return res; 768} 769 770INTERCEPTOR(int, glob64, const char *pattern, int flags, 771 int (*errfunc)(const char *epath, int eerrno), 772 sanitizer_glob_t *pglob) { 773 void *ctx; 774 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 775 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 776 if (res == 0) 777 unpoison_glob_t(ctx, pglob); 778 return res; 779} 780#define INIT_GLOB \ 781 INTERCEPT_FUNCTION(glob); \ 782 INTERCEPT_FUNCTION(glob64); 783#else // SANITIZER_INTERCEPT_GLOB 784#define INIT_GLOB 785#endif // SANITIZER_INTERCEPT_GLOB 786 787 788#if SANITIZER_INTERCEPT_WAIT 789// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 790// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 791// details. 792INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 793 void *ctx; 794 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 795 int res = REAL(wait)(status); 796 if (res != -1 && status) 797 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 798 return res; 799} 800INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 801 int options) { 802 void *ctx; 803 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 804 int res = REAL(waitid)(idtype, id, infop, options); 805 if (res != -1 && infop) 806 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 807 return res; 808} 809INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 810 void *ctx; 811 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 812 int res = REAL(waitpid)(pid, status, options); 813 if (res != -1 && status) 814 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 815 return res; 816} 817INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 818 void *ctx; 819 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 820 int res = REAL(wait3)(status, options, rusage); 821 if (res != -1) { 822 if (status) 823 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 824 if (rusage) 825 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 826 } 827 return res; 828} 829INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 830 void *ctx; 831 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 832 int res = REAL(wait4)(pid, status, options, rusage); 833 if (res != -1) { 834 if (status) 835 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 836 if (rusage) 837 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 838 } 839 return res; 840} 841#define INIT_WAIT \ 842 INTERCEPT_FUNCTION(wait); \ 843 INTERCEPT_FUNCTION(waitid); \ 844 INTERCEPT_FUNCTION(waitpid); \ 845 INTERCEPT_FUNCTION(wait3); \ 846 INTERCEPT_FUNCTION(wait4); 847#else 848#define INIT_WAIT 849#endif 850 851#if SANITIZER_INTERCEPT_INET 852INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 853 void *ctx; 854 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 855 uptr sz = __sanitizer_in_addr_sz(af); 856 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 857 // FIXME: figure out read size based on the address family. 858 char *res = REAL(inet_ntop)(af, src, dst, size); 859 if (res) 860 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 861 return res; 862} 863INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 864 void *ctx; 865 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 866 // FIXME: figure out read size based on the address family. 867 int res = REAL(inet_pton)(af, src, dst); 868 if (res == 1) { 869 uptr sz = __sanitizer_in_addr_sz(af); 870 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 871 } 872 return res; 873} 874#define INIT_INET \ 875 INTERCEPT_FUNCTION(inet_ntop); \ 876 INTERCEPT_FUNCTION(inet_pton); 877#else 878#define INIT_INET 879#endif 880 881#if SANITIZER_INTERCEPT_INET 882INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 883 void *ctx; 884 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 885 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 886 int res = REAL(inet_aton)(cp, dst); 887 if (res != 0) { 888 uptr sz = __sanitizer_in_addr_sz(af_inet); 889 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 890 } 891 return res; 892} 893#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 894#else 895#define INIT_INET_ATON 896#endif 897 898#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 899INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 900 void *ctx; 901 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 902 int res = REAL(pthread_getschedparam)(thread, policy, param); 903 if (res == 0) { 904 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 905 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 906 } 907 return res; 908} 909#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 910#else 911#define INIT_PTHREAD_GETSCHEDPARAM 912#endif 913 914#if SANITIZER_INTERCEPT_GETADDRINFO 915INTERCEPTOR(int, getaddrinfo, char *node, char *service, 916 struct __sanitizer_addrinfo *hints, 917 struct __sanitizer_addrinfo **out) { 918 void *ctx; 919 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 920 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 921 if (service) 922 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 923 if (hints) 924 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 925 int res = REAL(getaddrinfo)(node, service, hints, out); 926 if (res == 0 && out) { 927 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 928 struct __sanitizer_addrinfo *p = *out; 929 while (p) { 930 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 931 if (p->ai_addr) 932 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 933 if (p->ai_canonname) 934 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 935 REAL(strlen)(p->ai_canonname) + 1); 936 p = p->ai_next; 937 } 938 } 939 return res; 940} 941#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 942#else 943#define INIT_GETADDRINFO 944#endif 945 946#if SANITIZER_INTERCEPT_GETSOCKNAME 947INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 948 void *ctx; 949 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 950 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 951 int addrlen_in = *addrlen; 952 int res = REAL(getsockname)(sock_fd, addr, addrlen); 953 if (res == 0) { 954 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 955 } 956 return res; 957} 958#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 959#else 960#define INIT_GETSOCKNAME 961#endif 962 963#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 964static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 966 if (h->h_name) 967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 968 char **p = h->h_aliases; 969 while (*p) { 970 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 971 ++p; 972 } 973 COMMON_INTERCEPTOR_WRITE_RANGE( 974 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 975 p = h->h_addr_list; 976 while (*p) { 977 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 978 ++p; 979 } 980 COMMON_INTERCEPTOR_WRITE_RANGE( 981 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 982} 983#endif 984 985#if SANITIZER_INTERCEPT_GETHOSTBYNAME 986INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 987 void *ctx; 988 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 989 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 990 if (res) write_hostent(ctx, res); 991 return res; 992} 993 994INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 995 int type) { 996 void *ctx; 997 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 998 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 999 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1000 if (res) write_hostent(ctx, res); 1001 return res; 1002} 1003 1004INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 1005 void *ctx; 1006 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 1007 struct __sanitizer_hostent *res = REAL(gethostent)(); 1008 if (res) write_hostent(ctx, res); 1009 return res; 1010} 1011 1012INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1013 void *ctx; 1014 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1015 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1016 if (res) write_hostent(ctx, res); 1017 return res; 1018} 1019#define INIT_GETHOSTBYNAME \ 1020 INTERCEPT_FUNCTION(gethostent); \ 1021 INTERCEPT_FUNCTION(gethostbyaddr); \ 1022 INTERCEPT_FUNCTION(gethostbyname); \ 1023 INTERCEPT_FUNCTION(gethostbyname2); 1024#else 1025#define INIT_GETHOSTBYNAME 1026#endif 1027 1028#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1029INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1030 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1031 void *ctx; 1032 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1033 h_errnop); 1034 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1035 if (res == 0) { 1036 if (result) { 1037 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1038 if (*result) write_hostent(ctx, *result); 1039 } 1040 if (h_errnop) 1041 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1042 } 1043 return res; 1044} 1045 1046INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1047 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1048 __sanitizer_hostent **result, int *h_errnop) { 1049 void *ctx; 1050 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1051 buflen, result, h_errnop); 1052 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1053 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1054 h_errnop); 1055 if (res == 0) { 1056 if (result) { 1057 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1058 if (*result) write_hostent(ctx, *result); 1059 } 1060 if (h_errnop) 1061 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1062 } 1063 return res; 1064} 1065 1066INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1067 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1068 int *h_errnop) { 1069 void *ctx; 1070 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1071 h_errnop); 1072 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1073 if (res == 0) { 1074 if (result) { 1075 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1076 if (*result) write_hostent(ctx, *result); 1077 } 1078 if (h_errnop) 1079 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1080 } 1081 return res; 1082} 1083 1084INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1085 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1086 __sanitizer_hostent **result, int *h_errnop) { 1087 void *ctx; 1088 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1089 result, h_errnop); 1090 int res = 1091 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1092 if (res == 0) { 1093 if (result) { 1094 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1095 if (*result) write_hostent(ctx, *result); 1096 } 1097 if (h_errnop) 1098 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1099 } 1100 return res; 1101} 1102#define INIT_GETHOSTBYNAME_R \ 1103 INTERCEPT_FUNCTION(gethostent_r); \ 1104 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1105 INTERCEPT_FUNCTION(gethostbyname_r); \ 1106 INTERCEPT_FUNCTION(gethostbyname2_r); 1107#else 1108#define INIT_GETHOSTBYNAME_R 1109#endif 1110 1111#if SANITIZER_INTERCEPT_GETSOCKOPT 1112INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1113 int *optlen) { 1114 void *ctx; 1115 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1116 optlen); 1117 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1118 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1119 if (res == 0) 1120 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1121 return res; 1122} 1123#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1124#else 1125#define INIT_GETSOCKOPT 1126#endif 1127 1128#if SANITIZER_INTERCEPT_ACCEPT 1129INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1130 void *ctx; 1131 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1132 unsigned addrlen0; 1133 if (addrlen) { 1134 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1135 addrlen0 = *addrlen; 1136 } 1137 int fd2 = REAL(accept)(fd, addr, addrlen); 1138 if (fd2 >= 0) { 1139 if (fd >= 0) 1140 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1141 if (addr && addrlen) 1142 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1143 } 1144 return fd2; 1145} 1146#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1147#else 1148#define INIT_ACCEPT 1149#endif 1150 1151#if SANITIZER_INTERCEPT_ACCEPT4 1152INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1153 void *ctx; 1154 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1155 unsigned addrlen0; 1156 if (addrlen) { 1157 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1158 addrlen0 = *addrlen; 1159 } 1160 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1161 if (fd2 >= 0) { 1162 if (fd >= 0) 1163 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1164 if (addr && addrlen) 1165 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1166 } 1167 return fd2; 1168} 1169#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1170#else 1171#define INIT_ACCEPT4 1172#endif 1173 1174#if SANITIZER_INTERCEPT_MODF 1175INTERCEPTOR(double, modf, double x, double *iptr) { 1176 void *ctx; 1177 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1178 double res = REAL(modf)(x, iptr); 1179 if (iptr) { 1180 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1181 } 1182 return res; 1183} 1184INTERCEPTOR(float, modff, float x, float *iptr) { 1185 void *ctx; 1186 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1187 float res = REAL(modff)(x, iptr); 1188 if (iptr) { 1189 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1190 } 1191 return res; 1192} 1193INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1194 void *ctx; 1195 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1196 long double res = REAL(modfl)(x, iptr); 1197 if (iptr) { 1198 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1199 } 1200 return res; 1201} 1202#define INIT_MODF \ 1203 INTERCEPT_FUNCTION(modf); \ 1204 INTERCEPT_FUNCTION(modff); \ 1205 INTERCEPT_FUNCTION(modfl); 1206#else 1207#define INIT_MODF 1208#endif 1209 1210#if SANITIZER_INTERCEPT_RECVMSG 1211static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1212 SSIZE_T maxlen) { 1213 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1214 if (msg->msg_name) 1215 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1216 REAL(strlen)((char *)msg->msg_name) + 1); 1217 if (msg->msg_iov) 1218 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1219 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1220 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1221 if (msg->msg_control) 1222 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1223} 1224 1225INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1226 int flags) { 1227 void *ctx; 1228 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1229 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1230 if (res >= 0) { 1231 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1232 if (msg) write_msghdr(ctx, msg, res); 1233 } 1234 return res; 1235} 1236#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1237#else 1238#define INIT_RECVMSG 1239#endif 1240 1241#if SANITIZER_INTERCEPT_GETPEERNAME 1242INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1243 void *ctx; 1244 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1245 unsigned addr_sz; 1246 if (addrlen) addr_sz = *addrlen; 1247 int res = REAL(getpeername)(sockfd, addr, addrlen); 1248 if (!res && addr && addrlen) 1249 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1250 return res; 1251} 1252#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1253#else 1254#define INIT_GETPEERNAME 1255#endif 1256 1257#if SANITIZER_INTERCEPT_SYSINFO 1258INTERCEPTOR(int, sysinfo, void *info) { 1259 void *ctx; 1260 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1261 int res = REAL(sysinfo)(info); 1262 if (!res && info) 1263 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1264 return res; 1265} 1266#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1267#else 1268#define INIT_SYSINFO 1269#endif 1270 1271#if SANITIZER_INTERCEPT_READDIR 1272INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1273 void *ctx; 1274 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1275 __sanitizer_dirent *res = REAL(readdir)(dirp); 1276 if (res) 1277 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1278 return res; 1279} 1280 1281INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1282 __sanitizer_dirent **result) { 1283 void *ctx; 1284 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1285 int res = REAL(readdir_r)(dirp, entry, result); 1286 if (!res) { 1287 if (result) 1288 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1289 if (entry) 1290 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1291 } 1292 return res; 1293} 1294 1295#define INIT_READDIR \ 1296 INTERCEPT_FUNCTION(readdir); \ 1297 INTERCEPT_FUNCTION(readdir_r); 1298#else 1299#define INIT_READDIR 1300#endif 1301 1302#if SANITIZER_INTERCEPT_READDIR64 1303INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1304 void *ctx; 1305 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1306 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1307 if (res) 1308 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1309 return res; 1310} 1311 1312INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1313 __sanitizer_dirent64 **result) { 1314 void *ctx; 1315 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1316 int res = REAL(readdir64_r)(dirp, entry, result); 1317 if (!res) { 1318 if (result) 1319 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1320 if (entry) 1321 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1322 } 1323 return res; 1324} 1325#define INIT_READDIR64 \ 1326 INTERCEPT_FUNCTION(readdir64); \ 1327 INTERCEPT_FUNCTION(readdir64_r); 1328#else 1329#define INIT_READDIR64 1330#endif 1331 1332#if SANITIZER_INTERCEPT_PTRACE 1333INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1334 void *ctx; 1335 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1336 1337 if (data) { 1338 if (request == ptrace_setregs) 1339 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1340 else if (request == ptrace_setfpregs) 1341 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1342 else if (request == ptrace_setfpxregs) 1343 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1344 else if (request == ptrace_setsiginfo) 1345 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1346 else if (request == ptrace_setregset) { 1347 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1348 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1349 } 1350 } 1351 1352 uptr res = REAL(ptrace)(request, pid, addr, data); 1353 1354 if (!res && data) { 1355 // Note that PEEK* requests assing different meaning to the return value. 1356 // This function does not handle them (nor does it need to). 1357 if (request == ptrace_getregs) 1358 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1359 else if (request == ptrace_getfpregs) 1360 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1361 else if (request == ptrace_getfpxregs) 1362 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1363 else if (request == ptrace_getsiginfo) 1364 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1365 else if (request == ptrace_getregset) { 1366 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1367 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1368 } 1369 } 1370 return res; 1371} 1372 1373#define INIT_PTRACE \ 1374 INTERCEPT_FUNCTION(ptrace); 1375#else 1376#define INIT_PTRACE 1377#endif 1378 1379 1380#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 1381 INIT_STRCASECMP; \ 1382 INIT_STRNCASECMP; \ 1383 INIT_READ; \ 1384 INIT_PREAD; \ 1385 INIT_PREAD64; \ 1386 INIT_READV; \ 1387 INIT_PREADV; \ 1388 INIT_PREADV64; \ 1389 INIT_WRITE; \ 1390 INIT_PWRITE; \ 1391 INIT_PWRITE64; \ 1392 INIT_WRITEV; \ 1393 INIT_PWRITEV; \ 1394 INIT_PWRITEV64; \ 1395 INIT_PRCTL; \ 1396 INIT_LOCALTIME_AND_FRIENDS; \ 1397 INIT_SCANF; \ 1398 INIT_FREXP; \ 1399 INIT_FREXPF_FREXPL; \ 1400 INIT_GETPWNAM_AND_FRIENDS; \ 1401 INIT_GETPWNAM_R_AND_FRIENDS; \ 1402 INIT_CLOCK_GETTIME; \ 1403 INIT_GETITIMER; \ 1404 INIT_TIME; \ 1405 INIT_GLOB; \ 1406 INIT_WAIT; \ 1407 INIT_INET; \ 1408 INIT_PTHREAD_GETSCHEDPARAM; \ 1409 INIT_GETADDRINFO; \ 1410 INIT_GETSOCKNAME; \ 1411 INIT_GETHOSTBYNAME; \ 1412 INIT_GETHOSTBYNAME_R; \ 1413 INIT_GETSOCKOPT; \ 1414 INIT_ACCEPT; \ 1415 INIT_ACCEPT4; \ 1416 INIT_MODF; \ 1417 INIT_RECVMSG; \ 1418 INIT_GETPEERNAME; \ 1419 INIT_IOCTL; \ 1420 INIT_INET_ATON; \ 1421 INIT_SYSINFO; \ 1422 INIT_READDIR; \ 1423 INIT_READDIR64; \ 1424 INIT_PTRACE; 1425