From d988bd86e4ba20c5938b194bc0bf9b408fdeed14 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 29 Jan 2021 14:36:46 +0100 Subject: [PATCH] LibELF: Map text segments read-only at first To support upcoming W^X changes in the kernel, the dynamic loader needs to be careful about the order in which permissions are added to shared library text segments. We now start by mapping text segments read-only (no-write, no-exec). If relocations are needed, we make them writable, and then finally, for all text segments, we finish by making them read+exec. --- Userland/Libraries/LibELF/DynamicLoader.cpp | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/Userland/Libraries/LibELF/DynamicLoader.cpp b/Userland/Libraries/LibELF/DynamicLoader.cpp index 5407633e9c..4e81c9d70c 100644 --- a/Userland/Libraries/LibELF/DynamicLoader.cpp +++ b/Userland/Libraries/LibELF/DynamicLoader.cpp @@ -209,18 +209,14 @@ void DynamicLoader::do_main_relocations(size_t total_tls_size) RefPtr DynamicLoader::load_stage_3(unsigned flags, size_t total_tls_size) { - do_lazy_relocations(total_tls_size); if (flags & RTLD_LAZY) { setup_plt_trampoline(); } - // Clean up our setting of .text to PROT_READ | PROT_WRITE - if (m_dynamic_object->has_text_relocations()) { - if (0 > mprotect(m_text_segment_load_address.as_ptr(), m_text_segment_size, PROT_READ | PROT_EXEC)) { - perror("mprotect .text: PROT_READ | PROT_EXEC"); // FIXME: dlerror? - return nullptr; - } + if (mprotect(m_text_segment_load_address.as_ptr(), m_text_segment_size, PROT_READ | PROT_EXEC) < 0) { + perror("mprotect .text: PROT_READ | PROT_EXEC"); // FIXME: dlerror? + return nullptr; } call_object_init_functions(); @@ -296,7 +292,7 @@ void DynamicLoader::load_program_headers() auto* text_segment_begin = (u8*)mmap_with_name( requested_load_address, total_mapping_size.value(), - text_region->mmap_prot(), + PROT_READ, text_mmap_flags, m_image_fd, text_region->offset(),