sanitizer_common_interceptors.inc revision 78d77c2638b8e02020737c9b296ce2198e4c58e6
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_INITIALIZE_RANGE 19// COMMON_INTERCEPTOR_FD_ACQUIRE 20// COMMON_INTERCEPTOR_FD_RELEASE 21// COMMON_INTERCEPTOR_FD_ACCESS 22// COMMON_INTERCEPTOR_SET_THREAD_NAME 23// COMMON_INTERCEPTOR_ON_EXIT 24// COMMON_INTERCEPTOR_MUTEX_LOCK 25// COMMON_INTERCEPTOR_MUTEX_UNLOCK 26// COMMON_INTERCEPTOR_SET_PTHREAD_NAME 27//===----------------------------------------------------------------------===// 28#include "interception/interception.h" 29#include "sanitizer_platform_interceptors.h" 30 31#include <stdarg.h> 32 33#if SANITIZER_WINDOWS 34#define va_copy(dst, src) ((dst) = (src)) 35#endif // _WIN32 36 37#ifndef COMMON_INTERCEPTOR_INITIALIZE_RANGE 38#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, p, size) {} 39#endif 40 41#ifndef COMMON_INTERCEPTOR_FD_ACCESS 42#define COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd) {} 43#endif 44 45#ifndef COMMON_INTERCEPTOR_MUTEX_LOCK 46#define COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m) {} 47#endif 48 49#ifndef COMMON_INTERCEPTOR_MUTEX_UNLOCK 50#define COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m) {} 51#endif 52 53#if SANITIZER_INTERCEPT_STRCMP 54static inline int CharCmpX(unsigned char c1, unsigned char c2) { 55 return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; 56} 57 58INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { 59 void *ctx; 60 COMMON_INTERCEPTOR_ENTER(ctx, strcmp, s1, s2); 61 unsigned char c1, c2; 62 uptr i; 63 for (i = 0; ; i++) { 64 c1 = (unsigned char)s1[i]; 65 c2 = (unsigned char)s2[i]; 66 if (c1 != c2 || c1 == '\0') break; 67 } 68 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 69 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 70 return CharCmpX(c1, c2); 71} 72 73INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { 74 void *ctx; 75 COMMON_INTERCEPTOR_ENTER(ctx, strncmp, s1, s2, size); 76 unsigned char c1 = 0, c2 = 0; 77 uptr i; 78 for (i = 0; i < size; i++) { 79 c1 = (unsigned char)s1[i]; 80 c2 = (unsigned char)s2[i]; 81 if (c1 != c2 || c1 == '\0') break; 82 } 83 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, size)); 84 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, size)); 85 return CharCmpX(c1, c2); 86} 87 88#define INIT_STRCMP INTERCEPT_FUNCTION(strcmp) 89#define INIT_STRNCMP INTERCEPT_FUNCTION(strncmp) 90#else 91#define INIT_STRCMP 92#define INIT_STRNCMP 93#endif 94 95#if SANITIZER_INTERCEPT_STRCASECMP 96static inline int CharCaseCmp(unsigned char c1, unsigned char c2) { 97 int c1_low = ToLower(c1); 98 int c2_low = ToLower(c2); 99 return c1_low - c2_low; 100} 101 102INTERCEPTOR(int, strcasecmp, const char *s1, const char *s2) { 103 void *ctx; 104 COMMON_INTERCEPTOR_ENTER(ctx, strcasecmp, s1, s2); 105 unsigned char c1 = 0, c2 = 0; 106 uptr i; 107 for (i = 0; ; i++) { 108 c1 = (unsigned char)s1[i]; 109 c2 = (unsigned char)s2[i]; 110 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 111 break; 112 } 113 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, i + 1); 114 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, i + 1); 115 return CharCaseCmp(c1, c2); 116} 117 118INTERCEPTOR(int, strncasecmp, const char *s1, const char *s2, SIZE_T n) { 119 void *ctx; 120 COMMON_INTERCEPTOR_ENTER(ctx, strncasecmp, s1, s2, n); 121 unsigned char c1 = 0, c2 = 0; 122 uptr i; 123 for (i = 0; i < n; i++) { 124 c1 = (unsigned char)s1[i]; 125 c2 = (unsigned char)s2[i]; 126 if (CharCaseCmp(c1, c2) != 0 || c1 == '\0') 127 break; 128 } 129 COMMON_INTERCEPTOR_READ_RANGE(ctx, s1, Min(i + 1, n)); 130 COMMON_INTERCEPTOR_READ_RANGE(ctx, s2, Min(i + 1, n)); 131 return CharCaseCmp(c1, c2); 132} 133 134#define INIT_STRCASECMP INTERCEPT_FUNCTION(strcasecmp) 135#define INIT_STRNCASECMP INTERCEPT_FUNCTION(strncasecmp) 136#else 137#define INIT_STRCASECMP 138#define INIT_STRNCASECMP 139#endif 140 141#if SANITIZER_INTERCEPT_FREXP 142INTERCEPTOR(double, frexp, double x, int *exp) { 143 void *ctx; 144 COMMON_INTERCEPTOR_ENTER(ctx, frexp, x, exp); 145 double res = REAL(frexp)(x, exp); 146 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 147 return res; 148} 149 150#define INIT_FREXP INTERCEPT_FUNCTION(frexp); 151#else 152#define INIT_FREXP 153#endif // SANITIZER_INTERCEPT_FREXP 154 155#if SANITIZER_INTERCEPT_FREXPF_FREXPL 156INTERCEPTOR(float, frexpf, float x, int *exp) { 157 void *ctx; 158 COMMON_INTERCEPTOR_ENTER(ctx, frexpf, x, exp); 159 float res = REAL(frexpf)(x, exp); 160 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 161 return res; 162} 163 164INTERCEPTOR(long double, frexpl, long double x, int *exp) { 165 void *ctx; 166 COMMON_INTERCEPTOR_ENTER(ctx, frexpl, x, exp); 167 long double res = REAL(frexpl)(x, exp); 168 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, exp, sizeof(*exp)); 169 return res; 170} 171 172#define INIT_FREXPF_FREXPL \ 173 INTERCEPT_FUNCTION(frexpf); \ 174 INTERCEPT_FUNCTION(frexpl) 175#else 176#define INIT_FREXPF_FREXPL 177#endif // SANITIZER_INTERCEPT_FREXPF_FREXPL 178 179#if SI_NOT_WINDOWS 180static void write_iovec(void *ctx, struct __sanitizer_iovec *iovec, 181 SIZE_T iovlen, SIZE_T maxlen) { 182 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 183 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 184 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec[i].iov_base, sz); 185 maxlen -= sz; 186 } 187} 188 189static void read_iovec(void *ctx, struct __sanitizer_iovec *iovec, 190 SIZE_T iovlen, SIZE_T maxlen) { 191 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec) * iovlen); 192 for (SIZE_T i = 0; i < iovlen && maxlen; ++i) { 193 SSIZE_T sz = Min(iovec[i].iov_len, maxlen); 194 COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec[i].iov_base, sz); 195 maxlen -= sz; 196 } 197} 198#endif 199 200#if SANITIZER_INTERCEPT_READ 201INTERCEPTOR(SSIZE_T, read, int fd, void *ptr, SIZE_T count) { 202 void *ctx; 203 COMMON_INTERCEPTOR_ENTER(ctx, read, fd, ptr, count); 204 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 205 SSIZE_T res = REAL(read)(fd, ptr, count); 206 if (res > 0) 207 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 208 if (res >= 0 && fd >= 0) 209 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 210 return res; 211} 212#define INIT_READ INTERCEPT_FUNCTION(read) 213#else 214#define INIT_READ 215#endif 216 217#if SANITIZER_INTERCEPT_PREAD 218INTERCEPTOR(SSIZE_T, pread, int fd, void *ptr, SIZE_T count, OFF_T offset) { 219 void *ctx; 220 COMMON_INTERCEPTOR_ENTER(ctx, pread, fd, ptr, count, offset); 221 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 222 SSIZE_T res = REAL(pread)(fd, ptr, count, offset); 223 if (res > 0) 224 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 225 if (res >= 0 && fd >= 0) 226 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 227 return res; 228} 229#define INIT_PREAD INTERCEPT_FUNCTION(pread) 230#else 231#define INIT_PREAD 232#endif 233 234#if SANITIZER_INTERCEPT_PREAD64 235INTERCEPTOR(SSIZE_T, pread64, int fd, void *ptr, SIZE_T count, OFF64_T offset) { 236 void *ctx; 237 COMMON_INTERCEPTOR_ENTER(ctx, pread64, fd, ptr, count, offset); 238 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 239 SSIZE_T res = REAL(pread64)(fd, ptr, count, offset); 240 if (res > 0) 241 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, res); 242 if (res >= 0 && fd >= 0) 243 COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 244 return res; 245} 246#define INIT_PREAD64 INTERCEPT_FUNCTION(pread64) 247#else 248#define INIT_PREAD64 249#endif 250 251#if SANITIZER_INTERCEPT_READV 252INTERCEPTOR_WITH_SUFFIX(SSIZE_T, readv, int fd, __sanitizer_iovec *iov, 253 int iovcnt) { 254 void *ctx; 255 COMMON_INTERCEPTOR_ENTER(ctx, readv, fd, iov, iovcnt); 256 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 257 SSIZE_T res = REAL(readv)(fd, iov, iovcnt); 258 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 259 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 260 return res; 261} 262#define INIT_READV INTERCEPT_FUNCTION(readv) 263#else 264#define INIT_READV 265#endif 266 267#if SANITIZER_INTERCEPT_PREADV 268INTERCEPTOR(SSIZE_T, preadv, int fd, __sanitizer_iovec *iov, int iovcnt, 269 OFF_T offset) { 270 void *ctx; 271 COMMON_INTERCEPTOR_ENTER(ctx, preadv, fd, iov, iovcnt, offset); 272 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 273 SSIZE_T res = REAL(preadv)(fd, iov, iovcnt, offset); 274 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 275 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 276 return res; 277} 278#define INIT_PREADV INTERCEPT_FUNCTION(preadv) 279#else 280#define INIT_PREADV 281#endif 282 283#if SANITIZER_INTERCEPT_PREADV64 284INTERCEPTOR(SSIZE_T, preadv64, int fd, __sanitizer_iovec *iov, int iovcnt, 285 OFF64_T offset) { 286 void *ctx; 287 COMMON_INTERCEPTOR_ENTER(ctx, preadv64, fd, iov, iovcnt, offset); 288 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 289 SSIZE_T res = REAL(preadv64)(fd, iov, iovcnt, offset); 290 if (res > 0) write_iovec(ctx, iov, iovcnt, res); 291 if (res >= 0 && fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 292 return res; 293} 294#define INIT_PREADV64 INTERCEPT_FUNCTION(preadv64) 295#else 296#define INIT_PREADV64 297#endif 298 299#if SANITIZER_INTERCEPT_WRITE 300INTERCEPTOR(SSIZE_T, write, int fd, void *ptr, SIZE_T count) { 301 void *ctx; 302 COMMON_INTERCEPTOR_ENTER(ctx, write, fd, ptr, count); 303 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 304 if (fd >= 0) 305 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 306 SSIZE_T res = REAL(write)(fd, ptr, count); 307 // FIXME: this check should be _before_ the call to REAL(write), not after 308 if (res > 0) 309 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 310 return res; 311} 312#define INIT_WRITE INTERCEPT_FUNCTION(write) 313#else 314#define INIT_WRITE 315#endif 316 317#if SANITIZER_INTERCEPT_PWRITE 318INTERCEPTOR(SSIZE_T, pwrite, int fd, void *ptr, SIZE_T count, OFF_T offset) { 319 void *ctx; 320 COMMON_INTERCEPTOR_ENTER(ctx, pwrite, fd, ptr, count, offset); 321 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 322 if (fd >= 0) 323 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 324 SSIZE_T res = REAL(pwrite)(fd, ptr, count, offset); 325 if (res > 0) 326 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 327 return res; 328} 329#define INIT_PWRITE INTERCEPT_FUNCTION(pwrite) 330#else 331#define INIT_PWRITE 332#endif 333 334#if SANITIZER_INTERCEPT_PWRITE64 335INTERCEPTOR(SSIZE_T, pwrite64, int fd, void *ptr, OFF64_T count, 336 OFF64_T offset) { 337 void *ctx; 338 COMMON_INTERCEPTOR_ENTER(ctx, pwrite64, fd, ptr, count, offset); 339 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 340 if (fd >= 0) 341 COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 342 SSIZE_T res = REAL(pwrite64)(fd, ptr, count, offset); 343 if (res > 0) 344 COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, res); 345 return res; 346} 347#define INIT_PWRITE64 INTERCEPT_FUNCTION(pwrite64) 348#else 349#define INIT_PWRITE64 350#endif 351 352#if SANITIZER_INTERCEPT_WRITEV 353INTERCEPTOR_WITH_SUFFIX(SSIZE_T, writev, int fd, __sanitizer_iovec *iov, 354 int iovcnt) { 355 void *ctx; 356 COMMON_INTERCEPTOR_ENTER(ctx, writev, fd, iov, iovcnt); 357 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 358 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 359 SSIZE_T res = REAL(writev)(fd, iov, iovcnt); 360 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 361 return res; 362} 363#define INIT_WRITEV INTERCEPT_FUNCTION(writev) 364#else 365#define INIT_WRITEV 366#endif 367 368#if SANITIZER_INTERCEPT_PWRITEV 369INTERCEPTOR(SSIZE_T, pwritev, int fd, __sanitizer_iovec *iov, int iovcnt, 370 OFF_T offset) { 371 void *ctx; 372 COMMON_INTERCEPTOR_ENTER(ctx, pwritev, fd, iov, iovcnt, offset); 373 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 374 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 375 SSIZE_T res = REAL(pwritev)(fd, iov, iovcnt, offset); 376 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 377 return res; 378} 379#define INIT_PWRITEV INTERCEPT_FUNCTION(pwritev) 380#else 381#define INIT_PWRITEV 382#endif 383 384#if SANITIZER_INTERCEPT_PWRITEV64 385INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, 386 OFF64_T offset) { 387 void *ctx; 388 COMMON_INTERCEPTOR_ENTER(ctx, pwritev64, fd, iov, iovcnt, offset); 389 COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); 390 if (fd >= 0) COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); 391 SSIZE_T res = REAL(pwritev64)(fd, iov, iovcnt, offset); 392 if (res > 0) read_iovec(ctx, iov, iovcnt, res); 393 return res; 394} 395#define INIT_PWRITEV64 INTERCEPT_FUNCTION(pwritev64) 396#else 397#define INIT_PWRITEV64 398#endif 399 400#if SANITIZER_INTERCEPT_PRCTL 401INTERCEPTOR(int, prctl, int option, 402 unsigned long arg2, unsigned long arg3, // NOLINT 403 unsigned long arg4, unsigned long arg5) { // NOLINT 404 void *ctx; 405 COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); 406 static const int PR_SET_NAME = 15; 407 int res = REAL(prctl(option, arg2, arg3, arg4, arg5)); 408 if (option == PR_SET_NAME) { 409 char buff[16]; 410 internal_strncpy(buff, (char *)arg2, 15); 411 buff[15] = 0; 412 COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, buff); 413 } 414 return res; 415} 416#define INIT_PRCTL INTERCEPT_FUNCTION(prctl) 417#else 418#define INIT_PRCTL 419#endif // SANITIZER_INTERCEPT_PRCTL 420 421 422#if SANITIZER_INTERCEPT_TIME 423INTERCEPTOR(unsigned long, time, unsigned long *t) { 424 void *ctx; 425 COMMON_INTERCEPTOR_ENTER(ctx, time, t); 426 unsigned long res = REAL(time)(t); 427 if (t && res != (unsigned long)-1) { 428 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, t, sizeof(*t)); 429 } 430 return res; 431} 432#define INIT_TIME \ 433 INTERCEPT_FUNCTION(time); 434#else 435#define INIT_TIME 436#endif // SANITIZER_INTERCEPT_TIME 437 438 439#if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 440static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { 441 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); 442 if (tm->tm_zone) { 443 // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone 444 // can point to shared memory and tsan would report a data race. 445 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, tm->tm_zone, 446 REAL(strlen(tm->tm_zone)) + 1); 447 } 448} 449 450INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { 451 void *ctx; 452 COMMON_INTERCEPTOR_ENTER(ctx, localtime, timep); 453 __sanitizer_tm *res = REAL(localtime)(timep); 454 if (res) { 455 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 456 unpoison_tm(ctx, res); 457 } 458 return res; 459} 460INTERCEPTOR(__sanitizer_tm *, localtime_r, unsigned long *timep, void *result) { 461 void *ctx; 462 COMMON_INTERCEPTOR_ENTER(ctx, localtime_r, timep, result); 463 __sanitizer_tm *res = REAL(localtime_r)(timep, result); 464 if (res) { 465 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 466 unpoison_tm(ctx, res); 467 } 468 return res; 469} 470INTERCEPTOR(__sanitizer_tm *, gmtime, unsigned long *timep) { 471 void *ctx; 472 COMMON_INTERCEPTOR_ENTER(ctx, gmtime, timep); 473 __sanitizer_tm *res = REAL(gmtime)(timep); 474 if (res) { 475 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 476 unpoison_tm(ctx, res); 477 } 478 return res; 479} 480INTERCEPTOR(__sanitizer_tm *, gmtime_r, unsigned long *timep, void *result) { 481 void *ctx; 482 COMMON_INTERCEPTOR_ENTER(ctx, gmtime_r, timep, result); 483 __sanitizer_tm *res = REAL(gmtime_r)(timep, result); 484 if (res) { 485 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 486 unpoison_tm(ctx, res); 487 } 488 return res; 489} 490INTERCEPTOR(char *, ctime, unsigned long *timep) { 491 void *ctx; 492 COMMON_INTERCEPTOR_ENTER(ctx, ctime, timep); 493 char *res = REAL(ctime)(timep); 494 if (res) { 495 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 496 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 497 } 498 return res; 499} 500INTERCEPTOR(char *, ctime_r, unsigned long *timep, char *result) { 501 void *ctx; 502 COMMON_INTERCEPTOR_ENTER(ctx, ctime_r, timep, result); 503 char *res = REAL(ctime_r)(timep, result); 504 if (res) { 505 COMMON_INTERCEPTOR_READ_RANGE(ctx, timep, sizeof(*timep)); 506 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 507 } 508 return res; 509} 510INTERCEPTOR(char *, asctime, __sanitizer_tm *tm) { 511 void *ctx; 512 COMMON_INTERCEPTOR_ENTER(ctx, asctime, tm); 513 char *res = REAL(asctime)(tm); 514 if (res) { 515 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 516 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 517 } 518 return res; 519} 520INTERCEPTOR(char *, asctime_r, __sanitizer_tm *tm, char *result) { 521 void *ctx; 522 COMMON_INTERCEPTOR_ENTER(ctx, asctime_r, tm, result); 523 char *res = REAL(asctime_r)(tm, result); 524 if (res) { 525 COMMON_INTERCEPTOR_READ_RANGE(ctx, tm, sizeof(*tm)); 526 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 527 } 528 return res; 529} 530#define INIT_LOCALTIME_AND_FRIENDS \ 531 INTERCEPT_FUNCTION(localtime); \ 532 INTERCEPT_FUNCTION(localtime_r); \ 533 INTERCEPT_FUNCTION(gmtime); \ 534 INTERCEPT_FUNCTION(gmtime_r); \ 535 INTERCEPT_FUNCTION(ctime); \ 536 INTERCEPT_FUNCTION(ctime_r); \ 537 INTERCEPT_FUNCTION(asctime); \ 538 INTERCEPT_FUNCTION(asctime_r); 539#else 540#define INIT_LOCALTIME_AND_FRIENDS 541#endif // SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS 542 543#if SANITIZER_INTERCEPT_SCANF 544 545#include "sanitizer_common_interceptors_scanf.inc" 546 547#define VSCANF_INTERCEPTOR_IMPL(vname, allowGnuMalloc, ...) \ 548 { \ 549 void *ctx; \ 550 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__); \ 551 va_list aq; \ 552 va_copy(aq, ap); \ 553 int res = REAL(vname)(__VA_ARGS__); \ 554 if (res > 0) \ 555 scanf_common(ctx, res, allowGnuMalloc, format, aq); \ 556 va_end(aq); \ 557 return res; \ 558 } 559 560INTERCEPTOR(int, vscanf, const char *format, va_list ap) 561VSCANF_INTERCEPTOR_IMPL(vscanf, true, format, ap) 562 563INTERCEPTOR(int, vsscanf, const char *str, const char *format, va_list ap) 564VSCANF_INTERCEPTOR_IMPL(vsscanf, true, str, format, ap) 565 566INTERCEPTOR(int, vfscanf, void *stream, const char *format, va_list ap) 567VSCANF_INTERCEPTOR_IMPL(vfscanf, true, stream, format, ap) 568 569#if SANITIZER_INTERCEPT_ISOC99_SCANF 570INTERCEPTOR(int, __isoc99_vscanf, const char *format, va_list ap) 571VSCANF_INTERCEPTOR_IMPL(__isoc99_vscanf, false, format, ap) 572 573INTERCEPTOR(int, __isoc99_vsscanf, const char *str, const char *format, 574 va_list ap) 575VSCANF_INTERCEPTOR_IMPL(__isoc99_vsscanf, false, str, format, ap) 576 577INTERCEPTOR(int, __isoc99_vfscanf, void *stream, const char *format, va_list ap) 578VSCANF_INTERCEPTOR_IMPL(__isoc99_vfscanf, false, stream, format, ap) 579#endif // SANITIZER_INTERCEPT_ISOC99_SCANF 580 581#define SCANF_INTERCEPTOR_IMPL(name, vname, ...) \ 582 { \ 583 void *ctx; \ 584 va_list ap; \ 585 va_start(ap, format); \ 586 COMMON_INTERCEPTOR_ENTER(ctx, vname, __VA_ARGS__, ap); \ 587 int res = vname(__VA_ARGS__, ap); \ 588 va_end(ap); \ 589 return res; \ 590 } 591 592INTERCEPTOR(int, scanf, const char *format, ...) 593SCANF_INTERCEPTOR_IMPL(scanf, vscanf, format) 594 595INTERCEPTOR(int, fscanf, void *stream, const char *format, ...) 596SCANF_INTERCEPTOR_IMPL(fscanf, vfscanf, stream, format) 597 598INTERCEPTOR(int, sscanf, const char *str, const char *format, ...) 599SCANF_INTERCEPTOR_IMPL(sscanf, vsscanf, str, format) 600 601#if SANITIZER_INTERCEPT_ISOC99_SCANF 602INTERCEPTOR(int, __isoc99_scanf, const char *format, ...) 603SCANF_INTERCEPTOR_IMPL(__isoc99_scanf, __isoc99_vscanf, format) 604 605INTERCEPTOR(int, __isoc99_fscanf, void *stream, const char *format, ...) 606SCANF_INTERCEPTOR_IMPL(__isoc99_fscanf, __isoc99_vfscanf, stream, format) 607 608INTERCEPTOR(int, __isoc99_sscanf, const char *str, const char *format, ...) 609SCANF_INTERCEPTOR_IMPL(__isoc99_sscanf, __isoc99_vsscanf, str, format) 610#endif 611 612#endif 613 614#if SANITIZER_INTERCEPT_SCANF 615#define INIT_SCANF \ 616 INTERCEPT_FUNCTION(scanf); \ 617 INTERCEPT_FUNCTION(sscanf); \ 618 INTERCEPT_FUNCTION(fscanf); \ 619 INTERCEPT_FUNCTION(vscanf); \ 620 INTERCEPT_FUNCTION(vsscanf); \ 621 INTERCEPT_FUNCTION(vfscanf); 622#else 623#define INIT_SCANF 624#endif 625 626#if SANITIZER_INTERCEPT_ISOC99_SCANF 627#define INIT_ISOC99_SCANF \ 628 INTERCEPT_FUNCTION(__isoc99_scanf); \ 629 INTERCEPT_FUNCTION(__isoc99_sscanf); \ 630 INTERCEPT_FUNCTION(__isoc99_fscanf); \ 631 INTERCEPT_FUNCTION(__isoc99_vscanf); \ 632 INTERCEPT_FUNCTION(__isoc99_vsscanf); \ 633 INTERCEPT_FUNCTION(__isoc99_vfscanf); 634#else 635#define INIT_ISOC99_SCANF 636#endif 637 638#if SANITIZER_INTERCEPT_IOCTL 639#include "sanitizer_common_interceptors_ioctl.inc" 640INTERCEPTOR(int, ioctl, int d, unsigned request, void *arg) { 641 void *ctx; 642 COMMON_INTERCEPTOR_ENTER(ctx, ioctl, d, request, arg); 643 644 CHECK(ioctl_initialized); 645 646 // Note: TSan does not use common flags, and they are zero-initialized. 647 // This effectively disables ioctl handling in TSan. 648 if (!common_flags()->handle_ioctl) 649 return REAL(ioctl)(d, request, arg); 650 651 const ioctl_desc *desc = ioctl_lookup(request); 652 if (!desc) 653 Printf("WARNING: unknown ioctl %x\n", request); 654 655 if (desc) 656 ioctl_common_pre(ctx, desc, d, request, arg); 657 int res = REAL(ioctl)(d, request, arg); 658 // FIXME: some ioctls have different return values for success and failure. 659 if (desc && res != -1) 660 ioctl_common_post(ctx, desc, res, d, request, arg); 661 return res; 662} 663#define INIT_IOCTL \ 664 ioctl_init(); \ 665 INTERCEPT_FUNCTION(ioctl); 666#else 667#define INIT_IOCTL 668#endif 669 670 671#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS 672INTERCEPTOR(void *, getpwnam, const char *name) { 673 void *ctx; 674 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); 675 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 676 void *res = REAL(getpwnam)(name); 677 if (res != 0) 678 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 679 return res; 680} 681INTERCEPTOR(void *, getpwuid, u32 uid) { 682 void *ctx; 683 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); 684 void *res = REAL(getpwuid)(uid); 685 if (res != 0) 686 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_passwd_sz); 687 return res; 688} 689INTERCEPTOR(void *, getgrnam, const char *name) { 690 void *ctx; 691 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); 692 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 693 void *res = REAL(getgrnam)(name); 694 if (res != 0) 695 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 696 return res; 697} 698INTERCEPTOR(void *, getgrgid, u32 gid) { 699 void *ctx; 700 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); 701 void *res = REAL(getgrgid)(gid); 702 if (res != 0) 703 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, struct_group_sz); 704 return res; 705} 706#define INIT_GETPWNAM_AND_FRIENDS \ 707 INTERCEPT_FUNCTION(getpwnam); \ 708 INTERCEPT_FUNCTION(getpwuid); \ 709 INTERCEPT_FUNCTION(getgrnam); \ 710 INTERCEPT_FUNCTION(getgrgid); 711#else 712#define INIT_GETPWNAM_AND_FRIENDS 713#endif 714 715 716#if SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS 717INTERCEPTOR(int, getpwnam_r, const char *name, void *pwd, 718 char *buf, SIZE_T buflen, void **result) { 719 void *ctx; 720 COMMON_INTERCEPTOR_ENTER(ctx, getpwnam_r, name, pwd, buf, buflen, result); 721 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 722 int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); 723 if (!res) { 724 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 725 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 726 } 727 return res; 728} 729INTERCEPTOR(int, getpwuid_r, u32 uid, void *pwd, 730 char *buf, SIZE_T buflen, void **result) { 731 void *ctx; 732 COMMON_INTERCEPTOR_ENTER(ctx, getpwuid_r, uid, pwd, buf, buflen, result); 733 int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); 734 if (!res) { 735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, struct_passwd_sz); 736 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 737 } 738 return res; 739} 740INTERCEPTOR(int, getgrnam_r, const char *name, void *grp, 741 char *buf, SIZE_T buflen, void **result) { 742 void *ctx; 743 COMMON_INTERCEPTOR_ENTER(ctx, getgrnam_r, name, grp, buf, buflen, result); 744 COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); 745 int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); 746 if (!res) { 747 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 748 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 749 } 750 return res; 751} 752INTERCEPTOR(int, getgrgid_r, u32 gid, void *grp, 753 char *buf, SIZE_T buflen, void **result) { 754 void *ctx; 755 COMMON_INTERCEPTOR_ENTER(ctx, getgrgid_r, gid, grp, buf, buflen, result); 756 int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); 757 if (!res) { 758 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, struct_group_sz); 759 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); 760 } 761 return res; 762} 763#define INIT_GETPWNAM_R_AND_FRIENDS \ 764 INTERCEPT_FUNCTION(getpwnam_r); \ 765 INTERCEPT_FUNCTION(getpwuid_r); \ 766 INTERCEPT_FUNCTION(getgrnam_r); \ 767 INTERCEPT_FUNCTION(getgrgid_r); 768#else 769#define INIT_GETPWNAM_R_AND_FRIENDS 770#endif 771 772 773#if SANITIZER_INTERCEPT_CLOCK_GETTIME 774INTERCEPTOR(int, clock_getres, u32 clk_id, void *tp) { 775 void *ctx; 776 COMMON_INTERCEPTOR_ENTER(ctx, clock_getres, clk_id, tp); 777 int res = REAL(clock_getres)(clk_id, tp); 778 if (!res && tp) { 779 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 780 } 781 return res; 782} 783INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { 784 void *ctx; 785 COMMON_INTERCEPTOR_ENTER(ctx, clock_gettime, clk_id, tp); 786 int res = REAL(clock_gettime)(clk_id, tp); 787 if (!res) { 788 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tp, struct_timespec_sz); 789 } 790 return res; 791} 792INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { 793 void *ctx; 794 COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); 795 COMMON_INTERCEPTOR_READ_RANGE(ctx, tp, struct_timespec_sz); 796 return REAL(clock_settime)(clk_id, tp); 797} 798#define INIT_CLOCK_GETTIME \ 799 INTERCEPT_FUNCTION(clock_getres); \ 800 INTERCEPT_FUNCTION(clock_gettime); \ 801 INTERCEPT_FUNCTION(clock_settime); 802#else 803#define INIT_CLOCK_GETTIME 804#endif 805 806 807#if SANITIZER_INTERCEPT_GETITIMER 808INTERCEPTOR(int, getitimer, int which, void *curr_value) { 809 void *ctx; 810 COMMON_INTERCEPTOR_ENTER(ctx, getitimer, which, curr_value); 811 int res = REAL(getitimer)(which, curr_value); 812 if (!res && curr_value) { 813 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, curr_value, struct_itimerval_sz); 814 } 815 return res; 816} 817INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { 818 void *ctx; 819 COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); 820 if (new_value) 821 COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); 822 int res = REAL(setitimer)(which, new_value, old_value); 823 if (!res && old_value) { 824 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, old_value, struct_itimerval_sz); 825 } 826 return res; 827} 828#define INIT_GETITIMER \ 829 INTERCEPT_FUNCTION(getitimer); \ 830 INTERCEPT_FUNCTION(setitimer); 831#else 832#define INIT_GETITIMER 833#endif 834 835#if SANITIZER_INTERCEPT_GLOB 836static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { 837 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pglob, sizeof(*pglob)); 838 // +1 for NULL pointer at the end. 839 if (pglob->gl_pathv) 840 COMMON_INTERCEPTOR_WRITE_RANGE( 841 ctx, pglob->gl_pathv, (pglob->gl_pathc + 1) * sizeof(*pglob->gl_pathv)); 842 for (SIZE_T i = 0; i < pglob->gl_pathc; ++i) { 843 char *p = pglob->gl_pathv[i]; 844 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, REAL(strlen)(p) + 1); 845 } 846} 847 848static THREADLOCAL __sanitizer_glob_t* pglob_copy; 849static THREADLOCAL void* glob_ctx; 850 851static void wrapped_gl_closedir(void *dir) { 852 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 853 pglob_copy->gl_closedir(dir); 854} 855 856static void *wrapped_gl_readdir(void *dir) { 857 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 858 return pglob_copy->gl_readdir(dir); 859} 860 861static void *wrapped_gl_opendir(const char *s) { 862 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 1); 863 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 864 return pglob_copy->gl_opendir(s); 865} 866 867static int wrapped_gl_lstat(const char *s, void *st) { 868 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 869 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 870 return pglob_copy->gl_lstat(s, st); 871} 872 873static int wrapped_gl_stat(const char *s, void *st) { 874 COMMON_INTERCEPTOR_UNPOISON_PARAM(glob_ctx, 2); 875 COMMON_INTERCEPTOR_WRITE_RANGE(glob_ctx, s, REAL(strlen)(s) + 1); 876 return pglob_copy->gl_stat(s, st); 877} 878 879INTERCEPTOR(int, glob, const char *pattern, int flags, 880 int (*errfunc)(const char *epath, int eerrno), 881 __sanitizer_glob_t *pglob) { 882 void *ctx; 883 COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); 884 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 885 wrapped_gl_readdir, wrapped_gl_opendir, 886 wrapped_gl_lstat, wrapped_gl_stat}; 887 if (flags & glob_altdirfunc) { 888 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 889 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 890 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 891 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 892 Swap(pglob->gl_stat, glob_copy.gl_stat); 893 pglob_copy = &glob_copy; 894 glob_ctx = ctx; 895 } 896 int res = REAL(glob)(pattern, flags, errfunc, pglob); 897 if (flags & glob_altdirfunc) { 898 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 899 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 900 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 901 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 902 Swap(pglob->gl_stat, glob_copy.gl_stat); 903 } 904 pglob_copy = 0; 905 glob_ctx = 0; 906 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 907 return res; 908} 909 910INTERCEPTOR(int, glob64, const char *pattern, int flags, 911 int (*errfunc)(const char *epath, int eerrno), 912 __sanitizer_glob_t *pglob) { 913 void *ctx; 914 COMMON_INTERCEPTOR_ENTER(ctx, glob64, pattern, flags, errfunc, pglob); 915 __sanitizer_glob_t glob_copy = {0, 0, 0, 0, wrapped_gl_closedir, 916 wrapped_gl_readdir, wrapped_gl_opendir, 917 wrapped_gl_lstat, wrapped_gl_stat}; 918 if (flags & glob_altdirfunc) { 919 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 920 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 921 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 922 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 923 Swap(pglob->gl_stat, glob_copy.gl_stat); 924 pglob_copy = &glob_copy; 925 glob_ctx = ctx; 926 } 927 int res = REAL(glob64)(pattern, flags, errfunc, pglob); 928 if (flags & glob_altdirfunc) { 929 Swap(pglob->gl_closedir, glob_copy.gl_closedir); 930 Swap(pglob->gl_readdir, glob_copy.gl_readdir); 931 Swap(pglob->gl_opendir, glob_copy.gl_opendir); 932 Swap(pglob->gl_lstat, glob_copy.gl_lstat); 933 Swap(pglob->gl_stat, glob_copy.gl_stat); 934 } 935 pglob_copy = 0; 936 glob_ctx = 0; 937 if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); 938 return res; 939} 940#define INIT_GLOB \ 941 INTERCEPT_FUNCTION(glob); \ 942 INTERCEPT_FUNCTION(glob64); 943#else // SANITIZER_INTERCEPT_GLOB 944#define INIT_GLOB 945#endif // SANITIZER_INTERCEPT_GLOB 946 947#if SANITIZER_INTERCEPT_WAIT 948// According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version 949// suffixes on Darwin. See the declaration of INTERCEPTOR_WITH_SUFFIX for 950// details. 951INTERCEPTOR_WITH_SUFFIX(int, wait, int *status) { 952 void *ctx; 953 COMMON_INTERCEPTOR_ENTER(ctx, wait, status); 954 int res = REAL(wait)(status); 955 if (res != -1 && status) 956 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 957 return res; 958} 959INTERCEPTOR_WITH_SUFFIX(int, waitid, int idtype, int id, void *infop, 960 int options) { 961 void *ctx; 962 COMMON_INTERCEPTOR_ENTER(ctx, waitid, idtype, id, infop, options); 963 int res = REAL(waitid)(idtype, id, infop, options); 964 if (res != -1 && infop) 965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, infop, siginfo_t_sz); 966 return res; 967} 968INTERCEPTOR_WITH_SUFFIX(int, waitpid, int pid, int *status, int options) { 969 void *ctx; 970 COMMON_INTERCEPTOR_ENTER(ctx, waitpid, pid, status, options); 971 int res = REAL(waitpid)(pid, status, options); 972 if (res != -1 && status) 973 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 974 return res; 975} 976INTERCEPTOR(int, wait3, int *status, int options, void *rusage) { 977 void *ctx; 978 COMMON_INTERCEPTOR_ENTER(ctx, wait3, status, options, rusage); 979 int res = REAL(wait3)(status, options, rusage); 980 if (res != -1) { 981 if (status) 982 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 983 if (rusage) 984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 985 } 986 return res; 987} 988INTERCEPTOR(int, wait4, int pid, int *status, int options, void *rusage) { 989 void *ctx; 990 COMMON_INTERCEPTOR_ENTER(ctx, wait4, pid, status, options, rusage); 991 int res = REAL(wait4)(pid, status, options, rusage); 992 if (res != -1) { 993 if (status) 994 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, status, sizeof(*status)); 995 if (rusage) 996 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rusage, struct_rusage_sz); 997 } 998 return res; 999} 1000#define INIT_WAIT \ 1001 INTERCEPT_FUNCTION(wait); \ 1002 INTERCEPT_FUNCTION(waitid); \ 1003 INTERCEPT_FUNCTION(waitpid); \ 1004 INTERCEPT_FUNCTION(wait3); \ 1005 INTERCEPT_FUNCTION(wait4); 1006#else 1007#define INIT_WAIT 1008#endif 1009 1010#if SANITIZER_INTERCEPT_INET 1011INTERCEPTOR(char *, inet_ntop, int af, const void *src, char *dst, u32 size) { 1012 void *ctx; 1013 COMMON_INTERCEPTOR_ENTER(ctx, inet_ntop, af, src, dst, size); 1014 uptr sz = __sanitizer_in_addr_sz(af); 1015 if (sz) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sz); 1016 // FIXME: figure out read size based on the address family. 1017 char *res = REAL(inet_ntop)(af, src, dst, size); 1018 if (res) 1019 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1020 return res; 1021} 1022INTERCEPTOR(int, inet_pton, int af, const char *src, void *dst) { 1023 void *ctx; 1024 COMMON_INTERCEPTOR_ENTER(ctx, inet_pton, af, src, dst); 1025 // FIXME: figure out read size based on the address family. 1026 int res = REAL(inet_pton)(af, src, dst); 1027 if (res == 1) { 1028 uptr sz = __sanitizer_in_addr_sz(af); 1029 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1030 } 1031 return res; 1032} 1033#define INIT_INET \ 1034 INTERCEPT_FUNCTION(inet_ntop); \ 1035 INTERCEPT_FUNCTION(inet_pton); 1036#else 1037#define INIT_INET 1038#endif 1039 1040#if SANITIZER_INTERCEPT_INET 1041INTERCEPTOR(int, inet_aton, const char *cp, void *dst) { 1042 void *ctx; 1043 COMMON_INTERCEPTOR_ENTER(ctx, inet_aton, cp, dst); 1044 if (cp) COMMON_INTERCEPTOR_READ_RANGE(ctx, cp, REAL(strlen)(cp) + 1); 1045 int res = REAL(inet_aton)(cp, dst); 1046 if (res != 0) { 1047 uptr sz = __sanitizer_in_addr_sz(af_inet); 1048 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sz); 1049 } 1050 return res; 1051} 1052#define INIT_INET_ATON INTERCEPT_FUNCTION(inet_aton); 1053#else 1054#define INIT_INET_ATON 1055#endif 1056 1057#if SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM 1058INTERCEPTOR(int, pthread_getschedparam, uptr thread, int *policy, int *param) { 1059 void *ctx; 1060 COMMON_INTERCEPTOR_ENTER(ctx, pthread_getschedparam, thread, policy, param); 1061 int res = REAL(pthread_getschedparam)(thread, policy, param); 1062 if (res == 0) { 1063 if (policy) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, policy, sizeof(*policy)); 1064 if (param) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, param, sizeof(*param)); 1065 } 1066 return res; 1067} 1068#define INIT_PTHREAD_GETSCHEDPARAM INTERCEPT_FUNCTION(pthread_getschedparam); 1069#else 1070#define INIT_PTHREAD_GETSCHEDPARAM 1071#endif 1072 1073#if SANITIZER_INTERCEPT_GETADDRINFO 1074INTERCEPTOR(int, getaddrinfo, char *node, char *service, 1075 struct __sanitizer_addrinfo *hints, 1076 struct __sanitizer_addrinfo **out) { 1077 void *ctx; 1078 COMMON_INTERCEPTOR_ENTER(ctx, getaddrinfo, node, service, hints, out); 1079 if (node) COMMON_INTERCEPTOR_READ_RANGE(ctx, node, REAL(strlen)(node) + 1); 1080 if (service) 1081 COMMON_INTERCEPTOR_READ_RANGE(ctx, service, REAL(strlen)(service) + 1); 1082 if (hints) 1083 COMMON_INTERCEPTOR_READ_RANGE(ctx, hints, sizeof(__sanitizer_addrinfo)); 1084 int res = REAL(getaddrinfo)(node, service, hints, out); 1085 if (res == 0 && out) { 1086 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, out, sizeof(*out)); 1087 struct __sanitizer_addrinfo *p = *out; 1088 while (p) { 1089 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 1090 if (p->ai_addr) 1091 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_addr, p->ai_addrlen); 1092 if (p->ai_canonname) 1093 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->ai_canonname, 1094 REAL(strlen)(p->ai_canonname) + 1); 1095 p = p->ai_next; 1096 } 1097 } 1098 return res; 1099} 1100#define INIT_GETADDRINFO INTERCEPT_FUNCTION(getaddrinfo); 1101#else 1102#define INIT_GETADDRINFO 1103#endif 1104 1105#if SANITIZER_INTERCEPT_GETNAMEINFO 1106INTERCEPTOR(int, getnameinfo, void *sockaddr, unsigned salen, char *host, 1107 unsigned hostlen, char *serv, unsigned servlen, int flags) { 1108 void *ctx; 1109 COMMON_INTERCEPTOR_ENTER(ctx, getnameinfo, sockaddr, salen, host, hostlen, 1110 serv, servlen, flags); 1111 // FIXME: consider adding READ_RANGE(sockaddr, salen) 1112 // There is padding in in_addr that may make this too noisy 1113 int res = 1114 REAL(getnameinfo)(sockaddr, salen, host, hostlen, serv, servlen, flags); 1115 if (res == 0) { 1116 if (host && hostlen) 1117 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, host, REAL(strlen)(host) + 1); 1118 if (serv && servlen) 1119 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, serv, REAL(strlen)(serv) + 1); 1120 } 1121 return res; 1122} 1123#define INIT_GETNAMEINFO INTERCEPT_FUNCTION(getnameinfo); 1124#else 1125#define INIT_GETNAMEINFO 1126#endif 1127 1128#if SANITIZER_INTERCEPT_GETSOCKNAME 1129INTERCEPTOR(int, getsockname, int sock_fd, void *addr, int *addrlen) { 1130 void *ctx; 1131 COMMON_INTERCEPTOR_ENTER(ctx, getsockname, sock_fd, addr, addrlen); 1132 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1133 int addrlen_in = *addrlen; 1134 int res = REAL(getsockname)(sock_fd, addr, addrlen); 1135 if (res == 0) { 1136 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addrlen_in, *addrlen)); 1137 } 1138 return res; 1139} 1140#define INIT_GETSOCKNAME INTERCEPT_FUNCTION(getsockname); 1141#else 1142#define INIT_GETSOCKNAME 1143#endif 1144 1145#if SANITIZER_INTERCEPT_GETHOSTBYNAME || SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1146static void write_hostent(void *ctx, struct __sanitizer_hostent *h) { 1147 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h, sizeof(__sanitizer_hostent)); 1148 if (h->h_name) 1149 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h->h_name, REAL(strlen)(h->h_name) + 1); 1150 char **p = h->h_aliases; 1151 while (*p) { 1152 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); 1153 ++p; 1154 } 1155 COMMON_INTERCEPTOR_WRITE_RANGE( 1156 ctx, h->h_aliases, (p - h->h_aliases + 1) * sizeof(*h->h_aliases)); 1157 p = h->h_addr_list; 1158 while (*p) { 1159 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, h->h_length); 1160 ++p; 1161 } 1162 COMMON_INTERCEPTOR_WRITE_RANGE( 1163 ctx, h->h_addr_list, (p - h->h_addr_list + 1) * sizeof(*h->h_addr_list)); 1164} 1165#endif 1166 1167#if SANITIZER_INTERCEPT_GETHOSTBYNAME 1168INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname, char *name) { 1169 void *ctx; 1170 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname, name); 1171 struct __sanitizer_hostent *res = REAL(gethostbyname)(name); 1172 if (res) write_hostent(ctx, res); 1173 return res; 1174} 1175 1176INTERCEPTOR(struct __sanitizer_hostent *, gethostbyaddr, void *addr, int len, 1177 int type) { 1178 void *ctx; 1179 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr, addr, len, type); 1180 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1181 struct __sanitizer_hostent *res = REAL(gethostbyaddr)(addr, len, type); 1182 if (res) write_hostent(ctx, res); 1183 return res; 1184} 1185 1186INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { 1187 void *ctx; 1188 COMMON_INTERCEPTOR_ENTER(ctx, gethostent, fake); 1189 struct __sanitizer_hostent *res = REAL(gethostent)(fake); 1190 if (res) write_hostent(ctx, res); 1191 return res; 1192} 1193 1194INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { 1195 void *ctx; 1196 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); 1197 struct __sanitizer_hostent *res = REAL(gethostbyname2)(name, af); 1198 if (res) write_hostent(ctx, res); 1199 return res; 1200} 1201#define INIT_GETHOSTBYNAME \ 1202 INTERCEPT_FUNCTION(gethostent); \ 1203 INTERCEPT_FUNCTION(gethostbyaddr); \ 1204 INTERCEPT_FUNCTION(gethostbyname); \ 1205 INTERCEPT_FUNCTION(gethostbyname2); 1206#else 1207#define INIT_GETHOSTBYNAME 1208#endif 1209 1210#if SANITIZER_INTERCEPT_GETHOSTBYNAME_R 1211INTERCEPTOR(int, gethostent_r, struct __sanitizer_hostent *ret, char *buf, 1212 SIZE_T buflen, __sanitizer_hostent **result, int *h_errnop) { 1213 void *ctx; 1214 COMMON_INTERCEPTOR_ENTER(ctx, gethostent_r, ret, buf, buflen, result, 1215 h_errnop); 1216 int res = REAL(gethostent_r)(ret, buf, buflen, result, h_errnop); 1217 if (res == 0) { 1218 if (result) { 1219 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1220 if (*result) write_hostent(ctx, *result); 1221 } 1222 if (h_errnop) 1223 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1224 } 1225 return res; 1226} 1227 1228INTERCEPTOR(int, gethostbyaddr_r, void *addr, int len, int type, 1229 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1230 __sanitizer_hostent **result, int *h_errnop) { 1231 void *ctx; 1232 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyaddr_r, addr, len, type, ret, buf, 1233 buflen, result, h_errnop); 1234 COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, len); 1235 int res = REAL(gethostbyaddr_r)(addr, len, type, ret, buf, buflen, result, 1236 h_errnop); 1237 if (res == 0) { 1238 if (result) { 1239 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1240 if (*result) write_hostent(ctx, *result); 1241 } 1242 if (h_errnop) 1243 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1244 } 1245 return res; 1246} 1247 1248INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, 1249 char *buf, SIZE_T buflen, __sanitizer_hostent **result, 1250 int *h_errnop) { 1251 void *ctx; 1252 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname_r, name, ret, buf, buflen, result, 1253 h_errnop); 1254 int res = REAL(gethostbyname_r)(name, ret, buf, buflen, result, h_errnop); 1255 if (res == 0) { 1256 if (result) { 1257 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1258 if (*result) write_hostent(ctx, *result); 1259 } 1260 if (h_errnop) 1261 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1262 } 1263 return res; 1264} 1265 1266INTERCEPTOR(int, gethostbyname2_r, char *name, int af, 1267 struct __sanitizer_hostent *ret, char *buf, SIZE_T buflen, 1268 __sanitizer_hostent **result, int *h_errnop) { 1269 void *ctx; 1270 COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2_r, name, af, ret, buf, buflen, 1271 result, h_errnop); 1272 int res = 1273 REAL(gethostbyname2_r)(name, af, ret, buf, buflen, result, h_errnop); 1274 if (res == 0) { 1275 if (result) { 1276 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1277 if (*result) write_hostent(ctx, *result); 1278 } 1279 if (h_errnop) 1280 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, h_errnop, sizeof(*h_errnop)); 1281 } 1282 return res; 1283} 1284#define INIT_GETHOSTBYNAME_R \ 1285 INTERCEPT_FUNCTION(gethostent_r); \ 1286 INTERCEPT_FUNCTION(gethostbyaddr_r); \ 1287 INTERCEPT_FUNCTION(gethostbyname_r); \ 1288 INTERCEPT_FUNCTION(gethostbyname2_r); 1289#else 1290#define INIT_GETHOSTBYNAME_R 1291#endif 1292 1293#if SANITIZER_INTERCEPT_GETSOCKOPT 1294INTERCEPTOR(int, getsockopt, int sockfd, int level, int optname, void *optval, 1295 int *optlen) { 1296 void *ctx; 1297 COMMON_INTERCEPTOR_ENTER(ctx, getsockopt, sockfd, level, optname, optval, 1298 optlen); 1299 if (optlen) COMMON_INTERCEPTOR_READ_RANGE(ctx, optlen, sizeof(*optlen)); 1300 int res = REAL(getsockopt)(sockfd, level, optname, optval, optlen); 1301 if (res == 0) 1302 if (optval && optlen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, optval, *optlen); 1303 return res; 1304} 1305#define INIT_GETSOCKOPT INTERCEPT_FUNCTION(getsockopt); 1306#else 1307#define INIT_GETSOCKOPT 1308#endif 1309 1310#if SANITIZER_INTERCEPT_ACCEPT 1311INTERCEPTOR(int, accept, int fd, void *addr, unsigned *addrlen) { 1312 void *ctx; 1313 COMMON_INTERCEPTOR_ENTER(ctx, accept, fd, addr, addrlen); 1314 unsigned addrlen0; 1315 if (addrlen) { 1316 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1317 addrlen0 = *addrlen; 1318 } 1319 int fd2 = REAL(accept)(fd, addr, addrlen); 1320 if (fd2 >= 0) { 1321 if (fd >= 0) 1322 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1323 if (addr && addrlen) 1324 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1325 } 1326 return fd2; 1327} 1328#define INIT_ACCEPT INTERCEPT_FUNCTION(accept); 1329#else 1330#define INIT_ACCEPT 1331#endif 1332 1333#if SANITIZER_INTERCEPT_ACCEPT4 1334INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { 1335 void *ctx; 1336 COMMON_INTERCEPTOR_ENTER(ctx, accept4, fd, addr, addrlen, f); 1337 unsigned addrlen0; 1338 if (addrlen) { 1339 COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); 1340 addrlen0 = *addrlen; 1341 } 1342 int fd2 = REAL(accept4)(fd, addr, addrlen, f); 1343 if (fd2 >= 0) { 1344 if (fd >= 0) 1345 COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); 1346 if (addr && addrlen) 1347 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); 1348 } 1349 return fd2; 1350} 1351#define INIT_ACCEPT4 INTERCEPT_FUNCTION(accept4); 1352#else 1353#define INIT_ACCEPT4 1354#endif 1355 1356#if SANITIZER_INTERCEPT_MODF 1357INTERCEPTOR(double, modf, double x, double *iptr) { 1358 void *ctx; 1359 COMMON_INTERCEPTOR_ENTER(ctx, modf, x, iptr); 1360 double res = REAL(modf)(x, iptr); 1361 if (iptr) { 1362 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1363 } 1364 return res; 1365} 1366INTERCEPTOR(float, modff, float x, float *iptr) { 1367 void *ctx; 1368 COMMON_INTERCEPTOR_ENTER(ctx, modff, x, iptr); 1369 float res = REAL(modff)(x, iptr); 1370 if (iptr) { 1371 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1372 } 1373 return res; 1374} 1375INTERCEPTOR(long double, modfl, long double x, long double *iptr) { 1376 void *ctx; 1377 COMMON_INTERCEPTOR_ENTER(ctx, modfl, x, iptr); 1378 long double res = REAL(modfl)(x, iptr); 1379 if (iptr) { 1380 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iptr, sizeof(*iptr)); 1381 } 1382 return res; 1383} 1384#define INIT_MODF \ 1385 INTERCEPT_FUNCTION(modf); \ 1386 INTERCEPT_FUNCTION(modff); \ 1387 INTERCEPT_FUNCTION(modfl); 1388#else 1389#define INIT_MODF 1390#endif 1391 1392#if SANITIZER_INTERCEPT_RECVMSG 1393static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, 1394 SSIZE_T maxlen) { 1395 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); 1396 if (msg->msg_name && msg->msg_namelen) 1397 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_name, msg->msg_namelen); 1398 if (msg->msg_iov && msg->msg_iovlen) 1399 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_iov, 1400 sizeof(*msg->msg_iov) * msg->msg_iovlen); 1401 write_iovec(ctx, msg->msg_iov, msg->msg_iovlen, maxlen); 1402 if (msg->msg_control && msg->msg_controllen) 1403 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); 1404} 1405 1406INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, 1407 int flags) { 1408 void *ctx; 1409 COMMON_INTERCEPTOR_ENTER(ctx, recvmsg, fd, msg, flags); 1410 SSIZE_T res = REAL(recvmsg)(fd, msg, flags); 1411 if (res >= 0) { 1412 if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); 1413 if (msg) write_msghdr(ctx, msg, res); 1414 } 1415 return res; 1416} 1417#define INIT_RECVMSG INTERCEPT_FUNCTION(recvmsg); 1418#else 1419#define INIT_RECVMSG 1420#endif 1421 1422#if SANITIZER_INTERCEPT_GETPEERNAME 1423INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { 1424 void *ctx; 1425 COMMON_INTERCEPTOR_ENTER(ctx, getpeername, sockfd, addr, addrlen); 1426 unsigned addr_sz; 1427 if (addrlen) addr_sz = *addrlen; 1428 int res = REAL(getpeername)(sockfd, addr, addrlen); 1429 if (!res && addr && addrlen) 1430 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(addr_sz, *addrlen)); 1431 return res; 1432} 1433#define INIT_GETPEERNAME INTERCEPT_FUNCTION(getpeername); 1434#else 1435#define INIT_GETPEERNAME 1436#endif 1437 1438#if SANITIZER_INTERCEPT_SYSINFO 1439INTERCEPTOR(int, sysinfo, void *info) { 1440 void *ctx; 1441 COMMON_INTERCEPTOR_ENTER(ctx, sysinfo, info); 1442 int res = REAL(sysinfo)(info); 1443 if (!res && info) 1444 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, struct_sysinfo_sz); 1445 return res; 1446} 1447#define INIT_SYSINFO INTERCEPT_FUNCTION(sysinfo); 1448#else 1449#define INIT_SYSINFO 1450#endif 1451 1452#if SANITIZER_INTERCEPT_READDIR 1453INTERCEPTOR(__sanitizer_dirent *, readdir, void *dirp) { 1454 void *ctx; 1455 COMMON_INTERCEPTOR_ENTER(ctx, readdir, dirp); 1456 __sanitizer_dirent *res = REAL(readdir)(dirp); 1457 if (res) 1458 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1459 return res; 1460} 1461 1462INTERCEPTOR(int, readdir_r, void *dirp, __sanitizer_dirent *entry, 1463 __sanitizer_dirent **result) { 1464 void *ctx; 1465 COMMON_INTERCEPTOR_ENTER(ctx, readdir_r, dirp, entry, result); 1466 int res = REAL(readdir_r)(dirp, entry, result); 1467 if (!res) { 1468 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1469 if (*result) 1470 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1471 } 1472 return res; 1473} 1474 1475#define INIT_READDIR \ 1476 INTERCEPT_FUNCTION(readdir); \ 1477 INTERCEPT_FUNCTION(readdir_r); 1478#else 1479#define INIT_READDIR 1480#endif 1481 1482#if SANITIZER_INTERCEPT_READDIR64 1483INTERCEPTOR(__sanitizer_dirent64 *, readdir64, void *dirp) { 1484 void *ctx; 1485 COMMON_INTERCEPTOR_ENTER(ctx, readdir64, dirp); 1486 __sanitizer_dirent64 *res = REAL(readdir64)(dirp); 1487 if (res) 1488 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, res->d_reclen); 1489 return res; 1490} 1491 1492INTERCEPTOR(int, readdir64_r, void *dirp, __sanitizer_dirent64 *entry, 1493 __sanitizer_dirent64 **result) { 1494 void *ctx; 1495 COMMON_INTERCEPTOR_ENTER(ctx, readdir64_r, dirp, entry, result); 1496 int res = REAL(readdir64_r)(dirp, entry, result); 1497 if (!res) { 1498 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 1499 if (*result) 1500 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *result, (*result)->d_reclen); 1501 } 1502 return res; 1503} 1504#define INIT_READDIR64 \ 1505 INTERCEPT_FUNCTION(readdir64); \ 1506 INTERCEPT_FUNCTION(readdir64_r); 1507#else 1508#define INIT_READDIR64 1509#endif 1510 1511#if SANITIZER_INTERCEPT_PTRACE 1512INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { 1513 void *ctx; 1514 COMMON_INTERCEPTOR_ENTER(ctx, ptrace, request, pid, addr, data); 1515 1516 if (data) { 1517 if (request == ptrace_setregs) 1518 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); 1519 else if (request == ptrace_setfpregs) 1520 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1521 else if (request == ptrace_setfpxregs) 1522 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1523 else if (request == ptrace_setsiginfo) 1524 COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); 1525 else if (request == ptrace_setregset) { 1526 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1527 COMMON_INTERCEPTOR_READ_RANGE(ctx, iov->iov_base, iov->iov_len); 1528 } 1529 } 1530 1531 uptr res = REAL(ptrace)(request, pid, addr, data); 1532 1533 if (!res && data) { 1534 // Note that PEEK* requests assing different meaning to the return value. 1535 // This function does not handle them (nor does it need to). 1536 if (request == ptrace_getregs) 1537 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); 1538 else if (request == ptrace_getfpregs) 1539 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); 1540 else if (request == ptrace_getfpxregs) 1541 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); 1542 else if (request == ptrace_getsiginfo) 1543 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); 1544 else if (request == ptrace_getregset) { 1545 __sanitizer_iovec *iov = (__sanitizer_iovec *)data; 1546 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iov->iov_base, iov->iov_len); 1547 } 1548 } 1549 return res; 1550} 1551 1552#define INIT_PTRACE \ 1553 INTERCEPT_FUNCTION(ptrace); 1554#else 1555#define INIT_PTRACE 1556#endif 1557 1558#if SANITIZER_INTERCEPT_SETLOCALE 1559INTERCEPTOR(char *, setlocale, int category, char *locale) { 1560 void *ctx; 1561 COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); 1562 if (locale) 1563 COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); 1564 char *res = REAL(setlocale)(category, locale); 1565 if (res) 1566 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1567 return res; 1568} 1569 1570#define INIT_SETLOCALE \ 1571 INTERCEPT_FUNCTION(setlocale); 1572#else 1573#define INIT_SETLOCALE 1574#endif 1575 1576#if SANITIZER_INTERCEPT_GETCWD 1577INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 1578 void *ctx; 1579 COMMON_INTERCEPTOR_ENTER(ctx, getcwd, buf, size); 1580 char *res = REAL(getcwd)(buf, size); 1581 if (res) 1582 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1583 return res; 1584} 1585#define INIT_GETCWD \ 1586 INTERCEPT_FUNCTION(getcwd); 1587#else 1588#define INIT_GETCWD 1589#endif 1590 1591#if SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME 1592INTERCEPTOR(char *, get_current_dir_name, int fake) { 1593 void *ctx; 1594 COMMON_INTERCEPTOR_ENTER(ctx, get_current_dir_name, fake); 1595 char *res = REAL(get_current_dir_name)(fake); 1596 if (res) 1597 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1598 return res; 1599} 1600 1601#define INIT_GET_CURRENT_DIR_NAME \ 1602 INTERCEPT_FUNCTION(get_current_dir_name); 1603#else 1604#define INIT_GET_CURRENT_DIR_NAME 1605#endif 1606 1607#if SANITIZER_INTERCEPT_STRTOIMAX 1608INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { 1609 void *ctx; 1610 COMMON_INTERCEPTOR_ENTER(ctx, strtoimax, nptr, endptr, base); 1611 INTMAX_T res = REAL(strtoimax)(nptr, endptr, base); 1612 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1613 return res; 1614} 1615 1616INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { 1617 void *ctx; 1618 COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); 1619 INTMAX_T res = REAL(strtoumax)(nptr, endptr, base); 1620 if (endptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, endptr, sizeof(*endptr)); 1621 return res; 1622} 1623 1624#define INIT_STRTOIMAX \ 1625 INTERCEPT_FUNCTION(strtoimax); \ 1626 INTERCEPT_FUNCTION(strtoumax); 1627#else 1628#define INIT_STRTOIMAX 1629#endif 1630 1631#if SANITIZER_INTERCEPT_MBSTOWCS 1632INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T len) { 1633 void *ctx; 1634 COMMON_INTERCEPTOR_ENTER(ctx, mbstowcs, dest, src, len); 1635 SIZE_T res = REAL(mbstowcs)(dest, src, len); 1636 if (res != (SIZE_T) - 1 && dest) { 1637 SIZE_T write_cnt = res + (res < len); 1638 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1639 } 1640 return res; 1641} 1642 1643INTERCEPTOR(SIZE_T, mbsrtowcs, wchar_t *dest, const char **src, SIZE_T len, 1644 void *ps) { 1645 void *ctx; 1646 COMMON_INTERCEPTOR_ENTER(ctx, mbsrtowcs, dest, src, len, ps); 1647 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1648 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1649 SIZE_T res = REAL(mbsrtowcs)(dest, src, len, ps); 1650 if (res != (SIZE_T)(-1) && dest && src) { 1651 // This function, and several others, may or may not write the terminating 1652 // \0 character. They write it iff they clear *src. 1653 SIZE_T write_cnt = res + !*src; 1654 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1655 } 1656 return res; 1657} 1658 1659#define INIT_MBSTOWCS \ 1660 INTERCEPT_FUNCTION(mbstowcs); \ 1661 INTERCEPT_FUNCTION(mbsrtowcs); 1662#else 1663#define INIT_MBSTOWCS 1664#endif 1665 1666#if SANITIZER_INTERCEPT_MBSNRTOWCS 1667INTERCEPTOR(SIZE_T, mbsnrtowcs, wchar_t *dest, const char **src, SIZE_T nms, 1668 SIZE_T len, void *ps) { 1669 void *ctx; 1670 COMMON_INTERCEPTOR_ENTER(ctx, mbsnrtowcs, dest, src, nms, len, ps); 1671 if (src) { 1672 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1673 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1674 } 1675 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1676 SIZE_T res = REAL(mbsnrtowcs)(dest, src, nms, len, ps); 1677 if (res != (SIZE_T)(-1) && dest && src) { 1678 SIZE_T write_cnt = res + !*src; 1679 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt * sizeof(wchar_t)); 1680 } 1681 return res; 1682} 1683 1684#define INIT_MBSNRTOWCS INTERCEPT_FUNCTION(mbsnrtowcs); 1685#else 1686#define INIT_MBSNRTOWCS 1687#endif 1688 1689#if SANITIZER_INTERCEPT_WCSTOMBS 1690INTERCEPTOR(SIZE_T, wcstombs, char *dest, const wchar_t *src, SIZE_T len) { 1691 void *ctx; 1692 COMMON_INTERCEPTOR_ENTER(ctx, wcstombs, dest, src, len); 1693 SIZE_T res = REAL(wcstombs)(dest, src, len); 1694 if (res != (SIZE_T) - 1 && dest) { 1695 SIZE_T write_cnt = res + (res < len); 1696 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1697 } 1698 return res; 1699} 1700 1701INTERCEPTOR(SIZE_T, wcsrtombs, char *dest, const wchar_t **src, SIZE_T len, 1702 void *ps) { 1703 void *ctx; 1704 COMMON_INTERCEPTOR_ENTER(ctx, wcsrtombs, dest, src, len, ps); 1705 if (src) COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1706 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1707 SIZE_T res = REAL(wcsrtombs)(dest, src, len, ps); 1708 if (res != (SIZE_T) - 1 && dest && src) { 1709 SIZE_T write_cnt = res + !*src; 1710 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1711 } 1712 return res; 1713} 1714 1715#define INIT_WCSTOMBS \ 1716 INTERCEPT_FUNCTION(wcstombs); \ 1717 INTERCEPT_FUNCTION(wcsrtombs); 1718#else 1719#define INIT_WCSTOMBS 1720#endif 1721 1722#if SANITIZER_INTERCEPT_WCSNRTOMBS 1723INTERCEPTOR(SIZE_T, wcsnrtombs, char *dest, const wchar_t **src, SIZE_T nms, 1724 SIZE_T len, void *ps) { 1725 void *ctx; 1726 COMMON_INTERCEPTOR_ENTER(ctx, wcsnrtombs, dest, src, nms, len, ps); 1727 if (src) { 1728 COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); 1729 if (nms) COMMON_INTERCEPTOR_READ_RANGE(ctx, *src, nms); 1730 } 1731 if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); 1732 SIZE_T res = REAL(wcsnrtombs)(dest, src, nms, len, ps); 1733 if (res != (SIZE_T) - 1 && dest && src) { 1734 SIZE_T write_cnt = res + !*src; 1735 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); 1736 } 1737 return res; 1738} 1739 1740#define INIT_WCSNRTOMBS INTERCEPT_FUNCTION(wcsnrtombs); 1741#else 1742#define INIT_WCSNRTOMBS 1743#endif 1744 1745 1746#if SANITIZER_INTERCEPT_TCGETATTR 1747INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { 1748 void *ctx; 1749 COMMON_INTERCEPTOR_ENTER(ctx, tcgetattr, fd, termios_p); 1750 int res = REAL(tcgetattr)(fd, termios_p); 1751 if (!res && termios_p) 1752 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, termios_p, struct_termios_sz); 1753 return res; 1754} 1755 1756#define INIT_TCGETATTR INTERCEPT_FUNCTION(tcgetattr); 1757#else 1758#define INIT_TCGETATTR 1759#endif 1760 1761 1762#if SANITIZER_INTERCEPT_REALPATH 1763INTERCEPTOR(char *, realpath, const char *path, char *resolved_path) { 1764 void *ctx; 1765 COMMON_INTERCEPTOR_ENTER(ctx, realpath, path, resolved_path); 1766 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1767 1768 // Workaround a bug in glibc where dlsym(RTLD_NEXT, ...) returns the oldest 1769 // version of a versioned symbol. For realpath(), this gives us something 1770 // (called __old_realpath) that does not handle NULL in the second argument. 1771 // Handle it as part of the interceptor. 1772 char *allocated_path = 0; 1773 if (!resolved_path) 1774 allocated_path = resolved_path = (char *)WRAP(malloc)(path_max + 1); 1775 1776 char *res = REAL(realpath)(path, resolved_path); 1777 if (allocated_path && !res) 1778 WRAP(free)(allocated_path); 1779 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1780 return res; 1781} 1782#define INIT_REALPATH INTERCEPT_FUNCTION(realpath); 1783#else 1784#define INIT_REALPATH 1785#endif 1786 1787#if SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME 1788INTERCEPTOR(char *, canonicalize_file_name, const char *path) { 1789 void *ctx; 1790 COMMON_INTERCEPTOR_ENTER(ctx, canonicalize_file_name, path); 1791 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 1792 char *res = REAL(canonicalize_file_name)(path); 1793 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1794 return res; 1795} 1796#define INIT_CANONICALIZE_FILE_NAME INTERCEPT_FUNCTION(canonicalize_file_name); 1797#else 1798#define INIT_CANONICALIZE_FILE_NAME 1799#endif 1800 1801#if SANITIZER_INTERCEPT_CONFSTR 1802INTERCEPTOR(SIZE_T, confstr, int name, char *buf, SIZE_T len) { 1803 void *ctx; 1804 COMMON_INTERCEPTOR_ENTER(ctx, confstr, name, buf, len); 1805 SIZE_T res = REAL(confstr)(name, buf, len); 1806 if (buf && res) 1807 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res < len ? res : len); 1808 return res; 1809} 1810#define INIT_CONFSTR INTERCEPT_FUNCTION(confstr); 1811#else 1812#define INIT_CONFSTR 1813#endif 1814 1815#if SANITIZER_INTERCEPT_SCHED_GETAFFINITY 1816INTERCEPTOR(int, sched_getaffinity, int pid, SIZE_T cpusetsize, void *mask) { 1817 void *ctx; 1818 COMMON_INTERCEPTOR_ENTER(ctx, sched_getaffinity, pid, cpusetsize, mask); 1819 int res = REAL(sched_getaffinity)(pid, cpusetsize, mask); 1820 if (mask && !res) 1821 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mask, cpusetsize); 1822 return res; 1823} 1824#define INIT_SCHED_GETAFFINITY INTERCEPT_FUNCTION(sched_getaffinity); 1825#else 1826#define INIT_SCHED_GETAFFINITY 1827#endif 1828 1829#if SANITIZER_INTERCEPT_STRERROR 1830INTERCEPTOR(char *, strerror, int errnum) { 1831 void *ctx; 1832 COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); 1833 char *res = REAL(strerror)(errnum); 1834 if (res) 1835 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1836 return res; 1837} 1838#define INIT_STRERROR INTERCEPT_FUNCTION(strerror); 1839#else 1840#define INIT_STRERROR 1841#endif 1842 1843#if SANITIZER_INTERCEPT_STRERROR_R 1844INTERCEPTOR(char *, strerror_r, int errnum, char *buf, SIZE_T buflen) { 1845 void *ctx; 1846 COMMON_INTERCEPTOR_ENTER(ctx, strerror_r, errnum, buf, buflen); 1847 char *res = REAL(strerror_r)(errnum, buf, buflen); 1848 // There are 2 versions of strerror_r: 1849 // * POSIX version returns 0 on success, negative error code on failure, 1850 // writes message to buf. 1851 // * GNU version returns message pointer, which points to either buf or some 1852 // static storage. 1853 SIZE_T posix_res = (SIZE_T)res; 1854 if (posix_res < 1024 || posix_res > (SIZE_T) - 1024) { 1855 // POSIX version. Spec is not clear on whether buf is NULL-terminated. 1856 // At least on OSX, buf contents are valid even when the call fails. 1857 SIZE_T sz = internal_strnlen(buf, buflen); 1858 if (sz < buflen) ++sz; 1859 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 1860 } else { 1861 // GNU version. 1862 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 1863 } 1864 return res; 1865} 1866#define INIT_STRERROR_R INTERCEPT_FUNCTION(strerror_r); 1867#else 1868#define INIT_STRERROR_R 1869#endif 1870 1871#if SANITIZER_INTERCEPT_SCANDIR 1872typedef int (*scandir_filter_f)(const struct __sanitizer_dirent *); 1873typedef int (*scandir_compar_f)(const struct __sanitizer_dirent **, 1874 const struct __sanitizer_dirent **); 1875 1876static THREADLOCAL void *scandir_ctx; 1877static THREADLOCAL scandir_filter_f scandir_filter; 1878static THREADLOCAL scandir_compar_f scandir_compar; 1879 1880static int wrapped_scandir_filter(const struct __sanitizer_dirent *dir) { 1881 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 1); 1882 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, dir, dir->d_reclen); 1883 return scandir_filter(dir); 1884} 1885 1886static int wrapped_scandir_compar(const struct __sanitizer_dirent **a, 1887 const struct __sanitizer_dirent **b) { 1888 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir_ctx, 2); 1889 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, a, sizeof(*a)); 1890 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *a, (*a)->d_reclen); 1891 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, b, sizeof(*b)); 1892 COMMON_INTERCEPTOR_WRITE_RANGE(scandir_ctx, *b, (*b)->d_reclen); 1893 return scandir_compar(a, b); 1894} 1895 1896INTERCEPTOR(int, scandir, char *dirp, __sanitizer_dirent ***namelist, 1897 scandir_filter_f filter, scandir_compar_f compar) { 1898 void *ctx; 1899 COMMON_INTERCEPTOR_ENTER(ctx, scandir, dirp, namelist, filter, compar); 1900 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1901 CHECK_EQ(0, scandir_ctx); 1902 scandir_ctx = ctx; 1903 scandir_filter = filter; 1904 scandir_compar = compar; 1905 int res = REAL(scandir)(dirp, namelist, filter ? wrapped_scandir_filter : 0, 1906 compar ? wrapped_scandir_compar : 0); 1907 scandir_ctx = 0; 1908 scandir_filter = 0; 1909 scandir_compar = 0; 1910 if (namelist && res > 0) { 1911 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1912 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1913 for (int i = 0; i < res; ++i) 1914 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1915 (*namelist)[i]->d_reclen); 1916 } 1917 return res; 1918} 1919#define INIT_SCANDIR INTERCEPT_FUNCTION(scandir); 1920#else 1921#define INIT_SCANDIR 1922#endif 1923 1924#if SANITIZER_INTERCEPT_SCANDIR64 1925typedef int (*scandir64_filter_f)(const struct __sanitizer_dirent64 *); 1926typedef int (*scandir64_compar_f)(const struct __sanitizer_dirent64 **, 1927 const struct __sanitizer_dirent64 **); 1928 1929static THREADLOCAL void *scandir64_ctx; 1930static THREADLOCAL scandir64_filter_f scandir64_filter; 1931static THREADLOCAL scandir64_compar_f scandir64_compar; 1932 1933static int wrapped_scandir64_filter(const struct __sanitizer_dirent64 *dir) { 1934 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 1); 1935 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, dir, dir->d_reclen); 1936 return scandir64_filter(dir); 1937} 1938 1939static int wrapped_scandir64_compar(const struct __sanitizer_dirent64 **a, 1940 const struct __sanitizer_dirent64 **b) { 1941 COMMON_INTERCEPTOR_UNPOISON_PARAM(scandir64_ctx, 2); 1942 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, a, sizeof(*a)); 1943 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *a, (*a)->d_reclen); 1944 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, b, sizeof(*b)); 1945 COMMON_INTERCEPTOR_WRITE_RANGE(scandir64_ctx, *b, (*b)->d_reclen); 1946 return scandir64_compar(a, b); 1947} 1948 1949INTERCEPTOR(int, scandir64, char *dirp, __sanitizer_dirent64 ***namelist, 1950 scandir64_filter_f filter, scandir64_compar_f compar) { 1951 void *ctx; 1952 COMMON_INTERCEPTOR_ENTER(ctx, scandir64, dirp, namelist, filter, compar); 1953 if (dirp) COMMON_INTERCEPTOR_READ_RANGE(ctx, dirp, REAL(strlen)(dirp) + 1); 1954 CHECK_EQ(0, scandir64_ctx); 1955 scandir64_ctx = ctx; 1956 scandir64_filter = filter; 1957 scandir64_compar = compar; 1958 int res = 1959 REAL(scandir64)(dirp, namelist, filter ? wrapped_scandir64_filter : 0, 1960 compar ? wrapped_scandir64_compar : 0); 1961 scandir64_ctx = 0; 1962 scandir64_filter = 0; 1963 scandir64_compar = 0; 1964 if (namelist && res > 0) { 1965 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelist, sizeof(*namelist)); 1966 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *namelist, sizeof(**namelist) * res); 1967 for (int i = 0; i < res; ++i) 1968 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, (*namelist)[i], 1969 (*namelist)[i]->d_reclen); 1970 } 1971 return res; 1972} 1973#define INIT_SCANDIR64 INTERCEPT_FUNCTION(scandir64); 1974#else 1975#define INIT_SCANDIR64 1976#endif 1977 1978#if SANITIZER_INTERCEPT_GETGROUPS 1979INTERCEPTOR(int, getgroups, int size, u32 *lst) { 1980 void *ctx; 1981 COMMON_INTERCEPTOR_ENTER(ctx, getgroups, size, lst); 1982 int res = REAL(getgroups)(size, lst); 1983 if (res && lst) 1984 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lst, res * sizeof(*lst)); 1985 return res; 1986} 1987#define INIT_GETGROUPS INTERCEPT_FUNCTION(getgroups); 1988#else 1989#define INIT_GETGROUPS 1990#endif 1991 1992#if SANITIZER_INTERCEPT_POLL 1993static void read_pollfd(void *ctx, __sanitizer_pollfd *fds, 1994 __sanitizer_nfds_t nfds) { 1995 for (unsigned i = 0; i < nfds; ++i) { 1996 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].fd, sizeof(fds[i].fd)); 1997 COMMON_INTERCEPTOR_READ_RANGE(ctx, &fds[i].events, sizeof(fds[i].events)); 1998 } 1999} 2000 2001static void write_pollfd(void *ctx, __sanitizer_pollfd *fds, 2002 __sanitizer_nfds_t nfds) { 2003 for (unsigned i = 0; i < nfds; ++i) 2004 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &fds[i].revents, 2005 sizeof(fds[i].revents)); 2006} 2007 2008INTERCEPTOR(int, poll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2009 int timeout) { 2010 void *ctx; 2011 COMMON_INTERCEPTOR_ENTER(ctx, poll, fds, nfds, timeout); 2012 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2013 int res = COMMON_INTERCEPTOR_BLOCK_REAL(poll)(fds, nfds, timeout); 2014 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2015 return res; 2016} 2017#define INIT_POLL INTERCEPT_FUNCTION(poll); 2018#else 2019#define INIT_POLL 2020#endif 2021 2022#if SANITIZER_INTERCEPT_PPOLL 2023INTERCEPTOR(int, ppoll, __sanitizer_pollfd *fds, __sanitizer_nfds_t nfds, 2024 void *timeout_ts, __sanitizer_sigset_t *sigmask) { 2025 void *ctx; 2026 COMMON_INTERCEPTOR_ENTER(ctx, ppoll, fds, nfds, timeout_ts, sigmask); 2027 if (fds && nfds) read_pollfd(ctx, fds, nfds); 2028 if (timeout_ts) 2029 COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout_ts, struct_timespec_sz); 2030 // FIXME: read sigmask when all of sigemptyset, etc are intercepted. 2031 int res = 2032 COMMON_INTERCEPTOR_BLOCK_REAL(ppoll)(fds, nfds, timeout_ts, sigmask); 2033 if (fds && nfds) write_pollfd(ctx, fds, nfds); 2034 return res; 2035} 2036#define INIT_PPOLL INTERCEPT_FUNCTION(ppoll); 2037#else 2038#define INIT_PPOLL 2039#endif 2040 2041#if SANITIZER_INTERCEPT_WORDEXP 2042INTERCEPTOR(int, wordexp, char *s, __sanitizer_wordexp_t *p, int flags) { 2043 void *ctx; 2044 COMMON_INTERCEPTOR_ENTER(ctx, wordexp, s, p, flags); 2045 if (s) COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); 2046 int res = REAL(wordexp)(s, p, flags); 2047 if (!res && p) { 2048 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); 2049 if (p->we_wordc) 2050 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->we_wordv, 2051 sizeof(*p->we_wordv) * p->we_wordc); 2052 for (uptr i = 0; i < p->we_wordc; ++i) { 2053 char *w = p->we_wordv[i]; 2054 if (w) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, w, REAL(strlen)(w) + 1); 2055 } 2056 } 2057 return res; 2058} 2059#define INIT_WORDEXP INTERCEPT_FUNCTION(wordexp); 2060#else 2061#define INIT_WORDEXP 2062#endif 2063 2064#if SANITIZER_INTERCEPT_SIGWAIT 2065INTERCEPTOR(int, sigwait, __sanitizer_sigset_t *set, int *sig) { 2066 void *ctx; 2067 COMMON_INTERCEPTOR_ENTER(ctx, sigwait, set, sig); 2068 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2069 int res = REAL(sigwait)(set, sig); 2070 if (!res && sig) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sig, sizeof(*sig)); 2071 return res; 2072} 2073#define INIT_SIGWAIT INTERCEPT_FUNCTION(sigwait); 2074#else 2075#define INIT_SIGWAIT 2076#endif 2077 2078#if SANITIZER_INTERCEPT_SIGWAITINFO 2079INTERCEPTOR(int, sigwaitinfo, __sanitizer_sigset_t *set, void *info) { 2080 void *ctx; 2081 COMMON_INTERCEPTOR_ENTER(ctx, sigwaitinfo, set, info); 2082 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2083 int res = REAL(sigwaitinfo)(set, info); 2084 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2085 return res; 2086} 2087#define INIT_SIGWAITINFO INTERCEPT_FUNCTION(sigwaitinfo); 2088#else 2089#define INIT_SIGWAITINFO 2090#endif 2091 2092#if SANITIZER_INTERCEPT_SIGTIMEDWAIT 2093INTERCEPTOR(int, sigtimedwait, __sanitizer_sigset_t *set, void *info, 2094 void *timeout) { 2095 void *ctx; 2096 COMMON_INTERCEPTOR_ENTER(ctx, sigtimedwait, set, info, timeout); 2097 if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); 2098 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2099 int res = REAL(sigtimedwait)(set, info, timeout); 2100 if (res > 0 && info) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, info, siginfo_t_sz); 2101 return res; 2102} 2103#define INIT_SIGTIMEDWAIT INTERCEPT_FUNCTION(sigtimedwait); 2104#else 2105#define INIT_SIGTIMEDWAIT 2106#endif 2107 2108#if SANITIZER_INTERCEPT_SIGSETOPS 2109INTERCEPTOR(int, sigemptyset, __sanitizer_sigset_t *set) { 2110 void *ctx; 2111 COMMON_INTERCEPTOR_ENTER(ctx, sigemptyset, set); 2112 int res = REAL(sigemptyset)(set); 2113 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2114 return res; 2115} 2116 2117INTERCEPTOR(int, sigfillset, __sanitizer_sigset_t *set) { 2118 void *ctx; 2119 COMMON_INTERCEPTOR_ENTER(ctx, sigfillset, set); 2120 int res = REAL(sigfillset)(set); 2121 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2122 return res; 2123} 2124#define INIT_SIGSETOPS \ 2125 INTERCEPT_FUNCTION(sigemptyset); \ 2126 INTERCEPT_FUNCTION(sigfillset); 2127#else 2128#define INIT_SIGSETOPS 2129#endif 2130 2131#if SANITIZER_INTERCEPT_SIGPENDING 2132INTERCEPTOR(int, sigpending, __sanitizer_sigset_t *set) { 2133 void *ctx; 2134 COMMON_INTERCEPTOR_ENTER(ctx, sigpending, set); 2135 int res = REAL(sigpending)(set); 2136 if (!res && set) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, set, sizeof(*set)); 2137 return res; 2138} 2139#define INIT_SIGPENDING INTERCEPT_FUNCTION(sigpending); 2140#else 2141#define INIT_SIGPENDING 2142#endif 2143 2144#if SANITIZER_INTERCEPT_SIGPROCMASK 2145INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, 2146 __sanitizer_sigset_t *oldset) { 2147 void *ctx; 2148 COMMON_INTERCEPTOR_ENTER(ctx, sigprocmask, how, set, oldset); 2149 // FIXME: read sigset_t when all of sigemptyset, etc are intercepted 2150 int res = REAL(sigprocmask)(how, set, oldset); 2151 if (!res && oldset) 2152 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); 2153 return res; 2154} 2155#define INIT_SIGPROCMASK INTERCEPT_FUNCTION(sigprocmask); 2156#else 2157#define INIT_SIGPROCMASK 2158#endif 2159 2160#if SANITIZER_INTERCEPT_BACKTRACE 2161INTERCEPTOR(int, backtrace, void **buffer, int size) { 2162 void *ctx; 2163 COMMON_INTERCEPTOR_ENTER(ctx, backtrace, buffer, size); 2164 int res = REAL(backtrace)(buffer, size); 2165 if (res && buffer) 2166 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buffer, res * sizeof(*buffer)); 2167 return res; 2168} 2169 2170INTERCEPTOR(char **, backtrace_symbols, void **buffer, int size) { 2171 void *ctx; 2172 COMMON_INTERCEPTOR_ENTER(ctx, backtrace_symbols, buffer, size); 2173 if (buffer && size) 2174 COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, size * sizeof(*buffer)); 2175 char ** res = REAL(backtrace_symbols)(buffer, size); 2176 if (res && size) { 2177 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, size * sizeof(*res)); 2178 for (int i = 0; i < size; ++i) 2179 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res[i], REAL(strlen(res[i])) + 1); 2180 } 2181 return res; 2182} 2183#define INIT_BACKTRACE \ 2184 INTERCEPT_FUNCTION(backtrace); \ 2185 INTERCEPT_FUNCTION(backtrace_symbols); 2186#else 2187#define INIT_BACKTRACE 2188#endif 2189 2190#if SANITIZER_INTERCEPT__EXIT 2191INTERCEPTOR(void, _exit, int status) { 2192 void *ctx; 2193 COMMON_INTERCEPTOR_ENTER(ctx, _exit, status); 2194 int status1 = COMMON_INTERCEPTOR_ON_EXIT(ctx); 2195 if (status == 0) 2196 status = status1; 2197 REAL(_exit)(status); 2198} 2199#define INIT__EXIT INTERCEPT_FUNCTION(_exit); 2200#else 2201#define INIT__EXIT 2202#endif 2203 2204#if SANITIZER_INTERCEPT_PHTREAD_MUTEX 2205INTERCEPTOR(int, pthread_mutex_lock, void *m) { 2206 void *ctx; 2207 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); 2208 int res = REAL(pthread_mutex_lock)(m); 2209 if (res == 0) 2210 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2211 return res; 2212} 2213 2214INTERCEPTOR(int, pthread_mutex_unlock, void *m) { 2215 void *ctx; 2216 COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_unlock, m); 2217 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2218 return REAL(pthread_mutex_unlock)(m); 2219} 2220 2221#define INIT_PTHREAD_MUTEX_LOCK INTERCEPT_FUNCTION(pthread_mutex_lock) 2222#define INIT_PTHREAD_MUTEX_UNLOCK INTERCEPT_FUNCTION(pthread_mutex_unlock) 2223#else 2224#define INIT_PTHREAD_MUTEX_LOCK 2225#define INIT_PTHREAD_MUTEX_UNLOCK 2226#endif 2227 2228#if SANITIZER_INTERCEPT_PTHREAD_COND 2229INTERCEPTOR(int, pthread_cond_wait, void *c, void *m) { 2230 void *ctx; 2231 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_wait, c, m); 2232 COMMON_INTERCEPTOR_MUTEX_UNLOCK(ctx, m); 2233 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2234 int res = REAL(pthread_cond_wait)(c, m); 2235 COMMON_INTERCEPTOR_MUTEX_LOCK(ctx, m); 2236 return res; 2237} 2238 2239INTERCEPTOR(int, pthread_cond_init, void *c, void *a) { 2240 void *ctx; 2241 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_init, c, a); 2242 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, c, pthread_cond_t_sz); 2243 return REAL(pthread_cond_init)(c, a); 2244} 2245 2246INTERCEPTOR(int, pthread_cond_signal, void *c) { 2247 void *ctx; 2248 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_signal, c); 2249 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2250 return REAL(pthread_cond_signal)(c); 2251} 2252 2253INTERCEPTOR(int, pthread_cond_broadcast, void *c) { 2254 void *ctx; 2255 COMMON_INTERCEPTOR_ENTER(ctx, pthread_cond_broadcast, c); 2256 COMMON_INTERCEPTOR_READ_RANGE(ctx, c, pthread_cond_t_sz); 2257 return REAL(pthread_cond_broadcast)(c); 2258} 2259 2260#define INIT_PTHREAD_COND_WAIT \ 2261 INTERCEPT_FUNCTION_VER(pthread_cond_wait, GLIBC_2.3.2) 2262#define INIT_PTHREAD_COND_INIT \ 2263 INTERCEPT_FUNCTION_VER(pthread_cond_init, GLIBC_2.3.2) 2264#define INIT_PTHREAD_COND_SIGNAL \ 2265 INTERCEPT_FUNCTION_VER(pthread_cond_signal, GLIBC_2.3.2) 2266#define INIT_PTHREAD_COND_BROADCAST \ 2267 INTERCEPT_FUNCTION_VER(pthread_cond_broadcast, GLIBC_2.3.2) 2268#else 2269#define INIT_PTHREAD_COND_WAIT 2270#define INIT_PTHREAD_COND_INIT 2271#define INIT_PTHREAD_COND_SIGNAL 2272#define INIT_PTHREAD_COND_BROADCAST 2273#endif 2274 2275#if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R 2276static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { 2277 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); 2278 if (mnt->mnt_fsname) 2279 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_fsname, 2280 REAL(strlen)(mnt->mnt_fsname) + 1); 2281 if (mnt->mnt_dir) 2282 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_dir, 2283 REAL(strlen)(mnt->mnt_dir) + 1); 2284 if (mnt->mnt_type) 2285 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_type, 2286 REAL(strlen)(mnt->mnt_type) + 1); 2287 if (mnt->mnt_opts) 2288 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt->mnt_opts, 2289 REAL(strlen)(mnt->mnt_opts) + 1); 2290} 2291#endif 2292 2293#if SANITIZER_INTERCEPT_GETMNTENT 2294INTERCEPTOR(__sanitizer_mntent *, getmntent, void *fp) { 2295 void *ctx; 2296 COMMON_INTERCEPTOR_ENTER(ctx, getmntent, fp); 2297 __sanitizer_mntent *res = REAL(getmntent)(fp); 2298 if (res) write_mntent(ctx, res); 2299 return res; 2300} 2301#define INIT_GETMNTENT INTERCEPT_FUNCTION(getmntent); 2302#else 2303#define INIT_GETMNTENT 2304#endif 2305 2306#if SANITIZER_INTERCEPT_GETMNTENT_R 2307INTERCEPTOR(__sanitizer_mntent *, getmntent_r, void *fp, 2308 __sanitizer_mntent *mntbuf, char *buf, int buflen) { 2309 void *ctx; 2310 COMMON_INTERCEPTOR_ENTER(ctx, getmntent_r, fp, mntbuf, buf, buflen); 2311 __sanitizer_mntent *res = REAL(getmntent_r)(fp, mntbuf, buf, buflen); 2312 if (res) write_mntent(ctx, res); 2313 return res; 2314} 2315#define INIT_GETMNTENT_R INTERCEPT_FUNCTION(getmntent_r); 2316#else 2317#define INIT_GETMNTENT_R 2318#endif 2319 2320#if SANITIZER_INTERCEPT_STATFS 2321INTERCEPTOR(int, statfs, char *path, void *buf) { 2322 void *ctx; 2323 COMMON_INTERCEPTOR_ENTER(ctx, statfs, path, buf); 2324 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2325 int res = REAL(statfs)(path, buf); 2326 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2327 return res; 2328} 2329INTERCEPTOR(int, fstatfs, int fd, void *buf) { 2330 void *ctx; 2331 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs, fd, buf); 2332 int res = REAL(fstatfs)(fd, buf); 2333 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs_sz); 2334 return res; 2335} 2336#define INIT_STATFS \ 2337 INTERCEPT_FUNCTION(statfs); \ 2338 INTERCEPT_FUNCTION(fstatfs); 2339#else 2340#define INIT_STATFS 2341#endif 2342 2343#if SANITIZER_INTERCEPT_STATFS64 2344INTERCEPTOR(int, statfs64, char *path, void *buf) { 2345 void *ctx; 2346 COMMON_INTERCEPTOR_ENTER(ctx, statfs64, path, buf); 2347 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2348 int res = REAL(statfs64)(path, buf); 2349 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2350 return res; 2351} 2352INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 2353 void *ctx; 2354 COMMON_INTERCEPTOR_ENTER(ctx, fstatfs64, fd, buf); 2355 int res = REAL(fstatfs64)(fd, buf); 2356 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statfs64_sz); 2357 return res; 2358} 2359#define INIT_STATFS64 \ 2360 INTERCEPT_FUNCTION(statfs64); \ 2361 INTERCEPT_FUNCTION(fstatfs64); 2362#else 2363#define INIT_STATFS64 2364#endif 2365 2366#if SANITIZER_INTERCEPT_STATVFS 2367INTERCEPTOR(int, statvfs, char *path, void *buf) { 2368 void *ctx; 2369 COMMON_INTERCEPTOR_ENTER(ctx, statvfs, path, buf); 2370 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2371 int res = REAL(statvfs)(path, buf); 2372 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2373 return res; 2374} 2375INTERCEPTOR(int, fstatvfs, int fd, void *buf) { 2376 void *ctx; 2377 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); 2378 int res = REAL(fstatvfs)(fd, buf); 2379 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); 2380 return res; 2381} 2382#define INIT_STATVFS \ 2383 INTERCEPT_FUNCTION(statvfs); \ 2384 INTERCEPT_FUNCTION(fstatvfs); 2385#else 2386#define INIT_STATVFS 2387#endif 2388 2389#if SANITIZER_INTERCEPT_STATVFS64 2390INTERCEPTOR(int, statvfs64, char *path, void *buf) { 2391 void *ctx; 2392 COMMON_INTERCEPTOR_ENTER(ctx, statvfs64, path, buf); 2393 if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); 2394 int res = REAL(statvfs64)(path, buf); 2395 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2396 return res; 2397} 2398INTERCEPTOR(int, fstatvfs64, int fd, void *buf) { 2399 void *ctx; 2400 COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs64, fd, buf); 2401 int res = REAL(fstatvfs64)(fd, buf); 2402 if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs64_sz); 2403 return res; 2404} 2405#define INIT_STATVFS64 \ 2406 INTERCEPT_FUNCTION(statvfs64); \ 2407 INTERCEPT_FUNCTION(fstatvfs64); 2408#else 2409#define INIT_STATVFS64 2410#endif 2411 2412#if SANITIZER_INTERCEPT_INITGROUPS 2413INTERCEPTOR(int, initgroups, char *user, u32 group) { 2414 void *ctx; 2415 COMMON_INTERCEPTOR_ENTER(ctx, initgroups, user, group); 2416 if (user) COMMON_INTERCEPTOR_READ_RANGE(ctx, user, REAL(strlen)(user) + 1); 2417 int res = REAL(initgroups)(user, group); 2418 return res; 2419} 2420#define INIT_INITGROUPS INTERCEPT_FUNCTION(initgroups); 2421#else 2422#define INIT_INITGROUPS 2423#endif 2424 2425#if SANITIZER_INTERCEPT_ETHER 2426INTERCEPTOR(char *, ether_ntoa, __sanitizer_ether_addr *addr) { 2427 void *ctx; 2428 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa, addr); 2429 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2430 char *res = REAL(ether_ntoa)(addr); 2431 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2432 return res; 2433} 2434INTERCEPTOR(__sanitizer_ether_addr *, ether_aton, char *buf) { 2435 void *ctx; 2436 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton, buf); 2437 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2438 __sanitizer_ether_addr *res = REAL(ether_aton)(buf); 2439 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, sizeof(*res)); 2440 return res; 2441} 2442INTERCEPTOR(int, ether_ntohost, char *hostname, __sanitizer_ether_addr *addr) { 2443 void *ctx; 2444 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntohost, hostname, addr); 2445 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2446 int res = REAL(ether_ntohost)(hostname, addr); 2447 if (!res && hostname) 2448 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2449 return res; 2450} 2451INTERCEPTOR(int, ether_hostton, char *hostname, __sanitizer_ether_addr *addr) { 2452 void *ctx; 2453 COMMON_INTERCEPTOR_ENTER(ctx, ether_hostton, hostname, addr); 2454 if (hostname) 2455 COMMON_INTERCEPTOR_READ_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2456 int res = REAL(ether_hostton)(hostname, addr); 2457 if (!res && addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2458 return res; 2459} 2460INTERCEPTOR(int, ether_line, char *line, __sanitizer_ether_addr *addr, 2461 char *hostname) { 2462 void *ctx; 2463 COMMON_INTERCEPTOR_ENTER(ctx, ether_line, line, addr, hostname); 2464 if (line) COMMON_INTERCEPTOR_READ_RANGE(ctx, line, REAL(strlen)(line) + 1); 2465 int res = REAL(ether_line)(line, addr, hostname); 2466 if (!res) { 2467 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2468 if (hostname) 2469 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hostname, REAL(strlen)(hostname) + 1); 2470 } 2471 return res; 2472} 2473#define INIT_ETHER \ 2474 INTERCEPT_FUNCTION(ether_ntoa); \ 2475 INTERCEPT_FUNCTION(ether_aton); \ 2476 INTERCEPT_FUNCTION(ether_ntohost); \ 2477 INTERCEPT_FUNCTION(ether_hostton); \ 2478 INTERCEPT_FUNCTION(ether_line); 2479#else 2480#define INIT_ETHER 2481#endif 2482 2483#if SANITIZER_INTERCEPT_ETHER_R 2484INTERCEPTOR(char *, ether_ntoa_r, __sanitizer_ether_addr *addr, char *buf) { 2485 void *ctx; 2486 COMMON_INTERCEPTOR_ENTER(ctx, ether_ntoa_r, addr, buf); 2487 if (addr) COMMON_INTERCEPTOR_READ_RANGE(ctx, addr, sizeof(*addr)); 2488 char *res = REAL(ether_ntoa_r)(addr, buf); 2489 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2490 return res; 2491} 2492INTERCEPTOR(__sanitizer_ether_addr *, ether_aton_r, char *buf, 2493 __sanitizer_ether_addr *addr) { 2494 void *ctx; 2495 COMMON_INTERCEPTOR_ENTER(ctx, ether_aton_r, buf, addr); 2496 if (buf) COMMON_INTERCEPTOR_READ_RANGE(ctx, buf, REAL(strlen)(buf) + 1); 2497 __sanitizer_ether_addr *res = REAL(ether_aton_r)(buf, addr); 2498 if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, sizeof(*res)); 2499 return res; 2500} 2501#define INIT_ETHER_R \ 2502 INTERCEPT_FUNCTION(ether_ntoa_r); \ 2503 INTERCEPT_FUNCTION(ether_aton_r); 2504#else 2505#define INIT_ETHER_R 2506#endif 2507 2508#if SANITIZER_INTERCEPT_SHMCTL 2509INTERCEPTOR(int, shmctl, int shmid, int cmd, void *buf) { 2510 void *ctx; 2511 COMMON_INTERCEPTOR_ENTER(ctx, shmctl, shmid, cmd, buf); 2512 int res = REAL(shmctl)(shmid, cmd, buf); 2513 if (res >= 0) { 2514 unsigned sz = 0; 2515 if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) 2516 sz = sizeof(__sanitizer_shmid_ds); 2517 else if (cmd == shmctl_ipc_info) 2518 sz = struct_shminfo_sz; 2519 else if (cmd == shmctl_shm_info) 2520 sz = struct_shm_info_sz; 2521 if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); 2522 } 2523 return res; 2524} 2525#define INIT_SHMCTL INTERCEPT_FUNCTION(shmctl); 2526#else 2527#define INIT_SHMCTL 2528#endif 2529 2530#if SANITIZER_INTERCEPT_RANDOM_R 2531INTERCEPTOR(int, random_r, void *buf, u32 *result) { 2532 void *ctx; 2533 COMMON_INTERCEPTOR_ENTER(ctx, random_r, buf, result); 2534 int res = REAL(random_r)(buf, result); 2535 if (!res && result) 2536 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2537 return res; 2538} 2539#define INIT_RANDOM_R INTERCEPT_FUNCTION(random_r); 2540#else 2541#define INIT_RANDOM_R 2542#endif 2543 2544#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ 2545 SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED 2546#define INTERCEPTOR_PTHREAD_ATTR_GET(what, sz) \ 2547 INTERCEPTOR(int, pthread_attr_get##what, void *attr, void *r) { \ 2548 void *ctx; \ 2549 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_get##what, attr, r); \ 2550 int res = REAL(pthread_attr_get##what)(attr, r); \ 2551 if (!res && r) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, r, sz); \ 2552 return res; \ 2553 } 2554#endif 2555 2556#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET 2557INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) 2558INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) 2559INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) 2560INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) 2561INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) 2562INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) 2563INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { 2564 void *ctx; 2565 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getstack, attr, addr, size); 2566 int res = REAL(pthread_attr_getstack)(attr, addr, size); 2567 if (!res) { 2568 if (addr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, sizeof(*addr)); 2569 if (size) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, size, sizeof(*size)); 2570 } 2571 return res; 2572} 2573 2574#define INIT_PTHREAD_ATTR_GET \ 2575 INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ 2576 INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ 2577 INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ 2578 INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ 2579 INTERCEPT_FUNCTION(pthread_attr_getscope); \ 2580 INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ 2581 INTERCEPT_FUNCTION(pthread_attr_getstack); 2582#else 2583#define INIT_PTHREAD_ATTR_GET 2584#endif 2585 2586#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED 2587INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) 2588 2589#define INIT_PTHREAD_ATTR_GETINHERITSCHED \ 2590 INTERCEPT_FUNCTION(pthread_attr_getinheritsched); 2591#else 2592#define INIT_PTHREAD_ATTR_GETINHERITSCHED 2593#endif 2594 2595#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP 2596INTERCEPTOR(int, pthread_attr_getaffinity_np, void *attr, SIZE_T cpusetsize, 2597 void *cpuset) { 2598 void *ctx; 2599 COMMON_INTERCEPTOR_ENTER(ctx, pthread_attr_getaffinity_np, attr, cpusetsize, 2600 cpuset); 2601 int res = REAL(pthread_attr_getaffinity_np)(attr, cpusetsize, cpuset); 2602 if (!res && cpusetsize && cpuset) 2603 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cpuset, cpusetsize); 2604 return res; 2605} 2606 2607#define INIT_PTHREAD_ATTR_GETAFFINITY_NP \ 2608 INTERCEPT_FUNCTION(pthread_attr_getaffinity_np); 2609#else 2610#define INIT_PTHREAD_ATTR_GETAFFINITY_NP 2611#endif 2612 2613#if SANITIZER_INTERCEPT_TMPNAM 2614INTERCEPTOR(char *, tmpnam, char *s) { 2615 void *ctx; 2616 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam, s); 2617 char *res = REAL(tmpnam)(s); 2618 if (res) { 2619 if (s) 2620 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 2621 else 2622 COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2623 } 2624 return res; 2625} 2626#define INIT_TMPNAM INTERCEPT_FUNCTION(tmpnam); 2627#else 2628#define INIT_TMPNAM 2629#endif 2630 2631#if SANITIZER_INTERCEPT_TMPNAM_R 2632INTERCEPTOR(char *, tmpnam_r, char *s) { 2633 void *ctx; 2634 COMMON_INTERCEPTOR_ENTER(ctx, tmpnam_r, s); 2635 char *res = REAL(tmpnam_r)(s); 2636 if (res && s) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); 2637 return res; 2638} 2639#define INIT_TMPNAM_R INTERCEPT_FUNCTION(tmpnam_r); 2640#else 2641#define INIT_TMPNAM_R 2642#endif 2643 2644#if SANITIZER_INTERCEPT_TEMPNAM 2645INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { 2646 void *ctx; 2647 COMMON_INTERCEPTOR_ENTER(ctx, tempnam, dir, pfx); 2648 if (dir) COMMON_INTERCEPTOR_READ_RANGE(ctx, dir, REAL(strlen)(dir) + 1); 2649 if (pfx) COMMON_INTERCEPTOR_READ_RANGE(ctx, pfx, REAL(strlen)(pfx) + 1); 2650 char *res = REAL(tempnam)(dir, pfx); 2651 if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(ctx, res, REAL(strlen)(res) + 1); 2652 return res; 2653} 2654#define INIT_TEMPNAM INTERCEPT_FUNCTION(tempnam); 2655#else 2656#define INIT_TEMPNAM 2657#endif 2658 2659#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP 2660INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { 2661 void *ctx; 2662 COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); 2663 COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name); 2664 return REAL(pthread_setname_np)(thread, name); 2665} 2666#define INIT_PTHREAD_SETNAME_NP INTERCEPT_FUNCTION(pthread_setname_np); 2667#else 2668#define INIT_PTHREAD_SETNAME_NP 2669#endif 2670 2671#if SANITIZER_INTERCEPT_SINCOS 2672INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { 2673 void *ctx; 2674 COMMON_INTERCEPTOR_ENTER(ctx, sincos, x, sin, cos); 2675 REAL(sincos)(x, sin, cos); 2676 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2677 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2678} 2679INTERCEPTOR(void, sincosf, float x, float *sin, float *cos) { 2680 void *ctx; 2681 COMMON_INTERCEPTOR_ENTER(ctx, sincosf, x, sin, cos); 2682 REAL(sincosf)(x, sin, cos); 2683 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2684 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2685} 2686INTERCEPTOR(void, sincosl, long double x, long double *sin, long double *cos) { 2687 void *ctx; 2688 COMMON_INTERCEPTOR_ENTER(ctx, sincosl, x, sin, cos); 2689 REAL(sincosl)(x, sin, cos); 2690 if (sin) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sin, sizeof(*sin)); 2691 if (cos) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cos, sizeof(*cos)); 2692} 2693#define INIT_SINCOS \ 2694 INTERCEPT_FUNCTION(sincos); \ 2695 INTERCEPT_FUNCTION(sincosf); \ 2696 INTERCEPT_FUNCTION(sincosl); 2697#else 2698#define INIT_SINCOS 2699#endif 2700 2701#if SANITIZER_INTERCEPT_REMQUO 2702INTERCEPTOR(double, remquo, double x, double y, int *quo) { 2703 void *ctx; 2704 COMMON_INTERCEPTOR_ENTER(ctx, remquo, x, y, quo); 2705 double res = REAL(remquo)(x, y, quo); 2706 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2707 return res; 2708} 2709INTERCEPTOR(float, remquof, float x, float y, int *quo) { 2710 void *ctx; 2711 COMMON_INTERCEPTOR_ENTER(ctx, remquof, x, y, quo); 2712 float res = REAL(remquof)(x, y, quo); 2713 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2714 return res; 2715} 2716INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { 2717 void *ctx; 2718 COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); 2719 long double res = REAL(remquol)(x, y, quo); 2720 if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); 2721 return res; 2722} 2723#define INIT_REMQUO \ 2724 INTERCEPT_FUNCTION(remquo); \ 2725 INTERCEPT_FUNCTION(remquof); \ 2726 INTERCEPT_FUNCTION(remquol); 2727#else 2728#define INIT_REMQUO 2729#endif 2730 2731#if SANITIZER_INTERCEPT_LGAMMA 2732extern int signgam; 2733INTERCEPTOR(double, lgamma, double x) { 2734 void *ctx; 2735 COMMON_INTERCEPTOR_ENTER(ctx, lgamma, x); 2736 double res = REAL(lgamma)(x); 2737 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2738 return res; 2739} 2740INTERCEPTOR(float, lgammaf, float x) { 2741 void *ctx; 2742 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf, x); 2743 float res = REAL(lgammaf)(x); 2744 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2745 return res; 2746} 2747INTERCEPTOR(long double, lgammal, long double x) { 2748 void *ctx; 2749 COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); 2750 long double res = REAL(lgammal)(x); 2751 COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); 2752 return res; 2753} 2754#define INIT_LGAMMA \ 2755 INTERCEPT_FUNCTION(lgamma); \ 2756 INTERCEPT_FUNCTION(lgammaf); \ 2757 INTERCEPT_FUNCTION(lgammal); 2758#else 2759#define INIT_LGAMMA 2760#endif 2761 2762#if SANITIZER_INTERCEPT_LGAMMA_R 2763INTERCEPTOR(double, lgamma_r, double x, int *signp) { 2764 void *ctx; 2765 COMMON_INTERCEPTOR_ENTER(ctx, lgamma_r, x, signp); 2766 double res = REAL(lgamma_r)(x, signp); 2767 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2768 return res; 2769} 2770INTERCEPTOR(float, lgammaf_r, float x, int *signp) { 2771 void *ctx; 2772 COMMON_INTERCEPTOR_ENTER(ctx, lgammaf_r, x, signp); 2773 float res = REAL(lgammaf_r)(x, signp); 2774 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2775 return res; 2776} 2777INTERCEPTOR(long double, lgammal_r, long double x, int *signp) { 2778 void *ctx; 2779 COMMON_INTERCEPTOR_ENTER(ctx, lgammal_r, x, signp); 2780 long double res = REAL(lgammal_r)(x, signp); 2781 if (signp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, signp, sizeof(*signp)); 2782 return res; 2783} 2784#define INIT_LGAMMA_R \ 2785 INTERCEPT_FUNCTION(lgamma_r); \ 2786 INTERCEPT_FUNCTION(lgammaf_r); \ 2787 INTERCEPT_FUNCTION(lgammal_r); 2788#else 2789#define INIT_LGAMMA_R 2790#endif 2791 2792#if SANITIZER_INTERCEPT_DRAND48_R 2793INTERCEPTOR(int, drand48_r, void *buffer, double *result) { 2794 void *ctx; 2795 COMMON_INTERCEPTOR_ENTER(ctx, drand48_r, buffer, result); 2796 int res = REAL(drand48_r)(buffer, result); 2797 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2798 return res; 2799} 2800INTERCEPTOR(int, lrand48_r, void *buffer, long *result) { 2801 void *ctx; 2802 COMMON_INTERCEPTOR_ENTER(ctx, lrand48_r, buffer, result); 2803 int res = REAL(lrand48_r)(buffer, result); 2804 if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); 2805 return res; 2806} 2807#define INIT_DRAND48_R \ 2808 INTERCEPT_FUNCTION(drand48_r); \ 2809 INTERCEPT_FUNCTION(lrand48_r); 2810#else 2811#define INIT_DRAND48_R 2812#endif 2813 2814#define SANITIZER_COMMON_INTERCEPTORS_INIT \ 2815 INIT_STRCMP; \ 2816 INIT_STRNCMP; \ 2817 INIT_STRCASECMP; \ 2818 INIT_STRNCASECMP; \ 2819 INIT_READ; \ 2820 INIT_PREAD; \ 2821 INIT_PREAD64; \ 2822 INIT_READV; \ 2823 INIT_PREADV; \ 2824 INIT_PREADV64; \ 2825 INIT_WRITE; \ 2826 INIT_PWRITE; \ 2827 INIT_PWRITE64; \ 2828 INIT_WRITEV; \ 2829 INIT_PWRITEV; \ 2830 INIT_PWRITEV64; \ 2831 INIT_PRCTL; \ 2832 INIT_LOCALTIME_AND_FRIENDS; \ 2833 INIT_SCANF; \ 2834 INIT_ISOC99_SCANF; \ 2835 INIT_FREXP; \ 2836 INIT_FREXPF_FREXPL; \ 2837 INIT_GETPWNAM_AND_FRIENDS; \ 2838 INIT_GETPWNAM_R_AND_FRIENDS; \ 2839 INIT_CLOCK_GETTIME; \ 2840 INIT_GETITIMER; \ 2841 INIT_TIME; \ 2842 INIT_GLOB; \ 2843 INIT_WAIT; \ 2844 INIT_INET; \ 2845 INIT_PTHREAD_GETSCHEDPARAM; \ 2846 INIT_GETADDRINFO; \ 2847 INIT_GETNAMEINFO; \ 2848 INIT_GETSOCKNAME; \ 2849 INIT_GETHOSTBYNAME; \ 2850 INIT_GETHOSTBYNAME_R; \ 2851 INIT_GETSOCKOPT; \ 2852 INIT_ACCEPT; \ 2853 INIT_ACCEPT4; \ 2854 INIT_MODF; \ 2855 INIT_RECVMSG; \ 2856 INIT_GETPEERNAME; \ 2857 INIT_IOCTL; \ 2858 INIT_INET_ATON; \ 2859 INIT_SYSINFO; \ 2860 INIT_READDIR; \ 2861 INIT_READDIR64; \ 2862 INIT_PTRACE; \ 2863 INIT_SETLOCALE; \ 2864 INIT_GETCWD; \ 2865 INIT_GET_CURRENT_DIR_NAME; \ 2866 INIT_STRTOIMAX; \ 2867 INIT_MBSTOWCS; \ 2868 INIT_MBSNRTOWCS; \ 2869 INIT_WCSTOMBS; \ 2870 INIT_WCSNRTOMBS; \ 2871 INIT_TCGETATTR; \ 2872 INIT_REALPATH; \ 2873 INIT_CANONICALIZE_FILE_NAME; \ 2874 INIT_CONFSTR; \ 2875 INIT_SCHED_GETAFFINITY; \ 2876 INIT_STRERROR; \ 2877 INIT_STRERROR_R; \ 2878 INIT_SCANDIR; \ 2879 INIT_SCANDIR64; \ 2880 INIT_GETGROUPS; \ 2881 INIT_POLL; \ 2882 INIT_PPOLL; \ 2883 INIT_WORDEXP; \ 2884 INIT_SIGWAIT; \ 2885 INIT_SIGWAITINFO; \ 2886 INIT_SIGTIMEDWAIT; \ 2887 INIT_SIGSETOPS; \ 2888 INIT_SIGPENDING; \ 2889 INIT_SIGPROCMASK; \ 2890 INIT_BACKTRACE; \ 2891 INIT__EXIT; \ 2892 INIT_PTHREAD_MUTEX_LOCK; \ 2893 INIT_PTHREAD_MUTEX_UNLOCK; \ 2894 INIT_PTHREAD_COND_WAIT; \ 2895 INIT_PTHREAD_COND_INIT; \ 2896 INIT_PTHREAD_COND_SIGNAL; \ 2897 INIT_PTHREAD_COND_BROADCAST; \ 2898 INIT_GETMNTENT; \ 2899 INIT_GETMNTENT_R; \ 2900 INIT_STATFS; \ 2901 INIT_STATFS64; \ 2902 INIT_STATVFS; \ 2903 INIT_STATVFS64; \ 2904 INIT_INITGROUPS; \ 2905 INIT_ETHER; \ 2906 INIT_ETHER_R; \ 2907 INIT_SHMCTL; \ 2908 INIT_RANDOM_R; \ 2909 INIT_PTHREAD_ATTR_GET; \ 2910 INIT_PTHREAD_ATTR_GETINHERITSCHED; \ 2911 INIT_PTHREAD_ATTR_GETAFFINITY_NP; \ 2912 INIT_TMPNAM; \ 2913 INIT_TMPNAM_R; \ 2914 INIT_TEMPNAM; \ 2915 INIT_PTHREAD_SETNAME_NP; \ 2916 INIT_SINCOS; \ 2917 INIT_REMQUO; \ 2918 INIT_LGAMMA; \ 2919 INIT_LGAMMA_R; \ 2920 INIT_DRAND48_R; \ 2921/**/ 2922