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