Skip to content

Section re-ordering confuses strip #10

@staticfloat

Description

@staticfloat

Running patchelf to enlarge my RUNPATH entry causes my section headers to change from this:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .interp           PROGBITS         0000000000400238  00000238
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.ABI-tag     NOTE             0000000000400254  00000254
       0000000000000020  0000000000000000   A       0     0     4
  [ 3] .note.gnu.build-i NOTE             0000000000400274  00000274
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .gnu.hash         GNU_HASH         0000000000400298  00000298
       0000000000000064  0000000000000000   A       5     0     8
  [ 5] .dynsym           DYNSYM           0000000000400300  00000300
       00000000000011b8  0000000000000018   A       6     1     8
  [ 6] .dynstr           STRTAB           00000000004014b8  000014b8
       0000000000000868  0000000000000000   A       0     0     1
...

To this:

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .dynsym           DYNSYM           00000000003ffb00  001ffb00
       00000000000011b8  0000000000000018   A       2     1     8
  [ 2] .dynstr           STRTAB           00000000003ff270  00000270
       0000000000000890  0000000000000000   A       0     0     8
  [ 3] .gnu.hash         GNU_HASH         0000000000400cb8  00001cb8
       0000000000000064  0000000000000000   A       1     0     8
  [ 4] .interp           PROGBITS         0000000000400d20  00001d20
       000000000000001c  0000000000000000   A       0     0     8
  [ 5] .note.ABI-tag     NOTE             0000000000400d40  00001d40
       0000000000000020  0000000000000000   A       0     0     8
  [ 6] .note.gnu.build-i NOTE             0000000000400d60  00001d60
       0000000000000024  0000000000000000   A       0     0     8
...

This confuses tools such as strip because they use a header offset of 0 as an error code; here's the relevant function assign_file_positions_for_non_load_sections in elf.c from binutils. Running e.g. gdb --args strip -g my_binary, and setting a breakpoint at that position shows that we get a valid section, but since its filepos is equal to zero, binutils ignores it and continues on, getting confused. Note that even readelf gets a little confused by this, as it doesn't even list the .dynsym segment:

$ readelf -l my_binary
...
 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.ABI-tag .note.gnu.build-id .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   03     .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
   04     .dynamic 
   05     .note.ABI-tag .note.gnu.build-id 
   06     .eh_frame_hdr 
   07     
   08     .init_array .fini_array .jcr .data.rel.ro .dynamic .got 
$ readelf my_patched_binary
...
 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02     .dynstr 
   03     .gnu.hash .interp .note.ABI-tag .note.gnu.build-id .gnu.version .gnu.version_r .rela.dyn .rela.plt .init .plt .text .fini .rodata .eh_frame_hdr .eh_frame 
   04     
   05     .interp 
   06     .eh_frame_hdr 
   07     .init_array .fini_array .jcr .data.rel.ro .dynamic .got .got.plt .data .bss 
   08     .init_array .fini_array .jcr .data.rel.ro .dynamic .got 
   09     .dynamic 

I theorize that if we keep the .interp section at the beginning of the file, we might be able to still use tools such as strip, but I don't actually know. Is there an easy way to permute the order of headers that patchelf outputs? If you can just point me in the direction of how to do this, I can submit a PR.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions