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