From 112f281fc48bcb6d73df2642df1e12b151dfafcc Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Mon, 25 Oct 2021 02:55:09 +0200 Subject: [PATCH] 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-.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-.so. Fallout from 6063eb27b98939942e316771224c5653a9b2e59b [1] Commit d03a5fee80f2f72d https://github.com/containers/toolbox/pull/827 https://github.com/containers/toolbox/issues/821 --- src/go-build-wrapper | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/src/go-build-wrapper b/src/go-build-wrapper index 677dca94b..24eac674c 100755 --- a/src/go-build-wrapper +++ b/src/go-build-wrapper @@ -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