diff options
author | Matthew Heon <matthew.heon@pm.me> | 2019-03-08 15:33:12 -0500 |
---|---|---|
committer | Matthew Heon <matthew.heon@pm.me> | 2019-03-11 14:39:29 -0400 |
commit | 66a72d9283475770707adc3f2be04a3b48635fd7 (patch) | |
tree | 2aecd6e34affe918660f1eb232a6d64cbe7a8bfb | |
parent | b8863b260a7885981def2b02b5acc7c9a209e0c6 (diff) | |
download | podman-66a72d9283475770707adc3f2be04a3b48635fd7.tar.gz podman-66a72d9283475770707adc3f2be04a3b48635fd7.tar.bz2 podman-66a72d9283475770707adc3f2be04a3b48635fd7.zip |
Ensure that tmpfs mounts do not have symlinks
When mounting a tmpfs, runc attempts to make the directory it
will be mounted at. Unfortunately, Golang's os.MkdirAll deals
very poorly with symlinks being part of the path. I looked into
fixing this in runc, but it's honestly much easier to just ensure
we don't trigger the issue on our end.
Fixes BZ #1686610
Signed-off-by: Matthew Heon <matthew.heon@pm.me>
-rw-r--r-- | libpod/container_internal_linux.go | 13 |
1 files changed, 13 insertions, 0 deletions
diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index c9f35dd75..3f3b22b6b 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -26,6 +26,7 @@ import ( "github.com/containers/libpod/pkg/resolvconf" "github.com/containers/libpod/pkg/rootless" "github.com/containers/storage/pkg/idtools" + "github.com/cyphar/filepath-securejoin" "github.com/opencontainers/runc/libcontainer/user" spec "github.com/opencontainers/runtime-spec/specs-go" "github.com/opencontainers/runtime-tools/generate" @@ -366,6 +367,18 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { // For private volumes any root propagation value should work. rootPropagation := "" for _, m := range mounts { + // We need to remove all symlinks from tmpfs mounts. + // Runc and other runtimes may choke on them. + // Easy solution: use securejoin to do a scoped evaluation of + // the links, then trim off the mount prefix. + if m.Type == "tmpfs" { + finalPath, err := securejoin.SecureJoin(c.state.Mountpoint, m.Destination) + if err != nil { + return nil, errors.Wrapf(err, "error resolving symlinks for mount destination %s", m.Destination) + } + trimmedPath := strings.TrimPrefix(finalPath, strings.TrimSuffix(c.state.Mountpoint, "/")) + m.Destination = trimmedPath + } g.AddMount(m) for _, opt := range m.Options { switch opt { |