diff -Nru containerd-1.5.9/debian/changelog containerd-1.5.9/debian/changelog --- containerd-1.5.9/debian/changelog 2022-02-09 20:38:58.000000000 +0000 +++ containerd-1.5.9/debian/changelog 2022-12-12 15:33:42.000000000 +0000 @@ -1,3 +1,26 @@ +containerd (1.5.9-0ubuntu1~18.04.2) bionic-security; urgency=medium + + * SECURITY UPDATE: Memory exhaustion through Exec + - debian/patches/CVE-2022-23471.patch: Prevent goroutine leak in Exec + in pkg/cri/streaming/remotecommand/httpstream.go. + - CVE-2022-23471 + * SECURITY UPDATE: Privilege escalation by inheritable file capabilities. + - debian/patches/CVE-2022-24769.patch: Unassign the Inheritable + capability in oci/spec.go and oci/spec_opts.go. + - CVE-2022-24769 + * SECURITY UPDATE: Improper access to images due to imgcrypt. + - debian/patches/CVE-2022-24778.patch: perform proper + authentication by adding platforms in + vendor/github.com/containerd/imgcrypt/images/ + encryption/encryption.go. + - CVE-2022-24778 + * SECURITY UPDATE: Memory exhaustion through ExecSync. + - debian/patches/CVE-2022-31030.patch: limit the response size + of ExecSync in pkg/cri/server/container_execsync.go. + - CVE-2022-31030 + + -- David Fernandez Gonzalez Mon, 12 Dec 2022 16:33:42 +0100 + containerd (1.5.9-0ubuntu1~18.04.1) bionic; urgency=medium * Backport version 1.5.9-0ubuntu1 from Jammy (LP: #1955413, #1960449). diff -Nru containerd-1.5.9/debian/patches/CVE-2022-23471.patch containerd-1.5.9/debian/patches/CVE-2022-23471.patch --- containerd-1.5.9/debian/patches/CVE-2022-23471.patch 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.5.9/debian/patches/CVE-2022-23471.patch 2022-12-12 10:25:11.000000000 +0000 @@ -0,0 +1,71 @@ +From f012617edfd887a29345888d65640a7ccd7c72ce Mon Sep 17 00:00:00 2001 +From: Danny Canter +Date: Mon, 28 Nov 2022 14:45:34 -0800 +Subject: [PATCH] CRI stream server: Fix goroutine leak in Exec + +In the CRI streaming server, a goroutine (`handleResizeEvents`) is launched +to handle terminal resize events if a TTY is asked for with an exec; this +is the sender of terminal resize events. Another goroutine is launched +shortly after successful process startup to actually do something with +these events, however the issue arises if the exec process fails to start +for any reason that would have `process.Start` return non-nil. The receiver +goroutine never gets launched so the sender is stuck blocked on a channel send +infinitely. + +This could be used in a malicious manner by repeatedly launching execs +with a command that doesn't exist in the image, as a single goroutine +will get leaked on every invocation which will slowly grow containerd's +memory usage. + +Signed-off-by: Danny Canter +--- + pkg/cri/streaming/remotecommand/httpstream.go | 15 ++++++++++++--- + 1 file changed, 12 insertions(+), 3 deletions(-) + +diff --git a/pkg/cri/streaming/remotecommand/httpstream.go b/pkg/cri/streaming/remotecommand/httpstream.go +index 0417a1a9e66..9177fa794d2 100644 +--- a/pkg/cri/streaming/remotecommand/httpstream.go ++++ b/pkg/cri/streaming/remotecommand/httpstream.go +@@ -33,6 +33,7 @@ limitations under the License. + package remotecommand + + import ( ++ gocontext "context" + "encoding/json" + "errors" + "fmt" +@@ -132,7 +133,7 @@ func createStreams(req *http.Request, w http.ResponseWriter, opts *Options, supp + + if ctx.resizeStream != nil { + ctx.resizeChan = make(chan remotecommand.TerminalSize) +- go handleResizeEvents(ctx.resizeStream, ctx.resizeChan) ++ go handleResizeEvents(req.Context(), ctx.resizeStream, ctx.resizeChan) + } + + return ctx, true +@@ -425,7 +426,7 @@ WaitForStreams: + // supportsTerminalResizing returns false because v1ProtocolHandler doesn't support it. + func (*v1ProtocolHandler) supportsTerminalResizing() bool { return false } + +-func handleResizeEvents(stream io.Reader, channel chan<- remotecommand.TerminalSize) { ++func handleResizeEvents(ctx gocontext.Context, stream io.Reader, channel chan<- remotecommand.TerminalSize) { + defer runtime.HandleCrash() + defer close(channel) + +@@ -435,7 +436,15 @@ func handleResizeEvents(stream io.Reader, channel chan<- remotecommand.TerminalS + if err := decoder.Decode(&size); err != nil { + break + } +- channel <- size ++ ++ select { ++ case channel <- size: ++ case <-ctx.Done(): ++ // To avoid leaking this routine, exit if the http request finishes. This path ++ // would generally be hit if starting the process fails and nothing is started to ++ // ingest these resize events. ++ return ++ } + } + } + diff -Nru containerd-1.5.9/debian/patches/CVE-2022-24769.patch containerd-1.5.9/debian/patches/CVE-2022-24769.patch --- containerd-1.5.9/debian/patches/CVE-2022-24769.patch 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.5.9/debian/patches/CVE-2022-24769.patch 2022-12-12 08:49:02.000000000 +0000 @@ -0,0 +1,147 @@ +From 6906b57c721f9114377ceb069662b196876915c0 Mon Sep 17 00:00:00 2001 +From: "Andrew G. Morgan" +Date: Wed, 8 Sep 2021 12:57:23 -0700 +Subject: [PATCH] Fix the Inheritable capability defaults. + +The Linux kernel never sets the Inheritable capability flag to +anything other than empty. Non-empty values are always exclusively +set by userspace code. + +[The kernel stopped defaulting this set of capability values to the + full set in 2000 after a privilege escalation with Capabilities + affecting Sendmail and others.] + +Signed-off-by: Andrew G. Morgan +--- + oci/spec.go | 7 +++---- + oci/spec_opts.go | 5 +---- + oci/spec_opts_linux_test.go | 4 ---- + oci/spec_test.go | 5 ++--- + pkg/cri/server/container_create_linux_test.go | 3 +-- + 5 files changed, 7 insertions(+), 17 deletions(-) + +--- containerd-1.5.5.orig/oci/spec.go ++++ containerd-1.5.5/oci/spec.go +@@ -148,10 +148,9 @@ func populateDefaultUnixSpec(ctx context + GID: 0, + }, + Capabilities: &specs.LinuxCapabilities{ +- Bounding: defaultUnixCaps(), +- Permitted: defaultUnixCaps(), +- Inheritable: defaultUnixCaps(), +- Effective: defaultUnixCaps(), ++ Bounding: defaultUnixCaps(), ++ Permitted: defaultUnixCaps(), ++ Effective: defaultUnixCaps(), + }, + Rlimits: []specs.POSIXRlimit{ + { +--- containerd-1.5.5.orig/oci/spec_opts.go ++++ containerd-1.5.5/oci/spec_opts.go +@@ -788,7 +788,6 @@ func WithCapabilities(caps []string) Spe + s.Process.Capabilities.Bounding = caps + s.Process.Capabilities.Effective = caps + s.Process.Capabilities.Permitted = caps +- s.Process.Capabilities.Inheritable = caps + + return nil + } +@@ -823,7 +822,6 @@ func WithAddedCapabilities(caps []string + &s.Process.Capabilities.Bounding, + &s.Process.Capabilities.Effective, + &s.Process.Capabilities.Permitted, +- &s.Process.Capabilities.Inheritable, + } { + if !capsContain(*cl, c) { + *cl = append(*cl, c) +@@ -843,7 +841,6 @@ func WithDroppedCapabilities(caps []stri + &s.Process.Capabilities.Bounding, + &s.Process.Capabilities.Effective, + &s.Process.Capabilities.Permitted, +- &s.Process.Capabilities.Inheritable, + } { + removeCap(cl, c) + } +@@ -858,7 +855,7 @@ func WithDroppedCapabilities(caps []stri + func WithAmbientCapabilities(caps []string) SpecOpts { + return func(_ context.Context, _ Client, _ *containers.Container, s *Spec) error { + setCapabilities(s) +- ++ s.Process.Capabilities.Inheritable = caps + s.Process.Capabilities.Ambient = caps + return nil + } +--- containerd-1.5.5.orig/oci/spec_opts_linux_test.go ++++ containerd-1.5.5/oci/spec_opts_linux_test.go +@@ -40,7 +40,6 @@ func TestAddCaps(t *testing.T) { + s.Process.Capabilities.Bounding, + s.Process.Capabilities.Effective, + s.Process.Capabilities.Permitted, +- s.Process.Capabilities.Inheritable, + } { + if !capsContain(cl, "CAP_CHOWN") { + t.Errorf("cap list %d does not contain added cap", i) +@@ -64,7 +63,6 @@ func TestDropCaps(t *testing.T) { + s.Process.Capabilities.Bounding, + s.Process.Capabilities.Effective, + s.Process.Capabilities.Permitted, +- s.Process.Capabilities.Inheritable, + } { + if capsContain(cl, "CAP_CHOWN") { + t.Errorf("cap list %d contains dropped cap", i) +@@ -83,7 +81,6 @@ func TestDropCaps(t *testing.T) { + s.Process.Capabilities.Bounding, + s.Process.Capabilities.Effective, + s.Process.Capabilities.Permitted, +- s.Process.Capabilities.Inheritable, + } { + if capsContain(cl, "CAP_FOWNER") { + t.Errorf("cap list %d contains dropped cap", i) +@@ -104,7 +101,6 @@ func TestDropCaps(t *testing.T) { + s.Process.Capabilities.Bounding, + s.Process.Capabilities.Effective, + s.Process.Capabilities.Permitted, +- s.Process.Capabilities.Inheritable, + } { + if len(cl) != 0 { + t.Errorf("cap list %d is not empty", i) +--- containerd-1.5.5.orig/oci/spec_test.go ++++ containerd-1.5.5/oci/spec_test.go +@@ -45,7 +45,6 @@ func TestGenerateSpec(t *testing.T) { + for _, cl := range [][]string{ + s.Process.Capabilities.Bounding, + s.Process.Capabilities.Permitted, +- s.Process.Capabilities.Inheritable, + s.Process.Capabilities.Effective, + } { + for i := 0; i < len(defaults); i++ { +@@ -193,8 +192,8 @@ func TestWithCapabilities(t *testing.T) + if len(s.Process.Capabilities.Permitted) != 1 || s.Process.Capabilities.Permitted[0] != "CAP_SYS_ADMIN" { + t.Error("Unexpected capabilities set") + } +- if len(s.Process.Capabilities.Inheritable) != 1 || s.Process.Capabilities.Inheritable[0] != "CAP_SYS_ADMIN" { +- t.Error("Unexpected capabilities set") ++ if len(s.Process.Capabilities.Inheritable) != 0 { ++ t.Errorf("Unexpected capabilities set: length is non zero (%d)", len(s.Process.Capabilities.Inheritable)) + } + } + +--- containerd-1.5.5.orig/pkg/cri/server/container_create_linux_test.go ++++ containerd-1.5.5/pkg/cri/server/container_create_linux_test.go +@@ -254,15 +254,14 @@ func TestContainerCapabilities(t *testin + for _, include := range test.includes { + assert.Contains(t, spec.Process.Capabilities.Bounding, include) + assert.Contains(t, spec.Process.Capabilities.Effective, include) +- assert.Contains(t, spec.Process.Capabilities.Inheritable, include) + assert.Contains(t, spec.Process.Capabilities.Permitted, include) + } + for _, exclude := range test.excludes { + assert.NotContains(t, spec.Process.Capabilities.Bounding, exclude) + assert.NotContains(t, spec.Process.Capabilities.Effective, exclude) +- assert.NotContains(t, spec.Process.Capabilities.Inheritable, exclude) + assert.NotContains(t, spec.Process.Capabilities.Permitted, exclude) + } ++ assert.Empty(t, spec.Process.Capabilities.Inheritable) + assert.Empty(t, spec.Process.Capabilities.Ambient) + } + } diff -Nru containerd-1.5.9/debian/patches/CVE-2022-24778.patch containerd-1.5.9/debian/patches/CVE-2022-24778.patch --- containerd-1.5.9/debian/patches/CVE-2022-24778.patch 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.5.9/debian/patches/CVE-2022-24778.patch 2022-12-12 08:49:17.000000000 +0000 @@ -0,0 +1,68 @@ +From 6fdd9818a4d8142107b7ecd767d839c9707700d9 Mon Sep 17 00:00:00 2001 +From: Stefan Berger +Date: Thu, 17 Mar 2022 15:52:56 -0400 +Subject: [PATCH] images: Add list of Platforms to CheckAuthorization() + +To be able to properly perform an authorization check on an image we need +to know the platform to perform check when in cryptManifestList(). Extend +the logic for cryptoOp == cryptoOpUnwrapOnly to skip over manifests that +do not correspond to the local platform and return an error if no manifest +was found that matches the local platform. + +The following projects seem NOT to be affect due to the change in the code +path of CheckAuthorization() since they are not using it: + +- cri-o +- nerdctl +- skopeo +- buildah +- podman + +The impact on imgcrypt via ctr-enc is not so clear either since +CheckAuthorization() is not called on the server side but by the ctr-enc +client, thus can be modified easily. + +Resolves: https://github.com/containerd/imgcrypt/issues/69 +Signed-off-by: Stefan Berger +--- + images/encryption/encryption.go | 13 +++++++++++++ + 1 file changed, 13 insertions(+) + +diff --git a/images/encryption/encryption.go b/images/encryption/encryption.go +index 204d32c0..291424d1 100644 +--- a//vendor/github.com/containerd/imgcrypt/images/encryption/encryption.go ++++ b/vendor/github.com/containerd/imgcrypt/images/encryption/encryption.go +@@ -50,6 +50,13 @@ const ( + // LayerFilter allows to select Layers by certain criteria + type LayerFilter func(desc ocispec.Descriptor) bool + ++// isLocalPlatform determines whether the given platform matches the local one ++func isLocalPlatform(platform *ocispec.Platform) bool { ++ matcher := platforms.NewMatcher(*platform) ++ ++ return matcher.Match(platforms.DefaultSpec()) ++} ++ + // IsEncryptedDiff returns true if mediaType is a known encrypted media type. + func IsEncryptedDiff(ctx context.Context, mediaType string) bool { + switch mediaType { +@@ -380,6 +387,9 @@ func cryptManifestList(ctx context.Context, cs content.Store, desc ocispec.Descr + var newManifests []ocispec.Descriptor + modified := false + for _, manifest := range index.Manifests { ++ if cryptoOp == cryptoOpUnwrapOnly && !isLocalPlatform(manifest.Platform) { ++ continue ++ } + newManifest, m, err := cryptChildren(ctx, cs, manifest, cc, lf, cryptoOp, manifest.Platform) + if err != nil || cryptoOp == cryptoOpUnwrapOnly { + return ocispec.Descriptor{}, false, err +@@ -389,6 +399,9 @@ func cryptManifestList(ctx context.Context, cs content.Store, desc ocispec.Descr + } + newManifests = append(newManifests, newManifest) + } ++ if cryptoOp == cryptoOpUnwrapOnly { ++ return ocispec.Descriptor{}, false, fmt.Errorf("No manifest found for local platform") ++ } + + if modified { + // we need to update the index diff -Nru containerd-1.5.9/debian/patches/CVE-2022-31030.patch containerd-1.5.9/debian/patches/CVE-2022-31030.patch --- containerd-1.5.9/debian/patches/CVE-2022-31030.patch 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.5.9/debian/patches/CVE-2022-31030.patch 2022-12-12 08:49:27.000000000 +0000 @@ -0,0 +1,233 @@ +From 49ca87d7270091b8193301dc2f6759e9aa7c97b1 Mon Sep 17 00:00:00 2001 +From: Kazuyoshi Kato +Date: Mon, 16 May 2022 17:33:33 +0000 +Subject: [PATCH 1/2] Limit the response size of ExecSync + +Signed-off-by: Kazuyoshi Kato +--- + pkg/cri/server/container_execsync.go | 39 +++++++++++++++++- + pkg/cri/server/container_execsync_test.go | 49 +++++++++++++++++++++++ + 2 files changed, 86 insertions(+), 2 deletions(-) + create mode 100644 pkg/cri/server/container_execsync_test.go + +diff --git a/pkg/cri/server/container_execsync.go b/pkg/cri/server/container_execsync.go +index 3bf8d85c07b..15221f9bd09 100644 +--- a/pkg/cri/server/container_execsync.go ++++ b/pkg/cri/server/container_execsync.go +@@ -19,6 +19,7 @@ package server + import ( + "bytes" + "io" ++ "errors" + "syscall" + "time" + +@@ -38,14 +39,48 @@ import ( + cioutil "github.com/containerd/containerd/pkg/ioutil" + ) + ++type cappedWriter struct { ++ w io.WriteCloser ++ remain int ++} ++ ++var errNoRemain = errors.New("no more space to write") ++ ++func (cw *cappedWriter) Write(p []byte) (int, error) { ++ if cw.remain <= 0 { ++ return 0, errNoRemain ++ } ++ ++ 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 ++ } ++ if written < len(p) { ++ return written, errNoRemain ++ } ++ return written, nil ++} ++ ++func (cw *cappedWriter) Close() error { ++ return cw.w.Close() ++} ++ + // 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 + exitCode, err := c.execInContainer(ctx, r.GetContainerId(), execOptions{ + cmd: r.GetCmd(), +- stdout: cioutil.NewNopWriteCloser(&stdout), +- stderr: cioutil.NewNopWriteCloser(&stderr), ++ stdout: &cappedWriter{w: cioutil.NewNopWriteCloser(&stdout), remain: maxStreamSize}, ++ stderr: &cappedWriter{w: cioutil.NewNopWriteCloser(&stderr), remain: maxStreamSize}, + timeout: time.Duration(r.GetTimeout()) * time.Second, + }) + if err != nil { +diff --git a/pkg/cri/server/container_execsync_test.go b/pkg/cri/server/container_execsync_test.go +new file mode 100644 +index 00000000000..18856b8fca4 +--- /dev/null ++++ b/pkg/cri/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.Equal(t, []byte("hellohello"), buf.Bytes(), "partial write") ++ assert.Equal(t, 5, n) ++ assert.ErrorIs(t, err, errNoRemain) ++ ++ _, err = cw.Write([]byte("world")) ++ assert.ErrorIs(t, err, errNoRemain) ++} ++ ++func TestCWClose(t *testing.T) { ++ var buf bytes.Buffer ++ cw := &cappedWriter{w: cioutil.NewNopWriteCloser(&buf), remain: 5} ++ err := cw.Close() ++ assert.NoError(t, err) ++} + +From 40aa4f3f1bd7bd72839fa05d1ff61d58cba4430b Mon Sep 17 00:00:00 2001 +From: Kazuyoshi Kato +Date: Thu, 2 Jun 2022 03:53:11 +0000 +Subject: [PATCH 2/2] Implicitly discard the input to drain the reader + +Signed-off-by: Derek McGowan +--- + pkg/cri/server/container_execsync.go | 26 ++++++++++++++--------- + pkg/cri/server/container_execsync_test.go | 11 ++++++---- + 2 files changed, 23 insertions(+), 14 deletions(-) + +diff --git a/pkg/cri/server/container_execsync.go b/pkg/cri/server/container_execsync.go +index 15221f9bd09..1cb34443548 100644 +--- a/pkg/cri/server/container_execsync.go ++++ b/pkg/cri/server/container_execsync.go +@@ -19,7 +19,6 @@ package server + import ( + "bytes" + "io" +- "errors" + "syscall" + "time" + +@@ -44,11 +43,9 @@ type cappedWriter struct { + remain int + } + +-var errNoRemain = errors.New("no more space to write") +- + func (cw *cappedWriter) Write(p []byte) (int, error) { + if cw.remain <= 0 { +- return 0, errNoRemain ++ return len(p), nil + } + + end := cw.remain +@@ -61,26 +58,35 @@ func (cw *cappedWriter) Write(p []byte) (int, error) { + if err != nil { + return written, err + } +- if written < len(p) { +- return written, errNoRemain +- } +- return written, nil ++ 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: &cappedWriter{w: cioutil.NewNopWriteCloser(&stdout), remain: maxStreamSize}, +- stderr: &cappedWriter{w: cioutil.NewNopWriteCloser(&stderr), remain: maxStreamSize}, ++ stdout: cout, ++ stderr: cerr, + timeout: time.Duration(r.GetTimeout()) * time.Second, + }) + if err != nil { +diff --git a/pkg/cri/server/container_execsync_test.go b/pkg/cri/server/container_execsync_test.go +index 18856b8fca4..98990964963 100644 +--- a/pkg/cri/server/container_execsync_test.go ++++ b/pkg/cri/server/container_execsync_test.go +@@ -33,12 +33,15 @@ func TestCWWrite(t *testing.T) { + assert.Equal(t, 5, n) + + n, err = cw.Write([]byte("helloworld")) +- assert.Equal(t, []byte("hellohello"), buf.Bytes(), "partial write") +- assert.Equal(t, 5, n) +- assert.ErrorIs(t, err, errNoRemain) ++ 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.ErrorIs(t, err, errNoRemain) ++ 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) { diff -Nru containerd-1.5.9/debian/patches/series containerd-1.5.9/debian/patches/series --- containerd-1.5.9/debian/patches/series 2022-02-09 20:38:58.000000000 +0000 +++ containerd-1.5.9/debian/patches/series 2022-12-12 10:25:11.000000000 +0000 @@ -1,3 +1,7 @@ skip-tests-with-privilege.patch preserve-debug-info.patch CVE-2022-23648.patch +CVE-2022-23471.patch +CVE-2022-24769.patch +CVE-2022-24778.patch +CVE-2022-31030.patch