From 7f6f2f3f4a764f8e566752e61092254bd285424b Mon Sep 17 00:00:00 2001 From: Giuseppe Scrivano Date: Wed, 20 Mar 2019 12:05:02 +0100 Subject: userns: use the intermediate mountns for volumes when --uidmap is used, the user won't be able to access /var/lib/containers/storage/volumes. Use the intermediate mount namespace, that is accessible to root in the container, for mounting the volumes inside the container. Closes: https://github.com/containers/libpod/issues/2713 Signed-off-by: Giuseppe Scrivano --- libpod/container_internal_linux.go | 10 +++++++++- libpod/oci_linux.go | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 1 deletion(-) (limited to 'libpod') diff --git a/libpod/container_internal_linux.go b/libpod/container_internal_linux.go index 2a7808bdf..c6c9ceb0c 100644 --- a/libpod/container_internal_linux.go +++ b/libpod/container_internal_linux.go @@ -203,7 +203,8 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } // Check if the spec file mounts contain the label Relabel flags z or Z. // If they do, relabel the source directory and then remove the option. - for _, m := range g.Mounts() { + for i := range g.Config.Mounts { + m := &g.Config.Mounts[i] var options []string for _, o := range m.Options { switch o { @@ -219,6 +220,13 @@ func (c *Container) generateSpec(ctx context.Context) (*spec.Spec, error) { } } m.Options = options + + // If we are using a user namespace, we will use an intermediate + // directory to bind mount volumes + if c.state.UserNSRoot != "" && strings.HasPrefix(m.Source, c.runtime.config.VolumePath) { + newSourceDir := filepath.Join(c.state.UserNSRoot, "volumes") + m.Source = strings.Replace(m.Source, c.runtime.config.VolumePath, newSourceDir, 1) + } } g.SetProcessSelinuxLabel(c.ProcessLabel()) diff --git a/libpod/oci_linux.go b/libpod/oci_linux.go index 2737a641e..f85c5ee62 100644 --- a/libpod/oci_linux.go +++ b/libpod/oci_linux.go @@ -106,6 +106,23 @@ func (r *OCIRuntime) createContainer(ctr *Container, cgroupParent string, restor if err != nil { return } + + if ctr.state.UserNSRoot != "" { + _, err := os.Stat(ctr.runtime.config.VolumePath) + if err != nil && !os.IsNotExist(err) { + return + } + if err == nil { + volumesTarget := filepath.Join(ctr.state.UserNSRoot, "volumes") + if err := idtools.MkdirAs(volumesTarget, 0700, ctr.RootUID(), ctr.RootGID()); err != nil { + return + } + if err = unix.Mount(ctr.runtime.config.VolumePath, volumesTarget, "none", unix.MS_BIND, ""); err != nil { + return + } + } + } + err = r.createOCIContainer(ctr, cgroupParent, restoreOptions) }() wg.Wait() -- cgit v1.2.3-54-g00ecf