Package: release.debian.org
Severity: normal
Tags: bookworm
X-Debbugs-Cc: [email protected]
Control: affects -1 + src:containerd
User: [email protected]
Usertags: pu

[ Reason ]

Backport patch for CVE-2025-64329.

The previous upload 1.6.20~ds1-1+deb12u2 had a mistake in the changelog,
and while it fixed CVE-2024-40635, it claimed to have fixed
CVE-2025-64329.

This has been discussed with Maintainer and Security Team, the security
tracker had been updated [1], and Security Team confirmed that I should
proceed with an upload to bookworm-updates.

There's a bit of churn in this debdiff: on top of fixing CVE-2025-64329,
the changes also include:
- fix the _previous_ changelog entry
- rename a patch that fixes a CVE, for clarity

You can also see the changes on Salsa at [2], in case you find it easier
to see the Git history.

[1]: https://deb.freexian.com/extended-lts/tracker/source-package/containerd
[2]: 
https://salsa.debian.org/arnaudr/containerd/-/commits/debian/bookworm?ref_type=heads

[ Impact ]

Impact of CVE-2025-64329 is that a malicious user can exhaust memory on
the host by exploiting a bug in the CRI Attach implementation (goroutine
leaks).

[ Tests ]

I didn't come up with a test to confirm the fix , but the patch (that
comes from upstream) applies rather cleany. I did test that there's no
regression (ie. attaching to a running container still works).

[ Risks ]

The patch is rather trivial.

[ Checklist ]
  [x] *all* changes are documented in the d/changelog
  [x] I reviewed all changes and I approve them
  [x] attach debdiff against the package in (old)stable
  [x] the issue is verified as fixed in unstable

[ Changes ]

Backport patch for CVE-2025-64329:  a malicious user can exhaust memory
on the host by exploiting a bug in the CRI Attach implementation
(goroutine leaks).

Fix previous changelog entry (1.6.20~ds1-1+deb12u2).

Rename a patch that fixes a CVE with the name of the CVE itself, for
clarity.

Best,

Arnaud
diff -Nru containerd-1.6.20~ds1/debian/changelog 
containerd-1.6.20~ds1/debian/changelog
--- containerd-1.6.20~ds1/debian/changelog      2025-11-17 04:57:18.000000000 
+0700
+++ containerd-1.6.20~ds1/debian/changelog      2026-02-12 10:30:28.000000000 
+0700
@@ -1,9 +1,19 @@
-containerd (1.6.20~ds1-1+deb12u2) bookworm-security; urgency=medium
+containerd (1.6.20~ds1-1+deb12u3) bookworm; urgency=medium
 
-  * Fix overly broad directory permissions, Fixes: CVE-2024-25621
+  * Non-maintainer upload.
+  * Rename Fix-directory-permissions patch for clarity
   * Fix bug in the CRI Attach implementation, Fixes: CVE-2025-64329
     Closes: #1120343
 
+ -- Arnaud Rebillout <[email protected]>  Thu, 12 Feb 2026 10:30:28 +0700
+
+containerd (1.6.20~ds1-1+deb12u2) bookworm-security; urgency=medium
+
+  * Fix overly broad directory permissions, Fixes: CVE-2024-25621
+    Closes: #1120285
+  * Fix large UID:GID (> 32bit) overflow, Fixes: CVE-2024-40635
+    Closes: #1100806
+
  -- Reinhard Tartler <[email protected]>  Sun, 16 Nov 2025 16:57:18 -0500
 
 containerd (1.6.20~ds1-1+deb12u1) bookworm; urgency=medium
diff -Nru containerd-1.6.20~ds1/debian/gbp.conf 
containerd-1.6.20~ds1/debian/gbp.conf
--- containerd-1.6.20~ds1/debian/gbp.conf       2025-11-17 04:57:18.000000000 
+0700
+++ containerd-1.6.20~ds1/debian/gbp.conf       2026-02-12 10:30:28.000000000 
+0700
@@ -1,5 +1,5 @@
 [DEFAULT]
 pristine-tar = True
-debian-branch = debian/sid
+debian-branch = debian/bookworm
 upstream-branch = upstream/sid
 dist = DEP14
diff -Nru containerd-1.6.20~ds1/debian/patches/0012-CVE-2024-25621.patch 
containerd-1.6.20~ds1/debian/patches/0012-CVE-2024-25621.patch
--- containerd-1.6.20~ds1/debian/patches/0012-CVE-2024-25621.patch      
1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.6.20~ds1/debian/patches/0012-CVE-2024-25621.patch      
2026-02-12 10:30:28.000000000 +0700
@@ -0,0 +1,95 @@
+From: Akihiro Suda <[email protected]>
+Date: Mon, 27 Oct 2025 16:42:59 +0900
+Subject: Fix directory permissions
+
+- Create /var/lib/containerd with 0o700 (was: 0o711).
+- Create config.TempDir with 0o700 (was: 0o711).
+- Create /run/containerd/io.containerd.grpc.v1.cri with 0o700 (was: 0o755).
+- Create /run/containerd/io.containerd.sandbox.controller.v1.shim with 0o700 
(was: 0o711).
+- Leave /run/containerd and /run/containerd/io.containerd.runtime.v2.task 
created with 0o711,
+  as required by userns-remapped containers.
+  /run/containerd/io.containerd.runtime.v2.task/<NS>/<ID> is created with:
+  - 0o700 for non-userns-remapped containers
+  - 0o710 for userns-remapped containers with the remapped root group as the 
owner group.
+
+Signed-off-by: Akihiro Suda <[email protected]>
+(cherry picked from commit 51b0cf11dc5af7ed1919beba259e644138b28d96)
+Signed-off-by: Akihiro Suda <[email protected]>
+---
+ pkg/cri/cri.go            |  7 +++++++
+ runtime/v2/manager.go     |  2 ++
+ services/server/server.go | 14 ++++++++++++--
+ 3 files changed, 21 insertions(+), 2 deletions(-)
+
+Index: containerd/pkg/cri/cri.go
+===================================================================
+--- containerd.orig/pkg/cri/cri.go
++++ containerd/pkg/cri/cri.go
+@@ -19,6 +19,7 @@ package cri
+ import (
+       "flag"
+       "fmt"
++      "os"
+       "path/filepath"
+ 
+       "github.com/containerd/containerd"
+@@ -68,6 +69,13 @@ func initCRIService(ic *plugin.InitConte
+               return nil, fmt.Errorf("invalid plugin config: %w", err)
+       }
+ 
++      if err := os.MkdirAll(ic.State, 0700); err != nil {
++              return nil, err
++      }
++      // chmod is needed for upgrading from an older release that created the 
dir with 0755
++      if err := os.Chmod(ic.State, 0700); err != nil {
++              return nil, err
++      }
+       c := criconfig.Config{
+               PluginConfig:       *pluginConfig,
+               ContainerdRootDir:  filepath.Dir(ic.Root),
+Index: containerd/runtime/v2/manager.go
+===================================================================
+--- containerd.orig/runtime/v2/manager.go
++++ containerd/runtime/v2/manager.go
+@@ -109,6 +109,8 @@ type ManagerConfig struct {
+ // NewShimManager creates a manager for v2 shims
+ func NewShimManager(ctx context.Context, config *ManagerConfig) 
(*ShimManager, error) {
+       for _, d := range []string{config.Root, config.State} {
++              // root:  the parent of this directory is created as 0700, not 
0711.
++              // state: the parent of this directory is created as 0711 too, 
so as to support userns-remapped containers.
+               if err := os.MkdirAll(d, 0711); err != nil {
+                       return nil, err
+               }
+Index: containerd/services/server/server.go
+===================================================================
+--- containerd.orig/services/server/server.go
++++ containerd/services/server/server.go
+@@ -79,16 +79,26 @@ func CreateTopLevelDirectories(config *s
+               return errors.New("root and state must be different paths")
+       }
+ 
+-      if err := sys.MkdirAllWithACL(config.Root, 0711); err != nil {
++      if err := sys.MkdirAllWithACL(config.Root, 0700); err != nil {
++              return err
++      }
++      // chmod is needed for upgrading from an older release that created the 
dir with 0o711
++      if err := os.Chmod(config.Root, 0700); err != nil {
+               return err
+       }
+ 
++      // For supporting userns-remapped containers, the state dir cannot be 
just mkdired with 0o700.
++      // Each of plugins creates a dedicated directory beneath the state dir 
with appropriate permission bits.
+       if err := sys.MkdirAllWithACL(config.State, 0711); err != nil {
+               return err
+       }
+ 
+       if config.TempDir != "" {
+-              if err := sys.MkdirAllWithACL(config.TempDir, 0711); err != nil 
{
++              if err := sys.MkdirAllWithACL(config.TempDir, 0700); err != nil 
{
++                      return err
++              }
++              // chmod is needed for upgrading from an older release that 
created the dir with 0o711
++              if err := os.Chmod(config.Root, 0700); err != nil {
+                       return err
+               }
+               if runtime.GOOS == "windows" {
diff -Nru 
containerd-1.6.20~ds1/debian/patches/0013-Fix-directory-permissions.patch 
containerd-1.6.20~ds1/debian/patches/0013-Fix-directory-permissions.patch
--- containerd-1.6.20~ds1/debian/patches/0013-Fix-directory-permissions.patch   
2025-11-17 04:57:18.000000000 +0700
+++ containerd-1.6.20~ds1/debian/patches/0013-Fix-directory-permissions.patch   
1970-01-01 08:00:00.000000000 +0800
@@ -1,95 +0,0 @@
-From: Akihiro Suda <[email protected]>
-Date: Mon, 27 Oct 2025 16:42:59 +0900
-Subject: Fix directory permissions
-
-- Create /var/lib/containerd with 0o700 (was: 0o711).
-- Create config.TempDir with 0o700 (was: 0o711).
-- Create /run/containerd/io.containerd.grpc.v1.cri with 0o700 (was: 0o755).
-- Create /run/containerd/io.containerd.sandbox.controller.v1.shim with 0o700 
(was: 0o711).
-- Leave /run/containerd and /run/containerd/io.containerd.runtime.v2.task 
created with 0o711,
-  as required by userns-remapped containers.
-  /run/containerd/io.containerd.runtime.v2.task/<NS>/<ID> is created with:
-  - 0o700 for non-userns-remapped containers
-  - 0o710 for userns-remapped containers with the remapped root group as the 
owner group.
-
-Signed-off-by: Akihiro Suda <[email protected]>
-(cherry picked from commit 51b0cf11dc5af7ed1919beba259e644138b28d96)
-Signed-off-by: Akihiro Suda <[email protected]>
----
- pkg/cri/cri.go            |  7 +++++++
- runtime/v2/manager.go     |  2 ++
- services/server/server.go | 14 ++++++++++++--
- 3 files changed, 21 insertions(+), 2 deletions(-)
-
-Index: containerd/pkg/cri/cri.go
-===================================================================
---- containerd.orig/pkg/cri/cri.go
-+++ containerd/pkg/cri/cri.go
-@@ -19,6 +19,7 @@ package cri
- import (
-       "flag"
-       "fmt"
-+      "os"
-       "path/filepath"
- 
-       "github.com/containerd/containerd"
-@@ -68,6 +69,13 @@ func initCRIService(ic *plugin.InitConte
-               return nil, fmt.Errorf("invalid plugin config: %w", err)
-       }
- 
-+      if err := os.MkdirAll(ic.State, 0700); err != nil {
-+              return nil, err
-+      }
-+      // chmod is needed for upgrading from an older release that created the 
dir with 0755
-+      if err := os.Chmod(ic.State, 0700); err != nil {
-+              return nil, err
-+      }
-       c := criconfig.Config{
-               PluginConfig:       *pluginConfig,
-               ContainerdRootDir:  filepath.Dir(ic.Root),
-Index: containerd/runtime/v2/manager.go
-===================================================================
---- containerd.orig/runtime/v2/manager.go
-+++ containerd/runtime/v2/manager.go
-@@ -109,6 +109,8 @@ type ManagerConfig struct {
- // NewShimManager creates a manager for v2 shims
- func NewShimManager(ctx context.Context, config *ManagerConfig) 
(*ShimManager, error) {
-       for _, d := range []string{config.Root, config.State} {
-+              // root:  the parent of this directory is created as 0700, not 
0711.
-+              // state: the parent of this directory is created as 0711 too, 
so as to support userns-remapped containers.
-               if err := os.MkdirAll(d, 0711); err != nil {
-                       return nil, err
-               }
-Index: containerd/services/server/server.go
-===================================================================
---- containerd.orig/services/server/server.go
-+++ containerd/services/server/server.go
-@@ -79,16 +79,26 @@ func CreateTopLevelDirectories(config *s
-               return errors.New("root and state must be different paths")
-       }
- 
--      if err := sys.MkdirAllWithACL(config.Root, 0711); err != nil {
-+      if err := sys.MkdirAllWithACL(config.Root, 0700); err != nil {
-+              return err
-+      }
-+      // chmod is needed for upgrading from an older release that created the 
dir with 0o711
-+      if err := os.Chmod(config.Root, 0700); err != nil {
-               return err
-       }
- 
-+      // For supporting userns-remapped containers, the state dir cannot be 
just mkdired with 0o700.
-+      // Each of plugins creates a dedicated directory beneath the state dir 
with appropriate permission bits.
-       if err := sys.MkdirAllWithACL(config.State, 0711); err != nil {
-               return err
-       }
- 
-       if config.TempDir != "" {
--              if err := sys.MkdirAllWithACL(config.TempDir, 0711); err != nil 
{
-+              if err := sys.MkdirAllWithACL(config.TempDir, 0700); err != nil 
{
-+                      return err
-+              }
-+              // chmod is needed for upgrading from an older release that 
created the dir with 0o711
-+              if err := os.Chmod(config.Root, 0700); err != nil {
-                       return err
-               }
-               if runtime.GOOS == "windows" {
diff -Nru containerd-1.6.20~ds1/debian/patches/0014-CVE-2025-64329.patch 
containerd-1.6.20~ds1/debian/patches/0014-CVE-2025-64329.patch
--- containerd-1.6.20~ds1/debian/patches/0014-CVE-2025-64329.patch      
1970-01-01 08:00:00.000000000 +0800
+++ containerd-1.6.20~ds1/debian/patches/0014-CVE-2025-64329.patch      
2026-02-12 10:30:28.000000000 +0700
@@ -0,0 +1,70 @@
+From: wheat2018 <[email protected]>
+Date: Tue, 13 Aug 2024 15:56:31 +0800
+Subject: [PATCH] fix goroutine leak of container Attach
+
+The monitor goroutine (runs (*ContainerIO).Attach.func1) of Attach will
+never finish if it attaches to a container without any stdout or stderr
+output. Wait for http context cancel and break the pipe actively to
+address the issue.
+
+Signed-off-by: wheat2018 <[email protected]>
+Signed-off-by: Akihiro Suda <[email protected]>
+(cherry picked from commit a0d0f0ef68935338d2c710db164fa7820f692530)
+Signed-off-by: Akihiro Suda <[email protected]>
+Origin: backport, https://github.com/containerd/containerd/c575d1b5
+---
+ pkg/cri/io/container_io.go         | 14 +++++++++++---
+ pkg/cri/server/container_attach.go |  2 +-
+ 2 files changed, 12 insertions(+), 4 deletions(-)
+
+diff --git a/pkg/cri/io/container_io.go b/pkg/cri/io/container_io.go
+index 70bc8b7..e158410 100644
+--- a/pkg/cri/io/container_io.go
++++ b/pkg/cri/io/container_io.go
+@@ -17,6 +17,7 @@
+ package io
+ 
+ import (
++      "context"
+       "errors"
+       "io"
+       "strings"
+@@ -134,7 +135,7 @@ func (c *ContainerIO) Pipe() {
+ 
+ // Attach attaches container stdio.
+ // TODO(random-liu): Use pools.Copy in docker to reduce memory usage?
+-func (c *ContainerIO) Attach(opts AttachOptions) {
++func (c *ContainerIO) Attach(ctx context.Context, opts AttachOptions) {
+       var wg sync.WaitGroup
+       key := util.GenerateID()
+       stdinKey := streamKey(c.id, "attach-"+key, Stdin)
+@@ -175,8 +176,15 @@ func (c *ContainerIO) Attach(opts AttachOptions) {
+       }
+ 
+       attachStream := func(key string, close <-chan struct{}) {
+-              <-close
+-              logrus.Infof("Attach stream %q closed", key)
++              select {
++              case <-close:
++                      logrus.Infof("Attach stream %q closed", key)
++              case <-ctx.Done():
++                      logrus.Infof("Attach client of %q cancelled", key)
++                      // Avoid writeGroup heap up
++                      c.stdoutGroup.Remove(key)
++                      c.stderrGroup.Remove(key)
++              }
+               // Make sure stdin gets closed.
+               if stdinStreamRC != nil {
+                       stdinStreamRC.Close()
+diff --git a/pkg/cri/server/container_attach.go 
b/pkg/cri/server/container_attach.go
+index a952150..3625229 100644
+--- a/pkg/cri/server/container_attach.go
++++ b/pkg/cri/server/container_attach.go
+@@ -79,6 +79,6 @@ func (c *criService) attachContainer(ctx context.Context, id 
string, stdin io.Re
+               },
+       }
+       // TODO(random-liu): Figure out whether we need to support historical 
output.
+-      cntr.IO.Attach(opts)
++      cntr.IO.Attach(ctx, opts)
+       return nil
+ }
diff -Nru containerd-1.6.20~ds1/debian/patches/series 
containerd-1.6.20~ds1/debian/patches/series
--- containerd-1.6.20~ds1/debian/patches/series 2025-11-17 04:57:18.000000000 
+0700
+++ containerd-1.6.20~ds1/debian/patches/series 2026-02-12 10:30:28.000000000 
+0700
@@ -7,5 +7,6 @@
 0007-cri-fix-integration-test-on-cgroupsv2-system.patch
 0008-Add-Debian-specific-CNI-bin-dir-to-ctr-run-command.patch
 0011-allow-test-run-in-userns.patch
+0012-CVE-2024-25621.patch
 0013-CVE-2024-40635.patch
-0013-Fix-directory-permissions.patch
+0014-CVE-2025-64329.patch

Reply via email to