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 /Userland/Libraries/LibELF/DynamicLoader.cpp | |
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.
Diffstat (limited to 'Userland/Libraries/LibELF/DynamicLoader.cpp')
-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 }; |