From 884eccc4f061a3dbdbe63a4c73f1cc9bbf77fa7d Mon Sep 17 00:00:00 2001 From: Conrad Ratschan Date: Sat, 3 Oct 2020 20:17:24 -0500 Subject: [PATCH 1/2] Fix endianness issues for powerpc PIE 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. --- src/patchelf.cc | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/src/patchelf.cc b/src/patchelf.cc index c62d7b69..fd4ebcab 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -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); @@ -453,7 +453,7 @@ unsigned int ElfFile::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: @@ -665,7 +665,7 @@ void ElfFile::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)); } @@ -778,9 +778,9 @@ void ElfFile::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++; } @@ -835,7 +835,7 @@ void ElfFile::rewriteSectionsLibrary() assert(curOff == startOffset + neededSpace); /* Write out the updated program and section headers */ - rewriteHeaders(hdr->e_phoff); + rewriteHeaders(rdi(hdr->e_phoff)); } From b04764d2e78c58bd27b0c2f06920b88632751c9e Mon Sep 17 00:00:00 2001 From: Conrad Ratschan Date: Sat, 3 Oct 2020 23:24:07 -0500 Subject: [PATCH 2/2] Add regression tests for powerpc PIE endianness --- tests/Makefile.am | 1 + tests/no-rpath-pie-powerpc.sh | 54 +++++++++++++++++++ tests/no-rpath-prebuild/no-rpath-pie-powerpc | Bin 0 -> 68704 bytes 3 files changed, 55 insertions(+) create mode 100755 tests/no-rpath-pie-powerpc.sh create mode 100755 tests/no-rpath-prebuild/no-rpath-pie-powerpc diff --git a/tests/Makefile.am b/tests/Makefile.am index dbb7580e..db297386 100644 --- a/tests/Makefile.am +++ b/tests/Makefile.am @@ -25,6 +25,7 @@ src_TESTS = \ force-rpath.sh \ plain-needed.sh \ output-flag.sh \ + no-rpath-pie-powerpc.sh \ build-id.sh build_TESTS = \ diff --git a/tests/no-rpath-pie-powerpc.sh b/tests/no-rpath-pie-powerpc.sh new file mode 100755 index 00000000..5bdb7857 --- /dev/null +++ b/tests/no-rpath-pie-powerpc.sh @@ -0,0 +1,54 @@ +#! /bin/sh -e +set -x +SCRATCH=scratch/no-rpath-pie-powerpc + +no_rpath_bin="${srcdir}/no-rpath-prebuild/no-rpath-pie-powerpc" + +if [ ! -f $no_rpath_bin ]; then + echo "no 'no-rpath' binary for '$ARCH' in '${srcdir}/no-rpath-prebuild'" + exit 1 +fi + +rm -rf ${SCRATCH} +mkdir -p ${SCRATCH} + +cp $no_rpath_bin ${SCRATCH}/no-rpath + +oldRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath) +if test -n "$oldRPath"; then exit 1; fi +../src/patchelf \ + --set-interpreter "$(../src/patchelf --print-interpreter ../src/patchelf)" \ + --set-rpath /foo:/bar:/xxxxxxxxxxxxxxx ${SCRATCH}/no-rpath + +newRPath=$(../src/patchelf --print-rpath ${SCRATCH}/no-rpath) +if ! echo "$newRPath" | grep -q '/foo:/bar'; then + echo "incomplete RPATH" + exit 1 +fi + +# Tests for powerpc PIE endianness regressions +readelfData=$(readelf -l ${SCRATCH}/no-rpath 2>&1) + +if [ $(echo "$readelfData" | grep --count "PHDR") != 1 ]; then + # Triggered if PHDR errors appear on stderr + echo "Unexpected number of occurences of PHDR in readelf results" + exit 1 +fi + +virtAddr=$(echo "$readelfData" | grep "PHDR" | awk '{print $3}') +if [ "$virtAddr" != "0x00000034" ]; then + # Triggered if the virtual address is the incorrect endianness + echo "Unexpected virt addr, expected [0x00000034] got [$virtAddr]" + exit 1 +fi + +echo "$readelfData" | grep "LOAD" | while read -r line ; do + align=$(echo "$line" | awk '{print $NF}') + if [ "$align" != "0x10000" ]; then + # Triggered if the target arch was not detected properly + echo "Unexpected Align for LOAD segment, expected [0x10000] got [$align]" + echo "Load segment: [$line]" + exit 1 + fi +done + diff --git a/tests/no-rpath-prebuild/no-rpath-pie-powerpc b/tests/no-rpath-prebuild/no-rpath-pie-powerpc new file mode 100755 index 0000000000000000000000000000000000000000..09462b823217500827c92ee7c83dbbe3a733836a GIT binary patch literal 68704 zcmeH}e{5S<701tW+{Ib5k&Ubiv>Q&>Y3bCtX_bw1Eo+<~txJ=vZ9GjALvK!OH)f6< z*$$*t+PKRQD}S{rKZaDLorJ0alVH;R0I|XN15}CqF{HsiOj{8kRRW2CI>=bb<9qIV zH*vg7n)vbG_sZwpbM86s+;czo`n@+hFu2bNIkMauq!l^_!g=&v;zSOKR8@;gL^|Y? z@(GOJWPCbmMDI5_!cbHiV8drc?!uUg^_yVWL2G(ZL`By5Y4o~uU7SF~>377r4u50d z4~cj^;she{8hk2RS2$hyBWjK;u83^GxQdw{{=?AMYK<6df&WO|{LNSk#N6*}&*w(B z=hF{N^+6enm5Z@X*`6&Hw~wYuK~k(=ZiYl4O%R>8zF`f@32XN2R=>_~Vb(EHcYO;d zbOcFsp7qvyyRSs+?0c=f*;jP$OpE&6px=oEcDBwA(uxGiGpqb7C?-p}LM1D%>+^9Z zQn`XmPF2bn8kqrju<%@+( zGBujV9qL)RX|-?pmfBo6Bg%e*guux0bPuiG8t7LrzA4bd(4$6oJnV$0XJ!M=;SJ~= zLCovWJB=<)o1k|G<8MIU6T~lKK09yN%&mDO@(Ogn28p~5y~WQHc?-Hpn@~NMC3knfA7Bm()qIN6ttYlNT$;musISGZFC5kJ)ngKs(6Ki^%3Rg?YGh_EdT8d^4U;p^-U@NP9)HHn z+x#ES`=n(Wtg$Uv;}%`xxs){PI_FMSTTbs5(K&kN zV7#rG6G=G#d;$8Vxt~;{b4%4Nv#%x&&COS%v#)NLJhfM3_p6>ad-_^W&w1(CwN;$Q z?r(YcEXGglITTZ7!_{!R#%WCaym$4Ww{#5oI)XJegZnnjF|aEt&K&Ca7HXSA9doEd z&%+$*2IDqmu4hBfh2@KVZ`D0m*%ReIowWWB+iT3<8O+~;edzLQc<)!5t9Cz8Yq!m{ z)?BqdJyT%UJhONGbi#RWowBc<^xlI0L_*|&ncT){@M%7A&%x%h4_=!;LasN0|5z7tb)dd&etnA>b2etB?aT#mKI#1- z;Viy%(DQbjnUzTO0_3E3ZSWU6p27H8>|Z39tMkL^me7}4EswRhD;snEmheB@>)qIX z+Vk|kwcEqmgLCrbV7zDETd;e9bI=^@eM>!``n|{e%g>a9-i>$RU-djmj_1lz{P61S z*xD{)ZM=q!oyg?##pvV3Qa&w5GUcg!MWgRc-;8ICv#|ju6Xy#LJkMLwXKy$9ar952 ze;GZVh35Gz&haDI+_ zZH;!vx?-I+?t{J4rDF{!-uF4lz}EGm8CL4Y&)Aps3IjZ~8HQ?ur?Ic<6*jnP^TS{( zGqn?Xg{^qd!g;;IR&Ho!uhiE4Q2Q0V!q$C3i!ACDHuhIr(n6DG0XivD!V_!M;snm8=tMQ=izt*c3TktefYm!+WA-zs|2MF!>JRLCUdq(88os(7ZOZo_M#H7X|5h-j{w3tU zR$~XMjdvRC`9OU*A5Jq0*``6TaULA3&p(eCLT%3db^acW)#e{2XFvQAwQmdQkTZh( zYO0O>be=K>EdP-#M4h(})MD>goA6z9TfJM;kJ^B7AY9_PdP z(Q3c*YikGd{~q({vrqplIPcEeIKnT&%=`C;w!&{()Rf@-1!b7?13&)1&b#nm11p7x z^XA}L=xDu73KP2uhK=AR$spgIHS@t2y4%71@az1zKXeb`pMp6U#NTJ+ zyRMrqx<~WH(Nx}5ciBx%O-pg~3z@MB!XE1K!?LB+M8-`|O-vlKg$)e%o4WimeCq=# z$Cgu$rb<}UL@HPCm%T&W{wIdxLkIfA9qEs|z44I&UFQDb$K2(`CHjwuyMOS}-uR&V z=)Qd;14%a-?;S+oWGPpuWD%bn>T_)=29a+}PF2eAj!marpiSj-$1^a~<)S;DDx~u; zl)4VBaPt?LD`bn}9!L(k7AU4roXOOv-lv|Gn^ybWslI$}bj;OdBKK&y?3OF366VqU zmC-4!I9K>$@oB(3R!B|c#@u|a@H95f)e|9ZCY`FJ&=t}GVp<<;n`F5nx29Bym5)tS zQlscACBGlH8W?3tlM*{xn2L?3%HtBltO)n}N=ag+Og^Q9fi{`1NX(FlRWj4iP2I6l z(UcX-j0ZE1r*W^fBxbf5Np-g|Td}g!%%JOoqASuti2(?LixU%>LPh@sAGvKrr2bX$ zkJfJj^IdRP&E4j?1N%ORzUwtE>5J@vZT;G-+=FkQzXx$=5C@UAz=zJnXdIqN=2@-z zF8d-EF&4~W;_&yD2O)T^>b&~Rp<=$*(3z&SYx@jD^J?5xUz{jx9n+@0K6Ca5dhbdp z=KD_lt$|PD4ns6IzGw7VYo51TVB2Q%K8^t!mq(mRrwu}H<37I