summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Userland/Libraries/LibELF/DynamicLoader.cpp21
1 files changed, 21 insertions, 0 deletions
diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp
index 04939f93d8..eb21cfc352 100644
--- a/Userland/Libraries/LibELF/DynamicLoader.cpp
+++ b/Userland/Libraries/LibELF/DynamicLoader.cpp
@@ -323,12 +323,33 @@ void DynamicLoader::load_program_headers()
size_t total_mapping_size = ph_load_end - ph_load_base;
+ // Before we make our reservation, unmap our existing mapped ELF image that we used for reading header information.
+ // This leaves our pointers dangling momentarily, but it reduces the chance that we will conflict with ourselves.
+ // The regions that we collected above are still safe to use because they are independent copies.
+ if (munmap(m_file_data, m_file_size) < 0) {
+ perror("munmap old mapping");
+ VERIFY_NOT_REACHED();
+ }
+ m_elf_image = nullptr;
+ m_file_data = nullptr;
+
auto* reservation = mmap(requested_load_address, total_mapping_size, PROT_NONE, reservation_mmap_flags, 0, 0);
if (reservation == MAP_FAILED) {
perror("mmap reservation");
VERIFY_NOT_REACHED();
}
+ // Now that we can't accidentally block our requested space, re-map our ELF image.
+ String file_mmap_name = String::formatted("ELF_DYN: {}", m_filepath);
+ auto* data = mmap_with_name(nullptr, m_file_size, PROT_READ, MAP_SHARED, m_image_fd, 0, file_mmap_name.characters());
+ if (data == MAP_FAILED) {
+ perror("mmap new mapping");
+ VERIFY_NOT_REACHED();
+ }
+
+ m_file_data = data;
+ m_elf_image = adopt_own(*new ELF::Image((u8*)m_file_data, m_file_size));
+
VERIFY(requested_load_address == nullptr || reservation == requested_load_address);
m_base_address = VirtualAddress { reservation };