Skip to content

Invalid header generated when modifying rpath with v1.6.1 #426

@cubanpit

Description

@cubanpit

Describe the bug

We use patchelf to add rpath to a Python executable (literally python3.8) that we compile ourselves in order to find the libraries we ship in nearby directories. We use the patchelf package from PyPi that got recently updated from v15.0 to v16.1, when that happened the patched Python executable stopped working on AlmaLinux 8.6. We use CentOS 7.3 internally and for all our builds, everything works fine in there, but on CentOS 8.2 or AlmaLinux 8.6 the executable segfaults immediately.

$ strace ./python3.8
execve("./python3.8", ["./python3.8"], 0x7ffd7fddb850 /* 48 vars */) = -1 EEXIST (File exists)
+++ killed by SIGSEGV +++
Segmentation fault

We figured out it was probably an header problem because it was failing immediately and the two executables only differed in the header. Here I past the output of readelf -l python3.8, that shows some differences between the executables patched with the two version of patchelf.

Working:

Elf file type is EXEC (Executable file)
Entry point 0x401089
There are 12 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x00000000003ff040 0x00000000003ff040
                 0x00000000000002a0 0x00000000000002a0  R      0x8
  GNU_STACK      0x0000000000001000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  LOAD           0x0000000000000000 0x00000000003ff000 0x00000000003ff000
                 0x0000000000001000 0x0000000000001000  RW     0x1000
  DYNAMIC        0x00000000000002e0 0x00000000003ff2e0 0x00000000003ff2e0
                 0x0000000000000250 0x0000000000000250  RW     0x8
  INTERP         0x0000000000000918 0x00000000003ff918 0x00000000003ff918
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  NOTE           0x0000000000000938 0x00000000003ff938 0x00000000003ff938
                 0x0000000000000020 0x0000000000000020  R      0x4
  LOAD           0x0000000000001000 0x0000000000400000 0x0000000000400000
                 0x0000000000000730 0x0000000000000730  R      0x1000
  LOAD           0x0000000000002000 0x0000000000401000 0x0000000000401000
                 0x00000000000001ed 0x00000000000001ed  R E    0x1000
  LOAD           0x0000000000003000 0x0000000000402000 0x0000000000402000
                 0x0000000000000178 0x0000000000000178  R      0x1000
  GNU_EH_FRAME   0x0000000000003004 0x0000000000402004 0x0000000000402004
                 0x0000000000000044 0x0000000000000044  R      0x4
  LOAD           0x0000000000003da8 0x0000000000403da8 0x0000000000403da8
                 0x0000000000000290 0x00000000000002a0  RW     0x1000
  GNU_RELRO      0x0000000000003da8 0x0000000000403da8 0x0000000000403da8
                 0x0000000000000258 0x0000000000000258  R      0x1

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

Broken:

Elf file type is EXEC (Executable file)
Entry point 0x401089
There are 12 program headers, starting at offset 64

Program Headers:
  Type           Offset             VirtAddr           PhysAddr
                 FileSiz            MemSiz              Flags  Align
  PHDR           0x0000000000000040 0x00000000003ff040 0x00000000003ff040
                 0x00000000000002a0 0x00000000000002a0  R      0x8
  GNU_STACK      0x0000000000000000 0x0000000000000000 0x0000000000000000
                 0x0000000000000000 0x0000000000000000  RW     0x10
  LOAD           0x0000000000000000 0x00000000003ff000 0x00000000003ff000
                 0x00000000000016a2 0x00000000000016a2  RW     0x1000
  DYNAMIC        0x00000000000002e0 0x00000000003ff2e0 0x00000000003ff2e0
                 0x0000000000000250 0x0000000000000250  RW     0x8
  INTERP         0x0000000000000918 0x00000000003ff918 0x00000000003ff918
                 0x000000000000001c 0x000000000000001c  R      0x1
      [Requesting program interpreter: /lib64/ld-linux-x86-64.so.2]
  NOTE           0x0000000000000938 0x00000000003ff938 0x00000000003ff938
                 0x0000000000000020 0x0000000000000020  R      0x4
  LOAD           0x00000000000016a2 0x00000000004006a2 0x00000000004006a2
                 0x000000000000008e 0x000000000000008e  R      0x1000
  LOAD           0x0000000000002000 0x0000000000401000 0x0000000000401000
                 0x00000000000001ed 0x00000000000001ed  R E    0x1000
  LOAD           0x0000000000003000 0x0000000000402000 0x0000000000402000
                 0x0000000000000178 0x0000000000000178  R      0x1000
  GNU_EH_FRAME   0x0000000000003004 0x0000000000402004 0x0000000000402004
                 0x0000000000000044 0x0000000000000044  R      0x4
  LOAD           0x0000000000003da8 0x0000000000403da8 0x0000000000403da8
                 0x0000000000000290 0x00000000000002a0  RW     0x1000
  GNU_RELRO      0x0000000000003da8 0x0000000000403da8 0x0000000000403da8
                 0x0000000000000258 0x0000000000000258  R      0x1

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

I do not know much about ELF headers, so I did not investigate further. I hope this output already provides a hint to identify the issue, let me know how to provide more useful information if needed.

Steps To Reproduce

Execute the following command on CentOS 7.3 with patchelf v1.6.1:
patchelf --set-rpath '$$ORIGIN/../lib:$$ORIGIN/../../lib/pinned-libs' ${INSTALLER_BUILD_DIR}/foopython/bin/python3.8

Execute python3.8 on AlmaLinux 8.6.

Expected behavior

Python starts.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions