From e4ef326b59ba1fc8e6f92ff8c9fd8986ceadadae Mon Sep 17 00:00:00 2001 From: Johannes Schauer Marin Rodrigues Date: Sun, 29 May 2022 07:50:10 +0200 Subject: [PATCH] Only set up FAKECHROOT_CMD_SUBST for paths in PATH containing the original binary If FAKECHROOT_CMD_SUBST sets up wrong substitutions, then binaries cannot be found. For example if /usr/bin/chroot is listed in FAKECHROOT_CMD_SUBST but /usr/sbin (the actual location of the chroot binary) is not in PATH, the command fails --- coverage.txt | 3 +++ mmdebstrap | 25 ++++++++++++++++--------- tests/no-sbin-in-path | 22 ++++++++++++++++++++++ 3 files changed, 41 insertions(+), 9 deletions(-) create mode 100644 tests/no-sbin-in-path diff --git a/coverage.txt b/coverage.txt index dfc7a87..9ff7aa7 100644 --- a/coverage.txt +++ b/coverage.txt @@ -312,3 +312,6 @@ Skip-If: hostarch != "amd64" mode == "fakechroot" and not run_ma_same_tests not have_binfmt + +Test: no-sbin-in-path +Modes: fakechroot diff --git a/mmdebstrap b/mmdebstrap index 14ad01d..0f30e58 100755 --- a/mmdebstrap +++ b/mmdebstrap @@ -2346,17 +2346,24 @@ sub run_prepare { # /etc/fakechroot/debootstrap.env and # /etc/fakechroot/chroot.env { - my $ldconfig = getcwd() . '/ldconfig.fakechroot'; - if (!-x $ldconfig) { - $ldconfig = '/usr/libexec/mmdebstrap/ldconfig.fakechroot'; + my %subst = ( + chroot => "/usr/sbin/chroot.fakechroot", + mkfifo => "/bin/true", + ldconfig => (getcwd() . '/ldconfig.fakechroot'), + ldd => "/usr/bin/ldd.fakechroot", + ischroot => "/bin/true" + ); + if (!-x $subst{ldconfig}) { + $subst{ldconfig} + = '/usr/libexec/mmdebstrap/ldconfig.fakechroot'; } my @fakechrootsubst = (); - foreach my $d ('/usr/sbin', '/usr/bin', '/sbin', '/bin') { - push @fakechrootsubst, "$d/chroot=/usr/sbin/chroot.fakechroot"; - push @fakechrootsubst, "$d/mkfifo=/bin/true"; - push @fakechrootsubst, "$d/ldconfig=$ldconfig"; - push @fakechrootsubst, "$d/ldd=/usr/bin/ldd.fakechroot"; - push @fakechrootsubst, "$d/ischroot=/bin/true"; + foreach my $d (split ':', $ENV{PATH}) { + foreach my $k (sort keys %subst) { + if (-e "$d/$k") { + push @fakechrootsubst, "$d/$k=$subst{$k}"; + } + } } if (defined $ENV{FAKECHROOT_CMD_SUBST} && $ENV{FAKECHROOT_CMD_SUBST} ne "") { diff --git a/tests/no-sbin-in-path b/tests/no-sbin-in-path new file mode 100644 index 0000000..bf8628f --- /dev/null +++ b/tests/no-sbin-in-path @@ -0,0 +1,22 @@ +#!/bin/sh +# +# If FAKECHROOT_CMD_SUBST sets up wrong substitutions, then binaries cannot be +# found. For example if /usr/bin/chroot is listed in FAKECHROOT_CMD_SUBST but +# /usr/sbin (the actual location of the chroot binary) is not in PATH, the +# command fails + +set -eu +export LC_ALL=C.UTF-8 +[ "{{ MODE }}" = "fakechroot" ] +trap "rm -f /tmp/debian-chroot.tar" EXIT INT TERM +if [ "$(id -u)" -eq 0 ] && ! id -u user > /dev/null 2>&1; then + if [ ! -e /mmdebstrap-testenv ]; then + echo "this test modifies the system and should only be run inside a container" >&2 + exit 1 + fi + adduser --gecos user --disabled-password user +fi +prefix= +[ "$(id -u)" -eq 0 ] && prefix="runuser -u user --" +$prefix env PATH=/usr/bin:/bin fakechroot fakeroot {{ CMD }} --mode=fakechroot --variant=apt {{ DIST }} /tmp/debian-chroot.tar {{ MIRROR }} +tar -tf /tmp/debian-chroot.tar | sort | diff -u tar1.txt -