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 "msan_chained_origin_depot.h" 21#include "msan_origin.h" 22#include "msan_report.h" 23#include "msan_thread.h" 24#include "msan_poisoning.h" 25#include "sanitizer_common/sanitizer_platform_limits_posix.h" 26#include "sanitizer_common/sanitizer_platform_limits_netbsd.h" 27#include "sanitizer_common/sanitizer_allocator.h" 28#include "sanitizer_common/sanitizer_allocator_interface.h" 29#include "sanitizer_common/sanitizer_allocator_internal.h" 30#include "sanitizer_common/sanitizer_atomic.h" 31#include "sanitizer_common/sanitizer_common.h" 32#include "sanitizer_common/sanitizer_errno.h" 33#include "sanitizer_common/sanitizer_stackdepot.h" 34#include "sanitizer_common/sanitizer_libc.h" 35#include "sanitizer_common/sanitizer_linux.h" 36#include "sanitizer_common/sanitizer_tls_get_addr.h" 37#include "sanitizer_common/sanitizer_vector.h" 38 39#if SANITIZER_NETBSD 40#define fstat __fstat50 41#define gettimeofday __gettimeofday50 42#define getrusage __getrusage50 43#define tzset __tzset50 44#endif 45 46#include <stdarg.h> 47// ACHTUNG! No other system header includes in this file. 48// Ideally, we should get rid of stdarg.h as well. 49 50using namespace __msan; 51 52using __sanitizer::memory_order; 53using __sanitizer::atomic_load; 54using __sanitizer::atomic_store; 55using __sanitizer::atomic_uintptr_t; 56 57DECLARE_REAL(SIZE_T, strlen, const char *s) 58DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen) 59DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n) 60DECLARE_REAL(void *, memset, void *dest, int c, uptr n) 61 62// True if this is a nested interceptor. 63static THREADLOCAL int in_interceptor_scope; 64 65void __msan_scoped_disable_interceptor_checks() { ++in_interceptor_scope; } 66void __msan_scoped_enable_interceptor_checks() { --in_interceptor_scope; } 67 68struct InterceptorScope { 69 InterceptorScope() { ++in_interceptor_scope; } 70 ~InterceptorScope() { --in_interceptor_scope; } 71}; 72 73bool IsInInterceptorScope() { 74 return in_interceptor_scope; 75} 76 77static uptr allocated_for_dlsym; 78static const uptr kDlsymAllocPoolSize = 1024; 79static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize]; 80 81static bool IsInDlsymAllocPool(const void *ptr) { 82 uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym; 83 return off < sizeof(alloc_memory_for_dlsym); 84} 85 86static void *AllocateFromLocalPool(uptr size_in_bytes) { 87 uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize; 88 void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym]; 89 allocated_for_dlsym += size_in_words; 90 CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize); 91 return mem; 92} 93 94#define ENSURE_MSAN_INITED() do { \ 95 CHECK(!msan_init_is_running); \ 96 if (!msan_inited) { \ 97 __msan_init(); \ 98 } \ 99} while (0) 100 101// Check that [x, x+n) range is unpoisoned. 102#define CHECK_UNPOISONED_0(x, n) \ 103 do { \ 104 sptr __offset = __msan_test_shadow(x, n); \ 105 if (__msan::IsInSymbolizer()) break; \ 106 if (__offset >= 0 && __msan::flags()->report_umrs) { \ 107 GET_CALLER_PC_BP_SP; \ 108 (void)sp; \ 109 ReportUMRInsideAddressRange(__func__, x, n, __offset); \ 110 __msan::PrintWarningWithOrigin( \ 111 pc, bp, __msan_get_origin((const char *)x + __offset)); \ 112 if (__msan::flags()->halt_on_error) { \ 113 Printf("Exiting\n"); \ 114 Die(); \ 115 } \ 116 } \ 117 } while (0) 118 119// Check that [x, x+n) range is unpoisoned unless we are in a nested 120// interceptor. 121#define CHECK_UNPOISONED(x, n) \ 122 do { \ 123 if (!IsInInterceptorScope()) CHECK_UNPOISONED_0(x, n); \ 124 } while (0) 125 126#define CHECK_UNPOISONED_STRING_OF_LEN(x, len, n) \ 127 CHECK_UNPOISONED((x), \ 128 common_flags()->strict_string_checks ? (len) + 1 : (n) ) 129 130#define CHECK_UNPOISONED_STRING(x, n) \ 131 CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n)) 132 133#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 134INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb, 135 void *file) { 136 ENSURE_MSAN_INITED(); 137 SIZE_T res = REAL(fread_unlocked)(ptr, size, nmemb, file); 138 if (res > 0) 139 __msan_unpoison(ptr, res *size); 140 return res; 141} 142#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED INTERCEPT_FUNCTION(fread_unlocked) 143#else 144#define MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED 145#endif 146 147#if !SANITIZER_NETBSD 148INTERCEPTOR(void *, mempcpy, void *dest, const void *src, SIZE_T n) { 149 return (char *)__msan_memcpy(dest, src, n) + n; 150} 151#define MSAN_MAYBE_INTERCEPT_MEMPCPY INTERCEPT_FUNCTION(mempcpy) 152#else 153#define MSAN_MAYBE_INTERCEPT_MEMPCPY 154#endif 155 156INTERCEPTOR(void *, memccpy, void *dest, const void *src, int c, SIZE_T n) { 157 ENSURE_MSAN_INITED(); 158 void *res = REAL(memccpy)(dest, src, c, n); 159 CHECK(!res || (res >= dest && res <= (char *)dest + n)); 160 SIZE_T sz = res ? (char *)res - (char *)dest : n; 161 CHECK_UNPOISONED(src, sz); 162 __msan_unpoison(dest, sz); 163 return res; 164} 165 166INTERCEPTOR(void *, bcopy, const void *src, void *dest, SIZE_T n) { 167 return __msan_memmove(dest, src, n); 168} 169 170INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) { 171 GET_MALLOC_STACK_TRACE; 172 CHECK_NE(memptr, 0); 173 int res = msan_posix_memalign(memptr, alignment, size, &stack); 174 if (!res) 175 __msan_unpoison(memptr, sizeof(*memptr)); 176 return res; 177} 178 179#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 180INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) { 181 GET_MALLOC_STACK_TRACE; 182 return msan_memalign(alignment, size, &stack); 183} 184#define MSAN_MAYBE_INTERCEPT_MEMALIGN INTERCEPT_FUNCTION(memalign) 185#else 186#define MSAN_MAYBE_INTERCEPT_MEMALIGN 187#endif 188 189INTERCEPTOR(void *, aligned_alloc, SIZE_T alignment, SIZE_T size) { 190 GET_MALLOC_STACK_TRACE; 191 return msan_aligned_alloc(alignment, size, &stack); 192} 193 194#if !SANITIZER_NETBSD 195INTERCEPTOR(void *, __libc_memalign, SIZE_T alignment, SIZE_T size) { 196 GET_MALLOC_STACK_TRACE; 197 void *ptr = msan_memalign(alignment, size, &stack); 198 if (ptr) 199 DTLS_on_libc_memalign(ptr, size); 200 return ptr; 201} 202#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN INTERCEPT_FUNCTION(__libc_memalign) 203#else 204#define MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN 205#endif 206 207INTERCEPTOR(void *, valloc, SIZE_T size) { 208 GET_MALLOC_STACK_TRACE; 209 return msan_valloc(size, &stack); 210} 211 212#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 213INTERCEPTOR(void *, pvalloc, SIZE_T size) { 214 GET_MALLOC_STACK_TRACE; 215 return msan_pvalloc(size, &stack); 216} 217#define MSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc) 218#else 219#define MSAN_MAYBE_INTERCEPT_PVALLOC 220#endif 221 222INTERCEPTOR(void, free, void *ptr) { 223 GET_MALLOC_STACK_TRACE; 224 if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; 225 MsanDeallocate(&stack, ptr); 226} 227 228#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 229INTERCEPTOR(void, cfree, void *ptr) { 230 GET_MALLOC_STACK_TRACE; 231 if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; 232 MsanDeallocate(&stack, ptr); 233} 234#define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree) 235#else 236#define MSAN_MAYBE_INTERCEPT_CFREE 237#endif 238 239#if !SANITIZER_NETBSD 240INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { 241 return __sanitizer_get_allocated_size(ptr); 242} 243#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE \ 244 INTERCEPT_FUNCTION(malloc_usable_size) 245#else 246#define MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE 247#endif 248 249#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 250// This function actually returns a struct by value, but we can't unpoison a 251// temporary! The following is equivalent on all supported platforms but 252// aarch64 (which uses a different register for sret value). We have a test 253// to confirm that. 254INTERCEPTOR(void, mallinfo, __sanitizer_struct_mallinfo *sret) { 255#ifdef __aarch64__ 256 uptr r8; 257 asm volatile("mov %0,x8" : "=r" (r8)); 258 sret = reinterpret_cast<__sanitizer_struct_mallinfo*>(r8); 259#endif 260 REAL(memset)(sret, 0, sizeof(*sret)); 261 __msan_unpoison(sret, sizeof(*sret)); 262} 263#define MSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo) 264#else 265#define MSAN_MAYBE_INTERCEPT_MALLINFO 266#endif 267 268#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 269INTERCEPTOR(int, mallopt, int cmd, int value) { 270 return 0; 271} 272#define MSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt) 273#else 274#define MSAN_MAYBE_INTERCEPT_MALLOPT 275#endif 276 277#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 278INTERCEPTOR(void, malloc_stats, void) { 279 // FIXME: implement, but don't call REAL(malloc_stats)! 280} 281#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS INTERCEPT_FUNCTION(malloc_stats) 282#else 283#define MSAN_MAYBE_INTERCEPT_MALLOC_STATS 284#endif 285 286INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT 287 ENSURE_MSAN_INITED(); 288 GET_STORE_STACK_TRACE; 289 SIZE_T n = REAL(strlen)(src); 290 CHECK_UNPOISONED_STRING(src + n, 0); 291 char *res = REAL(strcpy)(dest, src); // NOLINT 292 CopyShadowAndOrigin(dest, src, n + 1, &stack); 293 return res; 294} 295 296INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { // NOLINT 297 ENSURE_MSAN_INITED(); 298 GET_STORE_STACK_TRACE; 299 SIZE_T copy_size = REAL(strnlen)(src, n); 300 if (copy_size < n) 301 copy_size++; // trailing \0 302 char *res = REAL(strncpy)(dest, src, n); // NOLINT 303 CopyShadowAndOrigin(dest, src, copy_size, &stack); 304 __msan_unpoison(dest + copy_size, n - copy_size); 305 return res; 306} 307 308#if !SANITIZER_NETBSD 309INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT 310 ENSURE_MSAN_INITED(); 311 GET_STORE_STACK_TRACE; 312 SIZE_T n = REAL(strlen)(src); 313 CHECK_UNPOISONED_STRING(src + n, 0); 314 char *res = REAL(stpcpy)(dest, src); // NOLINT 315 CopyShadowAndOrigin(dest, src, n + 1, &stack); 316 return res; 317} 318#define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy) 319#else 320#define MSAN_MAYBE_INTERCEPT_STPCPY 321#endif 322 323INTERCEPTOR(char *, strdup, char *src) { 324 ENSURE_MSAN_INITED(); 325 GET_STORE_STACK_TRACE; 326 // On FreeBSD strdup() leverages strlen(). 327 InterceptorScope interceptor_scope; 328 SIZE_T n = REAL(strlen)(src); 329 CHECK_UNPOISONED_STRING(src + n, 0); 330 char *res = REAL(strdup)(src); 331 CopyShadowAndOrigin(res, src, n + 1, &stack); 332 return res; 333} 334 335#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 336INTERCEPTOR(char *, __strdup, char *src) { 337 ENSURE_MSAN_INITED(); 338 GET_STORE_STACK_TRACE; 339 SIZE_T n = REAL(strlen)(src); 340 CHECK_UNPOISONED_STRING(src + n, 0); 341 char *res = REAL(__strdup)(src); 342 CopyShadowAndOrigin(res, src, n + 1, &stack); 343 return res; 344} 345#define MSAN_MAYBE_INTERCEPT___STRDUP INTERCEPT_FUNCTION(__strdup) 346#else 347#define MSAN_MAYBE_INTERCEPT___STRDUP 348#endif 349 350#if !SANITIZER_NETBSD 351INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { 352 ENSURE_MSAN_INITED(); 353 char *res = REAL(gcvt)(number, ndigit, buf); 354 SIZE_T n = REAL(strlen)(buf); 355 __msan_unpoison(buf, n + 1); 356 return res; 357} 358#define MSAN_MAYBE_INTERCEPT_GCVT INTERCEPT_FUNCTION(gcvt) 359#else 360#define MSAN_MAYBE_INTERCEPT_GCVT 361#endif 362 363INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT 364 ENSURE_MSAN_INITED(); 365 GET_STORE_STACK_TRACE; 366 SIZE_T src_size = REAL(strlen)(src); 367 SIZE_T dest_size = REAL(strlen)(dest); 368 CHECK_UNPOISONED_STRING(src + src_size, 0); 369 CHECK_UNPOISONED_STRING(dest + dest_size, 0); 370 char *res = REAL(strcat)(dest, src); // NOLINT 371 CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack); 372 return res; 373} 374 375INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT 376 ENSURE_MSAN_INITED(); 377 GET_STORE_STACK_TRACE; 378 SIZE_T dest_size = REAL(strlen)(dest); 379 SIZE_T copy_size = REAL(strnlen)(src, n); 380 CHECK_UNPOISONED_STRING(dest + dest_size, 0); 381 char *res = REAL(strncat)(dest, src, n); // NOLINT 382 CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack); 383 __msan_unpoison(dest + dest_size + copy_size, 1); // \0 384 return res; 385} 386 387// Hack: always pass nptr and endptr as part of __VA_ARGS_ to avoid having to 388// deal with empty __VA_ARGS__ in the case of INTERCEPTOR_STRTO. 389#define INTERCEPTOR_STRTO_BODY(ret_type, func, ...) \ 390 ENSURE_MSAN_INITED(); \ 391 ret_type res = REAL(func)(__VA_ARGS__); \ 392 __msan_unpoison(endptr, sizeof(*endptr)); \ 393 return res; 394 395#define INTERCEPTOR_STRTO(ret_type, func, char_type) \ 396 INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr) { \ 397 INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr); \ 398 } 399 400#define INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ 401 INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \ 402 int base) { \ 403 INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base); \ 404 } 405 406#define INTERCEPTOR_STRTO_LOC(ret_type, func, char_type) \ 407 INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \ 408 void *loc) { \ 409 INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, loc); \ 410 } 411 412#define INTERCEPTOR_STRTO_BASE_LOC(ret_type, func, char_type) \ 413 INTERCEPTOR(ret_type, func, const char_type *nptr, char_type **endptr, \ 414 int base, void *loc) { \ 415 INTERCEPTOR_STRTO_BODY(ret_type, func, nptr, endptr, base, loc); \ 416 } 417 418#if SANITIZER_NETBSD 419#define INTERCEPTORS_STRTO(ret_type, func, char_type) \ 420 INTERCEPTOR_STRTO(ret_type, func, char_type) \ 421 INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) 422 423#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \ 424 INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ 425 INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) 426 427#else 428#define INTERCEPTORS_STRTO(ret_type, func, char_type) \ 429 INTERCEPTOR_STRTO(ret_type, func, char_type) \ 430 INTERCEPTOR_STRTO_LOC(ret_type, func##_l, char_type) \ 431 INTERCEPTOR_STRTO_LOC(ret_type, __##func##_l, char_type) \ 432 INTERCEPTOR_STRTO_LOC(ret_type, __##func##_internal, char_type) 433 434#define INTERCEPTORS_STRTO_BASE(ret_type, func, char_type) \ 435 INTERCEPTOR_STRTO_BASE(ret_type, func, char_type) \ 436 INTERCEPTOR_STRTO_BASE_LOC(ret_type, func##_l, char_type) \ 437 INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_l, char_type) \ 438 INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type) 439#endif 440 441INTERCEPTORS_STRTO(double, strtod, char) // NOLINT 442INTERCEPTORS_STRTO(float, strtof, char) // NOLINT 443INTERCEPTORS_STRTO(long double, strtold, char) // NOLINT 444INTERCEPTORS_STRTO_BASE(long, strtol, char) // NOLINT 445INTERCEPTORS_STRTO_BASE(long long, strtoll, char) // NOLINT 446INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char) // NOLINT 447INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char) // NOLINT 448INTERCEPTORS_STRTO_BASE(u64, strtouq, char) // NOLINT 449 450INTERCEPTORS_STRTO(double, wcstod, wchar_t) // NOLINT 451INTERCEPTORS_STRTO(float, wcstof, wchar_t) // NOLINT 452INTERCEPTORS_STRTO(long double, wcstold, wchar_t) // NOLINT 453INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t) // NOLINT 454INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t) // NOLINT 455INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t) // NOLINT 456INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t) // NOLINT 457 458#if SANITIZER_NETBSD 459#define INTERCEPT_STRTO(func) \ 460 INTERCEPT_FUNCTION(func); \ 461 INTERCEPT_FUNCTION(func##_l); 462#else 463#define INTERCEPT_STRTO(func) \ 464 INTERCEPT_FUNCTION(func); \ 465 INTERCEPT_FUNCTION(func##_l); \ 466 INTERCEPT_FUNCTION(__##func##_l); \ 467 INTERCEPT_FUNCTION(__##func##_internal); 468#endif 469 470 471// FIXME: support *wprintf in common format interceptors. 472INTERCEPTOR(int, vswprintf, void *str, uptr size, void *format, va_list ap) { 473 ENSURE_MSAN_INITED(); 474 int res = REAL(vswprintf)(str, size, format, ap); 475 if (res >= 0) { 476 __msan_unpoison(str, 4 * (res + 1)); 477 } 478 return res; 479} 480 481INTERCEPTOR(int, swprintf, void *str, uptr size, void *format, ...) { 482 ENSURE_MSAN_INITED(); 483 va_list ap; 484 va_start(ap, format); 485 int res = vswprintf(str, size, format, ap); 486 va_end(ap); 487 return res; 488} 489 490#define INTERCEPTOR_STRFTIME_BODY(char_type, ret_type, func, s, ...) \ 491 ENSURE_MSAN_INITED(); \ 492 InterceptorScope interceptor_scope; \ 493 ret_type res = REAL(func)(s, __VA_ARGS__); \ 494 if (s) __msan_unpoison(s, sizeof(char_type) * (res + 1)); \ 495 return res; 496 497INTERCEPTOR(SIZE_T, strftime, char *s, SIZE_T max, const char *format, 498 __sanitizer_tm *tm) { 499 INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime, s, max, format, tm); 500} 501 502INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format, 503 __sanitizer_tm *tm, void *loc) { 504 INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc); 505} 506 507#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 508INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format, 509 __sanitizer_tm *tm, void *loc) { 510 INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm, 511 loc); 512} 513#define MSAN_MAYBE_INTERCEPT___STRFTIME_L INTERCEPT_FUNCTION(__strftime_l) 514#else 515#define MSAN_MAYBE_INTERCEPT___STRFTIME_L 516#endif 517 518INTERCEPTOR(SIZE_T, wcsftime, wchar_t *s, SIZE_T max, const wchar_t *format, 519 __sanitizer_tm *tm) { 520 INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime, s, max, format, tm); 521} 522 523INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format, 524 __sanitizer_tm *tm, void *loc) { 525 INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, wcsftime_l, s, max, format, tm, 526 loc); 527} 528 529#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 530INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format, 531 __sanitizer_tm *tm, void *loc) { 532 INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm, 533 loc); 534} 535#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L INTERCEPT_FUNCTION(__wcsftime_l) 536#else 537#define MSAN_MAYBE_INTERCEPT___WCSFTIME_L 538#endif 539 540INTERCEPTOR(int, mbtowc, wchar_t *dest, const char *src, SIZE_T n) { 541 ENSURE_MSAN_INITED(); 542 int res = REAL(mbtowc)(dest, src, n); 543 if (res != -1 && dest) __msan_unpoison(dest, sizeof(wchar_t)); 544 return res; 545} 546 547INTERCEPTOR(SIZE_T, mbrtowc, wchar_t *dest, const char *src, SIZE_T n, 548 void *ps) { 549 ENSURE_MSAN_INITED(); 550 SIZE_T res = REAL(mbrtowc)(dest, src, n, ps); 551 if (res != (SIZE_T)-1 && dest) __msan_unpoison(dest, sizeof(wchar_t)); 552 return res; 553} 554 555// wchar_t *wmemcpy(wchar_t *dest, const wchar_t *src, SIZE_T n); 556INTERCEPTOR(wchar_t *, wmemcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) { 557 ENSURE_MSAN_INITED(); 558 GET_STORE_STACK_TRACE; 559 wchar_t *res = REAL(wmemcpy)(dest, src, n); 560 CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack); 561 return res; 562} 563 564#if !SANITIZER_NETBSD 565INTERCEPTOR(wchar_t *, wmempcpy, wchar_t *dest, const wchar_t *src, SIZE_T n) { 566 ENSURE_MSAN_INITED(); 567 GET_STORE_STACK_TRACE; 568 wchar_t *res = REAL(wmempcpy)(dest, src, n); 569 CopyShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack); 570 return res; 571} 572#define MSAN_MAYBE_INTERCEPT_WMEMPCPY INTERCEPT_FUNCTION(wmempcpy) 573#else 574#define MSAN_MAYBE_INTERCEPT_WMEMPCPY 575#endif 576 577INTERCEPTOR(wchar_t *, wmemset, wchar_t *s, wchar_t c, SIZE_T n) { 578 CHECK(MEM_IS_APP(s)); 579 ENSURE_MSAN_INITED(); 580 wchar_t *res = REAL(wmemset)(s, c, n); 581 __msan_unpoison(s, n * sizeof(wchar_t)); 582 return res; 583} 584 585INTERCEPTOR(wchar_t *, wmemmove, wchar_t *dest, const wchar_t *src, SIZE_T n) { 586 ENSURE_MSAN_INITED(); 587 GET_STORE_STACK_TRACE; 588 wchar_t *res = REAL(wmemmove)(dest, src, n); 589 MoveShadowAndOrigin(dest, src, n * sizeof(wchar_t), &stack); 590 return res; 591} 592 593INTERCEPTOR(int, wcscmp, const wchar_t *s1, const wchar_t *s2) { 594 ENSURE_MSAN_INITED(); 595 int res = REAL(wcscmp)(s1, s2); 596 return res; 597} 598 599INTERCEPTOR(int, gettimeofday, void *tv, void *tz) { 600 ENSURE_MSAN_INITED(); 601 int res = REAL(gettimeofday)(tv, tz); 602 if (tv) 603 __msan_unpoison(tv, 16); 604 if (tz) 605 __msan_unpoison(tz, 8); 606 return res; 607} 608 609#if !SANITIZER_NETBSD 610INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) { 611 ENSURE_MSAN_INITED(); 612 char *res = REAL(fcvt)(x, a, b, c); 613 __msan_unpoison(b, sizeof(*b)); 614 __msan_unpoison(c, sizeof(*c)); 615 if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); 616 return res; 617} 618#define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt) 619#else 620#define MSAN_MAYBE_INTERCEPT_FCVT 621#endif 622 623INTERCEPTOR(char *, getenv, char *name) { 624 if (msan_init_is_running) 625 return REAL(getenv)(name); 626 ENSURE_MSAN_INITED(); 627 char *res = REAL(getenv)(name); 628 if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); 629 return res; 630} 631 632extern char **environ; 633 634static void UnpoisonEnviron() { 635 char **envp = environ; 636 for (; *envp; ++envp) { 637 __msan_unpoison(envp, sizeof(*envp)); 638 __msan_unpoison(*envp, REAL(strlen)(*envp) + 1); 639 } 640 // Trailing NULL pointer. 641 __msan_unpoison(envp, sizeof(*envp)); 642} 643 644INTERCEPTOR(int, setenv, const char *name, const char *value, int overwrite) { 645 ENSURE_MSAN_INITED(); 646 CHECK_UNPOISONED_STRING(name, 0); 647 int res = REAL(setenv)(name, value, overwrite); 648 if (!res) UnpoisonEnviron(); 649 return res; 650} 651 652INTERCEPTOR(int, putenv, char *string) { 653 ENSURE_MSAN_INITED(); 654 int res = REAL(putenv)(string); 655 if (!res) UnpoisonEnviron(); 656 return res; 657} 658 659#if SANITIZER_FREEBSD || SANITIZER_NETBSD 660INTERCEPTOR(int, fstat, int fd, void *buf) { 661 ENSURE_MSAN_INITED(); 662 int res = REAL(fstat)(fd, buf); 663 if (!res) 664 __msan_unpoison(buf, __sanitizer::struct_stat_sz); 665 return res; 666} 667#define MSAN_MAYBE_INTERCEPT_FSTAT INTERCEPT_FUNCTION(fstat) 668#else 669#define MSAN_MAYBE_INTERCEPT_FSTAT 670#endif 671 672#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 673INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { 674 ENSURE_MSAN_INITED(); 675 int res = REAL(__fxstat)(magic, fd, buf); 676 if (!res) 677 __msan_unpoison(buf, __sanitizer::struct_stat_sz); 678 return res; 679} 680#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat) 681#else 682#define MSAN_MAYBE_INTERCEPT___FXSTAT 683#endif 684 685#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 686INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) { 687 ENSURE_MSAN_INITED(); 688 int res = REAL(__fxstat64)(magic, fd, buf); 689 if (!res) 690 __msan_unpoison(buf, __sanitizer::struct_stat64_sz); 691 return res; 692} 693#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64) 694#else 695#define MSAN_MAYBE_INTERCEPT___FXSTAT64 696#endif 697 698#if SANITIZER_FREEBSD || SANITIZER_NETBSD 699INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) { 700 ENSURE_MSAN_INITED(); 701 int res = REAL(fstatat)(fd, pathname, buf, flags); 702 if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); 703 return res; 704} 705# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat) 706#else 707INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, 708 int flags) { 709 ENSURE_MSAN_INITED(); 710 int res = REAL(__fxstatat)(magic, fd, pathname, buf, flags); 711 if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); 712 return res; 713} 714# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat) 715#endif 716 717#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 718INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf, 719 int flags) { 720 ENSURE_MSAN_INITED(); 721 int res = REAL(__fxstatat64)(magic, fd, pathname, buf, flags); 722 if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz); 723 return res; 724} 725#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64) 726#else 727#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 728#endif 729 730INTERCEPTOR(int, pipe, int pipefd[2]) { 731 if (msan_init_is_running) 732 return REAL(pipe)(pipefd); 733 ENSURE_MSAN_INITED(); 734 int res = REAL(pipe)(pipefd); 735 if (!res) 736 __msan_unpoison(pipefd, sizeof(int[2])); 737 return res; 738} 739 740INTERCEPTOR(int, pipe2, int pipefd[2], int flags) { 741 ENSURE_MSAN_INITED(); 742 int res = REAL(pipe2)(pipefd, flags); 743 if (!res) 744 __msan_unpoison(pipefd, sizeof(int[2])); 745 return res; 746} 747 748INTERCEPTOR(int, socketpair, int domain, int type, int protocol, int sv[2]) { 749 ENSURE_MSAN_INITED(); 750 int res = REAL(socketpair)(domain, type, protocol, sv); 751 if (!res) 752 __msan_unpoison(sv, sizeof(int[2])); 753 return res; 754} 755 756#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 757INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) { 758 ENSURE_MSAN_INITED(); 759 char *res = REAL(fgets_unlocked)(s, size, stream); 760 if (res) 761 __msan_unpoison(s, REAL(strlen)(s) + 1); 762 return res; 763} 764#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked) 765#else 766#define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED 767#endif 768 769INTERCEPTOR(int, getrlimit, int resource, void *rlim) { 770 if (msan_init_is_running) 771 return REAL(getrlimit)(resource, rlim); 772 ENSURE_MSAN_INITED(); 773 int res = REAL(getrlimit)(resource, rlim); 774 if (!res) 775 __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); 776 return res; 777} 778 779#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 780INTERCEPTOR(int, getrlimit64, int resource, void *rlim) { 781 if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim); 782 ENSURE_MSAN_INITED(); 783 int res = REAL(getrlimit64)(resource, rlim); 784 if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz); 785 return res; 786} 787 788INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit, 789 void *old_rlimit) { 790 if (msan_init_is_running) 791 return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit); 792 ENSURE_MSAN_INITED(); 793 CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz); 794 int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit); 795 if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz); 796 return res; 797} 798 799INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit, 800 void *old_rlimit) { 801 if (msan_init_is_running) 802 return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit); 803 ENSURE_MSAN_INITED(); 804 CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz); 805 int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit); 806 if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz); 807 return res; 808} 809 810#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64) 811#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit) 812#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64) 813#else 814#define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 815#define MSAN_MAYBE_INTERCEPT_PRLIMIT 816#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 817#endif 818 819#if SANITIZER_FREEBSD 820// FreeBSD's <sys/utsname.h> define uname() as 821// static __inline int uname(struct utsname *name) { 822// return __xuname(SYS_NMLN, (void*)name); 823// } 824INTERCEPTOR(int, __xuname, int size, void *utsname) { 825 ENSURE_MSAN_INITED(); 826 int res = REAL(__xuname)(size, utsname); 827 if (!res) 828 __msan_unpoison(utsname, __sanitizer::struct_utsname_sz); 829 return res; 830} 831#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(__xuname) 832#else 833INTERCEPTOR(int, uname, struct utsname *utsname) { 834 ENSURE_MSAN_INITED(); 835 int res = REAL(uname)(utsname); 836 if (!res) 837 __msan_unpoison(utsname, __sanitizer::struct_utsname_sz); 838 return res; 839} 840#define MSAN_INTERCEPT_UNAME INTERCEPT_FUNCTION(uname) 841#endif 842 843INTERCEPTOR(int, gethostname, char *name, SIZE_T len) { 844 ENSURE_MSAN_INITED(); 845 int res = REAL(gethostname)(name, len); 846 if (!res) { 847 SIZE_T real_len = REAL(strnlen)(name, len); 848 if (real_len < len) 849 ++real_len; 850 __msan_unpoison(name, real_len); 851 } 852 return res; 853} 854 855#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 856INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents, 857 int timeout) { 858 ENSURE_MSAN_INITED(); 859 int res = REAL(epoll_wait)(epfd, events, maxevents, timeout); 860 if (res > 0) { 861 __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res); 862 } 863 return res; 864} 865#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT INTERCEPT_FUNCTION(epoll_wait) 866#else 867#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT 868#endif 869 870#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD 871INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents, 872 int timeout, void *sigmask) { 873 ENSURE_MSAN_INITED(); 874 int res = REAL(epoll_pwait)(epfd, events, maxevents, timeout, sigmask); 875 if (res > 0) { 876 __msan_unpoison(events, __sanitizer::struct_epoll_event_sz * res); 877 } 878 return res; 879} 880#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT INTERCEPT_FUNCTION(epoll_pwait) 881#else 882#define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT 883#endif 884 885INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) { 886 GET_MALLOC_STACK_TRACE; 887 if (UNLIKELY(!msan_inited)) 888 // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. 889 return AllocateFromLocalPool(nmemb * size); 890 return msan_calloc(nmemb, size, &stack); 891} 892 893INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { 894 GET_MALLOC_STACK_TRACE; 895 if (UNLIKELY(IsInDlsymAllocPool(ptr))) { 896 uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; 897 uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); 898 void *new_ptr; 899 if (UNLIKELY(!msan_inited)) { 900 new_ptr = AllocateFromLocalPool(copy_size); 901 } else { 902 copy_size = size; 903 new_ptr = msan_malloc(copy_size, &stack); 904 } 905 internal_memcpy(new_ptr, ptr, copy_size); 906 return new_ptr; 907 } 908 return msan_realloc(ptr, size, &stack); 909} 910 911INTERCEPTOR(void *, malloc, SIZE_T size) { 912 GET_MALLOC_STACK_TRACE; 913 if (UNLIKELY(!msan_inited)) 914 // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. 915 return AllocateFromLocalPool(size); 916 return msan_malloc(size, &stack); 917} 918 919void __msan_allocated_memory(const void *data, uptr size) { 920 GET_MALLOC_STACK_TRACE; 921 if (flags()->poison_in_malloc) { 922 stack.tag = STACK_TRACE_TAG_POISON; 923 PoisonMemory(data, size, &stack); 924 } 925} 926 927void __msan_copy_shadow(void *dest, const void *src, uptr n) { 928 GET_STORE_STACK_TRACE; 929 MoveShadowAndOrigin(dest, src, n, &stack); 930} 931 932void __sanitizer_dtor_callback(const void *data, uptr size) { 933 GET_MALLOC_STACK_TRACE; 934 if (flags()->poison_in_dtor) { 935 stack.tag = STACK_TRACE_TAG_POISON; 936 PoisonMemory(data, size, &stack); 937 } 938} 939 940template <class Mmap> 941static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length, 942 int prot, int flags, int fd, OFF64_T offset) { 943 if (addr && !MEM_IS_APP(addr)) { 944 if (flags & map_fixed) { 945 errno = errno_EINVAL; 946 return (void *)-1; 947 } else { 948 addr = nullptr; 949 } 950 } 951 void *res = real_mmap(addr, length, prot, flags, fd, offset); 952 if (res != (void *)-1) __msan_unpoison(res, RoundUpTo(length, GetPageSize())); 953 return res; 954} 955 956INTERCEPTOR(int, getrusage, int who, void *usage) { 957 ENSURE_MSAN_INITED(); 958 int res = REAL(getrusage)(who, usage); 959 if (res == 0) { 960 __msan_unpoison(usage, __sanitizer::struct_rusage_sz); 961 } 962 return res; 963} 964 965class SignalHandlerScope { 966 public: 967 SignalHandlerScope() { 968 if (MsanThread *t = GetCurrentThread()) 969 t->EnterSignalHandler(); 970 } 971 ~SignalHandlerScope() { 972 if (MsanThread *t = GetCurrentThread()) 973 t->LeaveSignalHandler(); 974 } 975}; 976 977// sigactions_mu guarantees atomicity of sigaction() and signal() calls. 978// Access to sigactions[] is gone with relaxed atomics to avoid data race with 979// the signal handler. 980const int kMaxSignals = 1024; 981static atomic_uintptr_t sigactions[kMaxSignals]; 982static StaticSpinMutex sigactions_mu; 983 984static void SignalHandler(int signo) { 985 SignalHandlerScope signal_handler_scope; 986 ScopedThreadLocalStateBackup stlsb; 987 UnpoisonParam(1); 988 989 typedef void (*signal_cb)(int x); 990 signal_cb cb = 991 (signal_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 992 cb(signo); 993} 994 995static void SignalAction(int signo, void *si, void *uc) { 996 SignalHandlerScope signal_handler_scope; 997 ScopedThreadLocalStateBackup stlsb; 998 UnpoisonParam(3); 999 __msan_unpoison(si, sizeof(__sanitizer_sigaction)); 1000 __msan_unpoison(uc, __sanitizer::ucontext_t_sz); 1001 1002 typedef void (*sigaction_cb)(int, void *, void *); 1003 sigaction_cb cb = 1004 (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); 1005 cb(signo, si, uc); 1006} 1007 1008static void read_sigaction(const __sanitizer_sigaction *act) { 1009 CHECK_UNPOISONED(&act->sa_flags, sizeof(act->sa_flags)); 1010 if (act->sa_flags & __sanitizer::sa_siginfo) 1011 CHECK_UNPOISONED(&act->sigaction, sizeof(act->sigaction)); 1012 else 1013 CHECK_UNPOISONED(&act->handler, sizeof(act->handler)); 1014 CHECK_UNPOISONED(&act->sa_mask, sizeof(act->sa_mask)); 1015} 1016 1017extern "C" int pthread_attr_init(void *attr); 1018extern "C" int pthread_attr_destroy(void *attr); 1019 1020static void *MsanThreadStartFunc(void *arg) { 1021 MsanThread *t = (MsanThread *)arg; 1022 SetCurrentThread(t); 1023 return t->ThreadStart(); 1024} 1025 1026INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), 1027 void * param) { 1028 ENSURE_MSAN_INITED(); // for GetTlsSize() 1029 __sanitizer_pthread_attr_t myattr; 1030 if (!attr) { 1031 pthread_attr_init(&myattr); 1032 attr = &myattr; 1033 } 1034 1035 AdjustStackSize(attr); 1036 1037 MsanThread *t = MsanThread::Create(callback, param); 1038 1039 int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t); 1040 1041 if (attr == &myattr) 1042 pthread_attr_destroy(&myattr); 1043 if (!res) { 1044 __msan_unpoison(th, __sanitizer::pthread_t_sz); 1045 } 1046 return res; 1047} 1048 1049INTERCEPTOR(int, pthread_key_create, __sanitizer_pthread_key_t *key, 1050 void (*dtor)(void *value)) { 1051 if (msan_init_is_running) return REAL(pthread_key_create)(key, dtor); 1052 ENSURE_MSAN_INITED(); 1053 int res = REAL(pthread_key_create)(key, dtor); 1054 if (!res && key) 1055 __msan_unpoison(key, sizeof(*key)); 1056 return res; 1057} 1058 1059#if SANITIZER_NETBSD 1060INTERCEPTOR(int, __libc_thr_keycreate, __sanitizer_pthread_key_t *m, void (*dtor)(void *value)) \ 1061 ALIAS(WRAPPER_NAME(pthread_key_create)); 1062#endif 1063 1064INTERCEPTOR(int, pthread_join, void *th, void **retval) { 1065 ENSURE_MSAN_INITED(); 1066 int res = REAL(pthread_join)(th, retval); 1067 if (!res && retval) 1068 __msan_unpoison(retval, sizeof(*retval)); 1069 return res; 1070} 1071 1072extern char *tzname[2]; 1073 1074INTERCEPTOR(void, tzset, int fake) { 1075 ENSURE_MSAN_INITED(); 1076 InterceptorScope interceptor_scope; 1077 REAL(tzset)(fake); 1078 if (tzname[0]) 1079 __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1); 1080 if (tzname[1]) 1081 __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1); 1082 return; 1083} 1084 1085struct MSanAtExitRecord { 1086 void (*func)(void *arg); 1087 void *arg; 1088}; 1089 1090struct InterceptorContext { 1091 BlockingMutex atexit_mu; 1092 Vector<struct MSanAtExitRecord *> AtExitStack; 1093 1094 InterceptorContext() 1095 : AtExitStack() { 1096 } 1097}; 1098 1099static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)]; 1100InterceptorContext *interceptor_ctx() { 1101 return reinterpret_cast<InterceptorContext*>(&interceptor_placeholder[0]); 1102} 1103 1104void MSanAtExitWrapper() { 1105 MSanAtExitRecord *r; 1106 { 1107 BlockingMutexLock l(&interceptor_ctx()->atexit_mu); 1108 1109 uptr element = interceptor_ctx()->AtExitStack.Size() - 1; 1110 r = interceptor_ctx()->AtExitStack[element]; 1111 interceptor_ctx()->AtExitStack.PopBack(); 1112 } 1113 1114 UnpoisonParam(1); 1115 ((void(*)())r->func)(); 1116 InternalFree(r); 1117} 1118 1119void MSanCxaAtExitWrapper(void *arg) { 1120 UnpoisonParam(1); 1121 MSanAtExitRecord *r = (MSanAtExitRecord *)arg; 1122 r->func(r->arg); 1123 InternalFree(r); 1124} 1125 1126static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso); 1127 1128// Unpoison argument shadow for C++ module destructors. 1129INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, 1130 void *dso_handle) { 1131 if (msan_init_is_running) return REAL(__cxa_atexit)(func, arg, dso_handle); 1132 return setup_at_exit_wrapper((void(*)())func, arg, dso_handle); 1133} 1134 1135// Unpoison argument shadow for C++ module destructors. 1136INTERCEPTOR(int, atexit, void (*func)()) { 1137 // Avoid calling real atexit as it is unrechable on at least on Linux. 1138 if (msan_init_is_running) 1139 return REAL(__cxa_atexit)((void (*)(void *a))func, 0, 0); 1140 return setup_at_exit_wrapper((void(*)())func, 0, 0); 1141} 1142 1143static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) { 1144 ENSURE_MSAN_INITED(); 1145 MSanAtExitRecord *r = 1146 (MSanAtExitRecord *)InternalAlloc(sizeof(MSanAtExitRecord)); 1147 r->func = (void(*)(void *a))f; 1148 r->arg = arg; 1149 int res; 1150 if (!dso) { 1151 // NetBSD does not preserve the 2nd argument if dso is equal to 0 1152 // Store ctx in a local stack-like structure 1153 1154 BlockingMutexLock l(&interceptor_ctx()->atexit_mu); 1155 1156 res = REAL(__cxa_atexit)((void (*)(void *a))MSanAtExitWrapper, 0, 0); 1157 if (!res) { 1158 interceptor_ctx()->AtExitStack.PushBack(r); 1159 } 1160 } else { 1161 res = REAL(__cxa_atexit)(MSanCxaAtExitWrapper, r, dso); 1162 } 1163 return res; 1164} 1165 1166static void BeforeFork() { 1167 StackDepotLockAll(); 1168 ChainedOriginDepotLockAll(); 1169} 1170 1171static void AfterFork() { 1172 ChainedOriginDepotUnlockAll(); 1173 StackDepotUnlockAll(); 1174} 1175 1176INTERCEPTOR(int, fork, void) { 1177 ENSURE_MSAN_INITED(); 1178 BeforeFork(); 1179 int pid = REAL(fork)(); 1180 AfterFork(); 1181 return pid; 1182} 1183 1184// NetBSD ships with openpty(3) in -lutil, that needs to be prebuilt explicitly 1185// with MSan. 1186#if SANITIZER_LINUX 1187INTERCEPTOR(int, openpty, int *amaster, int *aslave, char *name, 1188 const void *termp, const void *winp) { 1189 ENSURE_MSAN_INITED(); 1190 InterceptorScope interceptor_scope; 1191 int res = REAL(openpty)(amaster, aslave, name, termp, winp); 1192 if (!res) { 1193 __msan_unpoison(amaster, sizeof(*amaster)); 1194 __msan_unpoison(aslave, sizeof(*aslave)); 1195 } 1196 return res; 1197} 1198#define MSAN_MAYBE_INTERCEPT_OPENPTY INTERCEPT_FUNCTION(openpty) 1199#else 1200#define MSAN_MAYBE_INTERCEPT_OPENPTY 1201#endif 1202 1203// NetBSD ships with forkpty(3) in -lutil, that needs to be prebuilt explicitly 1204// with MSan. 1205#if SANITIZER_LINUX 1206INTERCEPTOR(int, forkpty, int *amaster, char *name, const void *termp, 1207 const void *winp) { 1208 ENSURE_MSAN_INITED(); 1209 InterceptorScope interceptor_scope; 1210 int res = REAL(forkpty)(amaster, name, termp, winp); 1211 if (res != -1) 1212 __msan_unpoison(amaster, sizeof(*amaster)); 1213 return res; 1214} 1215#define MSAN_MAYBE_INTERCEPT_FORKPTY INTERCEPT_FUNCTION(forkpty) 1216#else 1217#define MSAN_MAYBE_INTERCEPT_FORKPTY 1218#endif 1219 1220struct MSanInterceptorContext { 1221 bool in_interceptor_scope; 1222}; 1223 1224namespace __msan { 1225 1226int OnExit() { 1227 // FIXME: ask frontend whether we need to return failure. 1228 return 0; 1229} 1230 1231} // namespace __msan 1232 1233// A version of CHECK_UNPOISONED using a saved scope value. Used in common 1234// interceptors. 1235#define CHECK_UNPOISONED_CTX(ctx, x, n) \ 1236 do { \ 1237 if (!((MSanInterceptorContext *)ctx)->in_interceptor_scope) \ 1238 CHECK_UNPOISONED_0(x, n); \ 1239 } while (0) 1240 1241#define MSAN_INTERCEPT_FUNC(name) \ 1242 do { \ 1243 if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ 1244 VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \ 1245 } while (0) 1246 1247#define MSAN_INTERCEPT_FUNC_VER(name, ver) \ 1248 do { \ 1249 if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ 1250 VReport( \ 1251 1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ 1252 } while (0) 1253 1254#define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name) 1255#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ 1256 MSAN_INTERCEPT_FUNC_VER(name, ver) 1257#define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \ 1258 UnpoisonParam(count) 1259#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ 1260 __msan_unpoison(ptr, size) 1261#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \ 1262 CHECK_UNPOISONED_CTX(ctx, ptr, size) 1263#define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \ 1264 __msan_unpoison(ptr, size) 1265#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ 1266 if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \ 1267 ENSURE_MSAN_INITED(); \ 1268 MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \ 1269 ctx = (void *)&msan_ctx; \ 1270 (void)ctx; \ 1271 InterceptorScope interceptor_scope; \ 1272 __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */ 1273#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \ 1274 do { \ 1275 } while (false) 1276#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \ 1277 do { \ 1278 } while (false) 1279#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \ 1280 do { \ 1281 } while (false) 1282#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \ 1283 do { \ 1284 } while (false) 1285#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) \ 1286 do { \ 1287 } while (false) // FIXME 1288#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \ 1289 do { \ 1290 } while (false) // FIXME 1291#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name) 1292#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() 1293#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle) \ 1294 do { \ 1295 link_map *map = GET_LINK_MAP_BY_DLOPEN_HANDLE((handle)); \ 1296 if (filename && map) \ 1297 ForEachMappedRegion(map, __msan_unpoison); \ 1298 } while (false) 1299 1300#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \ 1301 if (MsanThread *t = GetCurrentThread()) { \ 1302 *begin = t->tls_begin(); \ 1303 *end = t->tls_end(); \ 1304 } else { \ 1305 *begin = *end = 0; \ 1306 } 1307 1308#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \ 1309 { \ 1310 (void)ctx; \ 1311 return __msan_memset(block, c, size); \ 1312 } 1313#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \ 1314 { \ 1315 (void)ctx; \ 1316 return __msan_memmove(to, from, size); \ 1317 } 1318#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \ 1319 { \ 1320 (void)ctx; \ 1321 return __msan_memcpy(to, from, size); \ 1322 } 1323 1324#define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) \ 1325 do { \ 1326 GET_STORE_STACK_TRACE; \ 1327 CopyShadowAndOrigin(to, from, size, &stack); \ 1328 __msan_unpoison(to + size, 1); \ 1329 } while (false) 1330 1331#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, length, prot, flags, fd, \ 1332 offset) \ 1333 do { \ 1334 return mmap_interceptor(REAL(mmap), addr, sz, prot, flags, fd, off); \ 1335 } while (false) 1336 1337#include "sanitizer_common/sanitizer_platform_interceptors.h" 1338#include "sanitizer_common/sanitizer_common_interceptors.inc" 1339 1340static uptr signal_impl(int signo, uptr cb); 1341static int sigaction_impl(int signo, const __sanitizer_sigaction *act, 1342 __sanitizer_sigaction *oldact); 1343 1344#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact) \ 1345 { return sigaction_impl(signo, act, oldact); } 1346 1347#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \ 1348 { \ 1349 handler = signal_impl(signo, handler); \ 1350 InterceptorScope interceptor_scope; \ 1351 return REAL(func)(signo, handler); \ 1352 } 1353 1354#include "sanitizer_common/sanitizer_signal_interceptors.inc" 1355 1356static int sigaction_impl(int signo, const __sanitizer_sigaction *act, 1357 __sanitizer_sigaction *oldact) { 1358 ENSURE_MSAN_INITED(); 1359 if (act) read_sigaction(act); 1360 int res; 1361 if (flags()->wrap_signals) { 1362 SpinMutexLock lock(&sigactions_mu); 1363 CHECK_LT(signo, kMaxSignals); 1364 uptr old_cb = atomic_load(&sigactions[signo], memory_order_relaxed); 1365 __sanitizer_sigaction new_act; 1366 __sanitizer_sigaction *pnew_act = act ? &new_act : nullptr; 1367 if (act) { 1368 REAL(memcpy)(pnew_act, act, sizeof(__sanitizer_sigaction)); 1369 uptr cb = (uptr)pnew_act->sigaction; 1370 uptr new_cb = (pnew_act->sa_flags & __sanitizer::sa_siginfo) 1371 ? (uptr)SignalAction 1372 : (uptr)SignalHandler; 1373 if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { 1374 atomic_store(&sigactions[signo], cb, memory_order_relaxed); 1375 pnew_act->sigaction = (decltype(pnew_act->sigaction))new_cb; 1376 } 1377 } 1378 res = REAL(SIGACTION_SYMNAME)(signo, pnew_act, oldact); 1379 if (res == 0 && oldact) { 1380 uptr cb = (uptr)oldact->sigaction; 1381 if (cb == (uptr)SignalAction || cb == (uptr)SignalHandler) { 1382 oldact->sigaction = (decltype(oldact->sigaction))old_cb; 1383 } 1384 } 1385 } else { 1386 res = REAL(SIGACTION_SYMNAME)(signo, act, oldact); 1387 } 1388 1389 if (res == 0 && oldact) { 1390 __msan_unpoison(oldact, sizeof(__sanitizer_sigaction)); 1391 } 1392 return res; 1393} 1394 1395static uptr signal_impl(int signo, uptr cb) { 1396 ENSURE_MSAN_INITED(); 1397 if (flags()->wrap_signals) { 1398 CHECK_LT(signo, kMaxSignals); 1399 SpinMutexLock lock(&sigactions_mu); 1400 if (cb != __sanitizer::sig_ign && cb != __sanitizer::sig_dfl) { 1401 atomic_store(&sigactions[signo], cb, memory_order_relaxed); 1402 cb = (uptr)&SignalHandler; 1403 } 1404 } 1405 return cb; 1406} 1407 1408#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s) 1409#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) \ 1410 do { \ 1411 } while (false) 1412#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \ 1413 do { \ 1414 } while (false) 1415#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s) 1416#include "sanitizer_common/sanitizer_common_syscalls.inc" 1417#include "sanitizer_common/sanitizer_syscalls_netbsd.inc" 1418 1419struct dlinfo { 1420 char *dli_fname; 1421 void *dli_fbase; 1422 char *dli_sname; 1423 void *dli_saddr; 1424}; 1425 1426INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { 1427 void *ctx; 1428 COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info); 1429 int res = REAL(dladdr)(addr, info); 1430 if (res != 0) { 1431 __msan_unpoison(info, sizeof(*info)); 1432 if (info->dli_fname) 1433 __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1); 1434 if (info->dli_sname) 1435 __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1); 1436 } 1437 return res; 1438} 1439 1440INTERCEPTOR(char *, dlerror, int fake) { 1441 void *ctx; 1442 COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake); 1443 char *res = REAL(dlerror)(fake); 1444 if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); 1445 return res; 1446} 1447 1448typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size, 1449 void *data); 1450struct dl_iterate_phdr_data { 1451 dl_iterate_phdr_cb callback; 1452 void *data; 1453}; 1454 1455static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, 1456 void *data) { 1457 if (info) { 1458 __msan_unpoison(info, size); 1459 if (info->dlpi_phdr && info->dlpi_phnum) 1460 __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum); 1461 if (info->dlpi_name) 1462 __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1); 1463 } 1464 dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; 1465 UnpoisonParam(3); 1466 return cbdata->callback(info, size, cbdata->data); 1467} 1468 1469INTERCEPTOR(void *, shmat, int shmid, const void *shmaddr, int shmflg) { 1470 ENSURE_MSAN_INITED(); 1471 void *p = REAL(shmat)(shmid, shmaddr, shmflg); 1472 if (p != (void *)-1) { 1473 __sanitizer_shmid_ds ds; 1474 int res = REAL(shmctl)(shmid, shmctl_ipc_stat, &ds); 1475 if (!res) { 1476 __msan_unpoison(p, ds.shm_segsz); 1477 } 1478 } 1479 return p; 1480} 1481 1482INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { 1483 void *ctx; 1484 COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data); 1485 dl_iterate_phdr_data cbdata; 1486 cbdata.callback = callback; 1487 cbdata.data = data; 1488 int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata); 1489 return res; 1490} 1491 1492// wchar_t *wcschr(const wchar_t *wcs, wchar_t wc); 1493INTERCEPTOR(wchar_t *, wcschr, void *s, wchar_t wc, void *ps) { 1494 ENSURE_MSAN_INITED(); 1495 wchar_t *res = REAL(wcschr)(s, wc, ps); 1496 return res; 1497} 1498 1499// wchar_t *wcscpy(wchar_t *dest, const wchar_t *src); 1500INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) { 1501 ENSURE_MSAN_INITED(); 1502 GET_STORE_STACK_TRACE; 1503 wchar_t *res = REAL(wcscpy)(dest, src); 1504 CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1), 1505 &stack); 1506 return res; 1507} 1508 1509INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, 1510 SIZE_T n) { // NOLINT 1511 ENSURE_MSAN_INITED(); 1512 GET_STORE_STACK_TRACE; 1513 SIZE_T copy_size = REAL(wcsnlen)(src, n); 1514 if (copy_size < n) copy_size++; // trailing \0 1515 wchar_t *res = REAL(wcsncpy)(dest, src, n); // NOLINT 1516 CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack); 1517 __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t)); 1518 return res; 1519} 1520 1521// These interface functions reside here so that they can use 1522// REAL(memset), etc. 1523void __msan_unpoison(const void *a, uptr size) { 1524 if (!MEM_IS_APP(a)) return; 1525 SetShadow(a, size, 0); 1526} 1527 1528void __msan_poison(const void *a, uptr size) { 1529 if (!MEM_IS_APP(a)) return; 1530 SetShadow(a, size, __msan::flags()->poison_heap_with_zeroes ? 0 : -1); 1531} 1532 1533void __msan_poison_stack(void *a, uptr size) { 1534 if (!MEM_IS_APP(a)) return; 1535 SetShadow(a, size, __msan::flags()->poison_stack_with_zeroes ? 0 : -1); 1536} 1537 1538void __msan_clear_and_unpoison(void *a, uptr size) { 1539 REAL(memset)(a, 0, size); 1540 SetShadow(a, size, 0); 1541} 1542 1543void *__msan_memcpy(void *dest, const void *src, SIZE_T n) { 1544 if (!msan_inited) return internal_memcpy(dest, src, n); 1545 if (msan_init_is_running || __msan::IsInSymbolizer()) 1546 return REAL(memcpy)(dest, src, n); 1547 ENSURE_MSAN_INITED(); 1548 GET_STORE_STACK_TRACE; 1549 void *res = REAL(memcpy)(dest, src, n); 1550 CopyShadowAndOrigin(dest, src, n, &stack); 1551 return res; 1552} 1553 1554void *__msan_memset(void *s, int c, SIZE_T n) { 1555 if (!msan_inited) return internal_memset(s, c, n); 1556 if (msan_init_is_running) return REAL(memset)(s, c, n); 1557 ENSURE_MSAN_INITED(); 1558 void *res = REAL(memset)(s, c, n); 1559 __msan_unpoison(s, n); 1560 return res; 1561} 1562 1563void *__msan_memmove(void *dest, const void *src, SIZE_T n) { 1564 if (!msan_inited) return internal_memmove(dest, src, n); 1565 if (msan_init_is_running) return REAL(memmove)(dest, src, n); 1566 ENSURE_MSAN_INITED(); 1567 GET_STORE_STACK_TRACE; 1568 void *res = REAL(memmove)(dest, src, n); 1569 MoveShadowAndOrigin(dest, src, n, &stack); 1570 return res; 1571} 1572 1573void __msan_unpoison_string(const char* s) { 1574 if (!MEM_IS_APP(s)) return; 1575 __msan_unpoison(s, REAL(strlen)(s) + 1); 1576} 1577 1578namespace __msan { 1579 1580void InitializeInterceptors() { 1581 static int inited = 0; 1582 CHECK_EQ(inited, 0); 1583 1584 new(interceptor_ctx()) InterceptorContext(); 1585 1586 InitializeCommonInterceptors(); 1587 InitializeSignalInterceptors(); 1588 1589 INTERCEPT_FUNCTION(posix_memalign); 1590 MSAN_MAYBE_INTERCEPT_MEMALIGN; 1591 MSAN_MAYBE_INTERCEPT___LIBC_MEMALIGN; 1592 INTERCEPT_FUNCTION(valloc); 1593 MSAN_MAYBE_INTERCEPT_PVALLOC; 1594 INTERCEPT_FUNCTION(malloc); 1595 INTERCEPT_FUNCTION(calloc); 1596 INTERCEPT_FUNCTION(realloc); 1597 INTERCEPT_FUNCTION(free); 1598 MSAN_MAYBE_INTERCEPT_CFREE; 1599 MSAN_MAYBE_INTERCEPT_MALLOC_USABLE_SIZE; 1600 MSAN_MAYBE_INTERCEPT_MALLINFO; 1601 MSAN_MAYBE_INTERCEPT_MALLOPT; 1602 MSAN_MAYBE_INTERCEPT_MALLOC_STATS; 1603 INTERCEPT_FUNCTION(fread); 1604 MSAN_MAYBE_INTERCEPT_FREAD_UNLOCKED; 1605 INTERCEPT_FUNCTION(memccpy); 1606 MSAN_MAYBE_INTERCEPT_MEMPCPY; 1607 INTERCEPT_FUNCTION(bcopy); 1608 INTERCEPT_FUNCTION(wmemset); 1609 INTERCEPT_FUNCTION(wmemcpy); 1610 MSAN_MAYBE_INTERCEPT_WMEMPCPY; 1611 INTERCEPT_FUNCTION(wmemmove); 1612 INTERCEPT_FUNCTION(strcpy); // NOLINT 1613 MSAN_MAYBE_INTERCEPT_STPCPY; // NOLINT 1614 INTERCEPT_FUNCTION(strdup); 1615 MSAN_MAYBE_INTERCEPT___STRDUP; 1616 INTERCEPT_FUNCTION(strncpy); // NOLINT 1617 MSAN_MAYBE_INTERCEPT_GCVT; 1618 INTERCEPT_FUNCTION(strcat); // NOLINT 1619 INTERCEPT_FUNCTION(strncat); // NOLINT 1620 INTERCEPT_STRTO(strtod); 1621 INTERCEPT_STRTO(strtof); 1622 INTERCEPT_STRTO(strtold); 1623 INTERCEPT_STRTO(strtol); 1624 INTERCEPT_STRTO(strtoul); 1625 INTERCEPT_STRTO(strtoll); 1626 INTERCEPT_STRTO(strtoull); 1627 INTERCEPT_STRTO(strtouq); 1628 INTERCEPT_STRTO(wcstod); 1629 INTERCEPT_STRTO(wcstof); 1630 INTERCEPT_STRTO(wcstold); 1631 INTERCEPT_STRTO(wcstol); 1632 INTERCEPT_STRTO(wcstoul); 1633 INTERCEPT_STRTO(wcstoll); 1634 INTERCEPT_STRTO(wcstoull); 1635#ifdef SANITIZER_NLDBL_VERSION 1636 INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION); 1637 INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION); 1638#else 1639 INTERCEPT_FUNCTION(vswprintf); 1640 INTERCEPT_FUNCTION(swprintf); 1641#endif 1642 INTERCEPT_FUNCTION(strftime); 1643 INTERCEPT_FUNCTION(strftime_l); 1644 MSAN_MAYBE_INTERCEPT___STRFTIME_L; 1645 INTERCEPT_FUNCTION(wcsftime); 1646 INTERCEPT_FUNCTION(wcsftime_l); 1647 MSAN_MAYBE_INTERCEPT___WCSFTIME_L; 1648 INTERCEPT_FUNCTION(mbtowc); 1649 INTERCEPT_FUNCTION(mbrtowc); 1650 INTERCEPT_FUNCTION(wcslen); 1651 INTERCEPT_FUNCTION(wcsnlen); 1652 INTERCEPT_FUNCTION(wcschr); 1653 INTERCEPT_FUNCTION(wcscpy); 1654 INTERCEPT_FUNCTION(wcsncpy); 1655 INTERCEPT_FUNCTION(wcscmp); 1656 INTERCEPT_FUNCTION(getenv); 1657 INTERCEPT_FUNCTION(setenv); 1658 INTERCEPT_FUNCTION(putenv); 1659 INTERCEPT_FUNCTION(gettimeofday); 1660 MSAN_MAYBE_INTERCEPT_FCVT; 1661 MSAN_MAYBE_INTERCEPT_FSTAT; 1662 MSAN_MAYBE_INTERCEPT___FXSTAT; 1663 MSAN_INTERCEPT_FSTATAT; 1664 MSAN_MAYBE_INTERCEPT___FXSTAT64; 1665 MSAN_MAYBE_INTERCEPT___FXSTATAT64; 1666 INTERCEPT_FUNCTION(pipe); 1667 INTERCEPT_FUNCTION(pipe2); 1668 INTERCEPT_FUNCTION(socketpair); 1669 MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED; 1670 INTERCEPT_FUNCTION(getrlimit); 1671 MSAN_MAYBE_INTERCEPT_GETRLIMIT64; 1672 MSAN_MAYBE_INTERCEPT_PRLIMIT; 1673 MSAN_MAYBE_INTERCEPT_PRLIMIT64; 1674 MSAN_INTERCEPT_UNAME; 1675 INTERCEPT_FUNCTION(gethostname); 1676 MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; 1677 MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; 1678 INTERCEPT_FUNCTION(dladdr); 1679 INTERCEPT_FUNCTION(dlerror); 1680 INTERCEPT_FUNCTION(dl_iterate_phdr); 1681 INTERCEPT_FUNCTION(getrusage); 1682#if defined(__mips__) 1683 INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2"); 1684#else 1685 INTERCEPT_FUNCTION(pthread_create); 1686#endif 1687 INTERCEPT_FUNCTION(pthread_key_create); 1688 1689#if SANITIZER_NETBSD 1690 INTERCEPT_FUNCTION(__libc_thr_keycreate); 1691#endif 1692 1693 INTERCEPT_FUNCTION(pthread_join); 1694 INTERCEPT_FUNCTION(tzset); 1695 INTERCEPT_FUNCTION(atexit); 1696 INTERCEPT_FUNCTION(__cxa_atexit); 1697 INTERCEPT_FUNCTION(shmat); 1698 INTERCEPT_FUNCTION(fork); 1699 MSAN_MAYBE_INTERCEPT_OPENPTY; 1700 MSAN_MAYBE_INTERCEPT_FORKPTY; 1701 1702 inited = 1; 1703} 1704} // namespace __msan 1705