improve error message for missing /etc/subuid entry (closes: #9)

This commit is contained in:
Joe Groocock 2021-08-18 22:15:05 +02:00 committed by Johannes Schauer Marin Rodrigues
parent 3c37d692a0
commit 15029c1c3b
Signed by untrusted user: josch
GPG key ID: F2CBA5C78FBD83E1
2 changed files with 83 additions and 5 deletions

View file

@ -120,7 +120,7 @@ if [ ! -e shared/hooks/eatmydata/customize.sh ] || [ hooks/eatmydata/customize.s
fi fi
fi fi
starttime= starttime=
total=196 total=198
skipped=0 skipped=0
runtests=0 runtests=0
i=1 i=1
@ -526,6 +526,63 @@ else
runtests=$((runtests+1)) runtests=$((runtests+1))
fi fi
print_header "mode=unshare,variant=apt: fail without /etc/subuid"
cat << END > shared/test.sh
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
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
sysctl -w kernel.unprivileged_userns_clone=1
rm /etc/subuid
ret=0
runuser -u user -- $CMD --mode=unshare --variant=apt $DEFAULT_DIST /tmp/debian-chroot $mirror || ret=\$?
if [ "\$ret" = 0 ]; then
echo expected failure but got exit \$ret >&2
exit 1
fi
rm -r /tmp/debian-chroot
END
if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh
runtests=$((runtests+1))
else
echo "HAVE_QEMU != yes -- Skipping test..." >&2
skipped=$((skipped+1))
fi
print_header "mode=unshare,variant=apt: fail without username in /etc/subuid"
cat << END > shared/test.sh
#!/bin/sh
set -eu
export LC_ALL=C.UTF-8
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
sysctl -w kernel.unprivileged_userns_clone=1
awk -F: '\$1!="user"' /etc/subuid > /etc/subuid.tmp
mv /etc/subuid.tmp /etc/subuid
ret=0
runuser -u user -- $CMD --mode=unshare --variant=apt $DEFAULT_DIST /tmp/debian-chroot $mirror || ret=\$?
if [ "\$ret" = 0 ]; then
echo expected failure but got exit \$ret >&2
exit 1
fi
rm -r /tmp/debian-chroot
END
if [ "$HAVE_QEMU" = "yes" ]; then
./run_qemu.sh
runtests=$((runtests+1))
else
echo "HAVE_QEMU != yes -- Skipping test..." >&2
skipped=$((skipped+1))
fi
# Before running unshare mode as root, we run "unshare --mount" but that fails # Before running unshare mode as root, we run "unshare --mount" but that fails
# if mmdebstrap itself is executed from within a chroot: # if mmdebstrap itself is executed from within a chroot:
# unshare: cannot change root filesystem propagation: Invalid argument # unshare: cannot change root filesystem propagation: Invalid argument

View file

@ -345,6 +345,14 @@ sub read_subuid_subgid() {
last if ($n eq $username); last if ($n eq $username);
} }
close $fh; close $fh;
if (!length $subid) {
warning "/etc/subuid is empty";
return;
}
if ($n ne $username) {
warning "no entry in /etc/subuid for $username";
return;
}
push @result, ["u", 0, $subid, $num_subid]; push @result, ["u", 0, $subid, $num_subid];
if (scalar(@result) < 1) { if (scalar(@result) < 1) {
@ -363,6 +371,14 @@ sub read_subuid_subgid() {
last if ($n eq $username); last if ($n eq $username);
} }
close $fh; close $fh;
if (!length $subid) {
warning "/etc/subgid is empty";
return;
}
if ($n ne $username) {
warning "no entry in /etc/subgid for $username";
return;
}
push @result, ["g", 0, $subid, $num_subid]; push @result, ["g", 0, $subid, $num_subid];
if (scalar(@result) < 2) { if (scalar(@result) < 2) {
@ -4250,8 +4266,11 @@ sub main() {
if ($EFFECTIVE_USER_ID != 0 && !test_unshare_userns(1)) { if ($EFFECTIVE_USER_ID != 0 && !test_unshare_userns(1)) {
exit 1; exit 1;
} }
my @idmap = read_subuid_subgid; my @idmap = ();
my $pid = get_unshare_cmd( if ($EFFECTIVE_USER_ID != 0) {
@idmap = read_subuid_subgid;
}
my $pid = get_unshare_cmd(
sub { sub {
0 == system @ARGV[1 .. $#ARGV] or error "system failed: $?"; 0 == system @ARGV[1 .. $#ARGV] or error "system failed: $?";
}, },
@ -5372,12 +5391,14 @@ sub main() {
my @idmap; my @idmap;
# for unshare mode the rootfs directory has to have appropriate # for unshare mode the rootfs directory has to have appropriate
# permissions # permissions
if ($options->{mode} eq 'unshare') { if ($EFFECTIVE_USER_ID != 0 and $options->{mode} eq 'unshare') {
@idmap = read_subuid_subgid; @idmap = read_subuid_subgid;
# sanity check # sanity check
if ( scalar(@idmap) != 2 if ( scalar(@idmap) != 2
|| $idmap[0][0] ne 'u' || $idmap[0][0] ne 'u'
|| $idmap[1][0] ne 'g') { || $idmap[1][0] ne 'g'
|| !length $idmap[0][2]
|| !length $idmap[1][2]) {
error "invalid idmap"; error "invalid idmap";
} }