diff options
author | Marcin Koscielnicki <koriakin@0x04.net> | 2016-04-25 22:25:49 +0000 |
---|---|---|
committer | Marcin Koscielnicki <koriakin@0x04.net> | 2016-04-25 22:25:49 +0000 |
commit | 499e62c45ec2c67ecdc5440aa45cadc0402e93f1 (patch) | |
tree | 1b5165bc60b73c038c447f4ab1ea109d716a599b /lib/msan/msan_interceptors.cc | |
parent | bbe3712e298cd62b38de49be24cb715aa3a114a1 (diff) |
[MSan] Use COMMON_INTERCEPTOR_ENTER in libdl interceptors.
This fixes fails in test/msan/dlerror.cc - when real dlerror calls strcmp,
our strcmp interceptor now skips poison checking, since it's called in
interceptor context. Strictly speaking, only the dlerror change is
necessary to fix the fail, but let's also change the other two just in case.
Differential Revision: http://reviews.llvm.org/D19499
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@267486 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/msan/msan_interceptors.cc')
-rw-r--r-- | lib/msan/msan_interceptors.cc | 117 |
1 files changed, 60 insertions, 57 deletions
diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cc index 6602cf8f0..8c90aef88 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cc @@ -1052,63 +1052,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); @@ -1453,6 +1396,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) { |