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

Using patchelf and llvm-strip in sequence corrupts ELF files #507

Open
mologie opened this issue Jul 14, 2023 · 1 comment
Open

Using patchelf and llvm-strip in sequence corrupts ELF files #507

mologie opened this issue Jul 14, 2023 · 1 comment
Labels

Comments

@mologie
Copy link

mologie commented Jul 14, 2023

Describe the bug

Running patchelf on any ELF file causes llvm-strip-14 to corrupt it afterwards. (One might argue that this is an llvm-strip bug, and it probably is, but patchelf might be able to produce an ELF file in a format that's still processable with LLVM.)

Affects: All patchelf versions from 0.14 to 0.18 that I tested, LLVM 14 and 15

Steps To Reproduce

tl;dr: Run patchelf --set-rpath '$ORIGIN' on any binary, then run llvm-strip with standard args on it. The output is always corrupted.

Use an Ubuntu 22.04 image and install llvm-14-tools for llvm-strip-14. (llvm-15-tools is similarly affected.)

$ wget https://github.com/NixOS/patchelf/releases/download/0.18.0/patchelf-0.18.0-x86_64.tar.gz
[...]
$ tar xf patchelf-0.18.0-x86_64.tar.gz
$ export PATH=$PWD/bin:$PATH
$ echo 'int main() { return 0; }' > a.c
$ clang -Os -o a a.c
$ file a
a: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5a1afb6fe3c09ec9355fe3dfe35d4160dadb606d, for GNU/Linux 3.2.0, not stripped
$ ./a
$ llvm-strip --version
llvm-strip, compatible with GNU strip
Ubuntu LLVM version 14.0.0
  
  Optimized build.
  Default target: x86_64-pc-linux-gnu
  Host CPU: skylake
$ clang --version
Ubuntu clang version 14.0.0-1ubuntu1
Target: x86_64-pc-linux-gnu
Thread model: posix
InstalledDir: /usr/bin
$ patchelf --version
patchelf 0.18.0
$ llvm-strip -o a.stripped a
$ ./a.stripped
$ patchelf --set-rpath '$ORIGIN' --output a.patched a
$ ./a.patched
$ llvm-strip -o a.patched.stripped a.patched
$ ldd a.patched.stripped
	not a dynamic executable
$ file a.patched.stripped
a.patched.stripped: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=5a1afb6fe3c09ec9355fe3dfe35d4160dadb606d, for GNU/Linux 3.2.0, stripped
$ ./a.patched.stripped
[1]    31807 segmentation fault  ./a.patched.stripped

The a.* binaries are attached: patchelf-strip-corruption.tar.gz

Expected behavior

I expected llvm-strip to work. Specifically, I'd have expected the ldd a.patched.stripped command to report that it's still a dynamic executable, and ./a.patched.stripped should not have segfaulted.

patchelf --version output

patchelf 0.18.0

Additional context

Files in this report are from Ubuntu 22.04 x86_64, but it appears to happen on any OS and with any LLVM distribution. Gave Arch Linux x86_64 and Ubuntu for arm64 a shot. Strip from binutils does not corrupt the ELF files.

@mologie mologie added the bug label Jul 14, 2023
@HeavenVolkoff
Copy link

Just hit this bug. I have a script that, after building a couple of shared libraries, executes patchelf --set-rpath '$ORIGIN' then llvm-strip-16 -S, and I got that same result as @mologie:

ubuntu@ubuntu:~/Workspace/native-deps/out/lib$ ldd libpdfium.so 
	not a dynamic executable

Inverting the patchelf call with llvm-strip fixed the issue

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants