From c42e8ddc485017b416eb1f11d285e6f2010e8c07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?S=C3=B6nke=20Holz?= Date: Sat, 9 Sep 2023 21:04:00 +0200 Subject: [PATCH] LibELF: Calculate size of relocation table correctly in all cases RELASZ might include the PLT table as well. Check if that is the case and correct the size of the non-PLT relocation table. --- Userland/Libraries/LibELF/DynamicObject.cpp | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/Userland/Libraries/LibELF/DynamicObject.cpp b/Userland/Libraries/LibELF/DynamicObject.cpp index 54d03c4de8b..a7a377e5246 100644 --- a/Userland/Libraries/LibELF/DynamicObject.cpp +++ b/Userland/Libraries/LibELF/DynamicObject.cpp @@ -202,6 +202,19 @@ void DynamicObject::parse() m_size_of_relocation_entry = sizeof(ElfW(Rel)); } + // Whether or not RELASZ (stored in m_size_of_relocation_table) only refers to non-PLT entries is not clearly specified. + // So check if [JMPREL, JMPREL+PLTRELSZ) is in [RELA, RELA+RELASZ). + // If so, change the size of the non-PLT relocation table. + if (m_plt_relocation_offset_location >= m_relocation_table_offset // JMPREL >= RELA + && m_plt_relocation_offset_location < (m_relocation_table_offset + m_size_of_relocation_table)) { // JMPREL < (RELA + RELASZ) + // [JMPREL, JMPREL+PLTRELSZ) is in [RELA, RELA+RELASZ) + + // Verify that the ends of the tables match up + VERIFY(m_plt_relocation_offset_location + m_size_of_plt_relocation_entry_list == m_relocation_table_offset + m_size_of_relocation_table); + + m_size_of_relocation_table -= m_size_of_plt_relocation_entry_list; + } + auto hash_section_address = hash_section().address().as_ptr(); // TODO: consider base address - it might not be zero auto num_hash_chains = ((u32*)hash_section_address)[1];