diff options
author | openshift-ci[bot] <75433959+openshift-ci[bot]@users.noreply.github.com> | 2022-06-28 13:57:16 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-28 13:57:16 +0000 |
commit | 8267cd3c514ed1e8f41a7e4b6017f11400f134aa (patch) | |
tree | 19f30756ceda7e152ef3cdefaf5627b746e2a403 /libpod | |
parent | 9c5d97b5c5b583fc3b3c8af52bf3e1b6a5c2cb90 (diff) | |
parent | aada13f244d52dad9b6a1cfaa725e9d36d75a858 (diff) | |
download | podman-8267cd3c514ed1e8f41a7e4b6017f11400f134aa.tar.gz podman-8267cd3c514ed1e8f41a7e4b6017f11400f134aa.tar.bz2 podman-8267cd3c514ed1e8f41a7e4b6017f11400f134aa.zip |
Merge pull request #14734 from giuseppe/copyup-switch-order
volume: add two new options copy and nocopy
Diffstat (limited to 'libpod')
-rw-r--r-- | libpod/container_internal.go | 32 | ||||
-rw-r--r-- | libpod/runtime_volume_linux.go | 2 | ||||
-rw-r--r-- | libpod/volume_internal.go | 6 |
3 files changed, 23 insertions, 17 deletions
diff --git a/libpod/container_internal.go b/libpod/container_internal.go index ae61298f3..64696cc27 100644 --- a/libpod/container_internal.go +++ b/libpod/container_internal.go @@ -21,6 +21,7 @@ import ( "github.com/containers/common/pkg/cgroups" "github.com/containers/common/pkg/chown" "github.com/containers/common/pkg/config" + cutil "github.com/containers/common/pkg/util" "github.com/containers/podman/v4/libpod/define" "github.com/containers/podman/v4/libpod/events" "github.com/containers/podman/v4/pkg/ctime" @@ -1639,30 +1640,16 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) if err := vol.update(); err != nil { return nil, err } - if vol.state.NeedsCopyUp { + _, hasNoCopy := vol.config.Options["nocopy"] + if vol.state.NeedsCopyUp && !cutil.StringInSlice("nocopy", v.Options) && !hasNoCopy { logrus.Debugf("Copying up contents from container %s to volume %s", c.ID(), vol.Name()) - // If the volume is not empty, we should not copy up. - volMount := vol.mountPoint() - contents, err := ioutil.ReadDir(volMount) - if err != nil { - return nil, errors.Wrapf(err, "error listing contents of volume %s mountpoint when copying up from container %s", vol.Name(), c.ID()) - } - if len(contents) > 0 { - // The volume is not empty. It was likely modified - // outside of Podman. For safety, let's not copy up into - // it. Fixes CVE-2020-1726. - return vol, nil - } - srcDir, err := securejoin.SecureJoin(mountpoint, v.Dest) if err != nil { return nil, errors.Wrapf(err, "error calculating destination path to copy up container %s volume %s", c.ID(), vol.Name()) } // Do a manual stat on the source directory to verify existence. // Skip the rest if it exists. - // TODO: Should this be stat or lstat? I'm using lstat because I - // think copy-up doesn't happen when the source is a link. srcStat, err := os.Lstat(srcDir) if err != nil { if os.IsNotExist(err) { @@ -1688,6 +1675,19 @@ func (c *Container) mountNamedVolume(v *ContainerNamedVolume, mountpoint string) return vol, nil } + // If the volume is not empty, we should not copy up. + volMount := vol.mountPoint() + contents, err := ioutil.ReadDir(volMount) + if err != nil { + return nil, errors.Wrapf(err, "error listing contents of volume %s mountpoint when copying up from container %s", vol.Name(), c.ID()) + } + if len(contents) > 0 { + // The volume is not empty. It was likely modified + // outside of Podman. For safety, let's not copy up into + // it. Fixes CVE-2020-1726. + return vol, nil + } + // Set NeedsCopyUp to false since we are about to do first copy // Do not copy second time. vol.state.NeedsCopyUp = false diff --git a/libpod/runtime_volume_linux.go b/libpod/runtime_volume_linux.go index 877f3a1fd..17a48be86 100644 --- a/libpod/runtime_volume_linux.go +++ b/libpod/runtime_volume_linux.go @@ -76,7 +76,7 @@ func (r *Runtime) newVolume(noCreatePluginVolume bool, options ...VolumeCreateOp return nil, errors.Wrapf(err, "invalid volume option %s for driver 'local'", key) } } - case "o", "type", "uid", "gid", "size", "inodes", "noquota": + case "o", "type", "uid", "gid", "size", "inodes", "noquota", "copy", "nocopy": // Do nothing, valid keys default: return nil, errors.Wrapf(define.ErrInvalidArg, "invalid mount option %s for driver 'local'", key) diff --git a/libpod/volume_internal.go b/libpod/volume_internal.go index e0ebb729d..24522c0f9 100644 --- a/libpod/volume_internal.go +++ b/libpod/volume_internal.go @@ -55,6 +55,12 @@ func (v *Volume) needsMount() bool { if _, ok := v.config.Options["NOQUOTA"]; ok { index++ } + if _, ok := v.config.Options["nocopy"]; ok { + index++ + } + if _, ok := v.config.Options["copy"]; ok { + index++ + } // when uid or gid is set there is also the "o" option // set so we have to ignore this one as well if index > 0 { |