msan_interceptors.cc revision 0797ed4bfc4adaa1436dbd153b276ed9c917f1b7
1//===-- msan_interceptors.cc ----------------------------------------------===// 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// This file is a part of MemorySanitizer. 11// 12// Interceptors for standard library functions. 13// 14// FIXME: move as many interceptors as possible into 15// sanitizer_common/sanitizer_common_interceptors.h 16//===----------------------------------------------------------------------===// 17 18#include "interception/interception.h" 19#include "msan.h" 20#include "sanitizer_common/sanitizer_platform_limits_posix.h" 21#include "sanitizer_common/sanitizer_allocator.h" 22#include "sanitizer_common/sanitizer_common.h" 23#include "sanitizer_common/sanitizer_stackdepot.h" 24#include "sanitizer_common/sanitizer_libc.h" 25#include "sanitizer_common/sanitizer_linux.h" 26 27#include <stdarg.h> 28// ACHTUNG! No other system header includes in this file. 29// Ideally, we should get rid of stdarg.h as well. 30 31using namespace __msan; 32 33// True if this is a nested interceptor. 34static THREADLOCAL int in_interceptor_scope; 35 36struct InterceptorScope { 37 InterceptorScope() { ++in_interceptor_scope; } 38 ~InterceptorScope() { --in_interceptor_scope; } 39}; 40 41bool IsInInterceptorScope() { 42 return in_interceptor_scope; 43} 44 45#define ENSURE_MSAN_INITED() do { \ 46 CHECK(!msan_init_is_running); \ 47 if (!msan_inited) { \ 48 __msan_init(); \ 49 } \ 50} while (0) 51 52// Check that [x, x+n) range is unpoisoned. 53#define CHECK_UNPOISONED_0(x, n) \ 54 do { \ 55 sptr offset = __msan_test_shadow(x, n); \ 56 if (__msan::IsInSymbolizer()) break; \ 57 if (offset >= 0 && __msan::flags()->report_umrs) { \ 58 GET_CALLER_PC_BP_SP; \ 59 (void) sp; \ 60 Printf("UMR in %s at offset %d inside [%p, +%d) \n", __FUNCTION__, \ 61 offset, x, n); \ 62 __msan::PrintWarningWithOrigin(pc, bp, \ 63 __msan_get_origin((char *)x + offset)); \ 64 if (!__msan::flags()->keep_going) { \ 65 Printf("Exiting\n"); \ 66 Die(); \ 67 } \ 68 } \ 69 } while (0) 70 71// Check that [x, x+n) range is unpoisoned unless we are in a nested 72// interceptor. 73#define CHECK_UNPOISONED(x, n) \ 74 if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); 75 76static void *fast_memset(void *ptr, int c, SIZE_T n); 77static void *fast_memcpy(void *dst, const void *src, SIZE_T n); 78 79INTERCEPTOR(SIZE_T, fread, void *ptr, SIZE_T size, SIZE_T nmemb, void *file) { 80 ENSURE_MSAN_INITED(); 81 SIZE_T res = REAL(fread)(ptr, size, nmemb, file); 82 if (res > 0) 83 __msan_unpoison(ptr, res *size); 84 return res; 85} 86 87INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb, 88 void *file) { 89 ENSURE_MSAN_INITED(); 90 SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file); 91 if (res > 0) 92 __msan_unpoison(ptr, res *size); 93 return res; 94} 95 96INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { 97 ENSURE_MSAN_INITED(); 98 SSIZE_T res = REAL(readlink)(path, buf, bufsiz); 99 if (res > 0) 100 __msan_unpoison(buf, res); 101 return res; 102} 103 104INTERCEPTOR(void *, readdir, void *a) { 105 ENSURE_MSAN_INITED(); 106 void *res = REAL(readdir)(a); 107 __msan_unpoison(res, __sanitizer::struct_dirent_sz); 108 return res; 109} 110 111INTERCEPTOR(void *, readdir64, void *a) { 112 ENSURE_MSAN_INITED(); 113 void *res = REAL(readdir)(a); 114 __msan_unpoison(res, __sanitizer::struct_dirent64_sz); 115 return res; 116} 117 118INTERCEPTOR(void *, memcpy, void *dest, const void *src, SIZE_T n) { 119 return __msan_memcpy(dest, src, n); 120} 121 122INTERCEPTOR(void *, memmove, void *dest, const void *src, SIZE_T n) { 123 return __msan_memmove(dest, src, n); 124} 125 126INTERCEPTOR(void *, memset, void *s, int c, SIZE_T n) { 127 return __msan_memset(s, c, n); 128} 129 130INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) { 131 GET_MALLOC_STACK_TRACE; 132 CHECK_EQ(alignment & (alignment - 1), 0); 133 CHECK_NE(memptr, 0); 134 *memptr = MsanReallocate(&stack, 0, size, alignment, false); 135 CHECK_NE(*memptr, 0); 136 __msan_unpoison(memptr, sizeof(*memptr)); 137 return 0; 138} 139 140INTERCEPTOR(void, free, void *ptr) { 141 ENSURE_MSAN_INITED(); 142 if (ptr == 0) return; 143 MsanDeallocate(ptr); 144} 145 146INTERCEPTOR(SIZE_T, strlen, const char *s) { 147 ENSURE_MSAN_INITED(); 148 SIZE_T res = REAL(strlen)(s); 149 CHECK_UNPOISONED(s, res + 1); 150 return res; 151} 152 153INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) { 154 ENSURE_MSAN_INITED(); 155 SIZE_T res = REAL(strnlen)(s, n); 156 SIZE_T scan_size = (res == n) ? res : res + 1; 157 CHECK_UNPOISONED(s, scan_size); 158 return res; 159} 160 161// FIXME: Add stricter shadow checks in str* interceptors (ex.: strcpy should 162// check the shadow of the terminating \0 byte). 163 164INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT 165 ENSURE_MSAN_INITED(); 166 SIZE_T n = REAL(strlen)(src); 167 char *res = REAL(strcpy)(dest, src); // NOLINT 168 __msan_copy_poison(dest, src, n + 1); 169 return res; 170} 171 172INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { // NOLINT 173 ENSURE_MSAN_INITED(); 174 SIZE_T copy_size = REAL(strnlen)(src, n); 175 if (copy_size < n) 176 copy_size++; // trailing \0 177 char *res = REAL(strncpy)(dest, src, n); // NOLINT 178 __msan_copy_poison(dest, src, copy_size); 179 return res; 180} 181 182INTERCEPTOR(char *, strdup, char *src) { 183 ENSURE_MSAN_INITED(); 184 SIZE_T n = REAL(strlen)(src); 185 char *res = REAL(strdup)(src); 186 __msan_copy_poison(res, src, n + 1); 187 return res; 188} 189 190INTERCEPTOR(char *, __strdup, char *src) { 191 ENSURE_MSAN_INITED(); 192 SIZE_T n = REAL(strlen)(src); 193 char *res = REAL(__strdup)(src); 194 __msan_copy_poison(res, src, n + 1); 195 return res; 196} 197 198INTERCEPTOR(char *, strndup, char *src, SIZE_T n) { 199 ENSURE_MSAN_INITED(); 200 SIZE_T copy_size = REAL(strnlen)(src, n); 201 char *res = REAL(strndup)(src, n); 202 __msan_copy_poison(res, src, copy_size); 203 __msan_unpoison(res + copy_size, 1); // \0 204 return res; 205} 206 207INTERCEPTOR(char *, __strndup, char *src, SIZE_T n) { 208 ENSURE_MSAN_INITED(); 209 SIZE_T copy_size = REAL(strnlen)(src, n); 210 char *res = REAL(__strndup)(src, n); 211 __msan_copy_poison(res, src, copy_size); 212 __msan_unpoison(res + copy_size, 1); // \0 213 return res; 214} 215 216INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { 217 ENSURE_MSAN_INITED(); 218 char *res = REAL(gcvt)(number, ndigit, buf); 219 // DynamoRio tool will take care of unpoisoning gcvt result for us. 220 if (!__msan_has_dynamic_component()) { 221 SIZE_T n = REAL(strlen)(buf); 222 __msan_unpoison(buf, n + 1); 223 } 224 return res; 225} 226 227INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT 228 ENSURE_MSAN_INITED(); 229 SIZE_T src_size = REAL(strlen)(src); 230 SIZE_T dest_size = REAL(strlen)(dest); 231 char *res = REAL(strcat)(dest, src); // NOLINT 232 __msan_copy_poison(dest + dest_size, src, src_size + 1); 233 return res; 234} 235 236INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT 237 ENSURE_MSAN_INITED(); 238 SIZE_T dest_size = REAL(strlen)(dest); 239 SIZE_T copy_size = REAL(strlen)(src); 240 if (copy_size < n) 241 copy_size++; // trailing \0 242 char *res = REAL(strncat)(dest, src, n); // NOLINT 243 __msan_copy_poison(dest + dest_size, src, copy_size); 244 return res; 245} 246 247INTERCEPTOR(long, strtol, const char *nptr, char **endptr, // NOLINT 248 int base) { 249 ENSURE_MSAN_INITED(); 250 long res = REAL(strtol)(nptr, endptr, base); // NOLINT 251 if (!__msan_has_dynamic_component()) { 252 __msan_unpoison(endptr, sizeof(*endptr)); 253 } 254 return res; 255} 256 257INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, // NOLINT 258 int base) { 259 ENSURE_MSAN_INITED(); 260 long res = REAL(strtoll)(nptr, endptr, base); //NOLINT 261 if (!__msan_has_dynamic_component()) { 262 __msan_unpoison(endptr, sizeof(*endptr)); 263 } 264 return res; 265} 266 267INTERCEPTOR(unsigned long, strtoul, const char *nptr, char **endptr, // NOLINT 268 int base) { 269 ENSURE_MSAN_INITED(); 270 unsigned long res = REAL(strtoul)(nptr, endptr, base); // NOLINT 271 if (!__msan_has_dynamic_component()) { 272 __msan_unpoison(endptr, sizeof(*endptr)); 273 } 274 return res; 275} 276 277INTERCEPTOR(unsigned long long, strtoull, const char *nptr, // NOLINT 278 char **endptr, int base) { 279 ENSURE_MSAN_INITED(); 280 unsigned long res = REAL(strtoull)(nptr, endptr, base); // NOLINT 281 if (!__msan_has_dynamic_component()) { 282 __msan_unpoison(endptr, sizeof(*endptr)); 283 } 284 return res; 285} 286 287INTERCEPTOR(double, strtod, const char *nptr, char **endptr) { // NOLINT 288 ENSURE_MSAN_INITED(); 289 double res = REAL(strtod)(nptr, endptr); // NOLINT 290 if (!__msan_has_dynamic_component()) { 291 __msan_unpoison(endptr, sizeof(*endptr)); 292 } 293 return res; 294} 295 296INTERCEPTOR(float, strtof, const char *nptr, char **endptr) { // NOLINT 297 ENSURE_MSAN_INITED(); 298 float res = REAL(strtof)(nptr, endptr); // NOLINT 299 if (!__msan_has_dynamic_component()) { 300 __msan_unpoison(endptr, sizeof(*endptr)); 301 } 302 return res; 303} 304 305INTERCEPTOR(long double, strtold, const char *nptr, char **endptr) { // NOLINT 306 ENSURE_MSAN_INITED(); 307 long double res = REAL(strtold)(nptr, endptr); // NOLINT 308 if (!__msan_has_dynamic_component()) { 309 __msan_unpoison(endptr, sizeof(*endptr)); 310 } 311 return res; 312} 313 314INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) { 315 ENSURE_MSAN_INITED(); 316 int res = REAL(vasprintf)(strp, format, ap); 317 if (res >= 0 && !__msan_has_dynamic_component()) { 318 __msan_unpoison(strp, sizeof(*strp)); 319 __msan_unpoison(*strp, res + 1); 320 } 321 return res; 322} 323 324INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) { // NOLINT 325 ENSURE_MSAN_INITED(); 326 va_list ap; 327 va_start(ap, format); 328 int res = vasprintf(strp, format, ap); // NOLINT 329 va_end(ap); 330 return res; 331} 332 333INTERCEPTOR(int, vsnprintf, char *str, uptr size, 334 const char *format, va_list ap) { 335 ENSURE_MSAN_INITED(); 336 int res = REAL(vsnprintf)(str, size, format, ap); 337 if (res >= 0 && !__msan_has_dynamic_component()) { 338 __msan_unpoison(str, res + 1); 339 } 340 return res; 341} 342 343INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) { 344 ENSURE_MSAN_INITED(); 345 int res = REAL(vsprintf)(str, format, ap); 346 if (res >= 0 && !__msan_has_dynamic_component()) { 347 __msan_unpoison(str, res + 1); 348 } 349 return res; 350} 351 352INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) { 353 ENSURE_MSAN_INITED(); 354 int res = REAL(vswprintf)(str, size, format, ap); 355 if (res >= 0 && !__msan_has_dynamic_component()) { 356 __msan_unpoison(str, 4 * (res + 1)); 357 } 358 return res; 359} 360 361INTERCEPTOR(int, sprintf, char *str, const char *format, ...) { // NOLINT 362 ENSURE_MSAN_INITED(); 363 va_list ap; 364 va_start(ap, format); 365 int res = vsprintf(str, format, ap); // NOLINT 366 va_end(ap); 367 return res; 368} 369 370INTERCEPTOR(int, snprintf, char *str, uptr size, const char *format, ...) { 371 ENSURE_MSAN_INITED(); 372 va_list ap; 373 va_start(ap, format); 374 int res = vsnprintf(str, size, format, ap); 375 va_end(ap); 376 return res; 377} 378 379INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) { 380 ENSURE_MSAN_INITED(); 381 va_list ap; 382 va_start(ap, format); 383 int res = vswprintf(str, size, format, ap); 384 va_end(ap); 385 return res; 386} 387 388// SIZE_T strftime(char *s, SIZE_T max, const char *format,const struct tm *tm); 389INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format, 390 void *tm) { 391 ENSURE_MSAN_INITED(); 392 SIZE_T res = REAL(strftime)(s, max, format, tm); 393 if (res) __msan_unpoison(s, res + 1); 394 return res; 395} 396 397INTERCEPTOR(SIZE_T, wcstombs, void *dest, void *src, SIZE_T size) { 398 ENSURE_MSAN_INITED(); 399 SIZE_T res = REAL(wcstombs)(dest, src, size); 400 if (res != (SIZE_T)-1) __msan_unpoison(dest, res + 1); 401 return res; 402} 403 404// SIZE_T mbstowcs(wchar_t *dest, const char *src, SIZE_T n); 405INTERCEPTOR(SIZE_T, mbstowcs, wchar_t *dest, const char *src, SIZE_T n) { 406 ENSURE_MSAN_INITED(); 407 SIZE_T res = REAL(mbstowcs)(dest, src, n); 408 if (res != (SIZE_T)-1) __msan_unpoison(dest, (res + 1) * sizeof(wchar_t)); 409 return res; 410} 411 412INTERCEPTOR(SIZE_T, wcslen, const wchar_t *s) { 413 ENSURE_MSAN_INITED(); 414 SIZE_T res = REAL(wcslen)(s); 415 CHECK_UNPOISONED(s, sizeof(wchar_t) * (res + 1)); 416 return res; 417} 418 419// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc); 420INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) { 421 ENSURE_MSAN_INITED(); 422 wchar_t *res = REAL(wcschr)(s, wc, ps); 423 return res; 424} 425 426// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); 427INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) { 428 ENSURE_MSAN_INITED(); 429 wchar_t *res = REAL(wcscpy)(dest, src); 430 __msan_copy_poison(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1)); 431 return res; 432} 433 434// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n); 435INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) { 436 ENSURE_MSAN_INITED(); 437 wchar_t *res = REAL(wmemcpy)(dest, src, n); 438 __msan_copy_poison(dest, src, n * sizeof(wchar_t)); 439 return res; 440} 441 442INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) { 443 CHECK(MEM_IS_APP(s)); 444 ENSURE_MSAN_INITED(); 445 wchar_t *res = (wchar_t *)fast_memset(s, c, n * sizeof(wchar_t)); 446 __msan_unpoison(s, n * sizeof(wchar_t)); 447 return res; 448} 449 450INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) { 451 ENSURE_MSAN_INITED(); 452 wchar_t *res = REAL(wmemmove)(dest, src, n); 453 __msan_move_poison(dest, src, n * sizeof(wchar_t)); 454 return res; 455} 456 457INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) { 458 ENSURE_MSAN_INITED(); 459 int res = REAL(wcscmp)(s1, s2); 460 return res; 461} 462 463INTERCEPTOR(double, wcstod, const wchar_t *nptr, wchar_t **endptr) { 464 ENSURE_MSAN_INITED(); 465 double res = REAL(wcstod)(nptr, endptr); 466 __msan_unpoison(endptr, sizeof(*endptr)); 467 return res; 468} 469 470// #define UNSUPPORTED(name) \ 471// INTERCEPTOR(void, name, void) { \ 472// Printf("MSAN: Unsupported %s\n", __FUNCTION__); \ 473// Die(); \ 474// } 475 476// FIXME: intercept the following functions: 477// Note, they only matter when running without a dynamic tool. 478// UNSUPPORTED(wcscoll_l) 479// UNSUPPORTED(wcsnrtombs) 480// UNSUPPORTED(wcstol) 481// UNSUPPORTED(wcstoll) 482// UNSUPPORTED(wcstold) 483// UNSUPPORTED(wcstoul) 484// UNSUPPORTED(wcstoull) 485// UNSUPPORTED(wcsxfrm_l) 486// UNSUPPORTED(wcsdup) 487// UNSUPPORTED(wcsftime) 488// UNSUPPORTED(wcsstr) 489// UNSUPPORTED(wcsrchr) 490// UNSUPPORTED(wctob) 491 492INTERCEPTOR(int, gettimeofday, void *tv, void *tz) { 493 ENSURE_MSAN_INITED(); 494 int res = REAL(gettimeofday)(tv, tz); 495 if (tv) 496 __msan_unpoison(tv, 16); 497 if (tz) 498 __msan_unpoison(tz, 8); 499 return res; 500} 501 502INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) { 503 ENSURE_MSAN_INITED(); 504 char *res = REAL(fcvt)(x, a, b, c); 505 if (!__msan_has_dynamic_component()) { 506 __msan_unpoison(b, sizeof(*b)); 507 __msan_unpoison(c, sizeof(*c)); 508 } 509 return res; 510} 511 512INTERCEPTOR(char *, getenv, char *name) { 513 ENSURE_MSAN_INITED(); 514 char *res = REAL(getenv)(name); 515 if (!__msan_has_dynamic_component()) { 516 if (res) 517 __msan_unpoison(res, REAL(strlen)(res) + 1); 518 } 519 return res; 520} 521 522INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { 523 ENSURE_MSAN_INITED(); 524 int res = REAL(__fxstat)(magic, fd, buf); 525 if (!res) 526 __msan_unpoison(buf, __sanitizer::struct_stat_sz); 527 return res; 528} 529 530INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) { 531 ENSURE_MSAN_INITED(); 532 int res = REAL(__fxstat64)(magic, fd, buf); 533 if (!res) 534 __msan_unpoison(buf, __sanitizer::struct_stat64_sz); 535 return res; 536} 537 538INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) { 539 ENSURE_MSAN_INITED(); 540 int res = REAL(__xstat)(magic, path, buf); 541 if (!res) 542 __msan_unpoison(buf, __sanitizer::struct_stat_sz); 543 return res; 544} 545 546INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) { 547 ENSURE_MSAN_INITED(); 548 int res = REAL(__xstat64)(magic, path, buf); 549 if (!res) 550 __msan_unpoison(buf, __sanitizer::struct_stat64_sz); 551 return res; 552} 553 554INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) { 555 ENSURE_MSAN_INITED(); 556 int res = REAL(__lxstat)(magic, path, buf); 557 if (!res) 558 __msan_unpoison(buf, __sanitizer::struct_stat_sz); 559 return res; 560} 561 562INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) { 563 ENSURE_MSAN_INITED(); 564 int res = REAL(__lxstat64)(magic, path, buf); 565 if (!res) 566 __msan_unpoison(buf, __sanitizer::struct_stat64_sz); 567 return res; 568} 569 570INTERCEPTOR(int, pipe, int pipefd[2]) { 571 if (msan_init_is_running) 572 return REAL(pipe)(pipefd); 573 ENSURE_MSAN_INITED(); 574 int res = REAL(pipe)(pipefd); 575 if (!res) 576 __msan_unpoison(pipefd, sizeof(int[2])); 577 return res; 578} 579 580INTERCEPTOR(int, pipe2, int pipefd[2], int flags) { 581 ENSURE_MSAN_INITED(); 582 int res = REAL(pipe2)(pipefd, flags); 583 if (!res) 584 __msan_unpoison(pipefd, sizeof(int[2])); 585 return res; 586} 587 588INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) { 589 ENSURE_MSAN_INITED(); 590 int res = REAL(socketpair)(domain, type, protocol, sv); 591 if (!res) 592 __msan_unpoison(sv, sizeof(int[2])); 593 return res; 594} 595 596INTERCEPTOR(char *, fgets, char *s, int size, void *stream) { 597 ENSURE_MSAN_INITED(); 598 char *res = REAL(fgets)(s, size, stream); 599 if (res) 600 __msan_unpoison(s, REAL(strlen)(s) + 1); 601 return res; 602} 603 604INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) { 605 ENSURE_MSAN_INITED(); 606 char *res = REAL(fgets_unlocked)(s, size, stream); 607 if (res) 608 __msan_unpoison(s, REAL(strlen)(s) + 1); 609 return res; 610} 611 612INTERCEPTOR(char *, getcwd, char *buf, SIZE_T size) { 613 ENSURE_MSAN_INITED(); 614 char *res = REAL(getcwd)(buf, size); 615 if (res) 616 __msan_unpoison(res, REAL(strlen)(res) + 1); 617 return res; 618} 619 620INTERCEPTOR(char *, realpath, char *path, char *abspath) { 621 ENSURE_MSAN_INITED(); 622 char *res = REAL(realpath)(path, abspath); 623 if (res) 624 __msan_unpoison(abspath, REAL(strlen)(abspath) + 1); 625 return res; 626} 627 628INTERCEPTOR(int, getrlimit, int resource, void *rlim) { 629 if (msan_init_is_running) 630 return REAL(getrlimit)(resource, rlim); 631 ENSURE_MSAN_INITED(); 632 int res = REAL(getrlimit)(resource, rlim); 633 if (!res) 634 __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); 635 return res; 636} 637 638INTERCEPTOR(int, getrlimit64, int resource, void *rlim) { 639 if (msan_init_is_running) 640 return REAL(getrlimit64)(resource, rlim); 641 ENSURE_MSAN_INITED(); 642 int res = REAL(getrlimit64)(resource, rlim); 643 if (!res) 644 __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz); 645 return res; 646} 647 648INTERCEPTOR(int, statfs, const char *s, void *buf) { 649 ENSURE_MSAN_INITED(); 650 int res = REAL(statfs)(s, buf); 651 if (!res) 652 __msan_unpoison(buf, __sanitizer::struct_statfs_sz); 653 return res; 654} 655 656INTERCEPTOR(int, fstatfs, int fd, void *buf) { 657 ENSURE_MSAN_INITED(); 658 int res = REAL(fstatfs)(fd, buf); 659 if (!res) 660 __msan_unpoison(buf, __sanitizer::struct_statfs_sz); 661 return res; 662} 663 664INTERCEPTOR(int, statfs64, const char *s, void *buf) { 665 ENSURE_MSAN_INITED(); 666 int res = REAL(statfs64)(s, buf); 667 if (!res) 668 __msan_unpoison(buf, __sanitizer::struct_statfs64_sz); 669 return res; 670} 671 672INTERCEPTOR(int, fstatfs64, int fd, void *buf) { 673 ENSURE_MSAN_INITED(); 674 int res = REAL(fstatfs64)(fd, buf); 675 if (!res) 676 __msan_unpoison(buf, __sanitizer::struct_statfs64_sz); 677 return res; 678} 679 680INTERCEPTOR(int, uname, void *utsname) { 681 ENSURE_MSAN_INITED(); 682 int res = REAL(uname)(utsname); 683 if (!res) { 684 __msan_unpoison(utsname, __sanitizer::struct_utsname_sz); 685 } 686 return res; 687} 688 689INTERCEPTOR(int, gethostname, char *name, SIZE_T len) { 690 ENSURE_MSAN_INITED(); 691 int res = REAL(gethostname)(name, len); 692 if (!res) { 693 SIZE_T real_len = REAL(strnlen)(name, len); 694 if (real_len < len) 695 ++real_len; 696 __msan_unpoison(name, real_len); 697 } 698 return res; 699} 700 701INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents, 702 int timeout) { 703 ENSURE_MSAN_INITED(); 704 int res = REAL(epoll_wait)(epfd, events, maxevents, timeout); 705 if (res > 0) { 706 __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res); 707 } 708 return res; 709} 710 711INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents, 712 int timeout, void *sigmask) { 713 ENSURE_MSAN_INITED(); 714 int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask); 715 if (res > 0) { 716 __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res); 717 } 718 return res; 719} 720 721INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { 722 ENSURE_MSAN_INITED(); 723 SSIZE_T res = REAL(recv)(fd, buf, len, flags); 724 if (res > 0) 725 __msan_unpoison(buf, res); 726 return res; 727} 728 729INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, 730 void *srcaddr, int *addrlen) { 731 ENSURE_MSAN_INITED(); 732 SIZE_T srcaddr_sz; 733 if (srcaddr) srcaddr_sz = *addrlen; 734 SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); 735 if (res > 0) { 736 __msan_unpoison(buf, res); 737 if (srcaddr) { 738 SIZE_T sz = *addrlen; 739 __msan_unpoison(srcaddr, (sz < srcaddr_sz) ? sz : srcaddr_sz); 740 } 741 } 742 return res; 743} 744 745INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) { 746 if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0; 747 GET_MALLOC_STACK_TRACE; 748 if (!msan_inited) { 749 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 750 const SIZE_T kCallocPoolSize = 1024; 751 static uptr calloc_memory_for_dlsym[kCallocPoolSize]; 752 static SIZE_T allocated; 753 SIZE_T size_in_words = ((nmemb * size) + kWordSize - 1) / kWordSize; 754 void *mem = (void*)&calloc_memory_for_dlsym[allocated]; 755 allocated += size_in_words; 756 CHECK(allocated < kCallocPoolSize); 757 return mem; 758 } 759 return MsanReallocate(&stack, 0, nmemb * size, sizeof(u64), true); 760} 761 762INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { 763 GET_MALLOC_STACK_TRACE; 764 return MsanReallocate(&stack, ptr, size, sizeof(u64), false); 765} 766 767INTERCEPTOR(void *, malloc, SIZE_T size) { 768 GET_MALLOC_STACK_TRACE; 769 return MsanReallocate(&stack, 0, size, sizeof(u64), false); 770} 771 772void __msan_allocated_memory(const void* data, uptr size) { 773 GET_MALLOC_STACK_TRACE; 774 if (flags()->poison_in_malloc) 775 __msan_poison(data, size); 776 if (__msan_get_track_origins()) { 777 u32 stack_id = StackDepotPut(stack.trace, stack.size); 778 CHECK(stack_id); 779 CHECK_EQ((stack_id >> 31), 0); // Higher bit is occupied by stack origins. 780 __msan_set_origin(data, size, stack_id); 781 } 782} 783 784INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags, 785 int fd, OFF_T offset) { 786 ENSURE_MSAN_INITED(); 787 void *res = REAL(mmap)(addr, length, prot, flags, fd, offset); 788 if (res != (void*)-1) 789 __msan_unpoison(res, RoundUpTo(length, GetPageSize())); 790 return res; 791} 792 793INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, 794 int fd, OFF64_T offset) { 795 ENSURE_MSAN_INITED(); 796 void *res = REAL(mmap64)(addr, length, prot, flags, fd, offset); 797 if (res != (void*)-1) 798 __msan_unpoison(res, RoundUpTo(length, GetPageSize())); 799 return res; 800} 801 802struct dlinfo { 803 char *dli_fname; 804 void *dli_fbase; 805 char *dli_sname; 806 void *dli_saddr; 807}; 808 809INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { 810 ENSURE_MSAN_INITED(); 811 int res = REAL(dladdr)(addr, info); 812 if (res != 0) { 813 __msan_unpoison(info, sizeof(*info)); 814 if (info->dli_fname) 815 __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1); 816 if (info->dli_sname) 817 __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1); 818 } 819 return res; 820} 821 822// dlopen() ultimately calls mmap() down inside the loader, which generally 823// doesn't participate in dynamic symbol resolution. Therefore we won't 824// intercept its calls to mmap, and we have to hook it here. The loader 825// initializes the module before returning, so without the dynamic component, we 826// won't be able to clear the shadow before the initializers. Fixing this would 827// require putting our own initializer first to clear the shadow. 828INTERCEPTOR(void *, dlopen, const char *filename, int flag) { 829 ENSURE_MSAN_INITED(); 830 EnterLoader(); 831 link_map *map = (link_map *)REAL(dlopen)(filename, flag); 832 ExitLoader(); 833 if (!__msan_has_dynamic_component() && map) { 834 // If msandr didn't clear the shadow before the initializers ran, we do it 835 // ourselves afterwards. 836 UnpoisonMappedDSO(map); 837 } 838 return (void *)map; 839} 840 841typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size, 842 void *data); 843struct dl_iterate_phdr_data { 844 dl_iterate_phdr_cb callback; 845 void *data; 846}; 847 848static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, 849 void *data) { 850 if (info) { 851 __msan_unpoison(info, size); 852 if (info->dlpi_name) 853 __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1); 854 } 855 dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; 856 __msan_unpoison_param(3); 857 return cbdata->callback(info, size, cbdata->data); 858} 859 860INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { 861 ENSURE_MSAN_INITED(); 862 EnterLoader(); 863 dl_iterate_phdr_data cbdata; 864 cbdata.callback = callback; 865 cbdata.data = data; 866 int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata); 867 ExitLoader(); 868 return res; 869} 870 871INTERCEPTOR(int, getrusage, int who, void *usage) { 872 ENSURE_MSAN_INITED(); 873 int res = REAL(getrusage)(who, usage); 874 if (res == 0) { 875 __msan_unpoison(usage, __sanitizer::struct_rusage_sz); 876 } 877 return res; 878} 879 880const int kMaxSignals = 1024; 881static uptr sigactions[kMaxSignals]; 882static StaticSpinMutex sigactions_mu; 883 884static void SignalHandler(int signo) { 885 typedef void (*signal_cb)(int x); 886 signal_cb cb = (signal_cb)sigactions[signo]; 887 cb(signo); 888} 889 890static void SignalAction(int signo, void *si, void *uc) { 891 __msan_unpoison(si, __sanitizer::struct_sigaction_sz); 892 __msan_unpoison(uc, __sanitizer::ucontext_t_sz); 893 894 typedef void (*sigaction_cb)(int, void *, void *); 895 sigaction_cb cb = (sigaction_cb)sigactions[signo]; 896 cb(signo, si, uc); 897} 898 899INTERCEPTOR(int, sigaction, int signo, const __sanitizer_sigaction *act, 900 __sanitizer_sigaction *oldact) { 901 ENSURE_MSAN_INITED(); 902 // FIXME: check that *act is unpoisoned. 903 // That requires intercepting all of sigemptyset, sigfillset, etc. 904 int res; 905 if (flags()->wrap_signals) { 906 SpinMutexLock lock(&sigactions_mu); 907 CHECK_LT(signo, kMaxSignals); 908 uptr old_cb = sigactions[signo]; 909 __sanitizer_sigaction new_act; 910 __sanitizer_sigaction *pnew_act = act ? &new_act : 0; 911 if (act) { 912 internal_memcpy(pnew_act, act, __sanitizer::struct_sigaction_sz); 913 uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(pnew_act); 914 uptr new_cb = 915 __sanitizer::__sanitizer_get_sigaction_sa_siginfo(pnew_act) ? 916 (uptr)SignalAction : (uptr)SignalHandler; 917 if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { 918 sigactions[signo] = cb; 919 __sanitizer::__sanitizer_set_sigaction_sa_sigaction(pnew_act, new_cb); 920 } 921 } 922 res = REAL(sigaction)(signo, pnew_act, oldact); 923 if (res == 0 && oldact) { 924 uptr cb = __sanitizer::__sanitizer_get_sigaction_sa_sigaction(oldact); 925 if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { 926 __sanitizer::__sanitizer_set_sigaction_sa_sigaction(oldact, old_cb); 927 } 928 } 929 } else { 930 res = REAL(sigaction)(signo, act, oldact); 931 } 932 933 if (res == 0 && oldact) { 934 __msan_unpoison(oldact, __sanitizer::struct_sigaction_sz); 935 } 936 return res; 937} 938 939INTERCEPTOR(int, signal, int signo, uptr cb) { 940 ENSURE_MSAN_INITED(); 941 if (flags()->wrap_signals) { 942 CHECK_LT(signo, kMaxSignals); 943 SpinMutexLock lock(&sigactions_mu); 944 if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { 945 sigactions[signo] = cb; 946 cb = (uptr) SignalHandler; 947 } 948 return REAL(signal)(signo, cb); 949 } else { 950 return REAL(signal)(signo, cb); 951 } 952} 953 954extern "C" int pthread_attr_init(void *attr); 955extern "C" int pthread_attr_destroy(void *attr); 956extern "C" int pthread_attr_setstacksize(void *attr, uptr stacksize); 957extern "C" int pthread_attr_getstack(void *attr, uptr *stack, uptr *stacksize); 958 959INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), 960 void * param) { 961 ENSURE_MSAN_INITED(); // for GetTlsSize() 962 __sanitizer_pthread_attr_t myattr; 963 if (attr == 0) { 964 pthread_attr_init(&myattr); 965 attr = &myattr; 966 } 967 968 AdjustStackSizeLinux(attr, flags()->verbosity); 969 970 int res = REAL(pthread_create)(th, attr, callback, param); 971 if (attr == &myattr) 972 pthread_attr_destroy(&myattr); 973 if (!res) { 974 __msan_unpoison(th, __sanitizer::pthread_t_sz); 975 } 976 return res; 977} 978 979struct MSanInterceptorContext { 980 bool in_interceptor_scope; 981}; 982 983// A version of CHECK_UNPOISED using a saved scope value. Used in common 984// interceptors. 985#define CHECK_UNPOISONED_CTX(ctx, x, n) \ 986 if (!((MSanInterceptorContext *) ctx)->in_interceptor_scope) \ 987 CHECK_UNPOISONED_0(x, n); 988 989#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 990 __msan_unpoison(ptr, size) 991#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 992 CHECK_UNPOISONED_CTX(ctx, ptr, size); 993#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 994 if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \ 995 MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \ 996 ctx = (void *)&msan_ctx; \ 997 InterceptorScope interceptor_scope; \ 998 ENSURE_MSAN_INITED(); 999#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 1000 do { \ 1001 } while (false) 1002#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1003 do { \ 1004 } while (false) 1005#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 1006 do { \ 1007 } while (false) 1008#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \ 1009 do { \ 1010 } while (false) // FIXME 1011#include "sanitizer_common/sanitizer_common_interceptors.inc" 1012 1013#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s) 1014#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) 1015#define COMMON_SYSCALL_POST_READ_RANGE(p, s) 1016#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s) 1017#include "sanitizer_common/sanitizer_common_syscalls.inc" 1018 1019// static 1020void *fast_memset(void *ptr, int c, SIZE_T n) { 1021 // hack until we have a really fast internal_memset 1022 if (sizeof(uptr) == 8 && 1023 (n % 8) == 0 && 1024 ((uptr)ptr % 8) == 0 && 1025 (c == 0 || c == -1)) { 1026 // Printf("memset %p %zd %x\n", ptr, n, c); 1027 uptr to_store = c ? -1L : 0L; 1028 uptr *p = (uptr*)ptr; 1029 for (SIZE_T i = 0; i < n / 8; i++) 1030 p[i] = to_store; 1031 return ptr; 1032 } 1033 return internal_memset(ptr, c, n); 1034} 1035 1036// static 1037void *fast_memcpy(void *dst, const void *src, SIZE_T n) { 1038 // Same hack as in fast_memset above. 1039 if (sizeof(uptr) == 8 && 1040 (n % 8) == 0 && 1041 ((uptr)dst % 8) == 0 && 1042 ((uptr)src % 8) == 0) { 1043 uptr *d = (uptr*)dst; 1044 uptr *s = (uptr*)src; 1045 for (SIZE_T i = 0; i < n / 8; i++) 1046 d[i] = s[i]; 1047 return dst; 1048 } 1049 return internal_memcpy(dst, src, n); 1050} 1051 1052// These interface functions reside here so that they can use 1053// fast_memset, etc. 1054void __msan_unpoison(const void *a, uptr size) { 1055 if (!MEM_IS_APP(a)) return; 1056 fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size); 1057} 1058 1059void __msan_poison(const void *a, uptr size) { 1060 if (!MEM_IS_APP(a)) return; 1061 fast_memset((void*)MEM_TO_SHADOW((uptr)a), 1062 __msan::flags()->poison_heap_with_zeroes ? 0 : -1, size); 1063} 1064 1065void __msan_poison_stack(void *a, uptr size) { 1066 if (!MEM_IS_APP(a)) return; 1067 fast_memset((void*)MEM_TO_SHADOW((uptr)a), 1068 __msan::flags()->poison_stack_with_zeroes ? 0 : -1, size); 1069} 1070 1071void __msan_clear_and_unpoison(void *a, uptr size) { 1072 fast_memset(a, 0, size); 1073 fast_memset((void*)MEM_TO_SHADOW((uptr)a), 0, size); 1074} 1075 1076void __msan_copy_origin(void *dst, const void *src, uptr size) { 1077 if (!__msan_get_track_origins()) return; 1078 if (!MEM_IS_APP(dst) || !MEM_IS_APP(src)) return; 1079 uptr d = MEM_TO_ORIGIN(dst); 1080 uptr s = MEM_TO_ORIGIN(src); 1081 uptr beg = d & ~3UL; // align down. 1082 uptr end = (d + size + 3) & ~3UL; // align up. 1083 s = s & ~3UL; // align down. 1084 fast_memcpy((void*)beg, (void*)s, end - beg); 1085} 1086 1087void __msan_copy_poison(void *dst, const void *src, uptr size) { 1088 if (!MEM_IS_APP(dst)) return; 1089 if (!MEM_IS_APP(src)) return; 1090 fast_memcpy((void*)MEM_TO_SHADOW((uptr)dst), 1091 (void*)MEM_TO_SHADOW((uptr)src), size); 1092 __msan_copy_origin(dst, src, size); 1093} 1094 1095void __msan_move_poison(void *dst, const void *src, uptr size) { 1096 if (!MEM_IS_APP(dst)) return; 1097 if (!MEM_IS_APP(src)) return; 1098 internal_memmove((void*)MEM_TO_SHADOW((uptr)dst), 1099 (void*)MEM_TO_SHADOW((uptr)src), size); 1100 __msan_copy_origin(dst, src, size); 1101} 1102 1103void *__msan_memcpy(void *dest, const void *src, SIZE_T n) { 1104 ENSURE_MSAN_INITED(); 1105 void *res = fast_memcpy(dest, src, n); 1106 __msan_copy_poison(dest, src, n); 1107 return res; 1108} 1109 1110void *__msan_memset(void *s, int c, SIZE_T n) { 1111 ENSURE_MSAN_INITED(); 1112 void *res = fast_memset(s, c, n); 1113 __msan_unpoison(s, n); 1114 return res; 1115} 1116 1117void *__msan_memmove(void *dest, const void *src, SIZE_T n) { 1118 ENSURE_MSAN_INITED(); 1119 void *res = REAL(memmove)(dest, src, n); 1120 __msan_move_poison(dest, src, n); 1121 return res; 1122} 1123 1124namespace __msan { 1125void InitializeInterceptors() { 1126 static int inited = 0; 1127 CHECK_EQ(inited, 0); 1128 SANITIZER_COMMON_INTERCEPTORS_INIT; 1129 1130 INTERCEPT_FUNCTION(mmap); 1131 INTERCEPT_FUNCTION(mmap64); 1132 INTERCEPT_FUNCTION(posix_memalign); 1133 INTERCEPT_FUNCTION(malloc); 1134 INTERCEPT_FUNCTION(calloc); 1135 INTERCEPT_FUNCTION(realloc); 1136 INTERCEPT_FUNCTION(free); 1137 INTERCEPT_FUNCTION(fread); 1138 INTERCEPT_FUNCTION(fread_unlocked); 1139 INTERCEPT_FUNCTION(readlink); 1140 INTERCEPT_FUNCTION(readdir); 1141 INTERCEPT_FUNCTION(readdir64); 1142 INTERCEPT_FUNCTION(memcpy); 1143 INTERCEPT_FUNCTION(memset); 1144 INTERCEPT_FUNCTION(memmove); 1145 INTERCEPT_FUNCTION(wmemset); 1146 INTERCEPT_FUNCTION(wmemcpy); 1147 INTERCEPT_FUNCTION(wmemmove); 1148 INTERCEPT_FUNCTION(strcpy); // NOLINT 1149 INTERCEPT_FUNCTION(strdup); 1150 INTERCEPT_FUNCTION(__strdup); 1151 INTERCEPT_FUNCTION(strndup); 1152 INTERCEPT_FUNCTION(__strndup); 1153 INTERCEPT_FUNCTION(strncpy); // NOLINT 1154 INTERCEPT_FUNCTION(strlen); 1155 INTERCEPT_FUNCTION(strnlen); 1156 INTERCEPT_FUNCTION(gcvt); 1157 INTERCEPT_FUNCTION(strcat); // NOLINT 1158 INTERCEPT_FUNCTION(strncat); // NOLINT 1159 INTERCEPT_FUNCTION(strtol); 1160 INTERCEPT_FUNCTION(strtoll); 1161 INTERCEPT_FUNCTION(strtoul); 1162 INTERCEPT_FUNCTION(strtoull); 1163 INTERCEPT_FUNCTION(strtod); 1164 INTERCEPT_FUNCTION(strtof); 1165 INTERCEPT_FUNCTION(strtold); 1166 INTERCEPT_FUNCTION(vasprintf); 1167 INTERCEPT_FUNCTION(asprintf); 1168 INTERCEPT_FUNCTION(vsprintf); 1169 INTERCEPT_FUNCTION(vsnprintf); 1170 INTERCEPT_FUNCTION(vswprintf); 1171 INTERCEPT_FUNCTION(sprintf); // NOLINT 1172 INTERCEPT_FUNCTION(snprintf); 1173 INTERCEPT_FUNCTION(swprintf); 1174 INTERCEPT_FUNCTION(strftime); 1175 INTERCEPT_FUNCTION(wcstombs); 1176 INTERCEPT_FUNCTION(mbstowcs); 1177 INTERCEPT_FUNCTION(wcslen); 1178 INTERCEPT_FUNCTION(wcschr); 1179 INTERCEPT_FUNCTION(wcscpy); 1180 INTERCEPT_FUNCTION(wcscmp); 1181 INTERCEPT_FUNCTION(wcstod); 1182 INTERCEPT_FUNCTION(getenv); 1183 INTERCEPT_FUNCTION(gettimeofday); 1184 INTERCEPT_FUNCTION(fcvt); 1185 INTERCEPT_FUNCTION(__fxstat); 1186 INTERCEPT_FUNCTION(__xstat); 1187 INTERCEPT_FUNCTION(__lxstat); 1188 INTERCEPT_FUNCTION(__fxstat64); 1189 INTERCEPT_FUNCTION(__xstat64); 1190 INTERCEPT_FUNCTION(__lxstat64); 1191 INTERCEPT_FUNCTION(pipe); 1192 INTERCEPT_FUNCTION(pipe2); 1193 INTERCEPT_FUNCTION(socketpair); 1194 INTERCEPT_FUNCTION(fgets); 1195 INTERCEPT_FUNCTION(fgets_unlocked); 1196 INTERCEPT_FUNCTION(getcwd); 1197 INTERCEPT_FUNCTION(realpath); 1198 INTERCEPT_FUNCTION(getrlimit); 1199 INTERCEPT_FUNCTION(getrlimit64); 1200 INTERCEPT_FUNCTION(statfs); 1201 INTERCEPT_FUNCTION(fstatfs); 1202 INTERCEPT_FUNCTION(statfs64); 1203 INTERCEPT_FUNCTION(fstatfs64); 1204 INTERCEPT_FUNCTION(uname); 1205 INTERCEPT_FUNCTION(gethostname); 1206 INTERCEPT_FUNCTION(epoll_wait); 1207 INTERCEPT_FUNCTION(epoll_pwait); 1208 INTERCEPT_FUNCTION(recv); 1209 INTERCEPT_FUNCTION(recvfrom); 1210 INTERCEPT_FUNCTION(dladdr); 1211 INTERCEPT_FUNCTION(dlopen); 1212 INTERCEPT_FUNCTION(dl_iterate_phdr); 1213 INTERCEPT_FUNCTION(getrusage); 1214 INTERCEPT_FUNCTION(sigaction); 1215 INTERCEPT_FUNCTION(signal); 1216 INTERCEPT_FUNCTION(pthread_create); 1217 inited = 1; 1218} 1219} // namespace __msan 1220