From 4b1c228d40a7f376bae3391bd64932ab12340694 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Wed, 22 Feb 2023 20:17:44 +0100 Subject: [PATCH 1/2] rewriteSectionsLibrary cleanup Use reference instead of a copy of the struct as lambda argument. Use for loop to limit the scope of the iterator varible i. --- src/patchelf.cc | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index 126cada8..4de02880 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -787,24 +787,22 @@ void ElfFile::rewriteSectionsLibrary() /* When normalizing note segments we will in the worst case be adding 1 program header for each SHT_NOTE section. */ unsigned int num_notes = std::count_if(shdrs.begin(), shdrs.end(), - [this](Elf_Shdr shdr) { return rdi(shdr.sh_type) == SHT_NOTE; }); + [this](const Elf_Shdr & shdr) { return rdi(shdr.sh_type) == SHT_NOTE; }); /* Because we're adding a new section header, we're necessarily increasing the size of the program header table. This can cause the first section to overlap the program header table in memory; we need to shift the first few segments to someplace else. */ /* Some sections may already be replaced so account for that */ - unsigned int i = 1; Elf_Addr pht_size = sizeof(Elf_Ehdr) + (phdrs.size() + num_notes + 1)*sizeof(Elf_Phdr); - while( i < rdi(hdr()->e_shnum) && rdi(shdrs.at(i).sh_offset) <= pht_size ) { + for (unsigned int i = 1; i < rdi(hdr()->e_shnum) && rdi(shdrs.at(i).sh_offset) <= pht_size; i++) { if (not haveReplacedSection(getSectionName(shdrs.at(i)))) replaceSection(getSectionName(shdrs.at(i)), rdi(shdrs.at(i).sh_size)); - i++; } /* Compute the total space needed for the replaced sections */ off_t neededSpace = 0; - for (auto & s : replacedSections) + for (const auto & s : replacedSections) neededSpace += roundUp(s.second.size(), sectionAlignment); debug("needed space is %d\n", neededSpace); From 9bf837c273929b6b0fbddbc74c74dd9047a33aaa Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Christian=20G=C3=B6ttsche?= Date: Wed, 22 Feb 2023 20:24:26 +0100 Subject: [PATCH 2/2] Compute program header flags in rewriteSectionsLibrary Instead of using fixed flags of RW for the new program header, holding the replaced sections, check if the write or execute flags is required by any accompanying section. If many sections are going to be replaced a more strict method would be to split them up and add up-to 4 new program headers if necessary: read-only, read-write, read-execute, read-write-execute. --- src/patchelf.cc | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index 4de02880..1345898f 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -842,7 +842,17 @@ void ElfFile::rewriteSectionsLibrary() wri(phdr.p_offset, startOffset); wri(phdr.p_vaddr, wri(phdr.p_paddr, startPage)); wri(phdr.p_filesz, wri(phdr.p_memsz, neededSpace)); - wri(phdr.p_flags, PF_R | PF_W); + { + bool need_write = false, need_exec = false; + for (const auto & rs : replacedSections) { + const auto flags = findSectionHeader(rs.first).sh_flags; + if (flags & SHF_WRITE) + need_write = true; + if (flags & SHF_EXECINSTR) + need_exec = true; + } + wri(phdr.p_flags, PF_R | (need_write ? PF_W : 0) | (need_exec ? PF_X : 0)); + } wri(phdr.p_align, getPageSize());