From 0436d058b39572dfa0d0a267b0518fd8a793dc49 Mon Sep 17 00:00:00 2001 From: zhongjiawei Date: Mon, 4 Jul 2022 17:06:29 +0800 Subject: [PATCH] containerd: Limit the response size of ExecSync fix CVE-2022-31030 Signed-off-by: zhongjiawei --- containerd.spec | 8 +- git-commit | 2 +- ...-Limit-the-response-size-of-ExecSync.patch | 133 ++++++++++++++++++ series.conf | 1 + 4 files changed, 142 insertions(+), 2 deletions(-) create mode 100644 patch/0086-containerd-Limit-the-response-size-of-ExecSync.patch diff --git a/containerd.spec b/containerd.spec index 377667c..d617fb1 100644 --- a/containerd.spec +++ b/containerd.spec @@ -2,7 +2,7 @@ %global debug_package %{nil} Version: 1.2.0 Name: containerd -Release: 302 +Release: 303 Summary: An industry-standard container runtime License: ASL 2.0 URL: https://containerd.io @@ -52,6 +52,12 @@ install -p -m 755 bin/containerd-shim $RPM_BUILD_ROOT/%{_bindir}/containerd-shim %{_bindir}/containerd-shim %changelog +* Mon Jul 4 2022 zhongjiawei - 1.2.0-303 +- Type:bugfix +- ID:NA +- SUG:NA +- DESC: Limit the response size of ExecSync to fix CVE-2022-31030 + * Wed Jun 22 2022 zhangsong234 - 1.2.0-302 - Type:bugfix - ID:NA diff --git a/git-commit b/git-commit index 068a20e..b319817 100644 --- a/git-commit +++ b/git-commit @@ -1 +1 @@ -755bdc7a74588295ea632aa10da179cbcce8c64f +1493659ef0808b8f3a5b920b0f0661833af2782e diff --git a/patch/0086-containerd-Limit-the-response-size-of-ExecSync.patch b/patch/0086-containerd-Limit-the-response-size-of-ExecSync.patch new file mode 100644 index 0000000..e17da50 --- /dev/null +++ b/patch/0086-containerd-Limit-the-response-size-of-ExecSync.patch @@ -0,0 +1,133 @@ +From cf3bde2b5a78d7ba8773eadcc3b28dfb0001aee0 Mon Sep 17 00:00:00 2001 +From: zhongjiawei +Date: Mon, 4 Jul 2022 14:34:23 +0800 +Subject: [PATCH] containerd: Limit the response size of ExecSync + +fix CVE-2022-31030 +upstream:https://github.com/containerd/containerd/commit/c1bcabb4541930f643aa36a2b38655e131346382 +--- + .../cri/pkg/server/container_execsync.go | 45 ++++++++++++++++- + .../cri/pkg/server/container_execsync_test.go | 49 +++++++++++++++++++ + 2 files changed, 92 insertions(+), 2 deletions(-) + create mode 100644 vendor/github.com/containerd/cri/pkg/server/container_execsync_test.go + +diff --git a/vendor/github.com/containerd/cri/pkg/server/container_execsync.go b/vendor/github.com/containerd/cri/pkg/server/container_execsync.go +index fd54120..1ef93e5 100644 +--- a/vendor/github.com/containerd/cri/pkg/server/container_execsync.go ++++ b/vendor/github.com/containerd/cri/pkg/server/container_execsync.go +@@ -37,14 +37,55 @@ import ( + "github.com/containerd/cri/pkg/util" + ) + ++type cappedWriter struct { ++ w io.WriteCloser ++ remain int ++} ++ ++func (cw *cappedWriter) Write(p []byte) (int, error) { ++ if cw.remain <= 0 { ++ return len(p), nil ++ } ++ ++ end := cw.remain ++ if end > len(p) { ++ end = len(p) ++ } ++ written, err := cw.w.Write(p[0:end]) ++ cw.remain -= written ++ ++ if err != nil { ++ return written, err ++ } ++ return len(p), nil ++} ++ ++func (cw *cappedWriter) Close() error { ++ return cw.w.Close() ++} ++ ++func (cw *cappedWriter) isFull() bool { ++ return cw.remain <= 0 ++} ++ + // ExecSync executes a command in the container, and returns the stdout output. + // If command exits with a non-zero exit code, an error is returned. + func (c *criService) ExecSync(ctx context.Context, r *runtime.ExecSyncRequest) (*runtime.ExecSyncResponse, error) { ++ const maxStreamSize = 1024 * 1024 * 16 ++ + var stdout, stderr bytes.Buffer ++ ++ // cappedWriter truncates the output. In that case, the size of ++ // the ExecSyncResponse will hit the CRI plugin's gRPC response limit. ++ // Thus the callers outside of the containerd process (e.g. Kubelet) never see ++ // the truncated output. ++ cout := &cappedWriter{w: cioutil.NewNopWriteCloser(&stdout), remain: maxStreamSize} ++ cerr := &cappedWriter{w: cioutil.NewNopWriteCloser(&stderr), remain: maxStreamSize} ++ + exitCode, err := c.execInContainer(ctx, r.GetContainerId(), execOptions{ + cmd: r.GetCmd(), +- stdout: cioutil.NewNopWriteCloser(&stdout), +- stderr: cioutil.NewNopWriteCloser(&stderr), ++ stdout: cout, ++ stderr: cerr, + timeout: time.Duration(r.GetTimeout()) * time.Second, + }) + if err != nil { +diff --git a/vendor/github.com/containerd/cri/pkg/server/container_execsync_test.go b/vendor/github.com/containerd/cri/pkg/server/container_execsync_test.go +new file mode 100644 +index 0000000..c8641d0 +--- /dev/null ++++ b/vendor/github.com/containerd/cri/pkg/server/container_execsync_test.go +@@ -0,0 +1,49 @@ ++/* ++ Copyright The containerd Authors. ++ Licensed under the Apache License, Version 2.0 (the "License"); ++ you may not use this file except in compliance with the License. ++ You may obtain a copy of the License at ++ http://www.apache.org/licenses/LICENSE-2.0 ++ Unless required by applicable law or agreed to in writing, software ++ distributed under the License is distributed on an "AS IS" BASIS, ++ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. ++ See the License for the specific language governing permissions and ++ limitations under the License. ++*/ ++ ++package server ++ ++import ( ++ "bytes" ++ "testing" ++ ++ cioutil "github.com/containerd/containerd/pkg/ioutil" ++ "github.com/stretchr/testify/assert" ++) ++ ++func TestCWWrite(t *testing.T) { ++ var buf bytes.Buffer ++ cw := &cappedWriter{w: cioutil.NewNopWriteCloser(&buf), remain: 10} ++ ++ n, err := cw.Write([]byte("hello")) ++ assert.NoError(t, err) ++ assert.Equal(t, 5, n) ++ ++ n, err = cw.Write([]byte("helloworld")) ++ assert.NoError(t, err, "no errors even it hits the cap") ++ assert.Equal(t, 10, n, "no indication of partial write") ++ assert.True(t, cw.isFull()) ++ assert.Equal(t, []byte("hellohello"), buf.Bytes(), "the underlying writer is capped") ++ ++ _, err = cw.Write([]byte("world")) ++ assert.NoError(t, err) ++ assert.True(t, cw.isFull()) ++ assert.Equal(t, []byte("hellohello"), buf.Bytes(), "the underlying writer is capped") ++} ++ ++func TestCWClose(t *testing.T) { ++ var buf bytes.Buffer ++ cw := &cappedWriter{w: cioutil.NewNopWriteCloser(&buf), remain: 5} ++ err := cw.Close() ++ assert.NoError(t, err) ++} +-- +2.30.0 + diff --git a/series.conf b/series.conf index 176905a..1054096 100644 --- a/series.conf +++ b/series.conf @@ -90,4 +90,5 @@ patch/0082-containerd-fix-publish-command-wait-block-for.patch patch/0083-containerd-optimize-cgo-compile-options.patch patch/0084-containerd-Use-fs.RootPath-when-mounting-vo.patch patch/0085-containerd-put-get-pid-lock-after-set-process-exited-to-.patch +patch/0086-containerd-Limit-the-response-size-of-ExecSync.patch # end -- Gitee