patchelf
patchelf copied to clipboard
segfault following assert fail at patchelf.cc:556
patchelf segfauilts after printing an assertion error message, when applied a particular file, which I will attach. It seems to occur when --no-default-lib is used with both -set-interpreter and --set-rpath arguments of a certain minimum length.
Steps to reproduce
Here is a cut-down test which reproduces on my system (if it doesn't repro for you, please try making the /aaaa... and /bbb... much longer). /tmp/testprog is the file I will attach:
$ /tmp/patchelf/src/patchelf --no-default-lib --set-interpreter /aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa --set-rpath /bbbbbbbbbbbbb /tmp/testprog
patchelf: patchelf.cc:556: 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>::shiftFile(unsigned int, size_t, size_t) [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; size_t = long unsigned int]: Assertion `splitIndex != -1' failed.
Aborted (core dumped)
Here is a gdb backtrace:
__pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
warning: 44 ./nptl/pthread_kill.c: No such file or directory
(gdb) bt
#0 __pthread_kill_implementation (no_tid=0, signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:44
#1 __pthread_kill_internal (signo=6, threadid=<optimized out>) at ./nptl/pthread_kill.c:78
#2 __GI___pthread_kill (threadid=<optimized out>, signo=signo@entry=6) at ./nptl/pthread_kill.c:89
#3 0x00007ffff784526e in __GI_raise (sig=sig@entry=6) at ../sysdeps/posix/raise.c:26
#4 0x00007ffff78288ff in __GI_abort () at ./stdlib/abort.c:79
#5 0x00007ffff782881b in __assert_fail_base (fmt=0x7ffff79d01e8 "%s%s%s:%u: %s%sAssertion `%s' failed.\n%n",
assertion=assertion@entry=0x55555558a144 "splitIndex != -1", file=file@entry=0x555555589b99 "patchelf.cc", line=line@entry=556,
function=function@entry=0x555555587e60 "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>::shiftFile(unsigned int, siz"...) at ./assert/assert.c:94
#6 0x00007ffff783b507 in __assert_fail (assertion=0x55555558a144 "splitIndex != -1", file=0x555555589b99 "patchelf.cc", line=556,
function=0x555555587e60 "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>::shiftFile(unsigned int, siz"...) at ./assert/assert.c:103
#7 0x000055555556d0ec in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, unsigned short, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64u>::shiftFile (this=this@entry=0x7fffffffd320, extraPages=extraPages@entry=2,
startOffset=startOffset@entry=6672, extraBytes=extraBytes@entry=568) at patchelf.cc:556
#8 0x0000555555582675 in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, unsigned short, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64u>::rewriteSectionsExecutable (this=this@entry=0x7fffffffd320) at patchelf.cc:1078
#9 0x00005555555828f9 in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, unsigned short, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64u>::rewriteSections (this=this@entry=0x7fffffffd320, force=force@entry=false)
at patchelf.cc:1198
#10 0x0000555555584f82 in ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, unsigned short, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64u>::noDefaultLib (this=this@entry=0x7fffffffd320) at patchelf.cc:2022
#11 0x000055555555c804 in patchElf2<ElfFile<Elf64_Ehdr, Elf64_Phdr, Elf64_Shdr, unsigned long, unsigned long, Elf64_Dyn, Elf64_Sym, unsigned short, Elf64_Verdef, Elf64_Verdaux, Elf64_Verneed, Elf64_Vernaux, Elf64_Rel, Elf64_Rela, 64> > (fileName="/tmp/testprog",
fileContents=std::shared_ptr<std::vector<unsigned char, std::allocator<unsigned char> >> (use count 3, weak count 0) = {...}, elfFile=...)
at patchelf.cc:2493
#12 patchElf () at patchelf.cc:2522
#13 mainWrapped (argc=<optimized out>, argv=<optimized out>) at patchelf.cc:2746
#14 0x000055555555850a in main (argc=<optimized out>, argv=<optimized out>) at patchelf.cc:2759
Build Version
I compiled patchelf from git source current master, 739a486eced6c09e4c705f92fd6353e8f7f833c0, using gcc 13.3.0 on Ubuntu 24.04.1 LTS.
The compiled patchelf says it is version 0.18.0
The Test File
This is a copy of /usr/bin/x86_64-linux-gnu-cpp-13 i.e. gcc C Preprocessor executable (which I'm trying to patch to work on another server where I don't have root access to properly install anything...)
[Grumble... github would not let me attach the executable directly; so I put it in a tarball]