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