sanitizer_common_interceptors.inc revision b2dc6137eaa16f45401a6905f5aff1e894ae0975
1//===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// Common function interceptors for tools like AddressSanitizer, 11// ThreadSanitizer, MemorySanitizer, etc. 12// 13// This file should be included into the tool's interceptor file, 14// which has to define it's own macros: 15// COMMON_INTERCEPTOR_ENTER 16// COMMON_INTERCEPTOR_READ_RANGE 17// COMMON_INTERCEPTOR_WRITE_RANGE 18// COMMON_INTERCEPTOR_FD_ACQUIRE 19// COMMON_INTERCEPTOR_FD_RELEASE 20// COMMON_INTERCEPTOR_SET_THREAD_NAME 21//===----------------------------------------------------------------------===// 22#include "interception/interception.h" 23#include "sanitizer_platform_interceptors.h" 24 25#include <stdarg.h> 26 27#if SANITIZER_WINDOWS 28#define va_copy(dst, src) ((dst) = (src)) 29#endif // _WIN32 30 31#if SANITIZER_INTERCEPT_STRCMP 32static inline int CharCmpX(unsigned char c1, unsigned char c2) { 33 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 34} 35 36INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 37 void *ctx; 38 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 39 unsigned char c1, c2; 40 uptr i; 41 for (i = 0; ; i++) { 42 c1 = (unsigned char)s1[i]; 43 c2 = (unsigned char)s2[i]; 44 if (c1 != c2 || c1 == '\0') break; 45 } 46 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 47 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 48 return CharCmpX(c1, c2); 49} 50 51INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 52 void *ctx; 53 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 54 unsigned char c1 = 0, c2 = 0; 55 uptr i; 56 for (i = 0; i < size; i++) { 57 c1 = (unsigned char)s1[i]; 58 c2 = (unsigned char)s2[i]; 59 if (c1 != c2 || c1 == '\0') break; 60 } 61 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 62 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 63 return CharCmpX(c1, c2); 64} 65 66#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp) 67#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp) 68#else 69#define INIT_STRCMP 70#define INIT_STRNCMP 71#endif 72 73#if SANITIZER_INTERCEPT_STRCASECMP 74static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 75 int c1_low = ToLower(c1); 76 int c2_low = ToLower(c2); 77 return c1_low - c2_low; 78} 79 80INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 81 void *ctx; 82 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 83 unsigned char c1 = 0, c2 = 0; 84 uptr i; 85 for (i = 0; ; i++) { 86 c1 = (unsigned char)s1[i]; 87 c2 = (unsigned char)s2[i]; 88 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 89 break; 90 } 91 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 92 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 93 return CharCaseCmp(c1, c2); 94} 95 96INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 97 void *ctx; 98 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 99 unsigned char c1 = 0, c2 = 0; 100 uptr i; 101 for (i = 0; i < n; i++) { 102 c1 = (unsigned char)s1[i]; 103 c2 = (unsigned char)s2[i]; 104 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 105 break; 106 } 107 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 108 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 109 return CharCaseCmp(c1, c2); 110} 111 112#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 113#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 114#else 115#define INIT_STRCASECMP 116#define INIT_STRNCASECMP 117#endif 118 119#if SANITIZER_INTERCEPT_FREXP 120INTERCEPTOR(double, frexp, double x, int *exp) { 121 void *ctx; 122 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 123 double res = REAL(frexp)(x, exp); 124 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 125 return res; 126} 127 128#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 129#else 130#define INIT_FREXP 131#endif // SANITIZER_INTERCEPT_FREXP 132 133#if SANITIZER_INTERCEPT_FREXPF_FREXPL 134INTERCEPTOR(float, frexpf, float x, int *exp) { 135 void *ctx; 136 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 137 float res = REAL(frexpf)(x, exp); 138 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 139 return res; 140} 141 142INTERCEPTOR(long double, frexpl, long double x, int *exp) { 143 void *ctx; 144 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 145 long double res = REAL(frexpl)(x, exp); 146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 147 return res; 148} 149 150#define INIT_FREXPF_FREXPL \ 151 INTERCEPT_FUNCTION(frexpf); \ 152 INTERCEPT_FUNCTION(frexpl) 153#else 154#define INIT_FREXPF_FREXPL 155#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 156 157#if SI_NOT_WINDOWS 158static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 159 SIZE_T iovlen, SIZE_T maxlen) { 160 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 161 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 162 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 163 maxlen -= sz; 164 } 165} 166 167static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 168 SIZE_T iovlen, SIZE_T maxlen) { 169 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 170 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 171 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 172 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 173 maxlen -= sz; 174 } 175} 176#endif 177 178#if SANITIZER_INTERCEPT_READ 179INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 180 void *ctx; 181 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 182 SSIZE_T res = REAL(read)(fd, ptr, count); 183 if (res > 0) 184 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 185 if (res >= 0 && fd >= 0) 186 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 187 return res; 188} 189#define INIT_READ INTERCEPT_FUNCTION(read) 190#else 191#define INIT_READ 192#endif 193 194#if SANITIZER_INTERCEPT_PREAD 195INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 196 void *ctx; 197 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 198 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 199 if (res > 0) 200 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 201 if (res >= 0 && fd >= 0) 202 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 203 return res; 204} 205#define INIT_PREAD INTERCEPT_FUNCTION(pread) 206#else 207#define INIT_PREAD 208#endif 209 210#if SANITIZER_INTERCEPT_PREAD64 211INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 212 void *ctx; 213 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 214 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 215 if (res > 0) 216 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 217 if (res >= 0 && fd >= 0) 218 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 219 return res; 220} 221#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 222#else 223#define INIT_PREAD64 224#endif 225 226#if SANITIZER_INTERCEPT_READV 227INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 228 int iovcnt) { 229 void *ctx; 230 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 231 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 232 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 233 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 234 return res; 235} 236#define INIT_READV INTERCEPT_FUNCTION(readv) 237#else 238#define INIT_READV 239#endif 240 241#if SANITIZER_INTERCEPT_PREADV 242INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 243 OFF_T offset) { 244 void *ctx; 245 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 246 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 247 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 248 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 249 return res; 250} 251#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 252#else 253#define INIT_PREADV 254#endif 255 256#if SANITIZER_INTERCEPT_PREADV64 257INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 258 OFF64_T offset) { 259 void *ctx; 260 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 261 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 262 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 263 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 264 return res; 265} 266#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 267#else 268#define INIT_PREADV64 269#endif 270 271#if SANITIZER_INTERCEPT_WRITE 272INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 273 void *ctx; 274 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 275 if (fd >= 0) 276 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 277 SSIZE_T res = REAL(write)(fd, ptr, count); 278 // FIXME: this check should be _before_ the call to REAL(write), not after 279 if (res > 0) 280 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 281 return res; 282} 283#define INIT_WRITE INTERCEPT_FUNCTION(write) 284#else 285#define INIT_WRITE 286#endif 287 288#if SANITIZER_INTERCEPT_PWRITE 289INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 290 void *ctx; 291 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 292 if (fd >= 0) 293 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 294 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 295 if (res > 0) 296 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 297 return res; 298} 299#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 300#else 301#define INIT_PWRITE 302#endif 303 304#if SANITIZER_INTERCEPT_PWRITE64 305INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 306 OFF64_T offset) { 307 void *ctx; 308 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 309 if (fd >= 0) 310 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 311 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 312 if (res > 0) 313 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 314 return res; 315} 316#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 317#else 318#define INIT_PWRITE64 319#endif 320 321#if SANITIZER_INTERCEPT_WRITEV 322INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 323 int iovcnt) { 324 void *ctx; 325 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 326 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 327 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 328 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 329 return res; 330} 331#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 332#else 333#define INIT_WRITEV 334#endif 335 336#if SANITIZER_INTERCEPT_PWRITEV 337INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 338 OFF_T offset) { 339 void *ctx; 340 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 341 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 342 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 343 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 344 return res; 345} 346#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 347#else 348#define INIT_PWRITEV 349#endif 350 351#if SANITIZER_INTERCEPT_PWRITEV64 352INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 353 OFF64_T offset) { 354 void *ctx; 355 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 356 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 357 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 358 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 359 return res; 360} 361#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 362#else 363#define INIT_PWRITEV64 364#endif 365 366#if SANITIZER_INTERCEPT_PRCTL 367INTERCEPTOR(int, prctl, int option, 368 unsigned long arg2, unsigned long arg3, // NOLINT 369 unsigned long arg4, unsigned long arg5) { // NOLINT 370 void *ctx; 371 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 372 static const int PR_SET_NAME = 15; 373 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 374 if (option == PR_SET_NAME) { 375 char buff[16]; 376 internal_strncpy(buff, (char *)arg2, 15); 377 buff[15] = 0; 378 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 379 } 380 return res; 381} 382#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 383#else 384#define INIT_PRCTL 385#endif // SANITIZER_INTERCEPT_PRCTL 386 387 388#if SANITIZER_INTERCEPT_TIME 389INTERCEPTOR(unsigned long, time, unsigned long *t) { 390 void *ctx; 391 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 392 unsigned long res = REAL(time)(t); 393 if (t && res != (unsigned long)-1) { 394 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 395 } 396 return res; 397} 398#define INIT_TIME \ 399 INTERCEPT_FUNCTION(time); 400#else 401#define INIT_TIME 402#endif // SANITIZER_INTERCEPT_TIME 403 404 405#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 406INTERCEPTOR(void *, localtime, unsigned long *timep) { 407 void *ctx; 408 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 409 void *res = REAL(localtime)(timep); 410 if (res) { 411 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 412 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 413 } 414 return res; 415} 416INTERCEPTOR(void *, localtime_r, unsigned long *timep, void *result) { 417 void *ctx; 418 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 419 void *res = REAL(localtime_r)(timep, result); 420 if (res) { 421 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 422 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 423 } 424 return res; 425} 426INTERCEPTOR(void *, gmtime, unsigned long *timep) { 427 void *ctx; 428 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 429 void *res = REAL(gmtime)(timep); 430 if (res) { 431 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 432 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 433 } 434 return res; 435} 436INTERCEPTOR(void *, gmtime_r, unsigned long *timep, void *result) { 437 void *ctx; 438 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 439 void *res = REAL(gmtime_r)(timep, result); 440 if (res) { 441 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 442 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_tm_sz); 443 } 444 return res; 445} 446INTERCEPTOR(char *, ctime, unsigned long *timep) { 447 void *ctx; 448 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 449 char *res = REAL(ctime)(timep); 450 if (res) { 451 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 452 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 453 } 454 return res; 455} 456INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 457 void *ctx; 458 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 459 char *res = REAL(ctime_r)(timep, result); 460 if (res) { 461 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 462 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 463 } 464 return res; 465} 466INTERCEPTOR(char *, asctime, void *tm) { 467 void *ctx; 468 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 469 char *res = REAL(asctime)(tm); 470 if (res) { 471 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 472 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 473 } 474 return res; 475} 476INTERCEPTOR(char *, asctime_r, void *tm, char *result) { 477 void *ctx; 478 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 479 char *res = REAL(asctime_r)(tm, result); 480 if (res) { 481 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, struct_tm_sz); 482 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 483 } 484 return res; 485} 486#define INIT_LOCALTIME_AND_FRIENDS \ 487 INTERCEPT_FUNCTION(localtime); \ 488 INTERCEPT_FUNCTION(localtime_r); \ 489 INTERCEPT_FUNCTION(gmtime); \ 490 INTERCEPT_FUNCTION(gmtime_r); \ 491 INTERCEPT_FUNCTION(ctime); \ 492 INTERCEPT_FUNCTION(ctime_r); \ 493 INTERCEPT_FUNCTION(asctime); \ 494 INTERCEPT_FUNCTION(asctime_r); 495#else 496#define INIT_LOCALTIME_AND_FRIENDS 497#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 498 499#if SANITIZER_INTERCEPT_SCANF 500 501#include "sanitizer_common_interceptors_scanf.inc" 502 503#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 504 { \ 505 void *ctx; \ 506 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 507 va_list aq; \ 508 va_copy(aq, ap); \ 509 int res = REAL(vname)(__VA_ARGS__); \ 510 if (res > 0) \ 511 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 512 va_end(aq); \ 513 return res; \ 514 } 515 516INTERCEPTOR(int, vscanf, const char *format, va_list ap) 517VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 518 519INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 520VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 521 522INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 523VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 524 525#if SANITIZER_INTERCEPT_ISOC99_SCANF 526INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 527VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 528 529INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 530 va_list ap) 531VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 532 533INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 534VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 535#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 536 537#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 538 { \ 539 void *ctx; \ 540 COMMON_INTERCEPTOR_ENTER(ctx, name, __VA_ARGS__); \ 541 va_list ap; \ 542 va_start(ap, format); \ 543 int res = vname(__VA_ARGS__, ap); \ 544 va_end(ap); \ 545 return res; \ 546 } 547 548INTERCEPTOR(int, scanf, const char *format, ...) 549SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 550 551INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 552SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 553 554INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 555SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 556 557#if SANITIZER_INTERCEPT_ISOC99_SCANF 558INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 559SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 560 561INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 562SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 563 564INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 565SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 566#endif 567 568#define INIT_SCANF \ 569 INTERCEPT_FUNCTION(scanf); \ 570 INTERCEPT_FUNCTION(sscanf); \ 571 INTERCEPT_FUNCTION(fscanf); \ 572 INTERCEPT_FUNCTION(vscanf); \ 573 INTERCEPT_FUNCTION(vsscanf); \ 574 INTERCEPT_FUNCTION(vfscanf); \ 575 INTERCEPT_FUNCTION(__isoc99_scanf); \ 576 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 577 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 578 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 579 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 580 INTERCEPT_FUNCTION(__isoc99_vfscanf); 581 582#else 583#define INIT_SCANF 584#endif 585 586 587#if SANITIZER_INTERCEPT_IOCTL 588#include "sanitizer_common_interceptors_ioctl.inc" 589INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 590 void *ctx; 591 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 592 593 CHECK(ioctl_initialized); 594 595 // Note: TSan does not use common flags, and they are zero-initialized. 596 // This effectively disables ioctl handling in TSan. 597 if (!common_flags()->handle_ioctl) 598 return REAL(ioctl)(d, request, arg); 599 600 const ioctl_desc *desc = ioctl_lookup(request); 601 if (!desc) 602 Printf("WARNING: unknown ioctl %x\n", request); 603 604 if (desc) 605 ioctl_common_pre(ctx, desc, d, request, arg); 606 int res = REAL(ioctl)(d, request, arg); 607 // FIXME: some ioctls have different return values for success and failure. 608 if (desc && res != -1) 609 ioctl_common_post(ctx, desc, res, d, request, arg); 610 return res; 611} 612#define INIT_IOCTL \ 613 ioctl_init(); \ 614 INTERCEPT_FUNCTION(ioctl); 615#else 616#define INIT_IOCTL 617#endif 618 619 620#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 621INTERCEPTOR(void *, getpwnam, const char *name) { 622 void *ctx; 623 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 624 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 625 void *res = REAL(getpwnam)(name); 626 if (res != 0) 627 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 628 return res; 629} 630INTERCEPTOR(void *, getpwuid, u32 uid) { 631 void *ctx; 632 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 633 void *res = REAL(getpwuid)(uid); 634 if (res != 0) 635 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 636 return res; 637} 638INTERCEPTOR(void *, getgrnam, const char *name) { 639 void *ctx; 640 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 641 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 642 void *res = REAL(getgrnam)(name); 643 if (res != 0) 644 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 645 return res; 646} 647INTERCEPTOR(void *, getgrgid, u32 gid) { 648 void *ctx; 649 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 650 void *res = REAL(getgrgid)(gid); 651 if (res != 0) 652 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 653 return res; 654} 655#define INIT_GETPWNAM_AND_FRIENDS \ 656 INTERCEPT_FUNCTION(getpwnam); \ 657 INTERCEPT_FUNCTION(getpwuid); \ 658 INTERCEPT_FUNCTION(getgrnam); \ 659 INTERCEPT_FUNCTION(getgrgid); 660#else 661#define INIT_GETPWNAM_AND_FRIENDS 662#endif 663 664 665#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 666INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 667 char *buf, SIZE_T buflen, void **result) { 668 void *ctx; 669 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 670 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 671 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 672 if (!res) { 673 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 674 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 675 } 676 return res; 677} 678INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 679 char *buf, SIZE_T buflen, void **result) { 680 void *ctx; 681 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 682 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 683 if (!res) { 684 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 685 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 686 } 687 return res; 688} 689INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 690 char *buf, SIZE_T buflen, void **result) { 691 void *ctx; 692 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 693 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 694 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 695 if (!res) { 696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 697 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 698 } 699 return res; 700} 701INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 702 char *buf, SIZE_T buflen, void **result) { 703 void *ctx; 704 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 705 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 706 if (!res) { 707 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 708 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 709 } 710 return res; 711} 712#define INIT_GETPWNAM_R_AND_FRIENDS \ 713 INTERCEPT_FUNCTION(getpwnam_r); \ 714 INTERCEPT_FUNCTION(getpwuid_r); \ 715 INTERCEPT_FUNCTION(getgrnam_r); \ 716 INTERCEPT_FUNCTION(getgrgid_r); 717#else 718#define INIT_GETPWNAM_R_AND_FRIENDS 719#endif 720 721 722#if SANITIZER_INTERCEPT_CLOCK_GETTIME 723INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 724 void *ctx; 725 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 726 int res = REAL(clock_getres)(clk_id, tp); 727 if (!res && tp) { 728 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 729 } 730 return res; 731} 732INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 733 void *ctx; 734 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 735 int res = REAL(clock_gettime)(clk_id, tp); 736 if (!res) { 737 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 738 } 739 return res; 740} 741INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 742 void *ctx; 743 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 744 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 745 return REAL(clock_settime)(clk_id, tp); 746} 747#define INIT_CLOCK_GETTIME \ 748 INTERCEPT_FUNCTION(clock_getres); \ 749 INTERCEPT_FUNCTION(clock_gettime); \ 750 INTERCEPT_FUNCTION(clock_settime); 751#else 752#define INIT_CLOCK_GETTIME 753#endif 754 755 756#if SANITIZER_INTERCEPT_GETITIMER 757INTERCEPTOR(int, getitimer, int which, void *curr_value) { 758 void *ctx; 759 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 760 int res = REAL(getitimer)(which, curr_value); 761 if (!res) { 762 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 763 } 764 return res; 765} 766INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 767 void *ctx; 768 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 769 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 770 int res = REAL(setitimer)(which, new_value, old_value); 771 if (!res && old_value) { 772 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 773 } 774 return res; 775} 776#define INIT_GETITIMER \ 777 INTERCEPT_FUNCTION(getitimer); \ 778 INTERCEPT_FUNCTION(setitimer); 779#else 780#define INIT_GETITIMER 781#endif 782 783#if SANITIZER_INTERCEPT_GLOB 784static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 785 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 786 // +1 for NULL pointer at the end. 787 if (pglob->gl_pathv) 788 COMMON_INTERCEPTOR_WRITE_RANGE( 789 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 790 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 791 char *p = pglob->gl_pathv[i]; 792 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 793 } 794} 795 796static THREADLOCAL __sanitizer_glob_t* pglob_copy; 797static THREADLOCAL void* glob_ctx; 798 799static void wrapped_gl_closedir(void *dir) { 800 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 801 pglob_copy->gl_closedir(dir); 802} 803 804static void *wrapped_gl_readdir(void *dir) { 805 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 806 return pglob_copy->gl_readdir(dir); 807} 808 809static void *wrapped_gl_opendir(const char *s) { 810 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 811 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 812 return pglob_copy->gl_opendir(s); 813} 814 815static int wrapped_gl_lstat(const char *s, void *st) { 816 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 817 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 818 return pglob_copy->gl_lstat(s, st); 819} 820 821static int wrapped_gl_stat(const char *s, void *st) { 822 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 823 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 824 return pglob_copy->gl_stat(s, st); 825} 826 827INTERCEPTOR(int, glob, const char *pattern, int flags, 828 int (*errfunc)(const char *epath, int eerrno), 829 __sanitizer_glob_t *pglob) { 830 void *ctx; 831 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 832 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 833 wrapped_gl_readdir, wrapped_gl_opendir, 834 wrapped_gl_lstat, wrapped_gl_stat}; 835 if (flags & glob_altdirfunc) { 836 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 837 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 838 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 839 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 840 Swap(pglob->gl_stat, glob_copy.gl_stat); 841 pglob_copy = &glob_copy; 842 glob_ctx = ctx; 843 } 844 int res = REAL(glob)(pattern, flags, errfunc, pglob); 845 if (flags & glob_altdirfunc) { 846 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 847 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 848 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 849 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 850 Swap(pglob->gl_stat, glob_copy.gl_stat); 851 } 852 pglob_copy = 0; 853 glob_ctx = 0; 854 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 855 return res; 856} 857 858INTERCEPTOR(int, glob64, const char *pattern, int flags, 859 int (*errfunc)(const char *epath, int eerrno), 860 __sanitizer_glob_t *pglob) { 861 void *ctx; 862 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 863 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 864 wrapped_gl_readdir, wrapped_gl_opendir, 865 wrapped_gl_lstat, wrapped_gl_stat}; 866 if (flags & glob_altdirfunc) { 867 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 868 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 869 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 870 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 871 Swap(pglob->gl_stat, glob_copy.gl_stat); 872 pglob_copy = &glob_copy; 873 glob_ctx = ctx; 874 } 875 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 876 if (flags & glob_altdirfunc) { 877 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 878 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 879 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 880 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 881 Swap(pglob->gl_stat, glob_copy.gl_stat); 882 } 883 pglob_copy = 0; 884 glob_ctx = 0; 885 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 886 return res; 887} 888#define INIT_GLOB \ 889 INTERCEPT_FUNCTION(glob); \ 890 INTERCEPT_FUNCTION(glob64); 891#else // SANITIZER_INTERCEPT_GLOB 892#define INIT_GLOB 893#endif // SANITIZER_INTERCEPT_GLOB 894 895#if SANITIZER_INTERCEPT_WAIT 896// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 897// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 898// details. 899INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 900 void *ctx; 901 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 902 int res = REAL(wait)(status); 903 if (res != -1 && status) 904 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 905 return res; 906} 907INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 908 int options) { 909 void *ctx; 910 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 911 int res = REAL(waitid)(idtype, id, infop, options); 912 if (res != -1 && infop) 913 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 914 return res; 915} 916INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 917 void *ctx; 918 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 919 int res = REAL(waitpid)(pid, status, options); 920 if (res != -1 && status) 921 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 922 return res; 923} 924INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 925 void *ctx; 926 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 927 int res = REAL(wait3)(status, options, rusage); 928 if (res != -1) { 929 if (status) 930 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 931 if (rusage) 932 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 933 } 934 return res; 935} 936INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 937 void *ctx; 938 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 939 int res = REAL(wait4)(pid, status, options, rusage); 940 if (res != -1) { 941 if (status) 942 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 943 if (rusage) 944 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 945 } 946 return res; 947} 948#define INIT_WAIT \ 949 INTERCEPT_FUNCTION(wait); \ 950 INTERCEPT_FUNCTION(waitid); \ 951 INTERCEPT_FUNCTION(waitpid); \ 952 INTERCEPT_FUNCTION(wait3); \ 953 INTERCEPT_FUNCTION(wait4); 954#else 955#define INIT_WAIT 956#endif 957 958#if SANITIZER_INTERCEPT_INET 959INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 960 void *ctx; 961 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 962 uptr sz = __sanitizer_in_addr_sz(af); 963 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 964 // FIXME: figure out read size based on the address family. 965 char *res = REAL(inet_ntop)(af, src, dst, size); 966 if (res) 967 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 968 return res; 969} 970INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 971 void *ctx; 972 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 973 // FIXME: figure out read size based on the address family. 974 int res = REAL(inet_pton)(af, src, dst); 975 if (res == 1) { 976 uptr sz = __sanitizer_in_addr_sz(af); 977 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 978 } 979 return res; 980} 981#define INIT_INET \ 982 INTERCEPT_FUNCTION(inet_ntop); \ 983 INTERCEPT_FUNCTION(inet_pton); 984#else 985#define INIT_INET 986#endif 987 988#if SANITIZER_INTERCEPT_INET 989INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 990 void *ctx; 991 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 992 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 993 int res = REAL(inet_aton)(cp, dst); 994 if (res != 0) { 995 uptr sz = __sanitizer_in_addr_sz(af_inet); 996 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 997 } 998 return res; 999} 1000#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 1001#else 1002#define INIT_INET_ATON 1003#endif 1004 1005#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1006INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1007 void *ctx; 1008 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1009 int res = REAL(pthread_getschedparam)(thread, policy, param); 1010 if (res == 0) { 1011 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1012 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1013 } 1014 return res; 1015} 1016#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 1017#else 1018#define INIT_PTHREAD_GETSCHEDPARAM 1019#endif 1020 1021#if SANITIZER_INTERCEPT_GETADDRINFO 1022INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1023 struct __sanitizer_addrinfo *hints, 1024 struct __sanitizer_addrinfo **out) { 1025 void *ctx; 1026 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1027 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1028 if (service) 1029 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1030 if (hints) 1031 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1032 int res = REAL(getaddrinfo)(node, service, hints, out); 1033 if (res == 0 && out) { 1034 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1035 struct __sanitizer_addrinfo *p = *out; 1036 while (p) { 1037 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1038 if (p->ai_addr) 1039 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1040 if (p->ai_canonname) 1041 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1042 REAL(strlen)(p->ai_canonname) + 1); 1043 p = p->ai_next; 1044 } 1045 } 1046 return res; 1047} 1048#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 1049#else 1050#define INIT_GETADDRINFO 1051#endif 1052 1053#if SANITIZER_INTERCEPT_GETNAMEINFO 1054INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1055 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1056 void *ctx; 1057 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1058 serv, servlen, flags); 1059 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1060 // There is padding in in_addr that may make this too noisy 1061 int res = 1062 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1063 if (res == 0) { 1064 if (host && hostlen) 1065 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1066 if (serv && servlen) 1067 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1068 } 1069 return res; 1070} 1071#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1072#else 1073#define INIT_GETNAMEINFO 1074#endif 1075 1076#if SANITIZER_INTERCEPT_GETSOCKNAME 1077INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1078 void *ctx; 1079 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1080 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1081 int addrlen_in = *addrlen; 1082 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1083 if (res == 0) { 1084 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1085 } 1086 return res; 1087} 1088#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1089#else 1090#define INIT_GETSOCKNAME 1091#endif 1092 1093#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1094static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1095 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1096 if (h->h_name) 1097 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1098 char **p = h->h_aliases; 1099 while (*p) { 1100 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1101 ++p; 1102 } 1103 COMMON_INTERCEPTOR_WRITE_RANGE( 1104 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1105 p = h->h_addr_list; 1106 while (*p) { 1107 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1108 ++p; 1109 } 1110 COMMON_INTERCEPTOR_WRITE_RANGE( 1111 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1112} 1113#endif 1114 1115#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1116INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1117 void *ctx; 1118 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1119 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1120 if (res) write_hostent(ctx, res); 1121 return res; 1122} 1123 1124INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1125 int type) { 1126 void *ctx; 1127 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1128 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1129 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1130 if (res) write_hostent(ctx, res); 1131 return res; 1132} 1133 1134INTERCEPTOR(struct __sanitizer_hostent *, gethostent) { 1135 void *ctx; 1136 COMMON_INTERCEPTOR_ENTER(ctx, gethostent); 1137 struct __sanitizer_hostent *res = REAL(gethostent)(); 1138 if (res) write_hostent(ctx, res); 1139 return res; 1140} 1141 1142INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1143 void *ctx; 1144 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1145 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1146 if (res) write_hostent(ctx, res); 1147 return res; 1148} 1149#define INIT_GETHOSTBYNAME \ 1150 INTERCEPT_FUNCTION(gethostent); \ 1151 INTERCEPT_FUNCTION(gethostbyaddr); \ 1152 INTERCEPT_FUNCTION(gethostbyname); \ 1153 INTERCEPT_FUNCTION(gethostbyname2); 1154#else 1155#define INIT_GETHOSTBYNAME 1156#endif 1157 1158#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1159INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1160 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1161 void *ctx; 1162 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1163 h_errnop); 1164 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1165 if (res == 0) { 1166 if (result) { 1167 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1168 if (*result) write_hostent(ctx, *result); 1169 } 1170 if (h_errnop) 1171 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1172 } 1173 return res; 1174} 1175 1176INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1177 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1178 __sanitizer_hostent **result, int *h_errnop) { 1179 void *ctx; 1180 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1181 buflen, result, h_errnop); 1182 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1183 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1184 h_errnop); 1185 if (res == 0) { 1186 if (result) { 1187 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1188 if (*result) write_hostent(ctx, *result); 1189 } 1190 if (h_errnop) 1191 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1192 } 1193 return res; 1194} 1195 1196INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1197 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1198 int *h_errnop) { 1199 void *ctx; 1200 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1201 h_errnop); 1202 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1203 if (res == 0) { 1204 if (result) { 1205 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1206 if (*result) write_hostent(ctx, *result); 1207 } 1208 if (h_errnop) 1209 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1210 } 1211 return res; 1212} 1213 1214INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1215 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1216 __sanitizer_hostent **result, int *h_errnop) { 1217 void *ctx; 1218 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1219 result, h_errnop); 1220 int res = 1221 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1222 if (res == 0) { 1223 if (result) { 1224 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1225 if (*result) write_hostent(ctx, *result); 1226 } 1227 if (h_errnop) 1228 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1229 } 1230 return res; 1231} 1232#define INIT_GETHOSTBYNAME_R \ 1233 INTERCEPT_FUNCTION(gethostent_r); \ 1234 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1235 INTERCEPT_FUNCTION(gethostbyname_r); \ 1236 INTERCEPT_FUNCTION(gethostbyname2_r); 1237#else 1238#define INIT_GETHOSTBYNAME_R 1239#endif 1240 1241#if SANITIZER_INTERCEPT_GETSOCKOPT 1242INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1243 int *optlen) { 1244 void *ctx; 1245 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1246 optlen); 1247 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1248 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1249 if (res == 0) 1250 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1251 return res; 1252} 1253#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1254#else 1255#define INIT_GETSOCKOPT 1256#endif 1257 1258#if SANITIZER_INTERCEPT_ACCEPT 1259INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1260 void *ctx; 1261 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1262 unsigned addrlen0; 1263 if (addrlen) { 1264 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1265 addrlen0 = *addrlen; 1266 } 1267 int fd2 = REAL(accept)(fd, addr, addrlen); 1268 if (fd2 >= 0) { 1269 if (fd >= 0) 1270 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1271 if (addr && addrlen) 1272 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1273 } 1274 return fd2; 1275} 1276#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1277#else 1278#define INIT_ACCEPT 1279#endif 1280 1281#if SANITIZER_INTERCEPT_ACCEPT4 1282INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1283 void *ctx; 1284 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1285 unsigned addrlen0; 1286 if (addrlen) { 1287 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1288 addrlen0 = *addrlen; 1289 } 1290 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1291 if (fd2 >= 0) { 1292 if (fd >= 0) 1293 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1294 if (addr && addrlen) 1295 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1296 } 1297 return fd2; 1298} 1299#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1300#else 1301#define INIT_ACCEPT4 1302#endif 1303 1304#if SANITIZER_INTERCEPT_MODF 1305INTERCEPTOR(double, modf, double x, double *iptr) { 1306 void *ctx; 1307 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1308 double res = REAL(modf)(x, iptr); 1309 if (iptr) { 1310 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1311 } 1312 return res; 1313} 1314INTERCEPTOR(float, modff, float x, float *iptr) { 1315 void *ctx; 1316 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1317 float res = REAL(modff)(x, iptr); 1318 if (iptr) { 1319 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1320 } 1321 return res; 1322} 1323INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1324 void *ctx; 1325 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1326 long double res = REAL(modfl)(x, iptr); 1327 if (iptr) { 1328 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1329 } 1330 return res; 1331} 1332#define INIT_MODF \ 1333 INTERCEPT_FUNCTION(modf); \ 1334 INTERCEPT_FUNCTION(modff); \ 1335 INTERCEPT_FUNCTION(modfl); 1336#else 1337#define INIT_MODF 1338#endif 1339 1340#if SANITIZER_INTERCEPT_RECVMSG 1341static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1342 SSIZE_T maxlen) { 1343 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1344 if (msg->msg_name) 1345 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, 1346 REAL(strlen)((char *)msg->msg_name) + 1); 1347 if (msg->msg_iov) 1348 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1349 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1350 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1351 if (msg->msg_control) 1352 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1353} 1354 1355INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1356 int flags) { 1357 void *ctx; 1358 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1359 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1360 if (res >= 0) { 1361 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1362 if (msg) write_msghdr(ctx, msg, res); 1363 } 1364 return res; 1365} 1366#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1367#else 1368#define INIT_RECVMSG 1369#endif 1370 1371#if SANITIZER_INTERCEPT_GETPEERNAME 1372INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1373 void *ctx; 1374 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1375 unsigned addr_sz; 1376 if (addrlen) addr_sz = *addrlen; 1377 int res = REAL(getpeername)(sockfd, addr, addrlen); 1378 if (!res && addr && addrlen) 1379 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1380 return res; 1381} 1382#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1383#else 1384#define INIT_GETPEERNAME 1385#endif 1386 1387#if SANITIZER_INTERCEPT_SYSINFO 1388INTERCEPTOR(int, sysinfo, void *info) { 1389 void *ctx; 1390 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1391 int res = REAL(sysinfo)(info); 1392 if (!res && info) 1393 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1394 return res; 1395} 1396#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1397#else 1398#define INIT_SYSINFO 1399#endif 1400 1401#if SANITIZER_INTERCEPT_READDIR 1402INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1403 void *ctx; 1404 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1405 __sanitizer_dirent *res = REAL(readdir)(dirp); 1406 if (res) 1407 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1408 return res; 1409} 1410 1411INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1412 __sanitizer_dirent **result) { 1413 void *ctx; 1414 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1415 int res = REAL(readdir_r)(dirp, entry, result); 1416 if (!res) { 1417 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1418 if (*result) 1419 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1420 } 1421 return res; 1422} 1423 1424#define INIT_READDIR \ 1425 INTERCEPT_FUNCTION(readdir); \ 1426 INTERCEPT_FUNCTION(readdir_r); 1427#else 1428#define INIT_READDIR 1429#endif 1430 1431#if SANITIZER_INTERCEPT_READDIR64 1432INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1433 void *ctx; 1434 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1435 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1436 if (res) 1437 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1438 return res; 1439} 1440 1441INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1442 __sanitizer_dirent64 **result) { 1443 void *ctx; 1444 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1445 int res = REAL(readdir64_r)(dirp, entry, result); 1446 if (!res) { 1447 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1448 if (*result) 1449 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1450 } 1451 return res; 1452} 1453#define INIT_READDIR64 \ 1454 INTERCEPT_FUNCTION(readdir64); \ 1455 INTERCEPT_FUNCTION(readdir64_r); 1456#else 1457#define INIT_READDIR64 1458#endif 1459 1460#if SANITIZER_INTERCEPT_PTRACE 1461INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1462 void *ctx; 1463 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1464 1465 if (data) { 1466 if (request == ptrace_setregs) 1467 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1468 else if (request == ptrace_setfpregs) 1469 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1470 else if (request == ptrace_setfpxregs) 1471 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1472 else if (request == ptrace_setsiginfo) 1473 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1474 else if (request == ptrace_setregset) { 1475 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1476 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1477 } 1478 } 1479 1480 uptr res = REAL(ptrace)(request, pid, addr, data); 1481 1482 if (!res && data) { 1483 // Note that PEEK* requests assing different meaning to the return value. 1484 // This function does not handle them (nor does it need to). 1485 if (request == ptrace_getregs) 1486 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1487 else if (request == ptrace_getfpregs) 1488 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1489 else if (request == ptrace_getfpxregs) 1490 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1491 else if (request == ptrace_getsiginfo) 1492 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1493 else if (request == ptrace_getregset) { 1494 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1495 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1496 } 1497 } 1498 return res; 1499} 1500 1501#define INIT_PTRACE \ 1502 INTERCEPT_FUNCTION(ptrace); 1503#else 1504#define INIT_PTRACE 1505#endif 1506 1507#if SANITIZER_INTERCEPT_SETLOCALE 1508INTERCEPTOR(char *, setlocale, int category, char *locale) { 1509 void *ctx; 1510 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1511 if (locale) 1512 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1513 char *res = REAL(setlocale)(category, locale); 1514 if (res) 1515 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1516 return res; 1517} 1518 1519#define INIT_SETLOCALE \ 1520 INTERCEPT_FUNCTION(setlocale); 1521#else 1522#define INIT_SETLOCALE 1523#endif 1524 1525#if SANITIZER_INTERCEPT_GETCWD 1526INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1527 void *ctx; 1528 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1529 char *res = REAL(getcwd)(buf, size); 1530 if (res) 1531 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1532 return res; 1533} 1534#define INIT_GETCWD \ 1535 INTERCEPT_FUNCTION(getcwd); 1536#else 1537#define INIT_GETCWD 1538#endif 1539 1540#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1541INTERCEPTOR(char *, get_current_dir_name) { 1542 void *ctx; 1543 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name); 1544 char *res = REAL(get_current_dir_name)(); 1545 if (res) 1546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1547 return res; 1548} 1549 1550#define INIT_GET_CURRENT_DIR_NAME \ 1551 INTERCEPT_FUNCTION(get_current_dir_name); 1552#else 1553#define INIT_GET_CURRENT_DIR_NAME 1554#endif 1555 1556#if SANITIZER_INTERCEPT_STRTOIMAX 1557INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1558 void *ctx; 1559 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1560 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1561 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1562 return res; 1563} 1564 1565INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1566 void *ctx; 1567 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1568 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1569 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1570 return res; 1571} 1572 1573#define INIT_STRTOIMAX \ 1574 INTERCEPT_FUNCTION(strtoimax); \ 1575 INTERCEPT_FUNCTION(strtoumax); 1576#else 1577#define INIT_STRTOIMAX 1578#endif 1579 1580#if SANITIZER_INTERCEPT_MBSTOWCS 1581INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1582 void *ctx; 1583 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1584 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1585 if (res != (SIZE_T) - 1 && dest) { 1586 SIZE_T write_cnt = res + (res < len); 1587 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1588 } 1589 return res; 1590} 1591 1592INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1593 void *ps) { 1594 void *ctx; 1595 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1596 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1597 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1598 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1599 if (res != (SIZE_T)(-1) && dest && src) { 1600 // This function, and several others, may or may not write the terminating 1601 // \0 character. They write it iff they clear *src. 1602 SIZE_T write_cnt = res + !*src; 1603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1604 } 1605 return res; 1606} 1607 1608#define INIT_MBSTOWCS \ 1609 INTERCEPT_FUNCTION(mbstowcs); \ 1610 INTERCEPT_FUNCTION(mbsrtowcs); 1611#else 1612#define INIT_MBSTOWCS 1613#endif 1614 1615#if SANITIZER_INTERCEPT_MBSNRTOWCS 1616INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1617 SIZE_T len, void *ps) { 1618 void *ctx; 1619 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1620 if (src) { 1621 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1622 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1623 } 1624 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1625 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1626 if (res != (SIZE_T)(-1) && dest && src) { 1627 SIZE_T write_cnt = res + !*src; 1628 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1629 } 1630 return res; 1631} 1632 1633#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1634#else 1635#define INIT_MBSNRTOWCS 1636#endif 1637 1638#if SANITIZER_INTERCEPT_WCSTOMBS 1639INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1640 void *ctx; 1641 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1642 SIZE_T res = REAL(wcstombs)(dest, src, len); 1643 if (res != (SIZE_T) - 1 && dest) { 1644 SIZE_T write_cnt = res + (res < len); 1645 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1646 } 1647 return res; 1648} 1649 1650INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1651 void *ps) { 1652 void *ctx; 1653 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1654 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1655 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1656 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1657 if (res != (SIZE_T) - 1 && dest && src) { 1658 SIZE_T write_cnt = res + !*src; 1659 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1660 } 1661 return res; 1662} 1663 1664#define INIT_WCSTOMBS \ 1665 INTERCEPT_FUNCTION(wcstombs); \ 1666 INTERCEPT_FUNCTION(wcsrtombs); 1667#else 1668#define INIT_WCSTOMBS 1669#endif 1670 1671#if SANITIZER_INTERCEPT_WCSNRTOMBS 1672INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1673 SIZE_T len, void *ps) { 1674 void *ctx; 1675 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1676 if (src) { 1677 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1678 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1679 } 1680 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1681 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1682 if (res != (SIZE_T) - 1 && dest && src) { 1683 SIZE_T write_cnt = res + !*src; 1684 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1685 } 1686 return res; 1687} 1688 1689#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1690#else 1691#define INIT_WCSNRTOMBS 1692#endif 1693 1694 1695#if SANITIZER_INTERCEPT_TCGETATTR 1696INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1697 void *ctx; 1698 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1699 int res = REAL(tcgetattr)(fd, termios_p); 1700 if (!res && termios_p) 1701 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1702 return res; 1703} 1704 1705#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1706#else 1707#define INIT_TCGETATTR 1708#endif 1709 1710 1711#if SANITIZER_INTERCEPT_REALPATH 1712INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1713 void *ctx; 1714 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1715 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1716 1717 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1718 // version of a versioned symbol. For realpath(), this gives us something 1719 // (called __old_realpath) that does not handle NULL in the second argument. 1720 // Handle it as part of the interceptor. 1721 char *allocated_path = 0; 1722 if (!resolved_path) 1723 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1724 1725 char *res = REAL(realpath)(path, resolved_path); 1726 if (allocated_path && !res) 1727 WRAP(free)(allocated_path); 1728 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1729 return res; 1730} 1731#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1732#else 1733#define INIT_REALPATH 1734#endif 1735 1736#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1737INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1738 void *ctx; 1739 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1740 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1741 char *res = REAL(canonicalize_file_name)(path); 1742 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1743 return res; 1744} 1745#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1746#else 1747#define INIT_CANONICALIZE_FILE_NAME 1748#endif 1749 1750#if SANITIZER_INTERCEPT_CONFSTR 1751INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1752 void *ctx; 1753 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1754 SIZE_T res = REAL(confstr)(name, buf, len); 1755 if (buf && res) 1756 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1757 return res; 1758} 1759#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1760#else 1761#define INIT_CONFSTR 1762#endif 1763 1764#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1765INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1766 void *ctx; 1767 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1768 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1769 if (mask && !res) 1770 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1771 return res; 1772} 1773#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1774#else 1775#define INIT_SCHED_GETAFFINITY 1776#endif 1777 1778#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 1779 INIT_STRCMP; \ 1780 INIT_STRNCMP; \ 1781 INIT_STRCASECMP; \ 1782 INIT_STRNCASECMP; \ 1783 INIT_READ; \ 1784 INIT_PREAD; \ 1785 INIT_PREAD64; \ 1786 INIT_READV; \ 1787 INIT_PREADV; \ 1788 INIT_PREADV64; \ 1789 INIT_WRITE; \ 1790 INIT_PWRITE; \ 1791 INIT_PWRITE64; \ 1792 INIT_WRITEV; \ 1793 INIT_PWRITEV; \ 1794 INIT_PWRITEV64; \ 1795 INIT_PRCTL; \ 1796 INIT_LOCALTIME_AND_FRIENDS; \ 1797 INIT_SCANF; \ 1798 INIT_FREXP; \ 1799 INIT_FREXPF_FREXPL; \ 1800 INIT_GETPWNAM_AND_FRIENDS; \ 1801 INIT_GETPWNAM_R_AND_FRIENDS; \ 1802 INIT_CLOCK_GETTIME; \ 1803 INIT_GETITIMER; \ 1804 INIT_TIME; \ 1805 INIT_GLOB; \ 1806 INIT_WAIT; \ 1807 INIT_INET; \ 1808 INIT_PTHREAD_GETSCHEDPARAM; \ 1809 INIT_GETADDRINFO; \ 1810 INIT_GETNAMEINFO; \ 1811 INIT_GETSOCKNAME; \ 1812 INIT_GETHOSTBYNAME; \ 1813 INIT_GETHOSTBYNAME_R; \ 1814 INIT_GETSOCKOPT; \ 1815 INIT_ACCEPT; \ 1816 INIT_ACCEPT4; \ 1817 INIT_MODF; \ 1818 INIT_RECVMSG; \ 1819 INIT_GETPEERNAME; \ 1820 INIT_IOCTL; \ 1821 INIT_INET_ATON; \ 1822 INIT_SYSINFO; \ 1823 INIT_READDIR; \ 1824 INIT_READDIR64; \ 1825 INIT_PTRACE; \ 1826 INIT_SETLOCALE; \ 1827 INIT_GETCWD; \ 1828 INIT_GET_CURRENT_DIR_NAME; \ 1829 INIT_STRTOIMAX; \ 1830 INIT_MBSTOWCS; \ 1831 INIT_MBSNRTOWCS; \ 1832 INIT_WCSTOMBS; \ 1833 INIT_WCSNRTOMBS; \ 1834 INIT_TCGETATTR; \ 1835 INIT_REALPATH; \ 1836 INIT_CANONICALIZE_FILE_NAME; \ 1837 INIT_CONFSTR; \ 1838 INIT_SCHED_GETAFFINITY; 1839