Skip to content

Commit

Permalink
Ensure manually-created volumes have correct ownership
Browse files Browse the repository at this point in the history
As part of a fix for an earlier bug (containers#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 containers#9608

Signed-off-by: Matthew Heon <[email protected]>
  • Loading branch information
mheon committed Mar 29, 2021
1 parent 6b69892 commit 5e3445e
Show file tree
Hide file tree
Showing 4 changed files with 28 additions and 14 deletions.
13 changes: 0 additions & 13 deletions libpod/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -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
// should be removed when containers using it are removed and volumes are
// specified for removal.
Expand Down
2 changes: 1 addition & 1 deletion libpod/runtime_ctr.go
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,7 @@ func (r *Runtime) setupContainer(ctx context.Context, ctr *Container) (_ *Contai
logrus.Debugf("Creating new volume %s for container", vol.Name)

// 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 {
volOptions = append(volOptions, withSetAnon())
}
Expand Down
1 change: 1 addition & 0 deletions libpod/volume_internal.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ func newVolume(runtime *Runtime) *Volume {
volume.config.Labels = make(map[string]string)
volume.config.Options = make(map[string]string)
volume.state.NeedsCopyUp = true
volume.state.NeedsChown = true
return volume
}

Expand Down
26 changes: 26 additions & 0 deletions test/e2e/run_volume_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -642,4 +642,30 @@ VOLUME /test/`, ALPINE)
found, _ = session.GrepString("888:888")
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())

})
})

0 comments on commit 5e3445e

Please sign in to comment.