summaryrefslogtreecommitdiff
path: root/libpod
diff options
context:
space:
mode:
authorDaniel J Walsh <dwalsh@redhat.com>2021-05-13 08:45:29 -0400
committerDaniel J Walsh <dwalsh@redhat.com>2021-05-19 07:55:48 -0400
commitbc0e12a047cce2cc717320257545663073383f48 (patch)
treeca6e4710bd3b6894c736b33f45199bd9519f012d /libpod
parent18efc5a3a78ba7352e42517ba251212833b4583d (diff)
downloadpodman-bc0e12a047cce2cc717320257545663073383f48.tar.gz
podman-bc0e12a047cce2cc717320257545663073383f48.tar.bz2
podman-bc0e12a047cce2cc717320257545663073383f48.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 4210bc581..638e0b756 100644
--- a/libpod/container_inspect.go
+++ b/libpod/container_inspect.go
@@ -892,3 +892,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
+}