aboutsummaryrefslogtreecommitdiff
path: root/lib/msan/msan_interceptors.cc
diff options
context:
space:
mode:
Diffstat (limited to 'lib/msan/msan_interceptors.cc')
-rw-r--r--lib/msan/msan_interceptors.cc288
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);