Skip to content

Commit

Permalink
libpod: correctly map UID/GID for existing dirs
Browse files Browse the repository at this point in the history
if the target mount path already exists and the container uses a user
namespace, correctly map the target UID/GID to the host values before
attempting a chown.

Closes: #21608

Signed-off-by: Giuseppe Scrivano <gscrivan@redhat.com>
  • Loading branch information
giuseppe committed Feb 12, 2024
1 parent 6d107a2 commit c29fde2
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 1 deletion.
17 changes: 16 additions & 1 deletion libpod/container_internal_common.go
Expand Up @@ -2865,7 +2865,22 @@ func (c *Container) fixVolumePermissions(v *ContainerNamedVolume) error {
st, err := os.Lstat(filepath.Join(c.state.Mountpoint, v.Dest))
if err == nil {
if stat, ok := st.Sys().(*syscall.Stat_t); ok {
if err := idtools.SafeLchown(mountPoint, int(stat.Uid), int(stat.Gid)); err != nil {
uid, gid := int(stat.Uid), int(stat.Gid)

if c.config.IDMappings.UIDMap != nil {
p := idtools.IDPair{
UID: uid,
GID: gid,
}
mappings := idtools.NewIDMappingsFromMaps(c.config.IDMappings.UIDMap, c.config.IDMappings.GIDMap)
newUID, newGID, err := mappings.ToContainer(p)
if err != nil {
return fmt.Errorf("mapping user %d:%d: %w", uid, gid, err)
}
uid, gid = newUID, newGID
}

if err := idtools.SafeLchown(mountPoint, uid, gid); err != nil {
return err
}
}
Expand Down
16 changes: 16 additions & 0 deletions test/e2e/run_userns_test.go
Expand Up @@ -105,6 +105,22 @@ var _ = Describe("Podman UserNS support", func() {
Expect(session.OutputToString()).To(ContainSubstring("#0:0#"))
})

It("podman uidmapping and gidmapping with an idmapped volume on existing directory", func() {
SkipIfRunc(podmanTest, "Test not supported yet with runc (issue 17433, wontfix)")
SkipOnOSVersion("fedora", "36")
// The directory /mnt already exists in the image
session := podmanTest.Podman([]string{"run", "--uidmap=0:1:500", "--gidmap=0:200:5000", "-v", "my-foo-volume:/mnt:Z,idmap", "alpine", "stat", "-c", "#%u:%g#", "/mnt"})
session.WaitWithDefaultTimeout()
if strings.Contains(session.ErrorToString(), "Operation not permitted") {
Skip("not sufficiently privileged")
}
if strings.Contains(session.ErrorToString(), "Invalid argument") {
Skip("the file system doesn't support idmapped mounts")
}
Expect(session).Should(ExitCleanly())
Expect(session.OutputToString()).To(ContainSubstring("#0:0#"))
})

It("podman uidmapping and gidmapping --net=host", func() {
session := podmanTest.Podman([]string{"run", "--net=host", "--uidmap=0:1:5000", "--gidmap=0:200:5000", "alpine", "echo", "hello"})
session.WaitWithDefaultTimeout()
Expand Down

0 comments on commit c29fde2

Please sign in to comment.