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