diff options
author | Michal Sojka <michal.sojka@cvut.cz> | 2021-08-18 15:16:13 +0200 |
---|---|---|
committer | Jörg Thalheim <joerg@thalheim.io> | 2021-08-21 09:47:28 +0200 |
commit | 302da733bf956429d3e548a91110d10f012543aa (patch) | |
tree | 772a6b15e87fdce2c99a5f56696ea5c521c3ad7c | |
parent | 5fe7ce74c7d6abee774f4997649df3d0bc1f6ef2 (diff) | |
download | patchelf-nobits.tar.gz |
Don't try to parse .dynamic section of type NOBITSnobits
Otherwise, patchelf segfaults when it encounters DT_NEEDED in the read
garbage. Corresponding backtrace is:
#0 0x00007ffff7c275f7 in __strlen_avx2 () from /nix/store/cvr0kjg2q7z2wwhjblx6c73rv422k8cm-glibc-2.33-47/lib/libc.so.6
#1 0x00007ffff7f2d448 in std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >::basic_string(char const*, std::allocator<char> const&) () from /nix/store/lg104nh0szci8slz5z6494m457jm5y3p-gcc-10.3.0-lib/lib/libstdc++.so.6
#2 0x000000000040fe0f in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short>::modifyRPath (this=0x7fffffffbaa0,
op=ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short>::rpPrint, allowedRpathPrefixes=std::vector of length 0, capacity 0, newRPath="") at patchelf.cc:1351
#3 0x00000000004061c3 in patchElf2<ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, Elf64_Verneed, unsigned short> > (elfFile=..., fileContents=std::shared_ptr<std::vector<unsigned char, std::allocator<unsigned char> >> (use count 3, weak count 0) = {...},
fileName="libsystemd.debug") at patchelf.cc:1805
#4 0x0000000000404774 in patchElf () at patchelf.cc:1848
#5 0x000000000040551c in mainWrapped (argc=3, argv=0x7fffffffc148) at patchelf.cc:2003
#6 0x0000000000405913 in main (argc=3, argv=0x7fffffffc148) at patchelf.cc:2011
NOBIT sections are included in the section headers table but occupy no
actual space in the file. .dynamic sections of this types are created,
for example, by `strip --only-keep-debug`.
I'm not sure whether calling error() would be more appropriate than
ignoring this situation with debug/return. I chose ignoring it,
because error() caused autoPatchelfHook to fail with my package. Also
the rest of modifyRPath method simply calls debug/return in similar
situations.
-rw-r--r-- | src/patchelf.cc | 5 |
1 files changed, 5 insertions, 0 deletions
diff --git a/src/patchelf.cc b/src/patchelf.cc index 4b7ef43..3ca16c7 100644 --- a/src/patchelf.cc +++ b/src/patchelf.cc @@ -1330,6 +1330,11 @@ void ElfFile<ElfFileParamNames>::modifyRPath(RPathOp op, { auto shdrDynamic = findSection(".dynamic"); + if (rdi(shdrDynamic.sh_type) == SHT_NOBITS) { + debug("no dynamic section\n"); + return; + } + /* !!! We assume that the virtual address in the DT_STRTAB entry of the dynamic section corresponds to the .dynstr section. */ auto shdrDynStr = findSection(".dynstr"); |