diff options
Diffstat (limited to 'gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp')
-rw-r--r-- | gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp | 273 |
1 files changed, 170 insertions, 103 deletions
diff --git a/gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp b/gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp index 760f74e927d..058c10a1942 100644 --- a/gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp +++ b/gnu/llvm/compiler-rt/lib/msan/msan_interceptors.cpp @@ -18,21 +18,22 @@ #include "msan.h" #include "msan_chained_origin_depot.h" #include "msan_origin.h" +#include "msan_poisoning.h" #include "msan_report.h" #include "msan_thread.h" -#include "msan_poisoning.h" -#include "sanitizer_common/sanitizer_errno_codes.h" -#include "sanitizer_common/sanitizer_platform_limits_posix.h" -#include "sanitizer_common/sanitizer_platform_limits_netbsd.h" #include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_allocator_dlsym.h" #include "sanitizer_common/sanitizer_allocator_interface.h" -#include "sanitizer_common/sanitizer_allocator_internal.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_errno.h" -#include "sanitizer_common/sanitizer_stackdepot.h" +#include "sanitizer_common/sanitizer_errno_codes.h" +#include "sanitizer_common/sanitizer_glibc_version.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_linux.h" +#include "sanitizer_common/sanitizer_platform_limits_netbsd.h" +#include "sanitizer_common/sanitizer_platform_limits_posix.h" +#include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_tls_get_addr.h" #include "sanitizer_common/sanitizer_vector.h" @@ -74,22 +75,9 @@ bool IsInInterceptorScope() { return in_interceptor_scope; } -static uptr allocated_for_dlsym; -static const uptr kDlsymAllocPoolSize = 1024; -static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize]; - -static bool IsInDlsymAllocPool(const void *ptr) { - uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym; - return off < sizeof(alloc_memory_for_dlsym); -} - -static void *AllocateFromLocalPool(uptr size_in_bytes) { - uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize; - void *mem = (void *)&alloc_memory_for_dlsym[allocated_for_dlsym]; - allocated_for_dlsym += size_in_words; - CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize); - return mem; -} +struct DlsymAlloc : public DlSymAllocator<DlsymAlloc> { + static bool UseImpl() { return !msan_inited; } +}; #define ENSURE_MSAN_INITED() do { \ CHECK(!msan_init_is_running); \ @@ -102,7 +90,8 @@ static void *AllocateFromLocalPool(uptr size_in_bytes) { #define CHECK_UNPOISONED_0(x, n) \ do { \ sptr __offset = __msan_test_shadow(x, n); \ - if (__msan::IsInSymbolizer()) break; \ + if (__msan::IsInSymbolizerOrUnwider()) \ + break; \ if (__offset >= 0 && __msan::flags()->report_umrs) { \ GET_CALLER_PC_BP_SP; \ (void)sp; \ @@ -220,18 +209,24 @@ INTERCEPTOR(void *, pvalloc, SIZE_T size) { #endif INTERCEPTOR(void, free, void *ptr) { + if (UNLIKELY(!ptr)) + return; + if (DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Free(ptr); GET_MALLOC_STACK_TRACE; - if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; MsanDeallocate(&stack, ptr); } #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD INTERCEPTOR(void, cfree, void *ptr) { + if (UNLIKELY(!ptr)) + return; + if (DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Free(ptr); GET_MALLOC_STACK_TRACE; - if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return; MsanDeallocate(&stack, ptr); } -#define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree) +# define MSAN_MAYBE_INTERCEPT_CFREE INTERCEPT_FUNCTION(cfree) #else #define MSAN_MAYBE_INTERCEPT_CFREE #endif @@ -286,7 +281,7 @@ INTERCEPTOR(void, malloc_stats, void) { INTERCEPTOR(char *, strcpy, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T n = REAL(strlen)(src); + SIZE_T n = internal_strlen(src); CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(strcpy)(dest, src); CopyShadowAndOrigin(dest, src, n + 1, &stack); @@ -296,7 +291,7 @@ INTERCEPTOR(char *, strcpy, char *dest, const char *src) { INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T copy_size = REAL(strnlen)(src, n); + SIZE_T copy_size = internal_strnlen(src, n); if (copy_size < n) copy_size++; // trailing \0 char *res = REAL(strncpy)(dest, src, n); @@ -309,15 +304,27 @@ INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T n = REAL(strlen)(src); + SIZE_T n = internal_strlen(src); CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(stpcpy)(dest, src); CopyShadowAndOrigin(dest, src, n + 1, &stack); return res; } -#define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy) + +INTERCEPTOR(char *, stpncpy, char *dest, const char *src, SIZE_T n) { + ENSURE_MSAN_INITED(); + GET_STORE_STACK_TRACE; + SIZE_T copy_size = Min(n, internal_strnlen(src, n) + 1); + char *res = REAL(stpncpy)(dest, src, n); + CopyShadowAndOrigin(dest, src, copy_size, &stack); + __msan_unpoison(dest + copy_size, n - copy_size); + return res; +} +# define MSAN_MAYBE_INTERCEPT_STPCPY INTERCEPT_FUNCTION(stpcpy) +# define MSAN_MAYBE_INTERCEPT_STPNCPY INTERCEPT_FUNCTION(stpncpy) #else #define MSAN_MAYBE_INTERCEPT_STPCPY +# define MSAN_MAYBE_INTERCEPT_STPNCPY #endif INTERCEPTOR(char *, strdup, char *src) { @@ -325,7 +332,7 @@ INTERCEPTOR(char *, strdup, char *src) { GET_STORE_STACK_TRACE; // On FreeBSD strdup() leverages strlen(). InterceptorScope interceptor_scope; - SIZE_T n = REAL(strlen)(src); + SIZE_T n = internal_strlen(src); CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(strdup)(src); CopyShadowAndOrigin(res, src, n + 1, &stack); @@ -336,7 +343,7 @@ INTERCEPTOR(char *, strdup, char *src) { INTERCEPTOR(char *, __strdup, char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T n = REAL(strlen)(src); + SIZE_T n = internal_strlen(src); CHECK_UNPOISONED_STRING(src + n, 0); char *res = REAL(__strdup)(src); CopyShadowAndOrigin(res, src, n + 1, &stack); @@ -351,7 +358,7 @@ INTERCEPTOR(char *, __strdup, char *src) { INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { ENSURE_MSAN_INITED(); char *res = REAL(gcvt)(number, ndigit, buf); - SIZE_T n = REAL(strlen)(buf); + SIZE_T n = internal_strlen(buf); __msan_unpoison(buf, n + 1); return res; } @@ -363,8 +370,8 @@ INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { INTERCEPTOR(char *, strcat, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T src_size = REAL(strlen)(src); - SIZE_T dest_size = REAL(strlen)(dest); + SIZE_T src_size = internal_strlen(src); + SIZE_T dest_size = internal_strlen(dest); CHECK_UNPOISONED_STRING(src + src_size, 0); CHECK_UNPOISONED_STRING(dest + dest_size, 0); char *res = REAL(strcat)(dest, src); @@ -375,8 +382,8 @@ INTERCEPTOR(char *, strcat, char *dest, const char *src) { INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T dest_size = REAL(strlen)(dest); - SIZE_T copy_size = REAL(strnlen)(src, n); + SIZE_T dest_size = internal_strlen(dest); + SIZE_T copy_size = internal_strnlen(src, n); CHECK_UNPOISONED_STRING(dest + dest_size, 0); char *res = REAL(strncat)(dest, src, n); CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack); @@ -612,7 +619,8 @@ INTERCEPTOR(char *, fcvt, double x, int a, int *b, int *c) { char *res = REAL(fcvt)(x, a, b, c); __msan_unpoison(b, sizeof(*b)); __msan_unpoison(c, sizeof(*c)); - if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); + if (res) + __msan_unpoison(res, internal_strlen(res) + 1); return res; } #define MSAN_MAYBE_INTERCEPT_FCVT INTERCEPT_FUNCTION(fcvt) @@ -625,7 +633,8 @@ INTERCEPTOR(char *, getenv, char *name) { return REAL(getenv)(name); ENSURE_MSAN_INITED(); char *res = REAL(getenv)(name); - if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); + if (res) + __msan_unpoison(res, internal_strlen(res) + 1); return res; } @@ -635,7 +644,7 @@ static void UnpoisonEnviron() { char **envp = environ; for (; *envp; ++envp) { __msan_unpoison(envp, sizeof(*envp)); - __msan_unpoison(*envp, REAL(strlen)(*envp) + 1); + __msan_unpoison(*envp, internal_strlen(*envp) + 1); } // Trailing NULL pointer. __msan_unpoison(envp, sizeof(*envp)); @@ -656,7 +665,8 @@ INTERCEPTOR(int, putenv, char *string) { return res; } -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#define SANITIZER_STAT_LINUX (SANITIZER_LINUX && __GLIBC_PREREQ(2, 33)) +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX INTERCEPTOR(int, fstat, int fd, void *buf) { ENSURE_MSAN_INITED(); int res = REAL(fstat)(fd, buf); @@ -664,12 +674,25 @@ INTERCEPTOR(int, fstat, int fd, void *buf) { __msan_unpoison(buf, __sanitizer::struct_stat_sz); return res; } -#define MSAN_MAYBE_INTERCEPT_FSTAT INTERCEPT_FUNCTION(fstat) +# define MSAN_MAYBE_INTERCEPT_FSTAT MSAN_INTERCEPT_FUNC(fstat) #else #define MSAN_MAYBE_INTERCEPT_FSTAT #endif -#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD +#if SANITIZER_STAT_LINUX +INTERCEPTOR(int, fstat64, int fd, void *buf) { + ENSURE_MSAN_INITED(); + int res = REAL(fstat64)(fd, buf); + if (!res) + __msan_unpoison(buf, __sanitizer::struct_stat64_sz); + return res; +} +# define MSAN_MAYBE_INTERCEPT_FSTAT64 MSAN_INTERCEPT_FUNC(fstat64) +#else +# define MSAN_MAYBE_INTERCEPT_FSTAT64 +#endif + +#if SANITIZER_GLIBC INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { ENSURE_MSAN_INITED(); int res = REAL(__fxstat)(magic, fd, buf); @@ -677,12 +700,12 @@ INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) { __msan_unpoison(buf, __sanitizer::struct_stat_sz); return res; } -#define MSAN_MAYBE_INTERCEPT___FXSTAT INTERCEPT_FUNCTION(__fxstat) +# define MSAN_MAYBE_INTERCEPT___FXSTAT MSAN_INTERCEPT_FUNC(__fxstat) #else #define MSAN_MAYBE_INTERCEPT___FXSTAT #endif -#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD +#if SANITIZER_GLIBC INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) { ENSURE_MSAN_INITED(); int res = REAL(__fxstat64)(magic, fd, buf); @@ -690,20 +713,37 @@ INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) { __msan_unpoison(buf, __sanitizer::struct_stat64_sz); return res; } -#define MSAN_MAYBE_INTERCEPT___FXSTAT64 INTERCEPT_FUNCTION(__fxstat64) +# define MSAN_MAYBE_INTERCEPT___FXSTAT64 MSAN_INTERCEPT_FUNC(__fxstat64) #else -#define MSAN_MAYBE_INTERCEPT___FXSTAT64 +# define MSAN_MAYBE_INTERCEPT___FXSTAT64 #endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_STAT_LINUX INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) { ENSURE_MSAN_INITED(); int res = REAL(fstatat)(fd, pathname, buf, flags); if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); return res; } -# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(fstatat) +# define MSAN_MAYBE_INTERCEPT_FSTATAT MSAN_INTERCEPT_FUNC(fstatat) #else +# define MSAN_MAYBE_INTERCEPT_FSTATAT +#endif + +#if SANITIZER_STAT_LINUX +INTERCEPTOR(int, fstatat64, int fd, char *pathname, void *buf, int flags) { + ENSURE_MSAN_INITED(); + int res = REAL(fstatat64)(fd, pathname, buf, flags); + if (!res) + __msan_unpoison(buf, __sanitizer::struct_stat64_sz); + return res; +} +# define MSAN_MAYBE_INTERCEPT_FSTATAT64 MSAN_INTERCEPT_FUNC(fstatat64) +#else +# define MSAN_MAYBE_INTERCEPT_FSTATAT64 +#endif + +#if SANITIZER_GLIBC INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, int flags) { ENSURE_MSAN_INITED(); @@ -711,10 +751,12 @@ INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf, if (!res) __msan_unpoison(buf, __sanitizer::struct_stat_sz); return res; } -# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat) +# define MSAN_MAYBE_INTERCEPT___FXSTATAT MSAN_INTERCEPT_FUNC(__fxstatat) +#else +# define MSAN_MAYBE_INTERCEPT___FXSTATAT #endif -#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD +#if SANITIZER_GLIBC INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf, int flags) { ENSURE_MSAN_INITED(); @@ -722,9 +764,9 @@ INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf, if (!res) __msan_unpoison(buf, __sanitizer::struct_stat64_sz); return res; } -#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 INTERCEPT_FUNCTION(__fxstatat64) +# define MSAN_MAYBE_INTERCEPT___FXSTATAT64 MSAN_INTERCEPT_FUNC(__fxstatat64) #else -#define MSAN_MAYBE_INTERCEPT___FXSTATAT64 +# define MSAN_MAYBE_INTERCEPT___FXSTATAT64 #endif INTERCEPTOR(int, pipe, int pipefd[2]) { @@ -758,7 +800,7 @@ INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) { ENSURE_MSAN_INITED(); char *res = REAL(fgets_unlocked)(s, size, stream); if (res) - __msan_unpoison(s, REAL(strlen)(s) + 1); + __msan_unpoison(s, internal_strlen(s) + 1); return res; } #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED INTERCEPT_FUNCTION(fgets_unlocked) @@ -829,7 +871,7 @@ INTERCEPTOR(int, gethostname, char *name, SIZE_T len) { ENSURE_MSAN_INITED(); int res = REAL(gethostname)(name, len); if (!res || (res == -1 && errno == errno_ENAMETOOLONG)) { - SIZE_T real_len = REAL(strnlen)(name, len); + SIZE_T real_len = internal_strnlen(name, len); if (real_len < len) ++real_len; __msan_unpoison(name, real_len); @@ -869,27 +911,15 @@ INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents, INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) { GET_MALLOC_STACK_TRACE; - if (UNLIKELY(!msan_inited)) - // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. - return AllocateFromLocalPool(nmemb * size); + if (DlsymAlloc::Use()) + return DlsymAlloc::Callocate(nmemb, size); return msan_calloc(nmemb, size, &stack); } INTERCEPTOR(void *, realloc, void *ptr, SIZE_T size) { + if (DlsymAlloc::Use() || DlsymAlloc::PointerIsMine(ptr)) + return DlsymAlloc::Realloc(ptr, size); GET_MALLOC_STACK_TRACE; - if (UNLIKELY(IsInDlsymAllocPool(ptr))) { - uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; - uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); - void *new_ptr; - if (UNLIKELY(!msan_inited)) { - new_ptr = AllocateFromLocalPool(copy_size); - } else { - copy_size = size; - new_ptr = msan_malloc(copy_size, &stack); - } - internal_memcpy(new_ptr, ptr, copy_size); - return new_ptr; - } return msan_realloc(ptr, size, &stack); } @@ -899,16 +929,15 @@ INTERCEPTOR(void *, reallocarray, void *ptr, SIZE_T nmemb, SIZE_T size) { } INTERCEPTOR(void *, malloc, SIZE_T size) { + if (DlsymAlloc::Use()) + return DlsymAlloc::Allocate(size); GET_MALLOC_STACK_TRACE; - if (UNLIKELY(!msan_inited)) - // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. - return AllocateFromLocalPool(size); return msan_malloc(size, &stack); } void __msan_allocated_memory(const void *data, uptr size) { - GET_MALLOC_STACK_TRACE; if (flags()->poison_in_malloc) { + GET_MALLOC_STACK_TRACE; stack.tag = STACK_TRACE_TAG_POISON; PoisonMemory(data, size, &stack); } @@ -920,13 +949,29 @@ void __msan_copy_shadow(void *dest, const void *src, uptr n) { } void __sanitizer_dtor_callback(const void *data, uptr size) { - GET_MALLOC_STACK_TRACE; if (flags()->poison_in_dtor) { + GET_MALLOC_STACK_TRACE; stack.tag = STACK_TRACE_TAG_POISON; PoisonMemory(data, size, &stack); } } +void __sanitizer_dtor_callback_fields(const void *data, uptr size) { + if (flags()->poison_in_dtor) { + GET_MALLOC_STACK_TRACE; + stack.tag = STACK_TRACE_TAG_FIELDS; + PoisonMemory(data, size, &stack); + } +} + +void __sanitizer_dtor_callback_vptr(const void *data) { + if (flags()->poison_in_dtor) { + GET_MALLOC_STACK_TRACE; + stack.tag = STACK_TRACE_TAG_VPTR; + PoisonMemory(data, sizeof(void *), &stack); + } +} + template <class Mmap> static void *mmap_interceptor(Mmap real_mmap, void *addr, SIZE_T length, int prot, int flags, int fd, OFF64_T offset) { @@ -1000,12 +1045,13 @@ static void SignalAction(int signo, void *si, void *uc) { ScopedThreadLocalStateBackup stlsb; UnpoisonParam(3); __msan_unpoison(si, sizeof(__sanitizer_sigaction)); - __msan_unpoison(uc, __sanitizer::ucontext_t_sz); + __msan_unpoison(uc, ucontext_t_sz(uc)); typedef void (*sigaction_cb)(int, void *, void *); sigaction_cb cb = (sigaction_cb)atomic_load(&sigactions[signo], memory_order_relaxed); cb(signo, si, uc); + CHECK_UNPOISONED(uc, ucontext_t_sz(uc)); } static void read_sigaction(const __sanitizer_sigaction *act) { @@ -1023,6 +1069,8 @@ extern "C" int pthread_attr_destroy(void *attr); static void *MsanThreadStartFunc(void *arg) { MsanThread *t = (MsanThread *)arg; SetCurrentThread(t); + t->Init(); + SetSigProcMask(&t->starting_sigset_, nullptr); return t->ThreadStart(); } @@ -1038,7 +1086,7 @@ INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), AdjustStackSize(attr); MsanThread *t = MsanThread::Create(callback, param); - + ScopedBlockSignals block(&t->starting_sigset_); int res = REAL(pthread_create)(th, attr, MsanThreadStartFunc, t); if (attr == &myattr) @@ -1073,6 +1121,8 @@ INTERCEPTOR(int, pthread_join, void *th, void **retval) { return res; } +DEFINE_REAL_PTHREAD_FUNCTIONS + extern char *tzname[2]; INTERCEPTOR(void, tzset, int fake) { @@ -1080,9 +1130,9 @@ INTERCEPTOR(void, tzset, int fake) { InterceptorScope interceptor_scope; REAL(tzset)(fake); if (tzname[0]) - __msan_unpoison(tzname[0], REAL(strlen)(tzname[0]) + 1); + __msan_unpoison(tzname[0], internal_strlen(tzname[0]) + 1); if (tzname[1]) - __msan_unpoison(tzname[1], REAL(strlen)(tzname[1]) + 1); + __msan_unpoison(tzname[1], internal_strlen(tzname[1]) + 1); return; } @@ -1092,7 +1142,7 @@ struct MSanAtExitRecord { }; struct InterceptorContext { - BlockingMutex atexit_mu; + Mutex atexit_mu; Vector<struct MSanAtExitRecord *> AtExitStack; InterceptorContext() @@ -1108,7 +1158,7 @@ InterceptorContext *interceptor_ctx() { void MSanAtExitWrapper() { MSanAtExitRecord *r; { - BlockingMutexLock l(&interceptor_ctx()->atexit_mu); + Lock l(&interceptor_ctx()->atexit_mu); uptr element = interceptor_ctx()->AtExitStack.Size() - 1; r = interceptor_ctx()->AtExitStack[element]; @@ -1142,7 +1192,7 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, // Unpoison argument shadow for C++ module destructors. INTERCEPTOR(int, atexit, void (*func)()) { - // Avoid calling real atexit as it is unrechable on at least on Linux. + // Avoid calling real atexit as it is unreachable on at least on Linux. if (msan_init_is_running) return REAL(__cxa_atexit)((void (*)(void *a))func, 0, 0); return setup_at_exit_wrapper((void(*)())func, 0, 0); @@ -1159,7 +1209,7 @@ static int setup_at_exit_wrapper(void(*f)(), void *arg, void *dso) { // NetBSD does not preserve the 2nd argument if dso is equal to 0 // Store ctx in a local stack-like structure - BlockingMutexLock l(&interceptor_ctx()->atexit_mu); + Lock l(&interceptor_ctx()->atexit_mu); res = REAL(__cxa_atexit)((void (*)(void *a))MSanAtExitWrapper, 0, 0); if (!res) { @@ -1256,13 +1306,13 @@ int OnExit() { do { \ if (!INTERCEPT_FUNCTION_VER(name, ver)) \ VReport(1, "MemorySanitizer: failed to intercept '%s@@%s'\n", #name, \ - #ver); \ + ver); \ } while (0) #define MSAN_INTERCEPT_FUNC_VER_UNVERSIONED_FALLBACK(name, ver) \ do { \ if (!INTERCEPT_FUNCTION_VER(name, ver) && !INTERCEPT_FUNCTION(name)) \ VReport(1, "MemorySanitizer: failed to intercept '%s@@%s' or '%s'\n", \ - #name, #ver, #name); \ + #name, ver, #name); \ } while (0) #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name) @@ -1278,14 +1328,15 @@ int OnExit() { CHECK_UNPOISONED_CTX(ctx, ptr, size) #define COMMON_INTERCEPTOR_INITIALIZE_RANGE(ptr, size) \ __msan_unpoison(ptr, size) -#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ - if (msan_init_is_running) return REAL(func)(__VA_ARGS__); \ - ENSURE_MSAN_INITED(); \ - MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \ - ctx = (void *)&msan_ctx; \ - (void)ctx; \ - InterceptorScope interceptor_scope; \ - __msan_unpoison(__errno_location(), sizeof(int)); /* NOLINT */ +#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ + if (msan_init_is_running) \ + return REAL(func)(__VA_ARGS__); \ + ENSURE_MSAN_INITED(); \ + MSanInterceptorContext msan_ctx = {IsInInterceptorScope()}; \ + ctx = (void *)&msan_ctx; \ + (void)ctx; \ + InterceptorScope interceptor_scope; \ + __msan_unpoison(__errno_location(), sizeof(int)); #define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \ do { \ } while (false) @@ -1440,6 +1491,15 @@ static uptr signal_impl(int signo, uptr cb) { #include "sanitizer_common/sanitizer_common_syscalls.inc" #include "sanitizer_common/sanitizer_syscalls_netbsd.inc" +INTERCEPTOR(const char *, strsignal, int sig) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsignal, sig); + const char *res = REAL(strsignal)(sig); + if (res) + __msan_unpoison(res, internal_strlen(res) + 1); + return res; +} + struct dlinfo { char *dli_fname; void *dli_fbase; @@ -1454,9 +1514,9 @@ INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { if (res != 0) { __msan_unpoison(info, sizeof(*info)); if (info->dli_fname) - __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1); + __msan_unpoison(info->dli_fname, internal_strlen(info->dli_fname) + 1); if (info->dli_sname) - __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1); + __msan_unpoison(info->dli_sname, internal_strlen(info->dli_sname) + 1); } return res; } @@ -1465,7 +1525,8 @@ INTERCEPTOR(char *, dlerror, int fake) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, dlerror, fake); char *res = REAL(dlerror)(fake); - if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); + if (res) + __msan_unpoison(res, internal_strlen(res) + 1); return res; } @@ -1483,7 +1544,7 @@ static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, if (info->dlpi_phdr && info->dlpi_phnum) __msan_unpoison(info->dlpi_phdr, struct_ElfW_Phdr_sz * info->dlpi_phnum); if (info->dlpi_name) - __msan_unpoison(info->dlpi_name, REAL(strlen)(info->dlpi_name) + 1); + __msan_unpoison(info->dlpi_name, internal_strlen(info->dlpi_name) + 1); } dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; UnpoisonParam(3); @@ -1525,7 +1586,7 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; wchar_t *res = REAL(wcscpy)(dest, src); - CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (REAL(wcslen)(src) + 1), + CopyShadowAndOrigin(dest, src, sizeof(wchar_t) * (internal_wcslen(src) + 1), &stack); return res; } @@ -1533,7 +1594,7 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) { INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; - SIZE_T copy_size = REAL(wcsnlen)(src, n); + SIZE_T copy_size = internal_wcsnlen(src, n); if (copy_size < n) copy_size++; // trailing \0 wchar_t *res = REAL(wcsncpy)(dest, src, n); CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack); @@ -1567,7 +1628,7 @@ void __msan_clear_and_unpoison(void *a, uptr size) { void *__msan_memcpy(void *dest, const void *src, SIZE_T n) { if (!msan_inited) return internal_memcpy(dest, src, n); - if (msan_init_is_running || __msan::IsInSymbolizer()) + if (msan_init_is_running || __msan::IsInSymbolizerOrUnwider()) return REAL(memcpy)(dest, src, n); ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; @@ -1597,7 +1658,7 @@ void *__msan_memmove(void *dest, const void *src, SIZE_T n) { void __msan_unpoison_string(const char* s) { if (!MEM_IS_APP(s)) return; - __msan_unpoison(s, REAL(strlen)(s) + 1); + __msan_unpoison(s, internal_strlen(s) + 1); } namespace __msan { @@ -1637,6 +1698,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(wmemmove); INTERCEPT_FUNCTION(strcpy); MSAN_MAYBE_INTERCEPT_STPCPY; + MSAN_MAYBE_INTERCEPT_STPNCPY; INTERCEPT_FUNCTION(strdup); MSAN_MAYBE_INTERCEPT___STRDUP; INTERCEPT_FUNCTION(strncpy); @@ -1685,8 +1747,11 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(gettimeofday); MSAN_MAYBE_INTERCEPT_FCVT; MSAN_MAYBE_INTERCEPT_FSTAT; + MSAN_MAYBE_INTERCEPT_FSTAT64; MSAN_MAYBE_INTERCEPT___FXSTAT; - MSAN_INTERCEPT_FSTATAT; + MSAN_MAYBE_INTERCEPT_FSTATAT; + MSAN_MAYBE_INTERCEPT_FSTATAT64; + MSAN_MAYBE_INTERCEPT___FXSTATAT; MSAN_MAYBE_INTERCEPT___FXSTAT64; MSAN_MAYBE_INTERCEPT___FXSTATAT64; INTERCEPT_FUNCTION(pipe); @@ -1701,6 +1766,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(gethostname); MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; + INTERCEPT_FUNCTION(strsignal); INTERCEPT_FUNCTION(dladdr); INTERCEPT_FUNCTION(dlerror); INTERCEPT_FUNCTION(dl_iterate_phdr); @@ -1710,6 +1776,7 @@ void InitializeInterceptors() { #else INTERCEPT_FUNCTION(pthread_create); #endif + INTERCEPT_FUNCTION(pthread_join); INTERCEPT_FUNCTION(pthread_key_create); #if SANITIZER_NETBSD |