Yocto Meta Virtualization
 help / color / mirror / Atom feed
From: Bruce Ashfield <bruce.ashfield@gmail.com>
To: tgaige.opensource@witekio.com
Cc: meta-virtualization@lists.yoctoproject.org
Subject: Re: [meta-virtualization] [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635
Date: Mon, 13 Oct 2025 21:58:22 -0400	[thread overview]
Message-ID: <aO2uPmlFWj03x9R9@gmail.com> (raw)
In-Reply-To: <20251002080507.571150-1-tgaige.opensource@witekio.com>

merged.

Bruce


In message: [meta-virtualization] [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635
on 02/10/2025 Th�o Gaig� via lists.yoctoproject.org wrote:

> From: Theo GAIGE <tgaige.opensource@witekio.com>
> 
> Upstream-Status: Backport from https://github.com/containerd/containerd/commit/9639b9625554183d0c4d8d072dccb84fedd2320f
> 
> Signed-off-by: Theo GAIGE <tgaige.opensource@witekio.com>
> ---
>  .../CVE-2024-40635.patch                      | 180 ++++++++++++++++++
>  .../containerd-opencontainers_git.bb          |   1 +
>  2 files changed, 181 insertions(+)
>  create mode 100644 recipes-containers/containerd/containerd-opencontainers/CVE-2024-40635.patch
> 
> diff --git a/recipes-containers/containerd/containerd-opencontainers/CVE-2024-40635.patch b/recipes-containers/containerd/containerd-opencontainers/CVE-2024-40635.patch
> new file mode 100644
> index 00000000..71a0f8b6
> --- /dev/null
> +++ b/recipes-containers/containerd/containerd-opencontainers/CVE-2024-40635.patch
> @@ -0,0 +1,180 @@
> +From 6727fad7cc608f47304c073d758a04ca516e08fd Mon Sep 17 00:00:00 2001
> +From: Craig Ingram <Cjingram@google.com>
> +Date: Fri, 7 Mar 2025 13:27:58 +0000
> +Subject: [PATCH] validate uid/gid
> +
> +Upstream-Status: Backport [https://github.com/containerd/containerd/commit/9639b9625554183d0c4d8d072dccb84fedd2320f]
> +CVE: CVE-2024-40635
> +
> +Signed-off-by: Theo GAIGE <tgaige.opensource@witekio.com>
> +---
> + oci/spec_opts.go            | 24 ++++++++--
> + oci/spec_opts_linux_test.go | 92 +++++++++++++++++++++++++++++++++++++
> + 2 files changed, 112 insertions(+), 4 deletions(-)
> +
> +diff --git a/oci/spec_opts.go b/oci/spec_opts.go
> +index 3330ad108..1f10b24c6 100644
> +--- a/oci/spec_opts.go
> ++++ b/oci/spec_opts.go
> +@@ -22,6 +22,7 @@ import (
> + 	"encoding/json"
> + 	"errors"
> + 	"fmt"
> ++	"math"
> + 	"os"
> + 	"path/filepath"
> + 	"runtime"
> +@@ -536,6 +537,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
> +@@ -552,8 +567,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)
> +@@ -564,12 +579,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)
> +diff --git a/oci/spec_opts_linux_test.go b/oci/spec_opts_linux_test.go
> +index 904edcb42..f3be5ef27 100644
> +--- a/oci/spec_opts_linux_test.go
> ++++ b/oci/spec_opts_linux_test.go
> +@@ -31,6 +31,98 @@ import (
> + 	"golang.org/x/sys/unix"
> + )
> + 
> ++// 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()
> +-- 
> +2.43.0
> +
> diff --git a/recipes-containers/containerd/containerd-opencontainers_git.bb b/recipes-containers/containerd/containerd-opencontainers_git.bb
> index 6c0266ac..dd621705 100644
> --- a/recipes-containers/containerd/containerd-opencontainers_git.bb
> +++ b/recipes-containers/containerd/containerd-opencontainers_git.bb
> @@ -9,6 +9,7 @@ SRCREV = "1e1ea6e986c6c86565bc33d52e34b81b3e2bc71f"
>  SRC_URI = "git://github.com/containerd/containerd;branch=release/1.6;protocol=https;destsuffix=git/src/github.com/containerd/containerd \
>             file://0001-Makefile-allow-GO_BUILD_FLAGS-to-be-externally-speci.patch \
>             file://0001-build-don-t-use-gcflags-to-define-trimpath.patch \
> +           file://CVE-2024-40635.patch \
>            "
>  
>  # Apache-2.0 for containerd
> -- 
> 2.43.0
> 

> 
> -=-=-=-=-=-=-=-=-=-=-=-
> Links: You receive all messages sent to this group.
> View/Reply Online (#9410): https://lists.yoctoproject.org/g/meta-virtualization/message/9410
> Mute This Topic: https://lists.yoctoproject.org/mt/115548744/1050810
> Group Owner: meta-virtualization+owner@lists.yoctoproject.org
> Unsubscribe: https://lists.yoctoproject.org/g/meta-virtualization/unsub [bruce.ashfield@gmail.com]
> -=-=-=-=-=-=-=-=-=-=-=-
> 



      reply	other threads:[~2025-10-14  1:58 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2025-10-02  8:05 [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635 tgaige.opensource
2025-10-14  1:58 ` Bruce Ashfield [this message]

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=aO2uPmlFWj03x9R9@gmail.com \
    --to=bruce.ashfield@gmail.com \
    --cc=meta-virtualization@lists.yoctoproject.org \
    --cc=tgaige.opensource@witekio.com \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox