Skip to content

Commit 4e8c47f

Browse files
committed
Move section headers if they would be overwritten
When rewriting the sections of an executable, it can happen that the section headers occur too early in the file and would be overwritten by the replaced sections. If this would happen, we move the section headers to the end of the file.
1 parent bf4b579 commit 4e8c47f

File tree

1 file changed

+16
-5
lines changed

1 file changed

+16
-5
lines changed

src/patchelf.cc

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -711,11 +711,22 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsExecutable()
711711
Elf_Addr firstPage = startAddr - startOffset;
712712
debug("first page is 0x%llx\n", (unsigned long long) firstPage);
713713

714-
/* Right now we assume that the section headers are somewhere near
715-
the end, which appears to be the case most of the time.
716-
Therefore they're not accidentally overwritten by the replaced
717-
sections. !!! Fix this. */
718-
assert((off_t) rdi(hdr->e_shoff) >= startOffset);
714+
if ((off_t) rdi(hdr->e_shoff) < startOffset) {
715+
/* The section headers occur too early in the file and would be
716+
overwritten by the replaced sections. Move them to the end of the file
717+
before proceeding. */
718+
off_t shoffNew = fileSize;
719+
off_t shSize = rdi(hdr->e_shoff) + rdi(hdr->e_shnum) * rdi(hdr->e_shentsize);
720+
growFile (fileSize + shSize);
721+
wri(hdr->e_shoff, shoffNew);
722+
723+
/* Rewrite the section header table. For neatness, keep the
724+
sections sorted. */
725+
assert(rdi(hdr->e_shnum) == shdrs.size());
726+
sortShdrs();
727+
for (unsigned int i = 1; i < rdi(hdr->e_shnum); ++i)
728+
* ((Elf_Shdr *) (contents + rdi(hdr->e_shoff)) + i) = shdrs[i];
729+
}
719730

720731

721732
/* Compute the total space needed for the replaced sections, the

0 commit comments

Comments
 (0)