runc:sync some patches
This commit is contained in:
parent
c56a7bda7e
commit
8a63d08b9d
@ -1 +1 @@
|
|||||||
1b26f86af8e3288668d096f778e0d33a0ecfcb03
|
10d460b661a3a68e9f83784e2bd115d807eda098
|
||||||
|
|||||||
104
patch/0041-runc-libct-fix-shared-pidns-detection.patch
Normal file
104
patch/0041-runc-libct-fix-shared-pidns-detection.patch
Normal file
@ -0,0 +1,104 @@
|
|||||||
|
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
|
||||||
|
|
||||||
97
patch/0042-runc-libct-fix-a-race-with-systemd-removal.patch
Normal file
97
patch/0042-runc-libct-fix-a-race-with-systemd-removal.patch
Normal file
@ -0,0 +1,97 @@
|
|||||||
|
From 45abd12f084c62f3fbd24ab0fb0d3c1e3edf6ac7 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kir Kolyshkin <kolyshkin@gmail.com>
|
||||||
|
Date: Tue, 4 Apr 2023 16:59:43 -0700
|
||||||
|
Subject: [PATCH] libct: fix a race with systemd removal
|
||||||
|
|
||||||
|
For a previous attempt to fix that (and added test cases), see commit
|
||||||
|
9087f2e827d971.
|
||||||
|
|
||||||
|
Alas, it's not always working because of cgroup directory TOCTOU.
|
||||||
|
|
||||||
|
To solve this and avoid the race, add an error _after_ the operation.
|
||||||
|
Implement it as a method that ignores the error that should be ignored.
|
||||||
|
Instead of currentStatus(), use faster runType(), since we are not
|
||||||
|
interested in Paused status here.
|
||||||
|
|
||||||
|
For Processes(), remove the pre-op check, and only use it after getting
|
||||||
|
an error, making the non-error path more straightforward.
|
||||||
|
|
||||||
|
For Signal(), add a second check after getting an error. The first check
|
||||||
|
is left as is because signalAllProcesses might print a warning if the
|
||||||
|
cgroup does not exist, and we'd like to avoid that.
|
||||||
|
|
||||||
|
This should fix an occasional failure like this one:
|
||||||
|
|
||||||
|
not ok 84 kill detached busybox
|
||||||
|
# (in test file tests/integration/kill.bats, line 27)
|
||||||
|
# `[ "$status" -eq 0 ]' failed
|
||||||
|
....
|
||||||
|
# runc kill test_busybox KILL (status=0):
|
||||||
|
# runc kill -a test_busybox 0 (status=1):
|
||||||
|
# time="2023-04-04T18:24:27Z" level=error msg="lstat /sys/fs/cgroup/devices/system.slice/runc-test_busybox.scope: no such file or directory"
|
||||||
|
|
||||||
|
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
|
||||||
|
---
|
||||||
|
libcontainer/container_linux.go | 33 +++++++++++++++++++++------------
|
||||||
|
1 file changed, 21 insertions(+), 12 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libcontainer/container_linux.go b/libcontainer/container_linux.go
|
||||||
|
index 1a210fa2..1189e5af 100644
|
||||||
|
--- a/libcontainer/container_linux.go
|
||||||
|
+++ b/libcontainer/container_linux.go
|
||||||
|
@@ -146,19 +146,27 @@ func (c *linuxContainer) OCIState() (*specs.State, error) {
|
||||||
|
return c.currentOCIState()
|
||||||
|
}
|
||||||
|
|
||||||
|
-func (c *linuxContainer) Processes() ([]int, error) {
|
||||||
|
- var pids []int
|
||||||
|
- status, err := c.currentStatus()
|
||||||
|
- if err != nil {
|
||||||
|
- return pids, err
|
||||||
|
+// ignoreCgroupError filters out cgroup-related errors that can be ignored,
|
||||||
|
+// because the container is stopped and its cgroup is gone.
|
||||||
|
+func (c *linuxContainer) ignoreCgroupError(err error) error {
|
||||||
|
+ if err == nil {
|
||||||
|
+ return nil
|
||||||
|
}
|
||||||
|
- // for systemd cgroup, the unit's cgroup path will be auto removed if container's all processes exited
|
||||||
|
- if status == Stopped && !c.cgroupManager.Exists() {
|
||||||
|
- return pids, nil
|
||||||
|
+ if errors.Is(err, os.ErrNotExist) && c.runType() == Stopped && !c.cgroupManager.Exists() {
|
||||||
|
+ return nil
|
||||||
|
}
|
||||||
|
+ return err
|
||||||
|
+}
|
||||||
|
|
||||||
|
- pids, err = c.cgroupManager.GetAllPids()
|
||||||
|
- if err != nil {
|
||||||
|
+// Processes returns the PIDs inside this container. The PIDs are in the
|
||||||
|
+// namespace of the calling process.
|
||||||
|
+//
|
||||||
|
+// Some of the returned PIDs may no longer refer to processes in the container,
|
||||||
|
+// unless the container state is PAUSED in which case every PID in the slice is
|
||||||
|
+// valid.
|
||||||
|
+func (c *linuxContainer) Processes() ([]int, error) {
|
||||||
|
+ pids, err := c.cgroupManager.GetAllPids()
|
||||||
|
+ if err = c.ignoreCgroupError(err); err != nil {
|
||||||
|
return nil, fmt.Errorf("unable to get all container pids: %w", err)
|
||||||
|
}
|
||||||
|
return pids, nil
|
||||||
|
@@ -382,11 +390,12 @@ func (c *linuxContainer) Signal(s os.Signal, all bool) error {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
if all {
|
||||||
|
- // for systemd cgroup, the unit's cgroup path will be auto removed if container's all processes exited
|
||||||
|
if status == Stopped && !c.cgroupManager.Exists() {
|
||||||
|
+ // Avoid calling signalAllProcesses which may print
|
||||||
|
+ // a warning trying to freeze a non-existing cgroup.
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
- return signalAllProcesses(c.cgroupManager, s)
|
||||||
|
+ return c.ignoreCgroupError(signalAllProcesses(c.cgroupManager, s))
|
||||||
|
}
|
||||||
|
// to avoid a PID reuse attack
|
||||||
|
if status == Running || status == Created || status == Paused {
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
38
patch/0043-runc-run-refuse-a-non-empty-cgroup.patch
Normal file
38
patch/0043-runc-run-refuse-a-non-empty-cgroup.patch
Normal file
@ -0,0 +1,38 @@
|
|||||||
|
From 2132cc52fbf68f9bfaf5dd18a1a5a25ecdd37929 Mon Sep 17 00:00:00 2001
|
||||||
|
From: Kir Kolyshkin <kolyshkin@gmail.com>
|
||||||
|
Date: Thu, 23 Mar 2023 11:57:46 -0700
|
||||||
|
Subject: [PATCH] runc run: refuse a non-empty cgroup
|
||||||
|
|
||||||
|
Commit d08bc0c1b3bb2 ("runc run: warn on non-empty cgroup") introduced
|
||||||
|
a warning when a container is started in a non-empty cgroup. Such
|
||||||
|
configuration has lots of issues.
|
||||||
|
|
||||||
|
In addition to that, such configuration is not possible at all when
|
||||||
|
using the systemd cgroup driver.
|
||||||
|
|
||||||
|
As planned, let's promote this warning to an error, and fix the test
|
||||||
|
case accordingly.
|
||||||
|
|
||||||
|
Signed-off-by: Kir Kolyshkin <kolyshkin@gmail.com>
|
||||||
|
---
|
||||||
|
libcontainer/factory_linux.go | 4 +---
|
||||||
|
1 file changed, 1 insertion(+), 3 deletions(-)
|
||||||
|
|
||||||
|
diff --git a/libcontainer/factory_linux.go b/libcontainer/factory_linux.go
|
||||||
|
index e6c71ac3..39fc3121 100644
|
||||||
|
--- a/libcontainer/factory_linux.go
|
||||||
|
+++ b/libcontainer/factory_linux.go
|
||||||
|
@@ -179,9 +179,7 @@ func (l *LinuxFactory) Create(id string, config *configs.Config) (Container, err
|
||||||
|
return nil, fmt.Errorf("unable to get cgroup PIDs: %w", err)
|
||||||
|
}
|
||||||
|
if len(pids) != 0 {
|
||||||
|
- // TODO: return an error.
|
||||||
|
- logrus.Warnf("container's cgroup is not empty: %d process(es) found", len(pids))
|
||||||
|
- logrus.Warn("DEPRECATED: running container in a non-empty cgroup won't be supported in runc 1.2; https://github.com/opencontainers/runc/issues/3132")
|
||||||
|
+ return nil, fmt.Errorf("container's cgroup is not empty: %d process(es) found", len(pids))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
--
|
||||||
|
2.33.0
|
||||||
|
|
||||||
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
Name: docker-runc
|
Name: docker-runc
|
||||||
Version: 1.1.3
|
Version: 1.1.3
|
||||||
Release: 15
|
Release: 16
|
||||||
Summary: runc is a CLI tool for spawning and running containers according to the OCI specification.
|
Summary: runc is a CLI tool for spawning and running containers according to the OCI specification.
|
||||||
|
|
||||||
License: ASL 2.0
|
License: ASL 2.0
|
||||||
@ -58,6 +58,12 @@ install -p -m 755 runc $RPM_BUILD_ROOT/%{_bindir}/runc
|
|||||||
%{_bindir}/runc
|
%{_bindir}/runc
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Wed Jun 21 2023 zhongjiawei<zhongjiawei1@huawei.com> - 1.1.3-16
|
||||||
|
- Type:bugfix
|
||||||
|
- CVE:NA
|
||||||
|
- SUG:NA
|
||||||
|
- DESC:sync some patches
|
||||||
|
|
||||||
* Fri Jun 09 2023 zhongjiawei<zhongjiawei1@huawei.com> - 1.1.3-15
|
* Fri Jun 09 2023 zhongjiawei<zhongjiawei1@huawei.com> - 1.1.3-15
|
||||||
- Type:bugfix
|
- Type:bugfix
|
||||||
- CVE:NA
|
- CVE:NA
|
||||||
|
|||||||
@ -36,3 +36,6 @@ patch/0037-runc-Fixed-init-state-error-variable.patch
|
|||||||
patch/0038-runc-rootless-fix-sys-fs-cgroup-mounts.patch
|
patch/0038-runc-rootless-fix-sys-fs-cgroup-mounts.patch
|
||||||
patch/0039-runc-Prohibit-proc-and-sys-to-be-symlinks.patch
|
patch/0039-runc-Prohibit-proc-and-sys-to-be-symlinks.patch
|
||||||
patch/0040-runc-modify-runc-make-command-to-satisfy-the-compile.patch
|
patch/0040-runc-modify-runc-make-command-to-satisfy-the-compile.patch
|
||||||
|
patch/0041-runc-libct-fix-shared-pidns-detection.patch
|
||||||
|
patch/0042-runc-libct-fix-a-race-with-systemd-removal.patch
|
||||||
|
patch/0043-runc-run-refuse-a-non-empty-cgroup.patch
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user