From e46ae46f18d01a9b04ef414a4aa99087e7e0c7df Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Fri, 4 Oct 2024 16:09:54 +0200 Subject: [PATCH] libpod: hasCurrentUserMapped checks for gid too the kernel checks that both the uid and the gid are mapped inside the user namespace, not only the uid: /** * privileged_wrt_inode_uidgid - Do capabilities in the namespace work over the inode? * @ns: The user namespace in question * @idmap: idmap of the mount @inode was found from * @inode: The inode in question * * Return true if the inode uid and gid are within the namespace. */ bool privileged_wrt_inode_uidgid(struct user_namespace *ns, struct mnt_idmap *idmap, const struct inode *inode) { return vfsuid_has_mapping(ns, i_uid_into_vfsuid(idmap, inode)) && vfsgid_has_mapping(ns, i_gid_into_vfsgid(idmap, inode)); } for this reason, improve the check for hasCurrentUserMapped to verify that the gid is also mapped, and if it is not, use an intermediate mount for the container rootfs. Closes: https://github.com/containers/podman/issues/24159 Signed-off-by: Giuseppe Scrivano --- libpod/oci_conmon_common.go | 13 ++++++++----- test/system/170-run-userns.bats | 12 ++++++++++++ 2 files changed, 20 insertions(+), 5 deletions(-) diff --git a/libpod/oci_conmon_common.go b/libpod/oci_conmon_common.go index 9a9607305c..8aa103fb49 100644 --- a/libpod/oci_conmon_common.go +++ b/libpod/oci_conmon_common.go @@ -34,6 +34,7 @@ import ( "github.com/containers/podman/v5/pkg/specgenutil" "github.com/containers/podman/v5/pkg/util" "github.com/containers/podman/v5/utils" + "github.com/containers/storage/pkg/idtools" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/sirupsen/logrus" "golang.org/x/sys/unix" @@ -172,13 +173,15 @@ func hasCurrentUserMapped(ctr *Container) bool { if len(ctr.config.IDMappings.UIDMap) == 0 && len(ctr.config.IDMappings.GIDMap) == 0 { return true } - uid := os.Geteuid() - for _, m := range ctr.config.IDMappings.UIDMap { - if uid >= m.HostID && uid < m.HostID+m.Size { - return true + containsID := func(id int, mappings []idtools.IDMap) bool { + for _, m := range mappings { + if id >= m.HostID && id < m.HostID+m.Size { + return true + } } + return false } - return false + return containsID(os.Geteuid(), ctr.config.IDMappings.UIDMap) && containsID(os.Getegid(), ctr.config.IDMappings.GIDMap) } // CreateContainer creates a container. diff --git a/test/system/170-run-userns.bats b/test/system/170-run-userns.bats index 8d958e2841..26468661d2 100644 --- a/test/system/170-run-userns.bats +++ b/test/system/170-run-userns.bats @@ -169,3 +169,15 @@ EOF run_podman run --rm --userns=auto:uidmapping=$mapping $IMAGE awk '{if($1 == 1){print $2}}' /proc/self/uid_map assert "$output" == 1 } + +# bats test_tags=ci:parallel +@test "podman current user not mapped in the userns" { + # both uid and gid not mapped + run_podman run --rm --uidmap 0:1:1000 $IMAGE true + + # uid not mapped + run_podman run --rm --uidmap 0:1:1000 --gidmap 0:0:1000 $IMAGE true + + # gid not mapped + run_podman run --rm --uidmap 0:0:1000 --gidmap 0:1:1000 $IMAGE true +}