105 lines
3.5 KiB
Diff
105 lines
3.5 KiB
Diff
From acf196483ff8e2e5461a6c55ee64359863608b92 Mon Sep 17 00:00:00 2001
|
|
From: Kir Kolyshkin <kolyshkin@gmail.com>
|
|
Date: Fri, 12 May 2023 16:04:11 -0700
|
|
Subject: [PATCH] libct: fix shared pidns detection
|
|
|
|
When someone is using libcontainer to start and kill containers from a
|
|
long lived process (i.e. the same process creates and removes the
|
|
container), initProcess.wait method is used, which has a kludge to work
|
|
around killing containers that do not have their own PID namespace.
|
|
|
|
The code that checks for own PID namespace is not entirely correct.
|
|
To be exact, it does not set sharePidns flag when the host/caller PID
|
|
namespace is implicitly used. As a result, the above mentioned kludge
|
|
does not work.
|
|
|
|
Fix the issue, add a test case (which fails without the fix).
|
|
|
|
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
|
|
---
|
|
libcontainer/configs/namespaces_syscall.go | 12 ++++++++++++
|
|
libcontainer/container_linux.go | 3 +--
|
|
libcontainer/integration/exec_test.go | 20 +++++++++++++++-----
|
|
3 files changed, 28 insertions(+), 7 deletions(-)
|
|
|
|
diff --git a/libcontainer/configs/namespaces_syscall.go b/libcontainer/configs/namespaces_syscall.go
|
|
index 0516dba8..543e059a 100644
|
|
--- a/libcontainer/configs/namespaces_syscall.go
|
|
+++ b/libcontainer/configs/namespaces_syscall.go
|
|
@@ -31,3 +31,15 @@ func (n *Namespaces) CloneFlags() uintptr {
|
|
}
|
|
return uintptr(flag)
|
|
}
|
|
+
|
|
+// IsPrivate tells whether the namespace of type t is configured as private
|
|
+// (i.e. it exists and is not shared).
|
|
+func (n Namespaces) IsPrivate(t NamespaceType) bool {
|
|
+ for _, v := range n {
|
|
+ if v.Type == t {
|
|
+ return v.Path == ""
|
|
+ }
|
|
+ }
|
|
+ // Not found, so implicitly sharing a parent namespace.
|
|
+ return false
|
|
+}
|
|
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
|
index 1fc8feca..1a210fa2 100644
|
|
--- a/libcontainer/container_linux.go
|
|
+++ b/libcontainer/container_linux.go
|
|
@@ -555,7 +555,6 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPa
|
|
nsMaps[ns.Type] = ns.Path
|
|
}
|
|
}
|
|
- _, sharePidns := nsMaps[configs.NEWPID]
|
|
data, err := c.bootstrapData(c.config.Namespaces.CloneFlags(), nsMaps, initStandard)
|
|
if err != nil {
|
|
return nil, err
|
|
@@ -600,7 +599,7 @@ func (c *linuxContainer) newInitProcess(p *Process, cmd *exec.Cmd, messageSockPa
|
|
container: c,
|
|
process: p,
|
|
bootstrapData: data,
|
|
- sharePidns: sharePidns,
|
|
+ sharePidns: !c.config.Namespaces.IsPrivate(configs.NEWPID),
|
|
}
|
|
c.initProcess = init
|
|
return init, nil
|
|
diff --git a/libcontainer/integration/exec_test.go b/libcontainer/integration/exec_test.go
|
|
index 3da6d96c..1f19ced1 100644
|
|
--- a/libcontainer/integration/exec_test.go
|
|
+++ b/libcontainer/integration/exec_test.go
|
|
@@ -1456,16 +1456,26 @@ func TestPIDHost(t *testing.T) {
|
|
}
|
|
}
|
|
|
|
-func TestPIDHostInitProcessWait(t *testing.T) {
|
|
+func TestHostPidnsInitKill(t *testing.T) {
|
|
+ config := newTemplateConfig(t, nil)
|
|
+ // Implicitly use host pid ns.
|
|
+ config.Namespaces.Remove(configs.NEWPID)
|
|
+ testPidnsInitKill(t, config)
|
|
+}
|
|
+
|
|
+func TestSharedPidnsInitKill(t *testing.T) {
|
|
+ config := newTemplateConfig(t, nil)
|
|
+ // Explicitly use host pid ns.
|
|
+ config.Namespaces.Add(configs.NEWPID, "/proc/1/ns/pid")
|
|
+ testPidnsInitKill(t, config)
|
|
+}
|
|
+
|
|
+func testPidnsInitKill(t *testing.T, config *configs.Config) {
|
|
if testing.Short() {
|
|
return
|
|
}
|
|
|
|
- pidns := "/proc/1/ns/pid"
|
|
-
|
|
// Run a container with two long-running processes.
|
|
- config := newTemplateConfig(t, nil)
|
|
- config.Namespaces.Add(configs.NEWPID, pidns)
|
|
container, err := newContainer(t, config)
|
|
ok(t, err)
|
|
defer func() {
|
|
--
|
|
2.33.0
|
|
|