diff options
Diffstat (limited to 'lib/msan/msan_interceptors.cc')
-rw-r--r-- | lib/msan/msan_interceptors.cc | 288 |
1 files changed, 118 insertions, 170 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 0db2ac5b226c..f23d3eeb3eda 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -43,6 +43,9 @@ using __sanitizer::atomic_load; using __sanitizer::atomic_store; using __sanitizer::atomic_uintptr_t; +DECLARE_REAL(SIZE_T, strlen, const char *s) +DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen) + #if SANITIZER_FREEBSD #define __errno_location __error #endif @@ -195,7 +198,7 @@ INTERCEPTOR(void *, __libc_memalign, SIZE_T boundary, SIZE_T size) { GET_MALLOC_STACK_TRACE; CHECK_EQ(boundary & (boundary - 1), 0); void *ptr = MsanReallocate(&stack, nullptr, size, boundary, false); - DTLS_on_libc_memalign(ptr, size * boundary); + DTLS_on_libc_memalign(ptr, size); return ptr; } @@ -280,23 +283,6 @@ INTERCEPTOR(void, malloc_stats, void) { #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS #endif -INTERCEPTOR(SIZE_T, strlen, const char *s) { - if (msan_init_is_running) - return REAL(strlen)(s); - ENSURE_MSAN_INITED(); - SIZE_T res = REAL(strlen)(s); - CHECK_UNPOISONED(s, res + 1); - return res; -} - -INTERCEPTOR(SIZE_T, strnlen, const char *s, SIZE_T n) { - ENSURE_MSAN_INITED(); - SIZE_T res = REAL(strnlen)(s, n); - SIZE_T scan_size = (res == n) ? res : res + 1; - CHECK_UNPOISONED(s, scan_size); - return res; -} - INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; @@ -756,65 +742,6 @@ INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf, #define MSAN_MAYBE_INTERCEPT___FXSTATAT64 #endif -#if SANITIZER_FREEBSD -INTERCEPTOR(int, stat, char *path, void *buf) { - ENSURE_MSAN_INITED(); - int res = REAL(stat)(path, buf); - if (!res) - __msan_unpoison(buf, __sanitizer::struct_stat_sz); - return res; -} -# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(stat) -#else -INTERCEPTOR(int, __xstat, int magic, char *path, void *buf) { - ENSURE_MSAN_INITED(); - int res = REAL(__xstat)(magic, path, buf); - if (!res) - __msan_unpoison(buf, __sanitizer::struct_stat_sz); - return res; -} -# define MSAN_INTERCEPT_STAT INTERCEPT_FUNCTION(__xstat) -#endif - -#if !SANITIZER_FREEBSD -INTERCEPTOR(int, __xstat64, int magic, char *path, void *buf) { - ENSURE_MSAN_INITED(); - int res = REAL(__xstat64)(magic, path, buf); - if (!res) - __msan_unpoison(buf, __sanitizer::struct_stat64_sz); - return res; -} -#define MSAN_MAYBE_INTERCEPT___XSTAT64 INTERCEPT_FUNCTION(__xstat64) -#else -#define MSAN_MAYBE_INTERCEPT___XSTAT64 -#endif - -#if !SANITIZER_FREEBSD -INTERCEPTOR(int, __lxstat, int magic, char *path, void *buf) { - ENSURE_MSAN_INITED(); - int res = REAL(__lxstat)(magic, path, buf); - if (!res) - __msan_unpoison(buf, __sanitizer::struct_stat_sz); - return res; -} -#define MSAN_MAYBE_INTERCEPT___LXSTAT INTERCEPT_FUNCTION(__lxstat) -#else -#define MSAN_MAYBE_INTERCEPT___LXSTAT -#endif - -#if !SANITIZER_FREEBSD -INTERCEPTOR(int, __lxstat64, int magic, char *path, void *buf) { - ENSURE_MSAN_INITED(); - int res = REAL(__lxstat64)(magic, path, buf); - if (!res) - __msan_unpoison(buf, __sanitizer::struct_stat64_sz); - return res; -} -#define MSAN_MAYBE_INTERCEPT___LXSTAT64 INTERCEPT_FUNCTION(__lxstat64) -#else -#define MSAN_MAYBE_INTERCEPT___LXSTAT64 -#endif - INTERCEPTOR(int, pipe, int pipefd[2]) { if (msan_init_is_running) return REAL(pipe)(pipefd); @@ -874,17 +801,42 @@ INTERCEPTOR(int, getrlimit, int resource, void *rlim) { #if !SANITIZER_FREEBSD INTERCEPTOR(int, getrlimit64, int resource, void *rlim) { - if (msan_init_is_running) - return REAL(getrlimit64)(resource, rlim); + if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim); ENSURE_MSAN_INITED(); int res = REAL(getrlimit64)(resource, rlim); - if (!res) - __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz); + if (!res) __msan_unpoison(rlim, __sanitizer::struct_rlimit64_sz); return res; } + +INTERCEPTOR(int, prlimit, int pid, int resource, void *new_rlimit, + void *old_rlimit) { + if (msan_init_is_running) + return REAL(prlimit)(pid, resource, new_rlimit, old_rlimit); + ENSURE_MSAN_INITED(); + CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit_sz); + int res = REAL(prlimit)(pid, resource, new_rlimit, old_rlimit); + if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit_sz); + return res; +} + +INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit, + void *old_rlimit) { + if (msan_init_is_running) + return REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit); + ENSURE_MSAN_INITED(); + CHECK_UNPOISONED(new_rlimit, __sanitizer::struct_rlimit64_sz); + int res = REAL(prlimit64)(pid, resource, new_rlimit, old_rlimit); + if (!res) __msan_unpoison(old_rlimit, __sanitizer::struct_rlimit64_sz); + return res; +} + #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64) +#define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit) +#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64) #else #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 +#define MSAN_MAYBE_INTERCEPT_PRLIMIT +#define MSAN_MAYBE_INTERCEPT_PRLIMIT64 #endif #if SANITIZER_FREEBSD @@ -953,30 +905,6 @@ INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents, #define MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT #endif -INTERCEPTOR(SSIZE_T, recv, int fd, void *buf, SIZE_T len, int flags) { - ENSURE_MSAN_INITED(); - SSIZE_T res = REAL(recv)(fd, buf, len, flags); - if (res > 0) - __msan_unpoison(buf, res); - return res; -} - -INTERCEPTOR(SSIZE_T, recvfrom, int fd, void *buf, SIZE_T len, int flags, - void *srcaddr, int *addrlen) { - ENSURE_MSAN_INITED(); - SIZE_T srcaddr_sz; - if (srcaddr) srcaddr_sz = *addrlen; - SSIZE_T res = REAL(recvfrom)(fd, buf, len, flags, srcaddr, addrlen); - if (res > 0) { - __msan_unpoison(buf, res); - if (srcaddr) { - SIZE_T sz = *addrlen; - __msan_unpoison(srcaddr, Min(sz, srcaddr_sz)); - } - } - return res; -} - INTERCEPTOR(void *, calloc, SIZE_T nmemb, SIZE_T size) { GET_MALLOC_STACK_TRACE; if (UNLIKELY(!msan_inited)) { @@ -1065,63 +993,6 @@ INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags, #define MSAN_MAYBE_INTERCEPT_MMAP64 #endif -struct dlinfo { - char *dli_fname; - void *dli_fbase; - char *dli_sname; - void *dli_saddr; -}; - -INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { - ENSURE_MSAN_INITED(); - int res = REAL(dladdr)(addr, info); - if (res != 0) { - __msan_unpoison(info, sizeof(*info)); - if (info->dli_fname) - __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1); - if (info->dli_sname) - __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1); - } - return res; -} - -INTERCEPTOR(char *, dlerror, int fake) { - ENSURE_MSAN_INITED(); - char *res = REAL(dlerror)(fake); - if (res) __msan_unpoison(res, REAL(strlen)(res) + 1); - return res; -} - -typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size, - void *data); -struct dl_iterate_phdr_data { - dl_iterate_phdr_cb callback; - void *data; -}; - -static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, - void *data) { - if (info) { - __msan_unpoison(info, 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); - } - dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; - UnpoisonParam(3); - return cbdata->callback(info, size, cbdata->data); -} - -INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { - ENSURE_MSAN_INITED(); - dl_iterate_phdr_data cbdata; - cbdata.callback = callback; - cbdata.data = data; - int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata); - return res; -} - INTERCEPTOR(int, getrusage, int who, void *usage) { ENSURE_MSAN_INITED(); int res = REAL(getrusage)(who, usage); @@ -1397,7 +1268,16 @@ int OnExit() { VReport(1, "MemorySanitizer: failed to intercept '" #name "'\n"); \ } while (0) +#define MSAN_INTERCEPT_FUNC_VER(name, ver) \ + do { \ + if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ + VReport( \ + 1, "MemorySanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ + } while (0) + #define COMMON_INTERCEPT_FUNCTION(name) MSAN_INTERCEPT_FUNC(name) +#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ + MSAN_INTERCEPT_FUNC_VER(name, ver) #define COMMON_INTERCEPTOR_UNPOISON_PARAM(count) \ UnpoisonParam(count) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ @@ -1449,6 +1329,11 @@ int OnExit() { *begin = *end = 0; \ } +#include "sanitizer_common/sanitizer_platform_interceptors.h" +// Msan needs custom handling of these: +#undef SANITIZER_INTERCEPT_MEMSET +#undef SANITIZER_INTERCEPT_MEMMOVE +#undef SANITIZER_INTERCEPT_MEMCPY #include "sanitizer_common/sanitizer_common_interceptors.inc" #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) CHECK_UNPOISONED(p, s) @@ -1461,6 +1346,66 @@ int OnExit() { #define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) __msan_unpoison(p, s) #include "sanitizer_common/sanitizer_common_syscalls.inc" +struct dlinfo { + char *dli_fname; + void *dli_fbase; + char *dli_sname; + void *dli_saddr; +}; + +INTERCEPTOR(int, dladdr, void *addr, dlinfo *info) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, dladdr, addr, info); + int res = REAL(dladdr)(addr, info); + if (res != 0) { + __msan_unpoison(info, sizeof(*info)); + if (info->dli_fname) + __msan_unpoison(info->dli_fname, REAL(strlen)(info->dli_fname) + 1); + if (info->dli_sname) + __msan_unpoison(info->dli_sname, REAL(strlen)(info->dli_sname) + 1); + } + return res; +} + +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); + return res; +} + +typedef int (*dl_iterate_phdr_cb)(__sanitizer_dl_phdr_info *info, SIZE_T size, + void *data); +struct dl_iterate_phdr_data { + dl_iterate_phdr_cb callback; + void *data; +}; + +static int msan_dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, + void *data) { + if (info) { + __msan_unpoison(info, 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); + } + dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; + UnpoisonParam(3); + return cbdata->callback(info, size, cbdata->data); +} + +INTERCEPTOR(int, dl_iterate_phdr, dl_iterate_phdr_cb callback, void *data) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, dl_iterate_phdr, callback, data); + dl_iterate_phdr_data cbdata; + cbdata.callback = callback; + cbdata.data = data; + int res = REAL(dl_iterate_phdr)(msan_dl_iterate_phdr_cb, (void *)&cbdata); + return res; +} + // These interface functions reside here so that they can use // REAL(memset), etc. void __msan_unpoison(const void *a, uptr size) { @@ -1561,8 +1506,6 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(strndup); MSAN_MAYBE_INTERCEPT___STRNDUP; INTERCEPT_FUNCTION(strncpy); // NOLINT - INTERCEPT_FUNCTION(strlen); - INTERCEPT_FUNCTION(strnlen); INTERCEPT_FUNCTION(gcvt); INTERCEPT_FUNCTION(strcat); // NOLINT INTERCEPT_FUNCTION(strncat); // NOLINT @@ -1580,8 +1523,13 @@ void InitializeInterceptors() { INTERCEPT_STRTO(wcstoul); INTERCEPT_STRTO(wcstoll); INTERCEPT_STRTO(wcstoull); +#ifdef SANITIZER_NLDBL_VERSION + INTERCEPT_FUNCTION_VER(vswprintf, SANITIZER_NLDBL_VERSION); + INTERCEPT_FUNCTION_VER(swprintf, SANITIZER_NLDBL_VERSION); +#else INTERCEPT_FUNCTION(vswprintf); INTERCEPT_FUNCTION(swprintf); +#endif INTERCEPT_FUNCTION(strxfrm); INTERCEPT_FUNCTION(strxfrm_l); INTERCEPT_FUNCTION(strftime); @@ -1603,12 +1551,8 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(fcvt); MSAN_MAYBE_INTERCEPT___FXSTAT; MSAN_INTERCEPT_FSTATAT; - MSAN_INTERCEPT_STAT; - MSAN_MAYBE_INTERCEPT___LXSTAT; MSAN_MAYBE_INTERCEPT___FXSTAT64; MSAN_MAYBE_INTERCEPT___FXSTATAT64; - MSAN_MAYBE_INTERCEPT___XSTAT64; - MSAN_MAYBE_INTERCEPT___LXSTAT64; INTERCEPT_FUNCTION(pipe); INTERCEPT_FUNCTION(pipe2); INTERCEPT_FUNCTION(socketpair); @@ -1616,19 +1560,23 @@ void InitializeInterceptors() { MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED; INTERCEPT_FUNCTION(getrlimit); MSAN_MAYBE_INTERCEPT_GETRLIMIT64; + MSAN_MAYBE_INTERCEPT_PRLIMIT; + MSAN_MAYBE_INTERCEPT_PRLIMIT64; MSAN_INTERCEPT_UNAME; INTERCEPT_FUNCTION(gethostname); MSAN_MAYBE_INTERCEPT_EPOLL_WAIT; MSAN_MAYBE_INTERCEPT_EPOLL_PWAIT; - INTERCEPT_FUNCTION(recv); - INTERCEPT_FUNCTION(recvfrom); INTERCEPT_FUNCTION(dladdr); INTERCEPT_FUNCTION(dlerror); INTERCEPT_FUNCTION(dl_iterate_phdr); INTERCEPT_FUNCTION(getrusage); INTERCEPT_FUNCTION(sigaction); INTERCEPT_FUNCTION(signal); +#if defined(__mips__) + INTERCEPT_FUNCTION_VER(pthread_create, "GLIBC_2.2"); +#else INTERCEPT_FUNCTION(pthread_create); +#endif INTERCEPT_FUNCTION(pthread_key_create); INTERCEPT_FUNCTION(pthread_join); INTERCEPT_FUNCTION(tzset); |