meson: Fix rpath clearing

Meson allows projects to set `build_rpath` property, containing paths
that will be added during build but will be removed when installing.

When Meson removes build_rpath from `DT_RUNPATH` entry, it just writes
the shorter ␀-terminated new rpath over the old one to reduce
the risk of potentially breaking the ELF files
(when the linker does string de-duplication or something).
But this can cause much bigger problem for Nix, as it can produce
cut-in-half-by-␀ store path references.

For example, in systemd’s libudev, it was removing three `$ORIGIN`-relative paths from

    $ORIGIN/../libsystemd:$ORIGIN/../basic:$ORIGIN/../shared:…␀

resulting in the following `DT_RUNPATH` entry:

    …␀store/v589pqjhvxrj73g3r0xb41yr84z5pwb7-gcc-9.3.0-lib/lib␀

We previously handled this in `fix-rpath.patch` but the method we prevent
Meson from removing paths added to rpath through `NIX_LDFLAGS` was changed
during 0.55.0 update and I forgot about this second purpose of the patch.

Let’s re-add this clearing code, as it worked without issues for a long time.
This commit is contained in:
Jan Tojnar 2020-08-11 15:30:39 +02:00 committed by Frederik Rietdijk
parent 52419cc32e
commit e8bfa708c4
2 changed files with 28 additions and 0 deletions

View file

@ -0,0 +1,20 @@
diff --git a/mesonbuild/scripts/depfixer.py b/mesonbuild/scripts/depfixer.py
index 77ac03d66..d12f77592 100644
--- a/mesonbuild/scripts/depfixer.py
+++ b/mesonbuild/scripts/depfixer.py
@@ -337,6 +337,15 @@ class Elf(DataSizes):
if not new_rpath:
self.remove_rpath_entry(entrynum)
else:
+ # Clear old rpath to avoid stale references,
+ # not heeding the warning above about de-duplication
+ # since it does not seem to cause issues for us
+ # and not doing so trips up Nixs reference checker.
+ # See https://github.com/NixOS/nixpkgs/pull/46020
+ # and https://github.com/NixOS/nixpkgs/issues/95163
+ self.bf.seek(rp_off)
+ self.bf.write(b'\0'*len(old_rpath))
+
self.bf.seek(rp_off)
self.bf.write(new_rpath)
self.bf.write(b'\0')

View file

@ -43,6 +43,14 @@ python3.pkgs.buildPythonApplication rec {
src = ./fix-rpath.patch;
inherit (builtins) storeDir;
})
# When Meson removes build_rpath from DT_RUNPATH entry, it just writes
# the shorter NUL-terminated new rpath over the old one to reduce
# the risk of potentially breaking the ELF files.
# But this can cause much bigger problem for Nix as it can produce
# cut-in-half-by-\0 store path references.
# Lets just clear the whole rpath and hope for the best.
./clear-old-rpath.patch
];
setupHook = ./setup-hook.sh;