From: Waldemar Kozaczuk <jwkozac...@gmail.com> Committer: Waldemar Kozaczuk <jwkozac...@gmail.com> Branch: master
dynamic linker: fix the old bug in the logic to calculate the ELF base In order to properly calculate and then map an elf object in virtual memory, the set_base() method needs to identify the lowest and the highest PT_LOAD header in terms of the p_vaddr value. Unfortunately, there seems to be a bug in how it is implemented now and in some cases, when for example there are multiple PT_LOAD and non-PT_LOAD headers sharing the same p_vaddr value, it ends up using wrong header and then overwriting other segments data. This patch fixes it by separating filtering of PT_LOAD headers and indentifying the lowest and highest ones. Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com> --- diff --git a/core/elf.cc b/core/elf.cc --- a/core/elf.cc +++ b/core/elf.cc @@ -347,14 +347,19 @@ static bool intersects_with_kernel(Elf64_Addr elf_addr) void object::set_base(void* base) { - auto p = std::min_element(_phdrs.begin(), _phdrs.end(), - [](Elf64_Phdr a, Elf64_Phdr b) - { return a.p_type == PT_LOAD - && a.p_vaddr < b.p_vaddr; }); - auto q = std::min_element(_phdrs.begin(), _phdrs.end(), - [](Elf64_Phdr a, Elf64_Phdr b) - { return a.p_type == PT_LOAD - && a.p_vaddr > b.p_vaddr; }); + std::vector<const Elf64_Phdr*> pt_load_headers; + for (auto& p : _phdrs) { + if (p.p_type == PT_LOAD) { + pt_load_headers.push_back(&p); + } + } + + auto p = *std::min_element(pt_load_headers.begin(), pt_load_headers.end(), + [](const Elf64_Phdr* a, const Elf64_Phdr* b) + { return a->p_vaddr < b->p_vaddr; }); + auto q = *std::max_element(pt_load_headers.begin(), pt_load_headers.end(), + [](const Elf64_Phdr* a, const Elf64_Phdr* b) + { return a->p_vaddr < b->p_vaddr; }); if (!is_core() && is_non_pie_executable()) { // Verify non-PIE executable does not collide with the kernel -- You received this message because you are subscribed to the Google Groups "OSv Development" group. To unsubscribe from this group and stop receiving emails from it, send an email to osv-dev+unsubscr...@googlegroups.com. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/00000000000090464405aa5a0c40%40google.com.