From 165cc82f97ddf2315d3cc914cb748e8bd7a9ab14 Mon Sep 17 00:00:00 2001 From: Johannes 'josch' Schauer Date: Sun, 29 Nov 2020 20:54:31 +0100 Subject: [PATCH] preserve permissions of /etc/resolv.conf and /etc/hostname and resolve symlinks as debootstrap does it --- coverage.sh | 120 +++++++++++++++++++++++++++++++++++++++++++++++++++- mmdebstrap | 30 +++++++------ 2 files changed, 135 insertions(+), 15 deletions(-) diff --git a/coverage.sh b/coverage.sh index 99be8ac..5921170 100755 --- a/coverage.sh +++ b/coverage.sh @@ -118,9 +118,8 @@ if [ ! -e shared/hooks/eatmydata/customize.sh ] || [ hooks/eatmydata/customize.s cp -a /usr/share/mmdebstrap/hooks/eatmydata/customize.sh shared/hooks/eatmydata/ fi fi - starttime= -total=165 +total=166 skipped=0 runtests=0 i=1 @@ -2452,6 +2451,123 @@ else skipped=$((skipped+1)) fi +print_header "mode=$defaultmode,variant=custom: preserve mode of /etc/resolv.conf and /etc/hostname" +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 +for f in /etc/resolv.conf /etc/hostname; do + # preserve original content + cat "\$f" > "\$f.bak" + # in case \$f is a symlink, we replace it by a real file + if [ -L "\$f" ]; then + rm "\$f" + cp "\$f.bak" "\$f" + fi + chmod 644 "\$f" + [ "\$(stat --format=%A "\$f")" = "-rw-r--r--" ] +done +$CMD --variant=custom --mode=$defaultmode $DEFAULT_DIST /tmp/debian-chroot $mirror +for f in /etc/resolv.conf /etc/hostname; do + [ "\$(stat --format=%A "/tmp/debian-chroot/\$f")" = "-rw-r--r--" ] +done +rm /tmp/debian-chroot/dev/console +rm /tmp/debian-chroot/dev/fd +rm /tmp/debian-chroot/dev/full +rm /tmp/debian-chroot/dev/null +rm /tmp/debian-chroot/dev/ptmx +rm /tmp/debian-chroot/dev/random +rm /tmp/debian-chroot/dev/stderr +rm /tmp/debian-chroot/dev/stdin +rm /tmp/debian-chroot/dev/stdout +rm /tmp/debian-chroot/dev/tty +rm /tmp/debian-chroot/dev/urandom +rm /tmp/debian-chroot/dev/zero +rm /tmp/debian-chroot/etc/apt/sources.list +rm /tmp/debian-chroot/etc/fstab +rm /tmp/debian-chroot/etc/hostname +rm /tmp/debian-chroot/etc/resolv.conf +rm /tmp/debian-chroot/var/lib/apt/lists/lock +rm /tmp/debian-chroot/var/lib/dpkg/available +rm /tmp/debian-chroot/var/lib/dpkg/cmethopt +rm /tmp/debian-chroot/var/lib/dpkg/status +# the rest should be empty directories that we can rmdir recursively +find /tmp/debian-chroot -depth -print0 | xargs -0 rmdir +for f in /etc/resolv.conf /etc/hostname; do + chmod 755 "\$f" + [ "\$(stat --format=%A "\$f")" = "-rwxr-xr-x" ] +done +$CMD --variant=custom --mode=$defaultmode $DEFAULT_DIST /tmp/debian-chroot $mirror +for f in /etc/resolv.conf /etc/hostname; do + [ "\$(stat --format=%A "/tmp/debian-chroot/\$f")" = "-rwxr-xr-x" ] +done +rm /tmp/debian-chroot/dev/console +rm /tmp/debian-chroot/dev/fd +rm /tmp/debian-chroot/dev/full +rm /tmp/debian-chroot/dev/null +rm /tmp/debian-chroot/dev/ptmx +rm /tmp/debian-chroot/dev/random +rm /tmp/debian-chroot/dev/stderr +rm /tmp/debian-chroot/dev/stdin +rm /tmp/debian-chroot/dev/stdout +rm /tmp/debian-chroot/dev/tty +rm /tmp/debian-chroot/dev/urandom +rm /tmp/debian-chroot/dev/zero +rm /tmp/debian-chroot/etc/apt/sources.list +rm /tmp/debian-chroot/etc/fstab +rm /tmp/debian-chroot/etc/hostname +rm /tmp/debian-chroot/etc/resolv.conf +rm /tmp/debian-chroot/var/lib/apt/lists/lock +rm /tmp/debian-chroot/var/lib/dpkg/available +rm /tmp/debian-chroot/var/lib/dpkg/cmethopt +rm /tmp/debian-chroot/var/lib/dpkg/status +# the rest should be empty directories that we can rmdir recursively +find /tmp/debian-chroot -depth -print0 | xargs -0 rmdir +for f in /etc/resolv.conf /etc/hostname; do + rm "\$f" + ln -s "\$f.bak" "\$f" + [ "\$(stat --format=%A "\$f")" = "lrwxrwxrwx" ] +done +$CMD --variant=custom --mode=$defaultmode $DEFAULT_DIST /tmp/debian-chroot $mirror +for f in /etc/resolv.conf /etc/hostname; do + [ "\$(stat --format=%A "/tmp/debian-chroot/\$f")" = "-rw-r--r--" ] +done +rm /tmp/debian-chroot/dev/console +rm /tmp/debian-chroot/dev/fd +rm /tmp/debian-chroot/dev/full +rm /tmp/debian-chroot/dev/null +rm /tmp/debian-chroot/dev/ptmx +rm /tmp/debian-chroot/dev/random +rm /tmp/debian-chroot/dev/stderr +rm /tmp/debian-chroot/dev/stdin +rm /tmp/debian-chroot/dev/stdout +rm /tmp/debian-chroot/dev/tty +rm /tmp/debian-chroot/dev/urandom +rm /tmp/debian-chroot/dev/zero +rm /tmp/debian-chroot/etc/apt/sources.list +rm /tmp/debian-chroot/etc/fstab +rm /tmp/debian-chroot/etc/hostname +rm /tmp/debian-chroot/etc/resolv.conf +rm /tmp/debian-chroot/var/lib/apt/lists/lock +rm /tmp/debian-chroot/var/lib/dpkg/available +rm /tmp/debian-chroot/var/lib/dpkg/cmethopt +rm /tmp/debian-chroot/var/lib/dpkg/status +# the rest should be empty directories that we can rmdir recursively +find /tmp/debian-chroot -depth -print0 | xargs -0 rmdir +END +if [ "$HAVE_QEMU" = "yes" ]; then + ./run_qemu.sh + runtests=$((runtests+1)) +else + echo "HAVE_QEMU != yes -- Skipping test..." >&2 + skipped=$((skipped+1)) +fi +exit 0 + print_header "mode=$defaultmode,variant=essential: test not having to install apt in --include because a hook did it before" cat << END > shared/test.sh #!/bin/sh diff --git a/mmdebstrap b/mmdebstrap index 129b04a..ffcd1b1 100755 --- a/mmdebstrap +++ b/mmdebstrap @@ -1662,19 +1662,23 @@ sub run_setup() { } # allow network access from within - if (-e "/etc/resolv.conf") { - copy("/etc/resolv.conf", "$options->{root}/etc/resolv.conf") - or error "cannot copy /etc/resolv.conf: $!"; - } else { - warning("Host system does not have a /etc/resolv.conf to copy into the" - . " rootfs."); - } - if (-e "/etc/hostname") { - copy("/etc/hostname", "$options->{root}/etc/hostname") - or error "cannot copy /etc/hostname: $!"; - } else { - warning("Host system does not have a /etc/hostname to copy into the" - . " rootfs."); + foreach my $file ("/etc/resolv.conf", "/etc/hostname") { + if (-e $file) { + # this will create a new file with 644 permissions and copy + # contents only even if $file was a symlink + copy($file, "$options->{root}/$file") + or error "cannot copy $file: $!"; + # if the source was a regular file, preserve the permissions + if (-f $file) { + my $mode = (stat($file))[2]; + $mode &= oct(7777); # mask off bits that aren't the mode + chmod $mode, "$options->{root}/$file" + or error "cannot chmod $file: $!"; + } + } else { + warning("Host system does not have a $file to copy into the" + . " rootfs."); + } } if ($options->{havemknod}) {