From 5a735d593f63f183db908a6ada70621ecbea6565 Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Wed, 31 Jul 2024 17:10:07 -0300 Subject: [PATCH 1/3] tests: refactor logic that makes mntpoint private for tests The tests that use pivot_root or move mountpoints with mount have to make sure that / is private for the tests to work. Refactor that logic into a file to be sourced by the test scripts Signed-off-by: Georgia Garcia --- .../apparmor/attach_disconnected.sh | 26 +++---------------- tests/regression/apparmor/mount.inc | 26 +++++++++++++++++++ tests/regression/apparmor/mount.sh | 24 +++-------------- tests/regression/apparmor/pivot_root.sh | 26 +++---------------- 4 files changed, 35 insertions(+), 67 deletions(-) create mode 100644 tests/regression/apparmor/mount.inc diff --git a/tests/regression/apparmor/attach_disconnected.sh b/tests/regression/apparmor/attach_disconnected.sh index bb6dced26..b0a43862f 100644 --- a/tests/regression/apparmor/attach_disconnected.sh +++ b/tests/regression/apparmor/attach_disconnected.sh @@ -23,12 +23,13 @@ settest unix_fd_server disk_img=$tmpdir/disk_img new_root=$tmpdir/new_root/ put_old=${new_root}put_old/ -root_was_shared="no" fstype="ext2" file=$tmpdir/file socket=$tmpdir/unix_fd_test att_dis_client=$pwd/attach_disconnected +. $bin/mount.inc + attach_disconnected_cleanup() { if [ ! -z "$loop_device" ]; then losetup -d $loop_device @@ -39,10 +40,7 @@ attach_disconnected_cleanup() { umount "$new_root" fi - if [ "$root_was_shared" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as shared' - mount --make-shared / - fi + prop_cleanup } do_onexit="attach_disconnected_cleanup" @@ -50,24 +48,6 @@ if [ ! -b /dev/loop0 ] ; then modprobe loop fi -# systemd mounts / and everything under it MS_SHARED. This breaks -# pivot_root entirely, so attempt to detect it, and remount / -# MS_PRIVATE temporarily. -FINDMNT=/bin/findmnt -if [ -x "${FINDMNT}" ] && ${FINDMNT} -no PROPAGATION / > /dev/null 2>&1 ; then - if [ "$(${FINDMNT} -no PROPAGATION /)" = "shared" ] ; then - root_was_shared="yes" - fi -elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then - # no findmnt or findmnt doesn't know the PROPAGATION column, - # but init is systemd so assume rootfs is shared - root_was_shared="yes" -fi -if [ "${root_was_shared}" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as private' - mount --make-private / -fi - dd if=/dev/zero of="$disk_img" bs=1024 count=512 2> /dev/null /sbin/mkfs -t "$fstype" -F "$disk_img" > /dev/null 2> /dev/null # mounting will be done by the test binary diff --git a/tests/regression/apparmor/mount.inc b/tests/regression/apparmor/mount.inc new file mode 100644 index 000000000..b9e7fd6b2 --- /dev/null +++ b/tests/regression/apparmor/mount.inc @@ -0,0 +1,26 @@ +root_was_shared="no" + +# systemd mounts / and everything under it MS_SHARED. This breaks +# pivot_root and mount "move" operations entirely, so attempt to +# detect it, and remount / MS_PRIVATE temporarily. +FINDMNT=/bin/findmnt +if [ -x "${FINDMNT}" ] && ${FINDMNT} -no PROPAGATION / > /dev/null 2>&1 ; then + if [ "$(${FINDMNT} -no PROPAGATION /)" = "shared" ] ; then + root_was_shared="yes" + fi +elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then + # no findmnt or findmnt doesn't know the PROPAGATION column, + # but init is systemd so assume rootfs is shared + root_was_shared="yes" +fi +if [ "${root_was_shared}" = "yes" ] ; then + [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as private' + mount --make-private / +fi + +prop_cleanup() { + if [ "${root_was_shared}" = "yes" ] ; then + [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as shared' + mount --make-shared / + fi +} diff --git a/tests/regression/apparmor/mount.sh b/tests/regression/apparmor/mount.sh index 0154d1ac1..046252f41 100755 --- a/tests/regression/apparmor/mount.sh +++ b/tests/regression/apparmor/mount.sh @@ -32,7 +32,8 @@ mount_point2=$tmpdir/mountpoint2 mount_bad=$tmpdir/mountbad loop_device="unset" fstype="ext2" -root_was_shared="no" + +. $bin/mount.inc setup_mnt() { /bin/mount -n -t${fstype} ${loop_device} ${mount_point} @@ -59,9 +60,7 @@ mount_cleanup() { then /sbin/losetup -d ${loop_device} &> /dev/null fi - if [ "${root_was_shared}" = "yes" ] ; then - mount --make-shared / - fi + prop_cleanup } do_onexit="mount_cleanup" @@ -81,23 +80,6 @@ fi loop_device=$(losetup -f) || fatalerror 'Unable to find a free loop device' /sbin/losetup "$loop_device" ${mount_file} > /dev/null 2> /dev/null -# systemd mounts / and everything under it MS_SHARED which does -# not work with "move", so attempt to detect it, and remount / -# MS_PRIVATE temporarily. snippet from pivot_root.sh -FINDMNT=/bin/findmnt -if [ -x "${FINDMNT}" ] && ${FINDMNT} -no PROPAGATION / > /dev/null 2>&1 ; then - if [ "$(${FINDMNT} -no PROPAGATION /)" == "shared" ] ; then - root_was_shared="yes" - fi -elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then - # no findmnt or findmnt doesn't know the PROPAGATION column, - # but init is systemd so assume rootfs is shared - root_was_shared="yes" -fi -if [ "${root_was_shared}" = "yes" ] ; then - mount --make-private / -fi - options=( # default and non-default options "rw,ro" diff --git a/tests/regression/apparmor/pivot_root.sh b/tests/regression/apparmor/pivot_root.sh index 70abec5e7..5643eb851 100755 --- a/tests/regression/apparmor/pivot_root.sh +++ b/tests/regression/apparmor/pivot_root.sh @@ -25,7 +25,8 @@ put_old=${new_root}put_old/ bad=$tmpdir/BAD/ proc=$new_root/proc fstype="ext2" -root_was_shared="no" + +. $bin/mount.inc pivot_root_cleanup() { mountpoint -q "$proc" @@ -38,10 +39,7 @@ pivot_root_cleanup() { umount "$new_root" fi - if [ "${root_was_shared}" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as shared' - mount --make-shared / - fi + prop_cleanup } do_onexit="pivot_root_cleanup" @@ -50,24 +48,6 @@ if [ ! -b /dev/loop0 ] ; then modprobe loop fi -# systemd mounts / and everything under it MS_SHARED. This breaks -# pivot_root entirely, so attempt to detect it, and remount / -# MS_PRIVATE temporarily. -FINDMNT=/bin/findmnt -if [ -x "${FINDMNT}" ] && ${FINDMNT} -no PROPAGATION / > /dev/null 2>&1 ; then - if [ "$(${FINDMNT} -no PROPAGATION /)" = "shared" ] ; then - root_was_shared="yes" - fi -elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then - # no findmnt or findmnt doesn't know the PROPAGATION column, - # but init is systemd so assume rootfs is shared - root_was_shared="yes" -fi -if [ "${root_was_shared}" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as private' - mount --make-private / -fi - # Create disk image since pivot_root doesn't allow old root and new root to be # on the same filesystem dd if=/dev/zero of="$disk_img" bs=1024 count=512 2> /dev/null From 6a20eb0dd5e6f47bbee12e89523864e60276837f Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Wed, 31 Jul 2024 17:15:54 -0300 Subject: [PATCH 2/3] tests: remount $tmpdir as private instead of / When /tmp is mounted, remounting / as private for tests that don't work when shared still fail because /tmp remains as shared. The option -T in findmnt helps determine the mountpoint in a certain directory, so use that with $tmpdir to determine the root. Signed-off-by: Georgia Garcia --- tests/regression/apparmor/mount.inc | 18 +++++++++++------- 1 file changed, 11 insertions(+), 7 deletions(-) diff --git a/tests/regression/apparmor/mount.inc b/tests/regression/apparmor/mount.inc index b9e7fd6b2..a22b017c4 100644 --- a/tests/regression/apparmor/mount.inc +++ b/tests/regression/apparmor/mount.inc @@ -1,11 +1,15 @@ root_was_shared="no" +root="/" # systemd mounts / and everything under it MS_SHARED. This breaks # pivot_root and mount "move" operations entirely, so attempt to -# detect it, and remount / MS_PRIVATE temporarily. +# detect from which mount point the test is running from, and remount +# it MS_PRIVATE temporarily. FINDMNT=/bin/findmnt -if [ -x "${FINDMNT}" ] && ${FINDMNT} -no PROPAGATION / > /dev/null 2>&1 ; then - if [ "$(${FINDMNT} -no PROPAGATION /)" = "shared" ] ; then +if [ -x "${FINDMNT}" ] && ${FINDMNT} -no TARGET,PROPAGATION -T $tmpdir > /dev/null 2>&1 ; then + output="$(${FINDMNT} -no TARGET,PROPAGATION -T $tmpdir)" + root="$(echo $output | cut -d' ' -f1)" + if [ "$(echo $output | cut -d' ' -f2)" == "shared" ] ; then root_was_shared="yes" fi elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then @@ -14,13 +18,13 @@ elif [ "$(ps hp1 -ocomm)" = "systemd" ] ; then root_was_shared="yes" fi if [ "${root_was_shared}" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as private' - mount --make-private / + [ -n "$VERBOSE" ] && echo "notice: re-mounting $root as private" + mount --make-private $root fi prop_cleanup() { if [ "${root_was_shared}" = "yes" ] ; then - [ -n "$VERBOSE" ] && echo 'notice: re-mounting / as shared' - mount --make-shared / + [ -n "$VERBOSE" ] && echo "notice: re-mounting $root as shared" + mount --make-shared $root fi } From 4feb51700390bed74c22d189b86e9ff4150ee416 Mon Sep 17 00:00:00 2001 From: Georgia Garcia Date: Wed, 31 Jul 2024 19:27:38 -0300 Subject: [PATCH 3/3] tests: enable swap test when /tmp is tmpfs When /tmp is of type tmpfs, the test didn't run because you can't mount a swapfile on it. This patch mounts an ext2 mountpoint on $tmpdir so that the swapfile can be mounted on top of it instead of tmpfs. Signed-off-by: Georgia Garcia --- tests/regression/apparmor/swap.sh | 34 +++++++++++++++++++++++++------ 1 file changed, 28 insertions(+), 6 deletions(-) diff --git a/tests/regression/apparmor/swap.sh b/tests/regression/apparmor/swap.sh index 87b5c5c0b..39de6d2af 100755 --- a/tests/regression/apparmor/swap.sh +++ b/tests/regression/apparmor/swap.sh @@ -27,16 +27,38 @@ bin=$pwd ## A. SWAP ## -# check if we can run the test at all +swap_file=$tmpdir/swapfile + +# check if we can run the test in tmpdir fstype=$(stat -f --format '%T' "${tmpdir}") if [ "${fstype}" = "tmpfs" ] ; then - echo "ERROR: tmpdir '${tmpdir}' is of type tmpfs; can't mount a swapfile on it" 1>&2 - echo "ERROR: skipping swap tests" 1>&2 - num_testfailures=1 - exit + # create a mountpoint not tmpfs + mount_file=$tmpdir/mountfile + mount_point=$tmpdir/mountpoint + fstype="ext2" + dd if=/dev/zero of=${mount_file} bs=1024 count=900 2> /dev/null + /sbin/mkfs -t${fstype} -F ${mount_file} > /dev/null 2> /dev/null + /bin/mkdir ${mount_point} + + loop_device=$(losetup -f) || fatalerror 'Unable to find a free loop device' + /sbin/losetup "$loop_device" ${mount_file} > /dev/null 2> /dev/null + + /bin/mount -n -t${fstype} ${loop_device} ${mount_point} + + swap_file=$mount_point/swapfile fi -swap_file=$tmpdir/swapfile +remove_mnt() { + mountpoint -q "${mount_point}" + if [ $? -eq 0 ] ; then + /bin/umount -t${fstype} ${mount_point} + fi + if [ -n "$loop_device" ] + then + /sbin/losetup -d ${loop_device} &> /dev/null + fi +} +do_onexit="remove_mnt" # ppc64el wants this to be larger than 640KiB # arm/small machines want this as small as possible