capture-libs: Never undo our rewriting of the symlink target
Previously, if we were using --remap-link-prefix but not --link-target
(as in pressure-vessel), and if the path at which we found the
library in the provider (needed_path_in_provider
) was such that
after resolving symlinks, the canonicalized result (path
) did not
match any of the --remap-link-prefix options, then we would reset
to using the needed_path_in_provider
as the symlink target.
However, this was wrong, because it did not take into account the possibility that the original path might have matched one of the --remap-link-prefix options even though its canonicalized version didn't.
For example, consider the NixOS "FHS environment", a bwrap-based
container that has been populated with symlinks of the form
/lib/libGL.so.1 -> /nix/store/something. Depending on the precise
behaviour of libc and libdl (the exact trigger for the differing
behaviour is unknown), when we open that library, we might find
that the needed_path_in_provider
is either /lib/libGL.so.1
or a path below /nix/store.
If the needed_path_in_provider
is /lib/libGL.so.1, we would
canonicalize it to /nix/store/something, then decide that
/nix/store/something didn't match any of the remapping rules such
as /lib*
→ /run/host/lib*
, and go back to using /lib/libGL.so.1
as the symlink target. But, inside pressure-vessel's container, /lib
is from the container runtime and not the provider - which is precisely
why we need to rewrite /lib paths to /run/host/lib in order to be
able to find the library we want.
Instead, we must limit the situation where we keep the
needed_path_in_provider
as-is to the situation where there is no
symlink target rewriting: no --link-target, and no --remap-link-prefix.
In this situation, we are expecting the meaning of a symlink in the
container environment to be identical to the meaning of a symlink in
the environment from which we are running capsule-capture-libs,
therefore it's slightly preferable to use a non-canonicalized symlink
if we have one: that way, if the target of a symlink changes during
the container's lifetime (perhaps as a result of an OS upgrade),
it will still work.
Conversely, if we are using either --link-target or --remap-link-prefix, we want to stick to using only the canonicalized paths of libraries, because that's the only way we can avoid a symlink being interpreted differently outside and inside the container, for example as a result of its parent directory being mounted in a different place, or as a result of something different being mounted at its target.
This means that we have to relax one of our test assertions slightly.
Helps: https://github.com/ValveSoftware/steam-runtime/issues/684