-
-
Notifications
You must be signed in to change notification settings - Fork 506
Description
the bug
assertion at the bottom of rewriteSectionsLibrary
tripped when theres a null section at position 1 on the sht.
patchelf: patchelf.cc:961: void ElfFile<Elf_Ehdr, Elf_Phdr, Elf_Shdr, Elf_Addr, Elf_Off, Elf_Dyn, Elf_Sym, Elf_Versym, Elf_Verdef, Elf_Verdaux, Elf_Verneed, Elf_Vernaux, Elf_Rel, Elf_Rela, ElfClass>::rewriteSectionsLibrary() [with Elf_Ehdr = Elf64_Ehdr; Elf_Phdr = Elf64_Phdr; Elf_Shdr = Elf64_Shdr; Elf_Addr = long unsigned int; Elf_Off = long unsigned int; Elf_Dyn = Elf64_Dyn; Elf_Sym = Elf64_Sym; Elf_Versym = short unsigned int; Elf_Verdef = Elf64_Verdef; Elf_Verdaux = Elf64_Verdaux; Elf_Verneed = Elf64_Verneed; Elf_Vernaux = Elf64_Vernaux; Elf_Rel = Elf64_Rel; Elf_Rela = Elf64_Rela; unsigned int ElfClass = 64]: Assertion `curOff == startOffset + neededSpace' failed.
Aborted
Steps To Reproduce
-
take an elf executable (but with ET_DYN, havent tried other cases) that has a
SHT_NULL
entry (apart from the mandatory one at the top of the sht). i created one by appending 64 null bytes to a random gcc executable, because the section header table was at the end i could just add 1 to the counter on the elf header to get one. -
run
patchelf --add-needed libX.so.Y
on it, at least twice. the first time wont trip the assert if the null entry is not at position 1.
Expected behavior
no errors
patchelf --version
output
current git master, also patchelf 0.18.0 from debian repo
running the program under a debugger shows that the problem comes from calls to replaceSection
with a null section as the target, i dont understand quite well how that ends messing up the offset calculation, but adding a guard against it seems to help. also, using the --no-sort option prevents this.
this is my workaround, but im not sure if it makes sense, also its possible some non SHT_NULL sections might have an empty name?
diff --git a/src/patchelf.cc b/src/patchelf.cc
index 73f1b8d..693ac51 100644
--- a/src/patchelf.cc
+++ b/src/patchelf.cc
@@ -866,7 +866,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
const auto & sectionName = getSectionName(shdrs.at(i));
const auto sectionSize = rdi(shdrs.at(i).sh_size);
- if (!hasReplacedSection(sectionName)) {
+ if (sectionName != "" && !hasReplacedSection(sectionName) ) {
replaceSection(sectionName, sectionSize);
}
@@ -1015,7 +1015,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
lastReplaced = i - 1;
break;
}
- if (!replacedSections.count(sectionName)) {
+ if (sectionName != "" && !replacedSections.count(sectionName)) {
debug("replacing section '%s' which is in the way\n", sectionName.c_str());
replaceSection(sectionName, rdi(shdr.sh_size));
}
another workaround is strip
ing the executable which removes all null sections