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