mirror of
https://github.com/containers/podman.git
synced 2025-07-04 01:48:28 +08:00
Ensure manually-created volumes have correct ownership
As part of a fix for an earlier bug (#5698) we added the ability for Podman to chown volumes to correctly match the user running in the container, even in adverse circumstances (where we don't know the right UID/GID until very late in the process). However, we only did this for volumes created automatically by a `podman run` or `podman create`. Volumes made by `podman volume create` do not get this chown, so their permissions may not be correct. I've looked, and I don't think there's a good reason not to do this chwon for all volumes the first time the container is started. I would prefer to do this as part of volume copy-up, but I don't think that's really possible (copy-up happens earlier in the process and we don't have a spec). There is a small chance, as things stand, that a copy-up happens for one container and then a chown for a second, unrelated container, but the odds of this are astronomically small (we'd need a very close race between two starting containers). Fixes #9608 Signed-off-by: Matthew Heon <mheon@redhat.com>
This commit is contained in:

committed by
Matthew Heon

parent
5325957d53
commit
452decf8a4
@ -1627,19 +1627,6 @@ func WithVolumeGID(gid int) VolumeCreateOption {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithVolumeNeedsChown sets the NeedsChown flag for the volume.
|
|
||||||
func WithVolumeNeedsChown() VolumeCreateOption {
|
|
||||||
return func(volume *Volume) error {
|
|
||||||
if volume.valid {
|
|
||||||
return define.ErrVolumeFinalized
|
|
||||||
}
|
|
||||||
|
|
||||||
volume.state.NeedsChown = true
|
|
||||||
|
|
||||||
return nil
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// withSetAnon sets a bool notifying libpod that this volume is anonymous and
|
// withSetAnon sets a bool notifying libpod that this volume is anonymous and
|
||||||
// should be removed when containers using it are removed and volumes are
|
// should be removed when containers using it are removed and volumes are
|
||||||
// specified for removal.
|
// specified for removal.
|
||||||
|
@ -392,7 +392,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
|
|||||||
logrus.Debugf("Creating new volume %s for container", vol.Name)
|
logrus.Debugf("Creating new volume %s for container", vol.Name)
|
||||||
|
|
||||||
// The volume does not exist, so we need to create it.
|
// The volume does not exist, so we need to create it.
|
||||||
volOptions := []VolumeCreateOption{WithVolumeName(vol.Name), WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID()), WithVolumeNeedsChown()}
|
volOptions := []VolumeCreateOption{WithVolumeName(vol.Name), WithVolumeUID(ctr.RootUID()), WithVolumeGID(ctr.RootGID())}
|
||||||
if isAnonymous {
|
if isAnonymous {
|
||||||
volOptions = append(volOptions, withSetAnon())
|
volOptions = append(volOptions, withSetAnon())
|
||||||
}
|
}
|
||||||
|
@ -17,6 +17,7 @@ func newVolume(runtime *Runtime) *Volume {
|
|||||||
volume.config.Labels = make(map[string]string)
|
volume.config.Labels = make(map[string]string)
|
||||||
volume.config.Options = make(map[string]string)
|
volume.config.Options = make(map[string]string)
|
||||||
volume.state.NeedsCopyUp = true
|
volume.state.NeedsCopyUp = true
|
||||||
|
volume.state.NeedsChown = true
|
||||||
return volume
|
return volume
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -643,4 +643,30 @@ VOLUME /test/`
|
|||||||
found, _ = session.GrepString("888:888")
|
found, _ = session.GrepString("888:888")
|
||||||
Expect(found).Should(BeTrue())
|
Expect(found).Should(BeTrue())
|
||||||
})
|
})
|
||||||
|
|
||||||
|
It("volume permissions after run", func() {
|
||||||
|
imgName := "testimg"
|
||||||
|
dockerfile := `FROM fedora-minimal
|
||||||
|
RUN useradd -m testuser -u 1005
|
||||||
|
USER testuser`
|
||||||
|
podmanTest.BuildImage(dockerfile, imgName, "false")
|
||||||
|
|
||||||
|
testString := "testuser testuser"
|
||||||
|
|
||||||
|
test1 := podmanTest.Podman([]string{"run", "-v", "testvol1:/test", imgName, "bash", "-c", "ls -al /test | grep -v root | grep -v total"})
|
||||||
|
test1.WaitWithDefaultTimeout()
|
||||||
|
Expect(test1.ExitCode()).To(Equal(0))
|
||||||
|
Expect(strings.Contains(test1.OutputToString(), testString)).To(BeTrue())
|
||||||
|
|
||||||
|
volName := "testvol2"
|
||||||
|
vol := podmanTest.Podman([]string{"volume", "create", volName})
|
||||||
|
vol.WaitWithDefaultTimeout()
|
||||||
|
Expect(vol.ExitCode()).To(Equal(0))
|
||||||
|
|
||||||
|
test2 := podmanTest.Podman([]string{"run", "-v", fmt.Sprintf("%s:/test", volName), imgName, "bash", "-c", "ls -al /test | grep -v root | grep -v total"})
|
||||||
|
test2.WaitWithDefaultTimeout()
|
||||||
|
Expect(test2.ExitCode()).To(Equal(0))
|
||||||
|
Expect(strings.Contains(test2.OutputToString(), testString)).To(BeTrue())
|
||||||
|
|
||||||
|
})
|
||||||
})
|
})
|
||||||
|
Reference in New Issue
Block a user