aboutsummaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2021-05-13 08:45:29 -0400
committerMatthew Heon <mheon@redhat.com>2021-05-25 14:44:20 -0400
commitbb589bec24ede0ca7bc981a5a285fb66d7242655 (patch)
tree65d74e0f1d83260418743e1dfea608f707876b89 /libpod
parentb909bcaed613eb94333641fff4250c07f1ab4323 (diff)
downloadpodman-bb589bec24ede0ca7bc981a5a285fb66d7242655.tar.gz
podman-bb589bec24ede0ca7bc981a5a285fb66d7242655.tar.bz2
podman-bb589bec24ede0ca7bc981a5a285fb66d7242655.zip
Fix problem copying files when container is in host pid namespace
When attempting to copy files into and out of running containers within the host pidnamespace, the code was attempting to join the host pidns again, and getting an error. This was causing the podman cp command to fail. Since we are already in the host pid namespace, we should not be attempting to join. This PR adds a check to see if the container is in NOT host pid namespace, and only then attempts to join. Fixes: https://github.com/containers/podman/issues/9985 Signed-off-by: Daniel J Walsh <dwalsh@redhat.com>
Diffstat (limited to 'libpod')
-rw-r--r--libpod/container_copy_linux.go25
-rw-r--r--libpod/container_inspect.go23
2 files changed, 41 insertions, 7 deletions
diff --git a/libpod/container_copy_linux.go b/libpod/container_copy_linux.go
index 5c275c641..0ab322829 100644
--- a/libpod/container_copy_linux.go
+++ b/libpod/container_copy_linux.go
@@ -237,21 +237,32 @@ func (c *Container) joinMountAndExec(ctx context.Context, f func() error) error
}
defer mountFD.Close()
- pidFD, err := getFD(PIDNS)
+ inHostPidNS, err := c.inHostPidNS()
if err != nil {
- errChan <- err
+ errChan <- errors.Wrap(err, "checking inHostPidNS")
return
}
- defer pidFD.Close()
- if err := unix.Unshare(unix.CLONE_NEWNS); err != nil {
- errChan <- err
- return
+ var pidFD *os.File
+ if !inHostPidNS {
+ pidFD, err = getFD(PIDNS)
+ if err != nil {
+ errChan <- err
+ return
+ }
+ defer pidFD.Close()
}
- if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil {
+
+ if err := unix.Unshare(unix.CLONE_NEWNS); err != nil {
errChan <- err
return
}
+ if pidFD != nil {
+ if err := unix.Setns(int(pidFD.Fd()), unix.CLONE_NEWPID); err != nil {
+ errChan <- err
+ return
+ }
+ }
if err := unix.Setns(int(mountFD.Fd()), unix.CLONE_NEWNS); err != nil {
errChan <- err
return
diff --git a/libpod/container_inspect.go b/libpod/container_inspect.go
index 5b2103c92..b38c35697 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -890,3 +890,26 @@ func (c *Container) generateInspectContainerHostConfig(ctrSpec *spec.Spec, named
return hostConfig, nil
}
+
+// Return true if the container is running in the host's PID NS.
+func (c *Container) inHostPidNS() (bool, error) {
+ if c.config.PIDNsCtr != "" {
+ return false, nil
+ }
+ ctrSpec, err := c.specFromState()
+ if err != nil {
+ return false, err
+ }
+ if ctrSpec.Linux != nil {
+ // Locate the spec's PID namespace.
+ // If there is none, it's pid=host.
+ // If there is one and it has a path, it's "ns:".
+ // If there is no path, it's default - the empty string.
+ for _, ns := range ctrSpec.Linux.Namespaces {
+ if ns.Type == spec.PIDNamespace {
+ return false, nil
+ }
+ }
+ }
+ return true, nil
+}