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