libpod: do not cover idmapped mountpoint

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
This commit is contained in:
Giuseppe Scrivano
2025-03-10 21:11:07 +01:00
parent faf8574bb4
commit c9c44d400c
4 changed files with 29 additions and 11 deletions

View File

@ -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 {

View File

@ -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

View File

@ -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
}

View File

@ -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
###############################################################################