All of lore.kernel.org
 help / color / mirror / Atom feed
* [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635
@ 2025-10-02  8:05 tgaige.opensource
  2025-10-14  1:58 ` [meta-virtualization] " Bruce Ashfield
  0 siblings, 1 reply; 2+ messages in thread
From: tgaige.opensource @ 2025-10-02  8:05 UTC (permalink / raw)
  To: meta-virtualization; +Cc: Theo GAIGE

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



^ permalink raw reply related	[flat|nested] 2+ messages in thread

* Re: [meta-virtualization] [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635
  2025-10-02  8:05 [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635 tgaige.opensource
@ 2025-10-14  1:58 ` Bruce Ashfield
  0 siblings, 0 replies; 2+ messages in thread
From: Bruce Ashfield @ 2025-10-14  1:58 UTC (permalink / raw)
  To: tgaige.opensource; +Cc: meta-virtualization

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]
> -=-=-=-=-=-=-=-=-=-=-=-
> 



^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2025-10-14  1:58 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2025-10-02  8:05 [kirkstone][PATCH] containerd-opencontainers: fix CVE-2024-40635 tgaige.opensource
2025-10-14  1:58 ` [meta-virtualization] " Bruce Ashfield

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.