build: Restore backwards compatibility with existing containers

The path of the dynamic linker (ie., PT_INTERP), as specified in an
architecture's ABI, often starts with /lib or /lib64, not /usr/lib or
/usr/lib64. eg., it's /lib/ld-linux-aarch64.so.1 for aarch64 and
/lib64/ld-linux-x86-64.so.2 for x86_64.

Unfortunately, until very recently [1], only the host's /usr was
present inside a toolbox container's /run/host, not /lib or /lib64.
Therefore, simply prepending /run/host to the /usr/bin/toolbox
binary's existing PT_INTERP entry wouldn't locate the host's dynamic
linker inside the toolbox container. This broke backwards compatibility
with every container out there, except the ones created with the
current development version in Git.

To restore backwards compatibility, the /lib and /lib64 symbolic links
must be resolved to their respective locations inside /usr.

The following caveats must be noted:

  * With glibc, even the basename of the path of the dynamic linker as
    specified in an architecture's ABI, is a symbolic link to a file
    named ld-<glibc-version>.so. However, this file can't be used as
    the PT_INTERP entry, because its name will change when glibc is
    updated and the PT_INTERP entry will become invalid until the
    /usr/bin/toolbox binary is rebuilt.

  * On Debian, a path like /lib64/ld-linux-x86-64.so.2 doesn't resolve
    to something inside /usr/lib64. Instead it ends up inside
    /usr/lib/x86_64-linux-gnu through a series of symbolic links:
      - /lib64 -> usr/lib64
      - /usr/lib64/ld-linux-x86-64.so.2
          -> /lib/x86_64-linux-gnu/ld-2.28.so
      - /lib -> usr/lib

  * It's assumed that a symbolic link with the basename specified in
    the ABI lives in the same directory as the actual dynamic linker
    binary named ld-<glibc-version>.so.

Fallout from 6063eb27b9

[1] Commit d03a5fee80
    https://github.com/containers/toolbox/pull/827

https://github.com/containers/toolbox/issues/821
This commit is contained in:
Debarshi Ray 2021-10-25 02:55:09 +02:00
parent 606b37b226
commit 112f281fc4

View file

@ -34,8 +34,25 @@ if ! interpreter=$(patchelf --print-interpreter "$2/toolbox"); then
exit 1
fi
if ! patchelf --set-interpreter "/run/host$interpreter" "$2/toolbox"; then
echo "go-build-wrapper: failed to change PT_INTERP of $2/toolbox to /run/host$interpreter" >&2
if ! interpreter_canonical=$(readlink --canonicalize "$interpreter"); then
echo "go-build-wrapper: failed to canonicalize PT_INTERP" >&2
exit 1
fi
if ! interpreter_basename=$(basename "$interpreter"); then
echo "go-build-wrapper: failed to read the basename of PT_INTERP" >&2
exit 1
fi
if ! interpreter_canonical_dirname=$(dirname "$interpreter_canonical"); then
echo "go-build-wrapper: failed to read the dirname of the canonicalized PT_INTERP" >&2
exit 1
fi
interpreter="/run/host$interpreter_canonical_dirname/$interpreter_basename"
if ! patchelf --set-interpreter "$interpreter" "$2/toolbox"; then
echo "go-build-wrapper: failed to change PT_INTERP of $2/toolbox to $interpreter" >&2
exit 1
fi