Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

PT_NOTE logic in normalizeNoteSegments causes .dynstr not to be contained fully in a segment #403

Closed
haampie opened this issue Sep 23, 2022 · 0 comments · Fixed by #415
Closed
Labels

Comments

@haampie
Copy link
Contributor

haampie commented Sep 23, 2022

Describe the bug

When the .dynstr section is expanded due to a longer rpath, and the binary has a PT_NOTE segment, the program headers get updated in a way that's causing the .dynstr section to overlap two PT_LOAD segments.

I'm not sure what the implications are, but on a particular filesystem I've been using patchelf on, binaries are broken (mmap/mprotect errors in the dynamic loader or even segfaults). The above issue stands out.

gdb warns about this:

warning: Loadable section ".dynstr" outside of ELF segments

Steps To Reproduce

Run patchelf on itself:

$ cd $(mktemp -d)
$ curl -Lfs https://github.com/NixOS/patchelf/releases/download/0.15.0/patchelf-0.15.0.tar.gz | tar -zx --strip-components=1 -f -
$ ./configure
$ make "LDFLAGS=-Wl,-rpath,/example -no-pie" "CXXFLAGS=-O2 -g -fno-pic" install prefix=$PWD/install -j
$ cd install/bin
$ cp patchelf patchelf.copy
$ ./patchelf --set-rpath /longer/path patchelf.copy
$ gdb -ex r --args ./patchelf.copy

Reading symbols from ./patchelf.copy...

warning: Loadable section ".dynstr" outside of ELF segments
Starting program: /tmp/tmp.3gvU6yERyd/install/bin/patchelf.copy 

Notice: -no-pie and -fno-pic is required for me to trigger it.


Full details, see the binaries here https://github.com/NixOS/patchelf/files/9633732/bin.tar.gz.

Notice that the .dynstr section is not listed in the bottom "Section to Segment mapping"

Before:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x403c40
  Start of program headers:          64 (bytes into file)
  Start of section headers:          170992 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         13
  Size of section headers:           64 (bytes)
  Number of section headers:         33
  Section header string table index: 32

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         0000000000400318  00000318
       000000000000001c  0000000000000000   A       0     0     1
  [ 2] .note.gnu.propert NOTE             0000000000400338  00000338
       0000000000000020  0000000000000000   A       0     0     8
  [ 3] .note.gnu.build-i NOTE             0000000000400358  00000358
       0000000000000024  0000000000000000   A       0     0     4
  [ 4] .note.ABI-tag     NOTE             000000000040037c  0000037c
       0000000000000020  0000000000000000   A       0     0     4
  [ 5] .gnu.hash         GNU_HASH         00000000004003a0  000003a0
       000000000000005c  0000000000000000   A       6     0     8
  [ 6] .dynsym           DYNSYM           0000000000400400  00000400
       0000000000000828  0000000000000018   A       7     1     8
  [ 7] .dynstr           STRTAB           0000000000400c28  00000c28
       0000000000000e43  0000000000000000   A       0     0     1
  [ 8] .gnu.version      VERSYM           0000000000401a6c  00001a6c
       00000000000000ae  0000000000000002   A       6     0     2
  [ 9] .gnu.version_r    VERNEED          0000000000401b20  00001b20
       00000000000000f0  0000000000000000   A       7     3     8
  [10] .rela.dyn         RELA             0000000000401c10  00001c10
       00000000000000c0  0000000000000018   A       6     0     8
  [11] .rela.plt         RELA             0000000000401cd0  00001cd0
       0000000000000720  0000000000000018  AI       6    26     8
  [12] .init             PROGBITS         0000000000403000  00003000
       000000000000001b  0000000000000000  AX       0     0     4
  [13] .plt              PROGBITS         0000000000403020  00003020
       00000000000004d0  0000000000000010  AX       0     0     16
  [14] .plt.sec          PROGBITS         00000000004034f0  000034f0
       00000000000004c0  0000000000000010  AX       0     0     16
  [15] .text             PROGBITS         00000000004039b0  000039b0
       0000000000012024  0000000000000000  AX       0     0     16
  [16] .fini             PROGBITS         00000000004159d4  000159d4
       000000000000000d  0000000000000000  AX       0     0     4
  [17] .rodata           PROGBITS         0000000000416000  00016000
       0000000000001d60  0000000000000000   A       0     0     32
  [18] .eh_frame_hdr     PROGBITS         0000000000417d60  00017d60
       00000000000007e4  0000000000000000   A       0     0     4
  [19] .eh_frame         PROGBITS         0000000000418548  00018548
       0000000000003138  0000000000000000   A       0     0     8
  [20] .gcc_except_table PROGBITS         000000000041b680  0001b680
       0000000000000e14  0000000000000000   A       0     0     4
  [21] .init_array       INIT_ARRAY       000000000041dca8  0001cca8
       0000000000000010  0000000000000008  WA       0     0     8
  [22] .fini_array       FINI_ARRAY       000000000041dcb8  0001ccb8
       0000000000000008  0000000000000008  WA       0     0     8
  [23] .data.rel.ro      PROGBITS         000000000041dcc0  0001ccc0
       0000000000000118  0000000000000000  WA       0     0     32
  [24] .dynamic          DYNAMIC          000000000041ddd8  0001cdd8
       0000000000000200  0000000000000010  WA       7     0     8
  [25] .got              PROGBITS         000000000041dfd8  0001cfd8
       0000000000000010  0000000000000008  WA       0     0     8
  [26] .got.plt          PROGBITS         000000000041e000  0001d000
       0000000000000278  0000000000000008  WA       0     0     8
  [27] .data             PROGBITS         000000000041e278  0001d278
       0000000000000015  0000000000000000  WA       0     0     8
  [28] .bss              NOBITS           000000000041e2a0  0001d28d
       0000000000000240  0000000000000000  WA       0     0     32
  [29] .comment          PROGBITS         0000000000000000  0001d28d
       000000000000002b  0000000000000001  MS       0     0     1
  [30] .symtab           SYMTAB           0000000000000000  0001d2b8
       0000000000002a18  0000000000000018          31   106     8
  [31] .strtab           STRTAB           0000000000000000  0001fcd0
       0000000000009de1  0000000000000000           0     0     1
  [32] .shstrtab         STRTAB           0000000000000000  00029ab1
       000000000000013e  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x0000000000400040 0x0000000000400040
                 0x00000000000002d8 0x00000000000002d8  R      0x8
  INTERP         0x0000000000000318 0x0000000000400318 0x0000000000400318
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  LOAD           0x0000000000000000 0x0000000000400000 0x0000000000400000
                 0x00000000000023f0 0x00000000000023f0  R      0x1000
  LOAD           0x0000000000003000 0x0000000000403000 0x0000000000403000
                 0x00000000000129e1 0x00000000000129e1  R E    0x1000
  LOAD           0x0000000000016000 0x0000000000416000 0x0000000000416000
                 0x0000000000006494 0x0000000000006494  R      0x1000
  LOAD           0x000000000001cca8 0x000000000041dca8 0x000000000041dca8
                 0x00000000000005e5 0x0000000000000838  RW     0x1000
  DYNAMIC        0x000000000001cdd8 0x000000000041ddd8 0x000000000041ddd8
                 0x0000000000000200 0x0000000000000200  RW     0x8
  NOTE           0x0000000000000338 0x0000000000400338 0x0000000000400338
                 0x0000000000000020 0x0000000000000020  R      0x8
  NOTE           0x0000000000000358 0x0000000000400358 0x0000000000400358
                 0x0000000000000044 0x0000000000000044  R      0x4
  GNU_PROPERTY   0x0000000000000338 0x0000000000400338 0x0000000000400338
                 0x0000000000000020 0x0000000000000020  R      0x8
  GNU_EH_FRAME   0x0000000000017d60 0x0000000000417d60 0x0000000000417d60
                 0x00000000000007e4 0x00000000000007e4  R      0x4
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  GNU_RELRO      0x000000000001cca8 0x000000000041dca8 0x000000000041dca8
                 0x0000000000000358 0x0000000000000358  R      0x1

 Section to Segment mapping:
  Segment Sections...
   00     
   01     .interp 
   02     .interp .note.gnu.property .note.gnu.build-id .note.ABI-tag .gnu.hash .dynsym .dynstr .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   03     .init .plt .plt.sec .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame .gcc_except_table 
   05     .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss 
   06     .dynamic 
   07     .note.gnu.property 
   08     .note.gnu.build-id .note.ABI-tag 
   09     .note.gnu.property 
   10     .eh_frame_hdr 
   11     
   12     .init_array .fini_array .data.rel.ro .dynamic .got 

After:

ELF Header:
  Magic:   7f 45 4c 46 02 01 01 03 00 00 00 00 00 00 00 00 
  Class:                             ELF64
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - GNU
  ABI Version:                       0
  Type:                              EXEC (Executable file)
  Machine:                           Advanced Micro Devices X86-64
  Version:                           0x1
  Entry point address:               0x403c40
  Start of program headers:          64 (bytes into file)
  Start of section headers:          175088 (bytes into file)
  Flags:                             0x0
  Size of this header:               64 (bytes)
  Size of program headers:           56 (bytes)
  Number of program headers:         15
  Size of section headers:           64 (bytes)
  Number of section headers:         33
  Section header string table index: 32

Section Headers:
  [Nr] Name              Type             Address           Offset
       Size              EntSize          Flags  Link  Info  Align
  [ 0]                   NULL             0000000000000000  00000000
       0000000000000000  0000000000000000           0     0     0
  [ 1] .dynstr           STRTAB           00000000003ff388  00000388
       0000000000000e55  0000000000000000   A       0     0     8
  [ 2] .dynsym           DYNSYM           00000000004001e0  000011e0
       0000000000000828  0000000000000018   A       1     1     8
  [ 3] .gnu.hash         GNU_HASH         0000000000400a08  00001a08
       000000000000005c  0000000000000000   A       2     0     8
  [ 4] .interp           PROGBITS         0000000000400a68  00001a68
       000000000000001c  0000000000000000   A       0     0     8
  [ 5] .note.ABI-tag     NOTE             0000000000400a88  00001a88
       0000000000000020  0000000000000000   A       0     0     4
  [ 6] .note.gnu.build-i NOTE             0000000000400aa8  00001aa8
       0000000000000024  0000000000000000   A       0     0     4
  [ 7] .note.gnu.propert NOTE             0000000000400ad0  00001ad0
       0000000000000020  0000000000000000   A       0     0     8
  [ 8] .gnu.version      VERSYM           0000000000401a6c  00002a6c
       00000000000000ae  0000000000000002   A       2     0     2
  [ 9] .gnu.version_r    VERNEED          0000000000401b20  00002b20
       00000000000000f0  0000000000000000   A       1     3     8
  [10] .rela.dyn         RELA             0000000000401c10  00002c10
       00000000000000c0  0000000000000018   A       2     0     8
  [11] .rela.plt         RELA             0000000000401cd0  00002cd0
       0000000000000720  0000000000000018  AI       2    26     8
  [12] .init             PROGBITS         0000000000403000  00004000
       000000000000001b  0000000000000000  AX       0     0     4
  [13] .plt              PROGBITS         0000000000403020  00004020
       00000000000004d0  0000000000000010  AX       0     0     16
  [14] .plt.sec          PROGBITS         00000000004034f0  000044f0
       00000000000004c0  0000000000000010  AX       0     0     16
  [15] .text             PROGBITS         00000000004039b0  000049b0
       0000000000012024  0000000000000000  AX       0     0     16
  [16] .fini             PROGBITS         00000000004159d4  000169d4
       000000000000000d  0000000000000000  AX       0     0     4
  [17] .rodata           PROGBITS         0000000000416000  00017000
       0000000000001d60  0000000000000000   A       0     0     32
  [18] .eh_frame_hdr     PROGBITS         0000000000417d60  00018d60
       00000000000007e4  0000000000000000   A       0     0     4
  [19] .eh_frame         PROGBITS         0000000000418548  00019548
       0000000000003138  0000000000000000   A       0     0     8
  [20] .gcc_except_table PROGBITS         000000000041b680  0001c680
       0000000000000e14  0000000000000000   A       0     0     4
  [21] .init_array       INIT_ARRAY       000000000041dca8  0001dca8
       0000000000000010  0000000000000008  WA       0     0     8
  [22] .fini_array       FINI_ARRAY       000000000041dcb8  0001dcb8
       0000000000000008  0000000000000008  WA       0     0     8
  [23] .data.rel.ro      PROGBITS         000000000041dcc0  0001dcc0
       0000000000000118  0000000000000000  WA       0     0     32
  [24] .dynamic          DYNAMIC          000000000041ddd8  0001ddd8
       0000000000000200  0000000000000010  WA       1     0     8
  [25] .got              PROGBITS         000000000041dfd8  0001dfd8
       0000000000000010  0000000000000008  WA       0     0     8
  [26] .got.plt          PROGBITS         000000000041e000  0001e000
       0000000000000278  0000000000000008  WA       0     0     8
  [27] .data             PROGBITS         000000000041e278  0001e278
       0000000000000015  0000000000000000  WA       0     0     8
  [28] .bss              NOBITS           000000000041e2a0  0001e28d
       0000000000000240  0000000000000000  WA       0     0     32
  [29] .comment          PROGBITS         0000000000000000  0001e28d
       000000000000002b  0000000000000001  MS       0     0     1
  [30] .symtab           SYMTAB           0000000000000000  0001e2b8
       0000000000002a18  0000000000000018          31   106     8
  [31] .strtab           STRTAB           0000000000000000  00020cd0
       0000000000009de1  0000000000000000           0     0     1
  [32] .shstrtab         STRTAB           0000000000000000  0002aab1
       000000000000013e  0000000000000000           0     0     1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings), I (info),
  L (link order), O (extra OS processing required), G (group), T (TLS),
  C (compressed), x (unknown), o (OS specific), E (exclude),
  l (large), p (processor specific)

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x00000000003ff040 0x00000000003ff040
                 0x0000000000000348 0x0000000000000348  R      0x8
  GNU_STACK      0x0000000000001000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  LOAD           0x0000000000000000 0x00000000003ff000 0x00000000003ff000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  LOAD           0x0000000000001000 0x0000000000400000 0x0000000000400000
                 0x00000000000023f0 0x00000000000023f0  R      0x1000
  GNU_PROPERTY   0x0000000000001338 0x0000000000400338 0x0000000000400338
                 0x0000000000000020 0x0000000000000020  R      0x8
  INTERP         0x0000000000001a68 0x0000000000400a68 0x0000000000400a68
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  NOTE           0x0000000000001a88 0x0000000000400a88 0x0000000000400a88
                 0x0000000000000020 0x0000000000000020  R      0x4
  NOTE           0x0000000000001aa8 0x0000000000400aa8 0x0000000000400aa8
                 0x0000000000000024 0x0000000000000024  R      0x4
  NOTE           0x0000000000001ad0 0x0000000000400ad0 0x0000000000400ad0
                 0x0000000000000020 0x0000000000000020  R      0x8
  LOAD           0x0000000000004000 0x0000000000403000 0x0000000000403000
                 0x00000000000129e1 0x00000000000129e1  R E    0x1000
  LOAD           0x0000000000017000 0x0000000000416000 0x0000000000416000
                 0x0000000000006494 0x0000000000006494  R      0x1000
  GNU_EH_FRAME   0x0000000000018d60 0x0000000000417d60 0x0000000000417d60
                 0x00000000000007e4 0x00000000000007e4  R      0x4
  LOAD           0x000000000001dca8 0x000000000041dca8 0x000000000041dca8
                 0x00000000000005e5 0x0000000000000838  RW     0x1000
  GNU_RELRO      0x000000000001dca8 0x000000000041dca8 0x000000000041dca8
                 0x0000000000000358 0x0000000000000358  R      0x1
  DYNAMIC        0x000000000001ddd8 0x000000000041ddd8 0x000000000041ddd8
                 0x0000000000000200 0x0000000000000200  RW     0x8

 Section to Segment mapping:
  Segment Sections...
   00     
   01     
   02     
   03     .dynsym .gnu.hash .interp .note.ABI-tag .note.gnu.build-id .note.gnu.property .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   04     
   05     .interp 
   06     .note.ABI-tag 
   07     .note.gnu.build-id 
   08     .note.gnu.property 
   09     .init .plt .plt.sec .text .fini 
   10     .rodata .eh_frame_hdr .eh_frame .gcc_except_table 
   11     .eh_frame_hdr 
   12     .init_array .fini_array .data.rel.ro .dynamic .got .got.plt .data .bss 
   13     .init_array .fini_array .data.rel.ro .dynamic .got 
   14     .dynamic 
@haampie haampie added the bug label Sep 23, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 10, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 10, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 10, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 10, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 10, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 12, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 13, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 13, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 13, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 13, 2022
Bo98 added a commit to Bo98/patchelf that referenced this issue Oct 13, 2022
rcoup added a commit to koordinates/vcpkg that referenced this issue Apr 15, 2023
Fixes occasional lib corruption: NixOS/patchelf#403
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

Successfully merging a pull request may close this issue.

1 participant