From 827e375297ff975cabab494864c0ee3b24afd28a Mon Sep 17 00:00:00 2001 From: Andrew Kaster Date: Sat, 11 Apr 2020 12:34:00 -0600 Subject: [PATCH] LibELF: Validate the mapped file in DynamicLoader constructor ELF::DynamicLoader now validates the ELF header and the program headers in its constructor. The requested program interpreter from the PT_INTERP program header is now avaiable via a getter. The dynamic loader program will want to check that this matches its name, for extra shenanigans checking. --- Libraries/LibELF/DynamicLoader.cpp | 16 +++++++++++++++- Libraries/LibELF/DynamicLoader.h | 6 +++++- 2 files changed, 20 insertions(+), 2 deletions(-) diff --git a/Libraries/LibELF/DynamicLoader.cpp b/Libraries/LibELF/DynamicLoader.cpp index 78e94644bc..5136aa4fe7 100644 --- a/Libraries/LibELF/DynamicLoader.cpp +++ b/Libraries/LibELF/DynamicLoader.cpp @@ -26,6 +26,7 @@ #include #include +#include #include #include @@ -59,11 +60,24 @@ DynamicLoader::DynamicLoader(const char* filename, int fd, size_t size) , m_file_size(size) , m_image_fd(fd) { + if (m_file_size < sizeof(Elf32_Ehdr)) { + m_valid = false; + return; + } + String file_mmap_name = String::format("ELF_DYN: %s", m_filename.characters()); - m_file_mapping = mmap_with_name(nullptr, size, PROT_READ, MAP_PRIVATE, m_image_fd, 0, file_mmap_name.characters()); + m_file_mapping = mmap_with_name(nullptr, m_file_size, PROT_READ, MAP_PRIVATE, m_image_fd, 0, file_mmap_name.characters()); if (MAP_FAILED == m_file_mapping) { m_valid = false; + return; + } + + auto* elf_header = (Elf32_Ehdr*)m_file_mapping; + + if (!validate_elf_header(*elf_header, m_file_size) || + !validate_program_headers(*elf_header, m_file_size, (u8*)m_file_mapping, m_file_size, m_program_interpreter)) { + m_valid = false; } } diff --git a/Libraries/LibELF/DynamicLoader.h b/Libraries/LibELF/DynamicLoader.h index 94174fb9fc..db0a543982 100644 --- a/Libraries/LibELF/DynamicLoader.h +++ b/Libraries/LibELF/DynamicLoader.h @@ -64,6 +64,9 @@ public: // Will be called from _fixup_plt_entry, as part of the PLT trampoline Elf32_Addr patch_plt_entry(u32 relocation_offset); + // Requested program interpreter from program headers. May be empty string + StringView program_interpreter() const { return m_program_interpreter; } + private: class ProgramHeaderRegion { public: @@ -103,9 +106,10 @@ private: void call_object_init_functions(); String m_filename; + String m_program_interpreter; size_t m_file_size { 0 }; int m_image_fd { -1 }; - void* m_file_mapping { nullptr }; + void* m_file_mapping { MAP_FAILED }; bool m_valid { true }; OwnPtr m_dynamic_object;