From: Waldemar Kozaczuk <jwkozac...@gmail.com>
Committer: Nadav Har'El <n...@scylladb.com>
Branch: master
elf: separate loading segments from processing headers
The issue #1045 exposed a bug in the dynamic linker when processing
some headers like PT_NOTE require accessing data in the PT_LOAD segments.
If PT_NOTE headers come earlier than PT_NOTE we end up with the page fault
as the portions of ELF file have not been mapped yet.
This patch separates loading of segments - load_segments() - from
processing headers by adding new method - process_headers().
Fixes #1045
Signed-off-by: Waldemar Kozaczuk <jwkozac...@gmail.com>
Message-Id: <20200114125901.16800-1-jwkozac...@gmail.com>
---
diff --git a/core/elf.cc b/core/elf.cc
--- a/core/elf.cc
+++ b/core/elf.cc
@@ -452,14 +452,22 @@ extern "C" char _pie_static_tls_start,
_pie_static_tls_end;
void object::load_segments()
{
elf_debug("Loading segments\n");
+ for (unsigned i = 0; i < _ehdr.e_phnum; ++i) {
+ auto &phdr = _phdrs[i];
+ if (phdr.p_type == PT_LOAD) {
+ load_segment(phdr);
+ }
+ }
+}
+
+void object::process_headers()
+{
+ elf_debug("Processing headers\n");
for (unsigned i = 0; i < _ehdr.e_phnum; ++i) {
auto &phdr = _phdrs[i];
switch (phdr.p_type) {
case PT_NULL:
break;
- case PT_LOAD:
- load_segment(phdr);
- break;
case PT_DYNAMIC:
_dynamic_table = reinterpret_cast<Elf64_Dyn*>(_base +
phdr.p_vaddr);
break;
@@ -495,6 +503,7 @@ void object::load_segments()
}
break;
}
+ case PT_LOAD:
case PT_PHDR:
case PT_GNU_STACK:
case PT_GNU_RELRO:
@@ -1233,6 +1242,7 @@ program::program(void* addr)
_core->set_base(program_base);
assert(_core->module_index() == core_module_index);
_core->load_segments();
+ _core->process_headers();
set_search_path({"/", "/usr/lib"});
// Our kernel already supplies the features of a bunch of traditional
// shared libraries:
@@ -1361,6 +1371,7 @@ program::load_object(std::string name,
std::vector<std::string> extra_path,
_modules_rcu.assign(new_modules.release());
osv::rcu_dispose(old_modules);
ef->load_segments();
+ ef->process_headers();
if (!ef->is_non_pie_executable())
_next_alloc = ef->end();
add_debugger_obj(ef.get());
diff --git a/include/osv/elf.hh b/include/osv/elf.hh
--- a/include/osv/elf.hh
+++ b/include/osv/elf.hh
@@ -348,6 +348,7 @@ public:
void* end() const;
Elf64_Sym* lookup_symbol(const char* name, bool self_lookup);
void load_segments();
+ void process_headers();
void unload_segments();
void fix_permissions();
void* resolve_pltgot(unsigned index);
--
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/00000000000040843b059c1df478%40google.com.