Version in base suite: 1.6.20~ds1-1+deb12u1 Base version: containerd_1.6.20~ds1-1+deb12u1 Target version: containerd_1.6.20~ds1-1+deb12u2 Base file: /srv/ftp-master.debian.org/ftp/pool/main/c/containerd/containerd_1.6.20~ds1-1+deb12u1.dsc Target file: /srv/ftp-master.debian.org/policy/pool/main/c/containerd/containerd_1.6.20~ds1-1+deb12u2.dsc changelog | 8 + patches/0013-CVE-2024-40635.patch | 173 +++++++++++++++++++++++++++ patches/0013-Fix-directory-permissions.patch | 95 ++++++++++++++ patches/series | 2 4 files changed, 278 insertions(+) diff -Nru containerd-1.6.20~ds1/debian/changelog containerd-1.6.20~ds1/debian/changelog --- containerd-1.6.20~ds1/debian/changelog 2025-01-15 12:18:21.000000000 +0000 +++ containerd-1.6.20~ds1/debian/changelog 2025-11-16 21:57:18.000000000 +0000 @@ -1,3 +1,11 @@ +containerd (1.6.20~ds1-1+deb12u2) bookworm-security; urgency=medium + + * Fix overly broad directory permissions, Fixes: CVE-2024-25621 + * Fix bug in the CRI Attach implementation, Fixes: CVE-2025-64329 + Closes: #1120343 + + -- Reinhard Tartler Sun, 16 Nov 2025 16:57:18 -0500 + containerd (1.6.20~ds1-1+deb12u1) bookworm; urgency=medium * Non-maintainer upload. diff -Nru containerd-1.6.20~ds1/debian/patches/0013-CVE-2024-40635.patch containerd-1.6.20~ds1/debian/patches/0013-CVE-2024-40635.patch --- containerd-1.6.20~ds1/debian/patches/0013-CVE-2024-40635.patch 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.6.20~ds1/debian/patches/0013-CVE-2024-40635.patch 2025-11-16 21:57:18.000000000 +0000 @@ -0,0 +1,173 @@ +From: Craig Ingram +Date: Fri, 7 Mar 2025 13:29:47 +0000 +Subject: validate uid/gid + +(cherry picked from commit 11504c3fc5f45634f2d93d57743a998194430b82) +--- + oci/spec_opts.go | 24 ++++++++++-- + oci/spec_opts_linux_test.go | 92 +++++++++++++++++++++++++++++++++++++++++++++ + 2 files changed, 112 insertions(+), 4 deletions(-) + +Index: containerd/oci/spec_opts.go +=================================================================== +--- containerd.orig/oci/spec_opts.go ++++ containerd/oci/spec_opts.go +@@ -22,6 +22,7 @@ import ( + "encoding/json" + "errors" + "fmt" ++ "math" + "os" + "path/filepath" + "runtime" +@@ -582,6 +583,20 @@ func WithUser(userstr string) SpecOpts { + defer ensureAdditionalGids(s) + setProcess(s) + s.Process.User.AdditionalGids = nil ++ // While the Linux kernel allows the max UID to be MaxUint32 - 2, ++ // and the OCI Runtime Spec has no definition about the max UID, ++ // the runc implementation is known to require the UID to be <= MaxInt32. ++ // ++ // containerd follows runc's limitation here. ++ // ++ // In future we may relax this limitation to allow MaxUint32 - 2, ++ // or, amend the OCI Runtime Spec to codify the implementation limitation. ++ const ( ++ minUserID = 0 ++ maxUserID = math.MaxInt32 ++ minGroupID = 0 ++ maxGroupID = math.MaxInt32 ++ ) + + // For LCOW it's a bit harder to confirm that the user actually exists on the host as a rootfs isn't + // mounted on the host and shared into the guest, but rather the rootfs is constructed entirely in the +@@ -598,8 +613,8 @@ func WithUser(userstr string) SpecOpts { + switch len(parts) { + case 1: + v, err := strconv.Atoi(parts[0]) +- if err != nil { +- // if we cannot parse as a uint they try to see if it is a username ++ if err != nil || v < minUserID || v > maxUserID { ++ // if we cannot parse as an int32 then try to see if it is a username + return WithUsername(userstr)(ctx, client, c, s) + } + return WithUserID(uint32(v))(ctx, client, c, s) +@@ -610,12 +625,13 @@ func WithUser(userstr string) SpecOpts { + ) + var uid, gid uint32 + v, err := strconv.Atoi(parts[0]) +- if err != nil { ++ if err != nil || v < minUserID || v > maxUserID { + username = parts[0] + } else { + uid = uint32(v) + } +- if v, err = strconv.Atoi(parts[1]); err != nil { ++ v, err = strconv.Atoi(parts[1]) ++ if err != nil || v < minGroupID || v > maxGroupID { + groupname = parts[1] + } else { + gid = uint32(v) +Index: containerd/oci/spec_opts_linux_test.go +=================================================================== +--- containerd.orig/oci/spec_opts_linux_test.go ++++ containerd/oci/spec_opts_linux_test.go +@@ -32,6 +32,98 @@ import ( + ) + + //nolint:gosec ++func TestWithUser(t *testing.T) { ++ t.Parallel() ++ ++ expectedPasswd := `root:x:0:0:root:/root:/bin/ash ++guest:x:405:100:guest:/dev/null:/sbin/nologin ++` ++ expectedGroup := `root:x:0:root ++bin:x:1:root,bin,daemon ++daemon:x:2:root,bin,daemon ++sys:x:3:root,bin,adm ++guest:x:100:guest ++` ++ td := t.TempDir() ++ apply := fstest.Apply( ++ fstest.CreateDir("/etc", 0777), ++ fstest.CreateFile("/etc/passwd", []byte(expectedPasswd), 0777), ++ fstest.CreateFile("/etc/group", []byte(expectedGroup), 0777), ++ ) ++ if err := apply.Apply(td); err != nil { ++ t.Fatalf("failed to apply: %v", err) ++ } ++ c := containers.Container{ID: t.Name()} ++ testCases := []struct { ++ user string ++ expectedUID uint32 ++ expectedGID uint32 ++ err string ++ }{ ++ { ++ user: "0", ++ expectedUID: 0, ++ expectedGID: 0, ++ }, ++ { ++ user: "root:root", ++ expectedUID: 0, ++ expectedGID: 0, ++ }, ++ { ++ user: "guest", ++ expectedUID: 405, ++ expectedGID: 100, ++ }, ++ { ++ user: "guest:guest", ++ expectedUID: 405, ++ expectedGID: 100, ++ }, ++ { ++ user: "guest:nobody", ++ err: "no groups found", ++ }, ++ { ++ user: "405:100", ++ expectedUID: 405, ++ expectedGID: 100, ++ }, ++ { ++ user: "405:2147483648", ++ err: "no groups found", ++ }, ++ { ++ user: "-1000", ++ err: "no users found", ++ }, ++ { ++ user: "2147483648", ++ err: "no users found", ++ }, ++ } ++ for _, testCase := range testCases { ++ testCase := testCase ++ t.Run(testCase.user, func(t *testing.T) { ++ t.Parallel() ++ s := Spec{ ++ Version: specs.Version, ++ Root: &specs.Root{ ++ Path: td, ++ }, ++ Linux: &specs.Linux{}, ++ } ++ err := WithUser(testCase.user)(context.Background(), nil, &c, &s) ++ if err != nil { ++ assert.EqualError(t, err, testCase.err) ++ } ++ assert.Equal(t, testCase.expectedUID, s.Process.User.UID) ++ assert.Equal(t, testCase.expectedGID, s.Process.User.GID) ++ }) ++ } ++} ++ ++//nolint:gosec + func TestWithUserID(t *testing.T) { + t.Parallel() + 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 1970-01-01 00:00:00.000000000 +0000 +++ containerd-1.6.20~ds1/debian/patches/0013-Fix-directory-permissions.patch 2025-11-16 21:57:18.000000000 +0000 @@ -0,0 +1,95 @@ +From: Akihiro Suda +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// 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 +(cherry picked from commit 51b0cf11dc5af7ed1919beba259e644138b28d96) +Signed-off-by: Akihiro Suda +--- + 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/series containerd-1.6.20~ds1/debian/patches/series --- containerd-1.6.20~ds1/debian/patches/series 2025-01-15 12:17:38.000000000 +0000 +++ containerd-1.6.20~ds1/debian/patches/series 2025-11-16 21:57:18.000000000 +0000 @@ -7,3 +7,5 @@ 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 +0013-CVE-2024-40635.patch +0013-Fix-directory-permissions.patch