Skip to content

Commit 7b49a97

Browse files
ehmryJPEWdev
authored andcommitted
Expand LOAD segment to cover new .dynstr and .dynsym sections
This is not a robust fix, the first PT_LOAD segment is expanded forward to cover .dynstr or .dynsym. This is verified to fix segmentation faults in the loader when loading programs where the .dynstr or .dynstm section gets bumped out of the LOAD segment Fixes: NixOS#244
1 parent c401289 commit 7b49a97

File tree

1 file changed

+40
-0
lines changed

1 file changed

+40
-0
lines changed

src/patchelf.cc

+40
Original file line numberDiff line numberDiff line change
@@ -787,6 +787,46 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
787787
curOff += roundUp(i->second.size(), sectionAlignment);
788788
}
789789

790+
/* Expand the LOAD segment as neccessary */
791+
for (auto & i : replacedSections) {
792+
std::string sectionName = i.first;
793+
794+
/* If this is the .dynstr or .dynsym section, then a PT_LOAD segment
795+
must contain it. */
796+
if (sectionName == ".dynstr" || sectionName == ".dynsym") {
797+
auto const & shdr = findSectionHeader(sectionName);
798+
bool loaded = false;
799+
for (auto & phdr : phdrs) {
800+
if (rdi(phdr.p_type) == PT_LOAD) {
801+
if (rdi(phdr.p_offset) <= rdi(shdr.sh_offset) &&
802+
rdi(shdr.sh_size) <= rdi(phdr.p_filesz)) {
803+
debug("'%s' section is loaded\n", sectionName.c_str());
804+
loaded = true;
805+
break;
806+
}
807+
}
808+
}
809+
810+
if (!loaded) {
811+
debug("'%s' was moved out of a load segment…\n", sectionName.c_str());
812+
for (auto & phdr : phdrs) {
813+
if (rdi(phdr.p_type) == PT_LOAD) {
814+
if (rdi(shdr.sh_offset) < rdi(phdr.p_offset)) {
815+
Elf64_Xword gap = rdi(phdr.p_offset) - rdi(shdr.sh_offset);
816+
debug("grow PT_LOAD segment by 0x%x to cover '%s'\n",
817+
gap, sectionName.c_str());
818+
wri(phdr.p_filesz, rdi(phdr.p_filesz) + gap);
819+
wri(phdr.p_memsz, rdi(phdr.p_memsz) + gap);
820+
phdr.p_vaddr = phdr.p_paddr = shdr.sh_addr;
821+
phdr.p_offset = shdr.sh_offset;
822+
break;
823+
}
824+
}
825+
}
826+
}
827+
}
828+
}
829+
790830
replacedSections.clear();
791831
}
792832

0 commit comments

Comments
 (0)