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 <[email protected]> --- core/elf.cc | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/core/elf.cc b/core/elf.cc index ffb16004..0d33f63d 100644 --- 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 -- 2.25.1 -- 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 [email protected]. To view this discussion on the web visit https://groups.google.com/d/msgid/osv-dev/20200708184200.33634-1-jwkozaczuk%40gmail.com.
