https://sourceware.org/bugzilla/show_bug.cgi?id=34468
Bug ID: 34468
Summary: elf_update() with ELF_C_RDWR can overwrite gaps
between sections
Product: elfutils
Version: unspecified
Status: UNCONFIRMED
Severity: normal
Priority: P2
Component: libelf
Assignee: unassigned at sourceware dot org
Reporter: bmenrigh at brandonenright dot net
CC: elfutils-devel at sourceware dot org
Target Milestone: ---
Created attachment 16896
--> https://sourceware.org/bugzilla/attachment.cgi?id=16896&action=edit
Small example ELF to demonstrate corruption steps.
When editing a section, libelf when using ELF_C_RDWR can overwrite the section
gap immediately preceding the sectioning being edited. If there is critical
information in this section gap, it may be destroyed.
The problem doesn't arise with ELF_C_RDWR_MMAP, which properly skips over the
gap.
Attached is libelf-gap-reproducer.so that has been built to lead to the right
conditions.
Specifically:
Make a copy
$ cp libelf-gap-reproducer.so test.so
Check than the binary is as expected
$ readelf -SW test.so
Note that .shstrtab is last
[ 6] .shstrtab STRTAB 0000000000000000 000280 000041 00 0
0 1
Now update the elf with patchelf in a way that causes patchelf to relocated a
bunch of sections. We can do this by updating DT_SONAME to be a lot longer than
it currently is:
$ patchelf --set-soname longexamplename test.so
Confirm that the relocations have happened:
$ readelf -SW test.so
Notice now .note.gnu.build-id comes after .shstrtab:
[ 1] .shstrtab STRTAB 0000000000000000 000280 000041 00
0 0 1
[ 2] .note.gnu.build-id NOTE 0000000000002000 001000 000024 00 A
0 0 4
Now we update .note.gnu.build-id using debugedit which in turn uses libelf to
do the edit, using ELF_C_RDWR which will overwrite the preceding .shstrtab:
$ debugedit -i -s somenewseed test.so
Now the binary is corrupted:
readelf -SW test.so
<everything reported null/no strings>
readelf: Error: no .dynamic section in the dynamic segment
Some testing shows that updating debugedit to use ELF_C_RDWR_MMAP instead
avoids the issue. Looking at the libelf code, there is a function
fill_mmap(...) in elf32_updatefile.c which appears to be the correct logic.
Probably there needs to be a corresponding fill_file(...) that does the same
thing whenever ELF_C_RDWR is being used instead.
This came up in Gentoo bug 964356: https://bugs.gentoo.org/964356
--
You are receiving this mail because:
You are on the CC list for the bug.