diff options
author | Tim Schumacher <timschumi@gmx.de> | 2022-06-04 23:49:35 +0200 |
---|---|---|
committer | Linus Groh <mail@linusgroh.de> | 2022-06-21 22:38:15 +0100 |
commit | c0b31796a8b1d8ac792c480bfa8f586d332e8cab (patch) | |
tree | 9d73cdad22cd12d2e24d711c829410053dbdbdd3 | |
parent | c1d8612eb55b7f521ae3b5234b60f81555fe140d (diff) | |
download | serenity-c0b31796a8b1d8ac792c480bfa8f586d332e8cab.zip |
LibELF: Unmap the source file temporarily while reserving space
This further reduces the chance that we will conflict with data that is
already present at the target location.
-rw-r--r-- | Userland/Libraries/LibELF/DynamicLoader.cpp | 21 |
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 }; |