Skip to content

Commit

Permalink
Fix endianness issues for powerpc PIE
Browse files Browse the repository at this point in the history
Previously when running `patchelf --set-rpath "/usr/sbin" my_bin` on a
PIE ppc32 binary that had no RPATH a few issues were encountered.

This commit fixes:

1. The PT_PHDR being sorted improperly due to the type being read in
   incorrect endianness

2. The aligment being set to default 0x1000 due to the machine arch
   being read in incorrect endianness

3. The interpreter being clobbered due to the replace sections routine
   reading sh_offset and sh_size in incorrect endianness

4. The PHDR segment having an incorrect virt and phys address due to
   reading the e_phoff in the incorrect endianness

This also fixes a read of the shdr.sh_type in writeReplacedSections but
this was not encountered during testing.
  • Loading branch information
ratschance committed Oct 4, 2020
1 parent d2e81f0 commit 884eccc
Showing 1 changed file with 7 additions and 7 deletions.
14 changes: 7 additions & 7 deletions src/patchelf.cc
Original file line number Diff line number Diff line change
Expand Up @@ -136,8 +136,8 @@ class ElfFile
bool operator ()(const Elf_Phdr & x, const Elf_Phdr & y)
{
// A PHDR comes before everything else.
if (y.p_type == PT_PHDR) return false;
if (x.p_type == PT_PHDR) return true;
if (elfFile->rdi(y.p_type) == PT_PHDR) return false;
if (elfFile->rdi(x.p_type) == PT_PHDR) return true;

// Sort non-PHDRs by address.
return elfFile->rdi(x.p_paddr) < elfFile->rdi(y.p_paddr);
Expand Down Expand Up @@ -453,7 +453,7 @@ unsigned int ElfFile<ElfFileParamNames>::getPageSize() const
// Architectures (and ABIs) can have different minimum section alignment
// requirements. There is no authoritative list of these values. The
// current list is extracted from GNU gold's source code (abi_pagesize).
switch (hdr->e_machine) {
switch (rdi(hdr->e_machine)) {
case EM_SPARC:
case EM_MIPS:
case EM_PPC:
Expand Down Expand Up @@ -665,7 +665,7 @@ void ElfFile<ElfFileParamNames>::writeReplacedSections(Elf_Off & curOff,
for (auto & i : replacedSections) {
std::string sectionName = i.first;
Elf_Shdr & shdr = findSection(sectionName);
if (shdr.sh_type != SHT_NOBITS)
if (rdi(shdr.sh_type) != SHT_NOBITS)
memset(contents + rdi(shdr.sh_offset), 'X', rdi(shdr.sh_size));
}

Expand Down Expand Up @@ -778,9 +778,9 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
/* 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( shdrs[i].sh_offset <= pht_size && i < rdi(hdr->e_shnum) ) {
while( rdi(shdrs[i].sh_offset) <= pht_size && i < rdi(hdr->e_shnum) ) {
if (not haveReplacedSection(getSectionName(shdrs[i])))
replaceSection(getSectionName(shdrs[i]), shdrs[i].sh_size);
replaceSection(getSectionName(shdrs[i]), rdi(shdrs[i].sh_size));
i++;
}

Expand Down Expand Up @@ -835,7 +835,7 @@ void ElfFile<ElfFileParamNames>::rewriteSectionsLibrary()
assert(curOff == startOffset + neededSpace);

/* Write out the updated program and section headers */
rewriteHeaders(hdr->e_phoff);
rewriteHeaders(rdi(hdr->e_phoff));
}


Expand Down

0 comments on commit 884eccc

Please sign in to comment.