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