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 32 static inline int CharCmpX(unsigned char c1, unsigned char c2) { 33 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 34 } 35 36 INTERCEPTOR(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 51 INTERCEPTOR(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 74 static 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 80 INTERCEPTOR(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 96 INTERCEPTOR(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 120 INTERCEPTOR(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 134 INTERCEPTOR(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 142 INTERCEPTOR(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 158 static 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 167 static 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 179 INTERCEPTOR(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 195 INTERCEPTOR(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 211 INTERCEPTOR(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 227 INTERCEPTOR_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 242 INTERCEPTOR(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 257 INTERCEPTOR(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 272 INTERCEPTOR(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 289 INTERCEPTOR(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 305 INTERCEPTOR(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 322 INTERCEPTOR_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 337 INTERCEPTOR(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 352 INTERCEPTOR(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 367 INTERCEPTOR(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 389 INTERCEPTOR(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 406 INTERCEPTOR(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 } 416 INTERCEPTOR(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 } 426 INTERCEPTOR(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 } 436 INTERCEPTOR(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 } 446 INTERCEPTOR(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 } 456 INTERCEPTOR(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 } 466 INTERCEPTOR(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 } 476 INTERCEPTOR(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 516 INTERCEPTOR(int, vscanf, const char *format, va_list ap) 517 VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 518 519 INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 520 VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 521 522 INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 523 VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 524 525 #if SANITIZER_INTERCEPT_ISOC99_SCANF 526 INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 527 VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 528 529 INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 530 va_list ap) 531 VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 532 533 INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 534 VSCANF_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 548 INTERCEPTOR(int, scanf, const char *format, ...) 549 SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 550 551 INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 552 SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 553 554 INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 555 SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 556 557 #if SANITIZER_INTERCEPT_ISOC99_SCANF 558 INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 559 SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 560 561 INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 562 SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 563 564 INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 565 SCANF_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" 589 INTERCEPTOR(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 621 INTERCEPTOR(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 } 630 INTERCEPTOR(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 } 638 INTERCEPTOR(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 } 647 INTERCEPTOR(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 666 INTERCEPTOR(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 } 678 INTERCEPTOR(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 } 689 INTERCEPTOR(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 } 701 INTERCEPTOR(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 723 INTERCEPTOR(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 } 732 INTERCEPTOR(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 } 741 INTERCEPTOR(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 757 INTERCEPTOR(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 } 766 INTERCEPTOR(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 785 static 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 797 static THREADLOCAL __sanitizer_glob_t* pglob_copy; 798 static THREADLOCAL void* glob_ctx; 799 800 static void wrapped_gl_closedir(void *dir) { 801 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 802 pglob_copy->gl_closedir(dir); 803 } 804 805 static void *wrapped_gl_readdir(void *dir) { 806 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 807 return pglob_copy->gl_readdir(dir); 808 } 809 810 static 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 816 static 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 822 static 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 828 INTERCEPTOR(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 859 INTERCEPTOR(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. 900 INTERCEPTOR_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 } 908 INTERCEPTOR_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 } 917 INTERCEPTOR_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 } 925 INTERCEPTOR(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 } 937 INTERCEPTOR(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 960 INTERCEPTOR(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 } 971 INTERCEPTOR(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 990 INTERCEPTOR(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 1007 INTERCEPTOR(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 1023 INTERCEPTOR(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 1055 INTERCEPTOR(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 1078 INTERCEPTOR(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 1095 static 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 1117 INTERCEPTOR(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 1125 INTERCEPTOR(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 1135 INTERCEPTOR(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 1143 INTERCEPTOR(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 1160 INTERCEPTOR(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 1177 INTERCEPTOR(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 1197 INTERCEPTOR(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 1215 INTERCEPTOR(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 1243 INTERCEPTOR(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 1260 INTERCEPTOR(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 1283 INTERCEPTOR(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 1306 INTERCEPTOR(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 } 1315 INTERCEPTOR(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 } 1324 INTERCEPTOR(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 1342 static 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 1356 INTERCEPTOR(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 1373 INTERCEPTOR(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 1389 INTERCEPTOR(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 1403 INTERCEPTOR(__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 1412 INTERCEPTOR(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 1433 INTERCEPTOR(__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 1442 INTERCEPTOR(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 1462 INTERCEPTOR(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 1509 INTERCEPTOR(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 1527 INTERCEPTOR(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 1542 INTERCEPTOR(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 1558 INTERCEPTOR(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 1566 INTERCEPTOR(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 1582 INTERCEPTOR(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 1593 INTERCEPTOR(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 1617 INTERCEPTOR(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 1640 INTERCEPTOR(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 1651 INTERCEPTOR(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 1673 INTERCEPTOR(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 1697 INTERCEPTOR(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 1713 INTERCEPTOR(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 1738 INTERCEPTOR(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 1752 INTERCEPTOR(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 1766 INTERCEPTOR(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