From 4295db7bb52199d9ac995db629782e9bde51d313 Mon Sep 17 00:00:00 2001 From: Alexey Samsonov Date: Fri, 10 Jul 2015 00:03:54 +0000 Subject: [TSan] Fix dl_iterate_phdr callback for the case when info->dlpi_name is overwritten by user. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@241876 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/tsan/rtl/tsan_interceptors.cc | 12 ++++++++---- test/tsan/dl_iterate_phdr.cc | 2 ++ 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc index 7b5c50e2a..b1a7ae6de 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors.cc @@ -2153,6 +2153,10 @@ struct dl_iterate_phdr_data { void *data; }; +static bool IsAppNotRodata(uptr addr) { + return IsAppMem(addr) && *(u64*)MemToShadow(addr) != kShadowRodata; +} + static int dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, void *data) { dl_iterate_phdr_data *cbdata = (dl_iterate_phdr_data *)data; @@ -2161,13 +2165,13 @@ static int dl_iterate_phdr_cb(__sanitizer_dl_phdr_info *info, SIZE_T size, // inside of dynamic linker, so we "unpoison" it here in order to not // produce false reports. Ignoring malloc/free in dlopen/dlclose is not enough // because some libc functions call __libc_dlopen. - bool reset = info && IsAppMem((uptr)info->dlpi_name) && - *(u64*)MemToShadow((uptr)info->dlpi_name) != kShadowRodata; - if (reset) + if (info && IsAppNotRodata((uptr)info->dlpi_name)) MemoryResetRange(cbdata->thr, cbdata->pc, (uptr)info->dlpi_name, internal_strlen(info->dlpi_name)); int res = cbdata->cb(info, size, cbdata->data); - if (reset) + // Perform the check one more time in case info->dlpi_name was overwritten + // by user callback. + if (info && IsAppNotRodata((uptr)info->dlpi_name)) MemoryResetRange(cbdata->thr, cbdata->pc, (uptr)info->dlpi_name, internal_strlen(info->dlpi_name)); return res; diff --git a/test/tsan/dl_iterate_phdr.cc b/test/tsan/dl_iterate_phdr.cc index 6fb6a3e54..b230a920a 100644 --- a/test/tsan/dl_iterate_phdr.cc +++ b/test/tsan/dl_iterate_phdr.cc @@ -18,6 +18,8 @@ int exported_var = 0; #include static int callback(struct dl_phdr_info *info, size_t size, void *data) { + if (info->dlpi_name[0] == '\0') + info->dlpi_name = "/proc/self/exe"; return !strcmp(info->dlpi_name, "non existent module"); } -- cgit v1.2.1