From 7c6bf1cc9f0a084e7b29c74af4833fe5814b3a06 Mon Sep 17 00:00:00 2001 From: Francis Ricci Date: Mon, 17 Apr 2017 16:34:38 +0000 Subject: [PATCH] Don't read non-readable address ranges during lsan pointer scanning Summary: This specifically addresses the Mach-O zero page, which we cannot read from. Reviewers: kubamracek, samsonov, alekseyshl Subscribers: llvm-commits Differential Revision: https://reviews.llvm.org/D32044 llvm-svn: 300456 --- compiler-rt/lib/lsan/lsan_common_mac.cc | 2 +- compiler-rt/lib/sanitizer_common/sanitizer_common.cc | 5 +++-- compiler-rt/lib/sanitizer_common/sanitizer_common.h | 13 +++++++++---- compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc | 4 +++- .../lib/sanitizer_common/sanitizer_procmaps_common.cc | 3 ++- compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc | 3 ++- compiler-rt/lib/sanitizer_common/sanitizer_win.cc | 3 ++- 7 files changed, 22 insertions(+), 11 deletions(-) diff --git a/compiler-rt/lib/lsan/lsan_common_mac.cc b/compiler-rt/lib/lsan/lsan_common_mac.cc index d0ee181..dfb5ab4 100644 --- a/compiler-rt/lib/lsan/lsan_common_mac.cc +++ b/compiler-rt/lib/lsan/lsan_common_mac.cc @@ -108,7 +108,7 @@ void ProcessGlobalRegions(Frontier *frontier) { for (const __sanitizer::LoadedModule::AddressRange &range : modules[i].ranges()) { - if (range.executable) continue; + if (range.executable || !range.readable) continue; ScanGlobalRange(range.beg, range.end, frontier); } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc index 3ef366f..471c3de 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.cc @@ -284,9 +284,10 @@ void LoadedModule::clear() { } } -void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable) { +void LoadedModule::addAddressRange(uptr beg, uptr end, bool executable, + bool readable) { void *mem = InternalAlloc(sizeof(AddressRange)); - AddressRange *r = new(mem) AddressRange(beg, end, executable); + AddressRange *r = new(mem) AddressRange(beg, end, executable, readable); ranges_.push_back(r); if (executable && end > max_executable_address_) max_executable_address_ = end; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common.h b/compiler-rt/lib/sanitizer_common/sanitizer_common.h index 9d367ca..313f0cf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -717,7 +717,7 @@ class LoadedModule { void set(const char *module_name, uptr base_address, ModuleArch arch, u8 uuid[kModuleUUIDSize], bool instrumented); void clear(); - void addAddressRange(uptr beg, uptr end, bool executable); + void addAddressRange(uptr beg, uptr end, bool executable, bool readable); bool containsAddress(uptr address) const; const char *full_name() const { return full_name_; } @@ -732,9 +732,14 @@ class LoadedModule { uptr beg; uptr end; bool executable; - - AddressRange(uptr beg, uptr end, bool executable) - : next(nullptr), beg(beg), end(end), executable(executable) {} + bool readable; + + AddressRange(uptr beg, uptr end, bool executable, bool readable) + : next(nullptr), + beg(beg), + end(end), + executable(executable), + readable(readable) {} }; const IntrusiveList &ranges() const { return ranges_; } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc index 6fde671..25f1e12 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -447,7 +447,9 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; uptr cur_end = cur_beg + phdr->p_memsz; bool executable = phdr->p_flags & PF_X; - cur_module.addAddressRange(cur_beg, cur_end, executable); + bool readable = phdr->p_flags & PF_R; + cur_module.addAddressRange(cur_beg, cur_end, executable, + readable); } } data->modules->push_back(cur_module); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc index fac3fbd..67a6590 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cc @@ -141,7 +141,8 @@ void MemoryMappingLayout::DumpListOfModules( uptr base_address = (i ? cur_beg : 0) - cur_offset; LoadedModule cur_module; cur_module.set(cur_name, base_address); - cur_module.addAddressRange(cur_beg, cur_end, prot & kProtectionExecute); + cur_module.addAddressRange(cur_beg, cur_end, prot & kProtectionExecute, + prot & kProtectionRead); modules->push_back(cur_module); } } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc index 2831f28..be59b48 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_mac.cc @@ -262,7 +262,8 @@ void MemoryMappingLayout::DumpListOfModules( cur_module->set(cur_name, cur_beg, cur_arch, cur_uuid, current_instrumented_); } - cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute); + cur_module->addAddressRange(cur_beg, cur_end, prot & kProtectionExecute, + prot & kProtectionRead); } } diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc index b1a2a53..a8a8cd7 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_win.cc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_win.cc @@ -553,7 +553,8 @@ void ListOfModules::init() { LoadedModule cur_module; cur_module.set(module_name, adjusted_base); // We add the whole module as one single address range. - cur_module.addAddressRange(base_address, end_address, /*executable*/ true); + cur_module.addAddressRange(base_address, end_address, /*executable*/ true, + /*readable*/ true); modules_.push_back(cur_module); } UnmapOrDie(hmodules, modules_buffer_size); -- 2.7.4