diff --git a/libpod/oci_conmon_linux.go b/libpod/oci_conmon_linux.go index 05dc65d360..dcd0088aed 100644 --- a/libpod/oci_conmon_linux.go +++ b/libpod/oci_conmon_linux.go @@ -89,14 +89,16 @@ func (r *ConmonOCIRuntime) createRootlessContainer(ctr *Container, restoreOption } } - // do not propagate the bind mount on the parent mount namespace - if err := unix.Mount("", parentMount, "", unix.MS_SLAVE, ""); err != nil { - return 0, fmt.Errorf("failed to make %s slave: %w", parentMount, err) - } - // bind mount the containers' mount path to the path where the OCI runtime expects it to be - if err := unix.Mount(ctr.state.Mountpoint, rootPath, "", unix.MS_BIND, ""); err != nil { - return 0, fmt.Errorf("failed to bind mount %s to %s: %w", ctr.state.Mountpoint, rootPath, err) + // if the container is already mounted at the expected path, do not cover the mountpoint. + if filepath.Clean(ctr.state.Mountpoint) != filepath.Clean(rootPath) { + // do not propagate the bind mount on the parent mount namespace + if err := unix.Mount("", parentMount, "", unix.MS_SLAVE, ""); err != nil { + return 0, fmt.Errorf("failed to make %s slave: %w", parentMount, err) + } + if err := unix.Mount(ctr.state.Mountpoint, rootPath, "", unix.MS_BIND, ""); err != nil { + return 0, fmt.Errorf("failed to bind mount %s to %s: %w", ctr.state.Mountpoint, rootPath, err) + } } if isShared { diff --git a/test/system/030-run.bats b/test/system/030-run.bats index ee430d4b4c..81b6e41422 100644 --- a/test/system/030-run.bats +++ b/test/system/030-run.bats @@ -1419,17 +1419,23 @@ EOF # Any other error is fatal die "Cannot create idmap mount: $output" fi + ensure_no_mountpoint "$romount" - run_podman run --security-opt label=disable --rm --uidmap=0:1000:10000 --rootfs $romount:idmap stat -c %u:%g /bin + mkdir -p $PODMAN_TMPDIR/shared-volume + # test that there are no mount leaks also when a shared volume is used (with a shared volume the rootfs propagation is set to shared). + run_podman run --security-opt label=disable --rm --uidmap=0:1000:10000 -v $PODMAN_TMPDIR/shared-volume:/a-shared-volume:shared --rootfs $romount:idmap stat -c %u:%g /bin is "$output" "0:0" + ensure_no_mountpoint "$romount" run_podman run --security-opt label=disable --uidmap=0:1000:10000 --rm --rootfs "$romount:idmap=uids=0-1001-10000;gids=0-1002-10000" stat -c %u:%g /bin is "$output" "1:2" + ensure_no_mountpoint "$romount" touch $romount/testfile chown 2000:2000 $romount/testfile run_podman run --security-opt label=disable --uidmap=0:1000:200 --rm --rootfs "$romount:idmap=uids=@2000-1-1;gids=@2000-1-1" stat -c %u:%g /testfile is "$output" "1:1" + ensure_no_mountpoint "$romount" # verify that copyup with an empty idmap volume maintains the original ownership with different mappings and --rootfs myvolume=my-volume-$(safename) @@ -1439,6 +1445,7 @@ EOF for FROM in 1000 2000; do run_podman run --security-opt label=disable --rm --uidmap=0:$FROM:10000 -v $myvolume:/volume:idmap --rootfs $romount stat -c %u:%g /volume is "$output" "0:0" + ensure_no_mountpoint "$romount" done run_podman volume rm $myvolume diff --git a/test/system/060-mount.bats b/test/system/060-mount.bats index ff1e326462..3d5c09cd02 100644 --- a/test/system/060-mount.bats +++ b/test/system/060-mount.bats @@ -309,9 +309,7 @@ EOF # umount, and make sure mountpoint no longer exists run_podman umount $external_cname - if findmnt "$mount_path" >/dev/null ; then - die "'podman umount' did not umount $mount_path" - fi + ensure_no_mountpoint "$mount_path" buildah rm $external_cname } diff --git a/test/system/helpers.bash b/test/system/helpers.bash index 6f13394b7d..a0285bfdf2 100644 --- a/test/system/helpers.bash +++ b/test/system/helpers.bash @@ -1361,5 +1361,16 @@ function make_random_file() { dd if=/dev/urandom of="$1" bs=1 count=${2:-$((${RANDOM} % 8192 + 1024))} status=none } +########################### +# ensure there is no mount point at the specified path +########################### +function ensure_no_mountpoint() { + local path="$1" + if findmnt "$path"; then + die "there is a mountpoint at $path" + fi +} + + # END miscellaneous tools ###############################################################################