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

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

Closed
fzakaria opened this issue Dec 18, 2021 · 0 comments · Fixed by #361
Closed

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

fzakaria opened this issue Dec 18, 2021 · 0 comments · Fixed by #361
Labels

Comments

@fzakaria
Copy link
Contributor

fzakaria commented Dec 18, 2021

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

@fzakaria fzakaria added the bug label Dec 18, 2021
fzakaria added a commit to fzakaria/patchelf that referenced this issue Dec 21, 2021
`patchelf` previously would incorrectly patch the ELF header if it was
called with multiple changes at once such as _add_ & _replace_.

In order to support that, rewrite the sections in between each section
modification.

Fix NixOS#359
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