Skip to content

Cannot add-needed and replace-needed in same invocation #359

Closed
@fzakaria

Description

@fzakaria

Describe the bug

I cannot --add-needed and --replace-needed on the same invocation.
It produces a binary with incorrect DT_NEEDED and gnu.version_r sections.

Steps To Reproduce

❯ cp /usr/bin/ruby /tmp/ruby

❯ ./src/patchelf --print-needed /tmp/ruby
libruby-2.7.so.2.7
libc.so.6

❯ ./src/patchelf --replace-needed libruby-2.7.so.2.7 /lib/x86_64-linux-gnu/libruby-2.7.so.2.7 \
--replace-needed libc.so.6 /lib/x86_64-linux-gnu/libc.so.6 \
--add-needed /lib/x86_64-linux-gnu/libcrypt.so.1 \
--add-needed /lib/x86_64-linux-gnu/libdl.so.2 \
--add-needed /lib/x86_64-linux-gnu/libgmp.so.10 \
--add-needed /lib/x86_64-linux-gnu/libm.so.6 \
--add-needed /lib/x86_64-linux-gnu/libpthread.so.0 \
--add-needed /lib/x86_64-linux-gnu/librt.so.1 /tmp/ruby

❯ ./src/patchelf --print-needed /tmp/ruby
/lib/x86_64-linux-gnu/libcrypt.so.1
/lib/x86_64-linux-gnu/libdl.so.2
/lib/x86_64-linux-gnu/libgmp.so.10
/lib/x86_64-linux-gnu/libm.so.6
/lib/x86_64-linux-gnu/libpthread.so.0
/lib/x86_64-linux-gnu/librt.so.1
/lib/x86_64-linux-gnu/libcrypt.so.1
x86_64-linux-gnu/libdl.so.2

Please see that there are multiple copies of libcrypt.so.1 and libdl.so.2, the last one is not even a full path.

The .gnu.version_r also looks incorrect. It is now x86_64-linux-gnu/libdl.so.2 instead of glibc.

❯ readelf -a /tmp/ruby | grep -A 5 gnu.version_r
  [ 3] .gnu.version_r    VERNEED          00000000000006e0  000006e0
       0000000000000030  0000000000000000   A      22     1     8
  [ 4] .rela.dyn         RELA             0000000000000710  00000710
       00000000000000c0  0000000000000018   A       1     0     8
  [ 5] .rela.plt         RELA             00000000000007d0  000007d0
       00000000000000a8  0000000000000018  AI       1    16     8
--
   01     .dynsym .gnu.version .gnu.version_r .rela.dyn .rela.plt 
   02     
   03     .init .plt .plt.got .text .fini 
   04     .rodata .eh_frame_hdr .eh_frame 
   05     .eh_frame_hdr 
   06     .init_array .fini_array .got .data .bss 
--
Version needs section '.gnu.version_r' contains 1 entry:
 Addr: 0x00000000000006e0  Offset: 0x0006e0  Link: 22 (.dynstr)
  000000: Version: 1  File: x86_64-linux-gnu/libdl.so.2  Cnt: 2
  0x0010:   Name: GLIBC_2.4  Flags: none  Version: 3
  0x0020:   Name: GLIBC_2.2.5  Flags: none  Version: 2

Expected behavior

I expect the --print-needed to reflect what was passed in.

patchelf --version output

❯ ./src/patchelf --version
patchelf 0.14.3

Additional context

I discovered this also when trying to do the same in patchelf itself via #357

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