#417870 fakechroot: libtool's use of rpath fails under fakechroot

#417870#5
Date:
2007-04-05 05:25:06 UTC
From:
To:
A package using libtool to build shared libraries, and then run them
in-tree, ends up having two executables and a helper script... one of
the executables is .libs/lt-foo and it has a run-time-link-path encoded into
it (objdump -p, look for RPATH under "Dynamic Section:") that gives an
absolute path to the the build tree, so it can find the just-built
libraries (instead of looking for not-yet-installed ones.)

That works fine normally... but under fakechroot
  * the path is an "internal" path, ie. relative to $FAKECHROOT_BASE
  * /lib/ld-linux.so is not fakeroot-aware
  * /lib/ld-linux.so is loaded first (it *is* the dynamic linker,
    after all), so inherently can't have symbols overridden via LD_PRELOAD.

The *big* problem here is that if you have an older version of the
package installed on the "outside" system,
  * the libraries aren't found in the RPATH location, because it
    doesn't exist
  * the libraries are then found in the *outside* /usr/lib

(In my case, I found it because on one system (with a mostly current
outside version of the package), everything worked fine, and on
another system (with a stale outside version) shared lib
incompatiblities led to segfaults... which was actually *better*
because it exposed the problem :-)

A full solution could involve having the execve() wrapper notice that
an object is ELF, then that its interpreter is /lib/ld-linux.so, and
run an alternate fakechroot-aware version (giving a slightly different
path for the invocation of some executables, I'm not sure of the
subtleties here, but manual tests seem to work.)

A decent shortcut (which I'm using myself) is to have the execve()
wrapper check as above, but then also check for RPATH, and if one is
found, "unfake" it and stuff it into the start of LD_LIBRARY_PATH.
This has a bug -- if the raw RPATH value actually corresponds to an
existing outside directory, the libs will be taken from that outside
directory.  In practice, using this under pbuilder gets somewhat
unique directories, which is sufficient for some uses.

(Note that this exposes a secondary bug - all dynamic executables
[which in practice is everything] inside the fake chroot end up
running the *outside* /lib/ld-linux.so... which could matter if you
had a significantly different inside vs. outside linux.)

#417870#10
Date:
2023-02-02 12:19:15 UTC
From:
To:
Hi,

Johannes asked me to briefly explain how this bug affects mmdebstrap.

If you use mmdebstrap unprivileged on a Debian testing system without
user namespaces (e.g. during an unprivileged autopkgtest) and try to
bootstrap unstable, you may run into this issue, because systemd heavily
employs RPATHs to load libsystemd-shared. When e.g. systemd-sysusers is
invoked, it loads its libraries and - due to the RPATH - picks up the
system copy of libsystemd-shared rather than the chroot copy. If these
differ (e.g. because testing lags behind unstable), it may lack symbols
and the program may fail to start.

I think this makes mmdebstrap's --mode=fakechroot rather limited to
situations where the bootstrapped release exactly matches the system
release.

Helmut