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.

Reply via email to