sanitizer_common_interceptors.inc revision 3fa122e6a8e12db6583793861f6cf776fe1c98a0
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#if SANITIZER_INTERCEPT_GLOB 742static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 743 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 744 // +1 for NULL pointer at the end. 745 if (pglob->gl_pathv) 746 COMMON_INTERCEPTOR_WRITE_RANGE( 747 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 748 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 749 char *p = pglob->gl_pathv[i]; 750 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 751 } 752} 753 754static THREADLOCAL __sanitizer_glob_t* pglob_copy; 755static THREADLOCAL void* glob_ctx; 756 757static void wrapped_gl_closedir(void *dir) { 758 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 759 pglob_copy->gl_closedir(dir); 760} 761 762static void *wrapped_gl_readdir(void *dir) { 763 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 764 return pglob_copy->gl_readdir(dir); 765} 766 767static void *wrapped_gl_opendir(const char *s) { 768 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 769 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 770 return pglob_copy->gl_opendir(s); 771} 772 773static int wrapped_gl_lstat(const char *s, void *st) { 774 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 775 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 776 return pglob_copy->gl_lstat(s, st); 777} 778 779static int wrapped_gl_stat(const char *s, void *st) { 780 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 781 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 782 return pglob_copy->gl_stat(s, st); 783} 784 785INTERCEPTOR(int, glob, const char *pattern, int flags, 786 int (*errfunc)(const char *epath, int eerrno), 787 __sanitizer_glob_t *pglob) { 788 void *ctx; 789 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 790 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 791 wrapped_gl_readdir, wrapped_gl_opendir, 792 wrapped_gl_lstat, wrapped_gl_stat}; 793 if (flags & glob_altdirfunc) { 794 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 795 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 796 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 797 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 798 Swap(pglob->gl_stat, glob_copy.gl_stat); 799 pglob_copy = &glob_copy; 800 glob_ctx = ctx; 801 } 802 int res = REAL(glob)(pattern, flags, errfunc, pglob); 803 if (flags & glob_altdirfunc) { 804 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 805 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 806 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 807 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 808 Swap(pglob->gl_stat, glob_copy.gl_stat); 809 } 810 pglob_copy = 0; 811 glob_ctx = 0; 812 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 813 return res; 814} 815 816INTERCEPTOR(int, glob64, const char *pattern, int flags, 817 int (*errfunc)(const char *epath, int eerrno), 818 __sanitizer_glob_t *pglob) { 819 void *ctx; 820 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 821 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 822 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 823 return res; 824} 825#define INIT_GLOB \ 826 INTERCEPT_FUNCTION(glob); \ 827 INTERCEPT_FUNCTION(glob64); 828#else // SANITIZER_INTERCEPT_GLOB 829#define INIT_GLOB 830#endif // SANITIZER_INTERCEPT_GLOB 831 832#if SANITIZER_INTERCEPT_WAIT 833// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 834// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 835// details. 836INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 837 void *ctx; 838 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 839 int res = REAL(wait)(status); 840 if (res != -1 && status) 841 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 842 return res; 843} 844INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 845 int options) { 846 void *ctx; 847 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 848 int res = REAL(waitid)(idtype, id, infop, options); 849 if (res != -1 && infop) 850 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 851 return res; 852} 853INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 854 void *ctx; 855 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 856 int res = REAL(waitpid)(pid, status, options); 857 if (res != -1 && status) 858 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 859 return res; 860} 861INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 862 void *ctx; 863 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 864 int res = REAL(wait3)(status, options, rusage); 865 if (res != -1) { 866 if (status) 867 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 868 if (rusage) 869 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 870 } 871 return res; 872} 873INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 874 void *ctx; 875 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 876 int res = REAL(wait4)(pid, status, options, rusage); 877 if (res != -1) { 878 if (status) 879 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 880 if (rusage) 881 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 882 } 883 return res; 884} 885#define INIT_WAIT \ 886 INTERCEPT_FUNCTION(wait); \ 887 INTERCEPT_FUNCTION(waitid); \ 888 INTERCEPT_FUNCTION(waitpid); \ 889 INTERCEPT_FUNCTION(wait3); \ 890 INTERCEPT_FUNCTION(wait4); 891#else 892#define INIT_WAIT 893#endif 894 895#if SANITIZER_INTERCEPT_INET 896INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 897 void *ctx; 898 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 899 uptr sz = __sanitizer_in_addr_sz(af); 900 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 901 // FIXME: figure out read size based on the address family. 902 char *res = REAL(inet_ntop)(af, src, dst, size); 903 if (res) 904 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 905 return res; 906} 907INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 908 void *ctx; 909 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 910 // FIXME: figure out read size based on the address family. 911 int res = REAL(inet_pton)(af, src, dst); 912 if (res == 1) { 913 uptr sz = __sanitizer_in_addr_sz(af); 914 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 915 } 916 return res; 917} 918#define INIT_INET \ 919 INTERCEPT_FUNCTION(inet_ntop); \ 920 INTERCEPT_FUNCTION(inet_pton); 921#else 922#define INIT_INET 923#endif 924 925#if SANITIZER_INTERCEPT_INET 926INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 927 void *ctx; 928 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 929 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 930 int res = REAL(inet_aton)(cp, dst); 931 if (res != 0) { 932 uptr sz = __sanitizer_in_addr_sz(af_inet); 933 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 934 } 935 return res; 936} 937#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 938#else 939#define INIT_INET_ATON 940#endif 941 942#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 943INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 944 void *ctx; 945 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 946 int res = REAL(pthread_getschedparam)(thread, policy, param); 947 if (res == 0) { 948 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 949 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 950 } 951 return res; 952} 953#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 954#else 955#define INIT_PTHREAD_GETSCHEDPARAM 956#endif 957 958#if SANITIZER_INTERCEPT_GETADDRINFO 959INTERCEPTOR(int, getaddrinfo, char *node, char *service, 960 struct __sanitizer_addrinfo *hints, 961 struct __sanitizer_addrinfo **out) { 962 void *ctx; 963 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 964 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 965 if (service) 966 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 967 if (hints) 968 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 969 int res = REAL(getaddrinfo)(node, service, hints, out); 970 if (res == 0 && out) { 971 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 972 struct __sanitizer_addrinfo *p = *out; 973 while (p) { 974 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 975 if (p->ai_addr) 976 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 977 if (p->ai_canonname) 978 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 979 REAL(strlen)(p->ai_canonname) + 1); 980 p = p->ai_next; 981 } 982 } 983 return res; 984} 985#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 986#else 987#define INIT_GETADDRINFO 988#endif 989 990#if SANITIZER_INTERCEPT_GETNAMEINFO 991INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 992 unsigned hostlen, char *serv, unsigned servlen, int flags) { 993 void *ctx; 994 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 995 serv, servlen, flags); 996 // FIXME: consider adding READ_RANGE(sockaddr, salen) 997 // There is padding in in_addr that may make this too noisy 998 int res = 999 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1000 if (res == 0) { 1001 if (host && hostlen) 1002 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1003 if (serv && servlen) 1004 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1005 } 1006 return res; 1007} 1008#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1009#else 1010#define INIT_GETNAMEINFO 1011#endif 1012 1013#if SANITIZER_INTERCEPT_GETSOCKNAME 1014INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1015 void *ctx; 1016 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1017 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1018 int addrlen_in = *addrlen; 1019 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1020 if (res == 0) { 1021 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1022 } 1023 return res; 1024} 1025#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1026#else 1027#define INIT_GETSOCKNAME 1028#endif 1029 1030#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1031static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1032 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1033 if (h->h_name) 1034 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1035 char **p = h->h_aliases; 1036 while (*p) { 1037 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1038 ++p; 1039 } 1040 COMMON_INTERCEPTOR_WRITE_RANGE( 1041 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1042 p = h->h_addr_list; 1043 while (*p) { 1044 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1045 ++p; 1046 } 1047 COMMON_INTERCEPTOR_WRITE_RANGE( 1048 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1049} 1050#endif 1051 1052#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1053INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1054 void *ctx; 1055 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1056 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1057 if (res) write_hostent(ctx, res); 1058 return res; 1059} 1060 1061INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1062 int type) { 1063 void *ctx; 1064 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1065 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1066 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1067 if (res) write_hostent(ctx, res); 1068 return res; 1069} 1070 1071INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 1072 void *ctx; 1073 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 1074 struct __sanitizer_hostent *res = REAL(gethostent)(); 1075 if (res) write_hostent(ctx, res); 1076 return res; 1077} 1078 1079INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1080 void *ctx; 1081 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1082 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1083 if (res) write_hostent(ctx, res); 1084 return res; 1085} 1086#define INIT_GETHOSTBYNAME \ 1087 INTERCEPT_FUNCTION(gethostent); \ 1088 INTERCEPT_FUNCTION(gethostbyaddr); \ 1089 INTERCEPT_FUNCTION(gethostbyname); \ 1090 INTERCEPT_FUNCTION(gethostbyname2); 1091#else 1092#define INIT_GETHOSTBYNAME 1093#endif 1094 1095#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1096INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1097 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1098 void *ctx; 1099 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1100 h_errnop); 1101 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1102 if (res == 0) { 1103 if (result) { 1104 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1105 if (*result) write_hostent(ctx, *result); 1106 } 1107 if (h_errnop) 1108 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1109 } 1110 return res; 1111} 1112 1113INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1114 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1115 __sanitizer_hostent **result, int *h_errnop) { 1116 void *ctx; 1117 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1118 buflen, result, h_errnop); 1119 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1120 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1121 h_errnop); 1122 if (res == 0) { 1123 if (result) { 1124 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1125 if (*result) write_hostent(ctx, *result); 1126 } 1127 if (h_errnop) 1128 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1129 } 1130 return res; 1131} 1132 1133INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1134 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1135 int *h_errnop) { 1136 void *ctx; 1137 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1138 h_errnop); 1139 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1140 if (res == 0) { 1141 if (result) { 1142 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1143 if (*result) write_hostent(ctx, *result); 1144 } 1145 if (h_errnop) 1146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1147 } 1148 return res; 1149} 1150 1151INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1152 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1153 __sanitizer_hostent **result, int *h_errnop) { 1154 void *ctx; 1155 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1156 result, h_errnop); 1157 int res = 1158 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1159 if (res == 0) { 1160 if (result) { 1161 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1162 if (*result) write_hostent(ctx, *result); 1163 } 1164 if (h_errnop) 1165 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1166 } 1167 return res; 1168} 1169#define INIT_GETHOSTBYNAME_R \ 1170 INTERCEPT_FUNCTION(gethostent_r); \ 1171 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1172 INTERCEPT_FUNCTION(gethostbyname_r); \ 1173 INTERCEPT_FUNCTION(gethostbyname2_r); 1174#else 1175#define INIT_GETHOSTBYNAME_R 1176#endif 1177 1178#if SANITIZER_INTERCEPT_GETSOCKOPT 1179INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1180 int *optlen) { 1181 void *ctx; 1182 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1183 optlen); 1184 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1185 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1186 if (res == 0) 1187 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1188 return res; 1189} 1190#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1191#else 1192#define INIT_GETSOCKOPT 1193#endif 1194 1195#if SANITIZER_INTERCEPT_ACCEPT 1196INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1197 void *ctx; 1198 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1199 unsigned addrlen0; 1200 if (addrlen) { 1201 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1202 addrlen0 = *addrlen; 1203 } 1204 int fd2 = REAL(accept)(fd, addr, addrlen); 1205 if (fd2 >= 0) { 1206 if (fd >= 0) 1207 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1208 if (addr && addrlen) 1209 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1210 } 1211 return fd2; 1212} 1213#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1214#else 1215#define INIT_ACCEPT 1216#endif 1217 1218#if SANITIZER_INTERCEPT_ACCEPT4 1219INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1220 void *ctx; 1221 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1222 unsigned addrlen0; 1223 if (addrlen) { 1224 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1225 addrlen0 = *addrlen; 1226 } 1227 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1228 if (fd2 >= 0) { 1229 if (fd >= 0) 1230 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1231 if (addr && addrlen) 1232 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1233 } 1234 return fd2; 1235} 1236#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1237#else 1238#define INIT_ACCEPT4 1239#endif 1240 1241#if SANITIZER_INTERCEPT_MODF 1242INTERCEPTOR(double, modf, double x, double *iptr) { 1243 void *ctx; 1244 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1245 double res = REAL(modf)(x, iptr); 1246 if (iptr) { 1247 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1248 } 1249 return res; 1250} 1251INTERCEPTOR(float, modff, float x, float *iptr) { 1252 void *ctx; 1253 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1254 float res = REAL(modff)(x, iptr); 1255 if (iptr) { 1256 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1257 } 1258 return res; 1259} 1260INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1261 void *ctx; 1262 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1263 long double res = REAL(modfl)(x, iptr); 1264 if (iptr) { 1265 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1266 } 1267 return res; 1268} 1269#define INIT_MODF \ 1270 INTERCEPT_FUNCTION(modf); \ 1271 INTERCEPT_FUNCTION(modff); \ 1272 INTERCEPT_FUNCTION(modfl); 1273#else 1274#define INIT_MODF 1275#endif 1276 1277#if SANITIZER_INTERCEPT_RECVMSG 1278static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1279 SSIZE_T maxlen) { 1280 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1281 if (msg->msg_name) 1282 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1283 REAL(strlen)((char *)msg->msg_name) + 1); 1284 if (msg->msg_iov) 1285 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1286 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1287 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1288 if (msg->msg_control) 1289 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1290} 1291 1292INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1293 int flags) { 1294 void *ctx; 1295 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1296 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1297 if (res >= 0) { 1298 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1299 if (msg) write_msghdr(ctx, msg, res); 1300 } 1301 return res; 1302} 1303#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1304#else 1305#define INIT_RECVMSG 1306#endif 1307 1308#if SANITIZER_INTERCEPT_GETPEERNAME 1309INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1310 void *ctx; 1311 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1312 unsigned addr_sz; 1313 if (addrlen) addr_sz = *addrlen; 1314 int res = REAL(getpeername)(sockfd, addr, addrlen); 1315 if (!res && addr && addrlen) 1316 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1317 return res; 1318} 1319#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1320#else 1321#define INIT_GETPEERNAME 1322#endif 1323 1324#if SANITIZER_INTERCEPT_SYSINFO 1325INTERCEPTOR(int, sysinfo, void *info) { 1326 void *ctx; 1327 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1328 int res = REAL(sysinfo)(info); 1329 if (!res && info) 1330 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1331 return res; 1332} 1333#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1334#else 1335#define INIT_SYSINFO 1336#endif 1337 1338#if SANITIZER_INTERCEPT_READDIR 1339INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1340 void *ctx; 1341 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1342 __sanitizer_dirent *res = REAL(readdir)(dirp); 1343 if (res) 1344 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1345 return res; 1346} 1347 1348INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1349 __sanitizer_dirent **result) { 1350 void *ctx; 1351 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1352 int res = REAL(readdir_r)(dirp, entry, result); 1353 if (!res) { 1354 if (result) 1355 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1356 if (entry) 1357 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1358 } 1359 return res; 1360} 1361 1362#define INIT_READDIR \ 1363 INTERCEPT_FUNCTION(readdir); \ 1364 INTERCEPT_FUNCTION(readdir_r); 1365#else 1366#define INIT_READDIR 1367#endif 1368 1369#if SANITIZER_INTERCEPT_READDIR64 1370INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1371 void *ctx; 1372 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1373 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1374 if (res) 1375 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1376 return res; 1377} 1378 1379INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1380 __sanitizer_dirent64 **result) { 1381 void *ctx; 1382 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1383 int res = REAL(readdir64_r)(dirp, entry, result); 1384 if (!res) { 1385 if (result) 1386 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1387 if (entry) 1388 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, entry, entry->d_reclen); 1389 } 1390 return res; 1391} 1392#define INIT_READDIR64 \ 1393 INTERCEPT_FUNCTION(readdir64); \ 1394 INTERCEPT_FUNCTION(readdir64_r); 1395#else 1396#define INIT_READDIR64 1397#endif 1398 1399#if SANITIZER_INTERCEPT_PTRACE 1400INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1401 void *ctx; 1402 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1403 1404 if (data) { 1405 if (request == ptrace_setregs) 1406 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1407 else if (request == ptrace_setfpregs) 1408 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1409 else if (request == ptrace_setfpxregs) 1410 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1411 else if (request == ptrace_setsiginfo) 1412 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1413 else if (request == ptrace_setregset) { 1414 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1415 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1416 } 1417 } 1418 1419 uptr res = REAL(ptrace)(request, pid, addr, data); 1420 1421 if (!res && data) { 1422 // Note that PEEK* requests assing different meaning to the return value. 1423 // This function does not handle them (nor does it need to). 1424 if (request == ptrace_getregs) 1425 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1426 else if (request == ptrace_getfpregs) 1427 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1428 else if (request == ptrace_getfpxregs) 1429 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1430 else if (request == ptrace_getsiginfo) 1431 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1432 else if (request == ptrace_getregset) { 1433 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1434 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1435 } 1436 } 1437 return res; 1438} 1439 1440#define INIT_PTRACE \ 1441 INTERCEPT_FUNCTION(ptrace); 1442#else 1443#define INIT_PTRACE 1444#endif 1445 1446#if SANITIZER_INTERCEPT_SETLOCALE 1447INTERCEPTOR(char *, setlocale, int category, char *locale) { 1448 void *ctx; 1449 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1450 if (locale) 1451 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1452 char *res = REAL(setlocale)(category, locale); 1453 if (res) 1454 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1455 return res; 1456} 1457 1458#define INIT_SETLOCALE \ 1459 INTERCEPT_FUNCTION(setlocale); 1460#else 1461#define INIT_SETLOCALE 1462#endif 1463 1464#if SANITIZER_INTERCEPT_GETCWD 1465INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1466 void *ctx; 1467 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1468 char *res = REAL(getcwd)(buf, size); 1469 if (res) 1470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1471 return res; 1472} 1473#define INIT_GETCWD \ 1474 INTERCEPT_FUNCTION(getcwd); 1475#else 1476#define INIT_GETCWD 1477#endif 1478 1479#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1480INTERCEPTOR(char *, get_current_dir_name) { 1481 void *ctx; 1482 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name); 1483 char *res = REAL(get_current_dir_name)(); 1484 if (res) 1485 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1486 return res; 1487} 1488 1489#define INIT_GET_CURRENT_DIR_NAME \ 1490 INTERCEPT_FUNCTION(get_current_dir_name); 1491#else 1492#define INIT_GET_CURRENT_DIR_NAME 1493#endif 1494 1495#if SANITIZER_INTERCEPT_STRTOIMAX 1496INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1497 void *ctx; 1498 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1499 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1500 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1501 return res; 1502} 1503 1504INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1505 void *ctx; 1506 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1507 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1508 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1509 return res; 1510} 1511 1512#define INIT_STRTOIMAX \ 1513 INTERCEPT_FUNCTION(strtoimax); \ 1514 INTERCEPT_FUNCTION(strtoumax); 1515#else 1516#define INIT_STRTOIMAX 1517#endif 1518 1519#if SANITIZER_INTERCEPT_MBSTOWCS 1520INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1521 void *ctx; 1522 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1523 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1524 if (res != (SIZE_T) - 1 && dest) 1525 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1526 return res; 1527} 1528 1529INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1530 void *ps) { 1531 void *ctx; 1532 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1533 if (src) { 1534 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1535 } 1536 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1537 if (res != (SIZE_T) - 1 && dest) 1538 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1539 return res; 1540} 1541 1542#define INIT_MBSTOWCS \ 1543 INTERCEPT_FUNCTION(mbstowcs); \ 1544 INTERCEPT_FUNCTION(mbsrtowcs); 1545#else 1546#define INIT_MBSTOWCS 1547#endif 1548 1549#if SANITIZER_INTERCEPT_MBSNRTOWCS 1550INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1551 SIZE_T len, void *ps) { 1552 void *ctx; 1553 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1554 if (src) { 1555 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1556 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1557 } 1558 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1559 if (res != (SIZE_T) - 1 && dest) 1560 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, (res + 1) * sizeof(wchar_t)); 1561 return res; 1562} 1563 1564#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1565#else 1566#define INIT_MBSNRTOWCS 1567#endif 1568 1569#if SANITIZER_INTERCEPT_WCSTOMBS 1570INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1571 void *ctx; 1572 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1573 SIZE_T res = REAL(wcstombs)(dest, src, len); 1574 if (res != (SIZE_T) - 1 && dest) 1575 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1576 return res; 1577} 1578 1579INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1580 void *ps) { 1581 void *ctx; 1582 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1583 if (src) { 1584 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1585 } 1586 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1587 if (res != (SIZE_T) - 1 && dest) 1588 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1589 return res; 1590} 1591 1592#define INIT_WCSTOMBS \ 1593 INTERCEPT_FUNCTION(wcstombs); \ 1594 INTERCEPT_FUNCTION(wcsrtombs); 1595#else 1596#define INIT_WCSTOMBS 1597#endif 1598 1599#if SANITIZER_INTERCEPT_WCSNRTOMBS 1600INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1601 SIZE_T len, void *ps) { 1602 void *ctx; 1603 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1604 if (src) { 1605 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1606 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1607 } 1608 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1609 if (res != (SIZE_T) - 1 && dest) 1610 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res + 1); 1611 return res; 1612} 1613 1614#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1615#else 1616#define INIT_WCSNRTOMBS 1617#endif 1618 1619 1620#if SANITIZER_INTERCEPT_TCGETATTR 1621INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1622 void *ctx; 1623 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1624 int res = REAL(tcgetattr)(fd, termios_p); 1625 if (!res && termios_p) 1626 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1627 return res; 1628} 1629 1630#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1631#else 1632#define INIT_TCGETATTR 1633#endif 1634 1635 1636#if SANITIZER_INTERCEPT_REALPATH 1637INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1638 void *ctx; 1639 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1640 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1641 1642 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1643 // version of a versioned symbol. For realpath(), this gives us something 1644 // (called __old_realpath) that does not handle NULL in the second argument. 1645 // Handle it as part of the interceptor. 1646 char *allocated_path = 0; 1647 if (!resolved_path) 1648 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1649 1650 char *res = REAL(realpath)(path, resolved_path); 1651 if (allocated_path && !res) 1652 WRAP(free)(allocated_path); 1653 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1654 return res; 1655} 1656#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1657#else 1658#define INIT_REALPATH 1659#endif 1660 1661#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1662INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1663 void *ctx; 1664 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1665 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1666 char *res = REAL(canonicalize_file_name)(path); 1667 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1668 return res; 1669} 1670#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1671#else 1672#define INIT_CANONICALIZE_FILE_NAME 1673#endif 1674 1675#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 1676 INIT_STRCASECMP; \ 1677 INIT_STRNCASECMP; \ 1678 INIT_READ; \ 1679 INIT_PREAD; \ 1680 INIT_PREAD64; \ 1681 INIT_READV; \ 1682 INIT_PREADV; \ 1683 INIT_PREADV64; \ 1684 INIT_WRITE; \ 1685 INIT_PWRITE; \ 1686 INIT_PWRITE64; \ 1687 INIT_WRITEV; \ 1688 INIT_PWRITEV; \ 1689 INIT_PWRITEV64; \ 1690 INIT_PRCTL; \ 1691 INIT_LOCALTIME_AND_FRIENDS; \ 1692 INIT_SCANF; \ 1693 INIT_FREXP; \ 1694 INIT_FREXPF_FREXPL; \ 1695 INIT_GETPWNAM_AND_FRIENDS; \ 1696 INIT_GETPWNAM_R_AND_FRIENDS; \ 1697 INIT_CLOCK_GETTIME; \ 1698 INIT_GETITIMER; \ 1699 INIT_TIME; \ 1700 INIT_GLOB; \ 1701 INIT_WAIT; \ 1702 INIT_INET; \ 1703 INIT_PTHREAD_GETSCHEDPARAM; \ 1704 INIT_GETADDRINFO; \ 1705 INIT_GETNAMEINFO; \ 1706 INIT_GETSOCKNAME; \ 1707 INIT_GETHOSTBYNAME; \ 1708 INIT_GETHOSTBYNAME_R; \ 1709 INIT_GETSOCKOPT; \ 1710 INIT_ACCEPT; \ 1711 INIT_ACCEPT4; \ 1712 INIT_MODF; \ 1713 INIT_RECVMSG; \ 1714 INIT_GETPEERNAME; \ 1715 INIT_IOCTL; \ 1716 INIT_INET_ATON; \ 1717 INIT_SYSINFO; \ 1718 INIT_READDIR; \ 1719 INIT_READDIR64; \ 1720 INIT_PTRACE; \ 1721 INIT_SETLOCALE; \ 1722 INIT_GETCWD; \ 1723 INIT_GET_CURRENT_DIR_NAME; \ 1724 INIT_STRTOIMAX; \ 1725 INIT_MBSTOWCS; \ 1726 INIT_MBSNRTOWCS; \ 1727 INIT_WCSTOMBS; \ 1728 INIT_WCSNRTOMBS; \ 1729 INIT_TCGETATTR; \ 1730 INIT_REALPATH; \ 1731 INIT_CANONICALIZE_FILE_NAME; 1732