patchelf
patchelf copied to clipboard
To patch a binary with patchelf lead to inconsistency.
Describe the bug
Hello. I patched a binary with:
./patchelf --set-interpreter /media/34GB/Arquivos-de-Programas-Linux/Glibc-2.17-32bit/lib/ld-linux.so.2 --set-rpath /media/34GB/Arquivos-de-Programas-Linux/Glibc-2.17-32bit/ /media/34GB/Arquivos-de-Programas-Linux/palemoon/palemoon
then tried to run it with: "./palemoon", which returned:
"Inconsistency detected by ld.so: dl-lookup.c: 877: _dl_setup_hash: Assertion `(bitmask_nwords & (bitmask_nwords - 1)) == 0' failed!"
So, what is happening?
I would say the GNU_HASH section or offset is incorrect now. Do you have a simpler binary to reproduce this?
This is the assertion that broke. https://github.com/bminor/glibc/blob/1d7b32ee6145c46c4f4f8a208a6b72e0668d7cf3/elf/dl-lookup.c#L966
Unfortunately I am seeing this as well. Note that this is a different issue from https://github.com/NixOS/patchelf/pull/365. patchelf --set-rpath causes corruption, but patchelf --set-interpreter works correctly.
To reproduce, clone this branch, edit /nix/git/bootstrap/pkgs/stdenv/linux/bootstrap-files/mips64el.nix and set use_chrpath=false and then:
nix-build -E '(import nixpkgs/pkgs/stdenv/linux/make-bootstrap-tools-cross.nix { }).mips64el-linux-gnuabi64.build'
and then on a mips64el host,
nix-env -iA hello
which leads to:
patching /nix/store/rvd1jsza35vmzmdmmfbd1n847kkcdrld-bootstrap-tools/lib/libpcre.so.1.2.13
patching /nix/store/rvd1jsza35vmzmdmmfbd1n847kkcdrld-bootstrap-tools/lib/libpcreposix.so.0.0.7
Inconsistency detected by ld.so: dl-lookup.c: 966: _dl_setup_hash: Assertion `(bitmask_nwords & (bitmask_nwords - 1)) == 0' failed!
error: builder for '/nix/store/nqj5ibp0h24vmzag3xdjqri88l554c7r-bootstrap-tools.drv' failed with exit code 127
error: 1 dependencies of derivation '/nix/store/drdgqh268hwx9gx85i6hg09hwcv79p1j-acl-2.3.1.drv' failed to build
error: 1 dependencies of derivation '/nix/store/yslxxijchi29r32rinr4iq0iqhgh552v-bash-5.1-p12.drv' failed to build
error: 1 dependencies of derivation '/nix/store/m1f8mlb5g02pxd04n1gs6wi9l0dm17cc-hello-2.12.drv' failed to build
If you leave use_chrpath set to true everything will work, and you will get a full bootstrap of nixpkgs on mips64el.
Is this also reproducible with binfmt/qemu-user? That would greatly help with reproducing the issue.
~~I think I found the fix: https://github.com/a-m-joseph/patchelf/commit/75c9f5277d6ce3f7af6b4e46ef59434a04509f48~~
~~Testing now.~~
Hang on.
I found the culprit.
patchelf isn't corrupting the executable binaries.
It's corrupting librt-2.33.so, which is then loaded by (all of) the binaries, causing a crash in the dynamic loader.
Curiously, librt-2.33.so has no rpath at all, so there really is no need to --set-rpath it. I wonder if this is the source of the bug: that "patchelf --force-rpath --set-rpath" does not cope well with being invoked on a library that has no rpath to begin with?
In any event, the fix for nixpkgs is now easy: simply don't patchelf librt-2.33.so. This fixes it:
https://github.com/a-m-joseph/nixpkgs/tree/bootstrap-tools-dont-patchelf-librt
I'm not sure if I should submit this PR to nixpkgs, however... I can imagine that they might say "noticing empty RPATHs is patchelf's job". What do people think?
The branch below (which builds on the patch above) is now well on its way with the bootstrap on mips64el. Notably, this is the first time I've been able to get that to happen without inserting chrpath into the bootstrap-files.tar.xz tarball, which I always figured would have been a very unpopular change to try to make.
https://github.com/a-m-joseph/nixpkgs/tree/mips64-bootstrap
I'm not sure if I should submit this PR to nixpkgs, however... I can imagine that they might say "noticing empty RPATHs is patchelf's job".
Either case (change unpack-bootstrap-tools.sh vs change patchelf) will force a global rebuild of nixpkgs, so I proposed the PR to nixpkgs: https://github.com/NixOS/nixpkgs/pull/161925
I'm no longer sure that the issue I'm experiencing is the same one as the person who opened this bug, so I have created a separate bug #368 with reproducible steps to trigger the bug.