Skip to content

Commit 7d3bbd5

Browse files
Patch cri-o for CVE-2024-9676 (#13470)
Fixes CVE-2024-9676 in a vendored dependency of cri-o
1 parent fc50da0 commit 7d3bbd5

2 files changed

Lines changed: 192 additions & 1 deletion

File tree

SPECS/cri-o/CVE-2024-9676.patch

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
From 8e5231ee0aef99899c13157c3c4ed4cb30ad4694 Mon Sep 17 00:00:00 2001
2+
From: Sean Dougherty <sdougherty@microsoft.com>
3+
Date: Thu, 17 Apr 2025 21:38:26 +0000
4+
Subject: [PATCH] Backport CVE-2024-9676 fix from
5+
https://github.com/containers/storage/pull/2146 by Matt Heon
6+
<mheon@redhat.com>
7+
8+
---
9+
.../github.com/containers/storage/.cirrus.yml | 2 +-
10+
.../github.com/containers/storage/userns.go | 92 +++++++++++++------
11+
.../containers/storage/userns_unsupported.go | 14 +++
12+
3 files changed, 81 insertions(+), 27 deletions(-)
13+
create mode 100644 vendor/github.com/containers/storage/userns_unsupported.go
14+
15+
diff --git a/vendor/github.com/containers/storage/.cirrus.yml b/vendor/github.com/containers/storage/.cirrus.yml
16+
index 20bede4..7f20643 100644
17+
--- a/vendor/github.com/containers/storage/.cirrus.yml
18+
+++ b/vendor/github.com/containers/storage/.cirrus.yml
19+
@@ -128,7 +128,7 @@ lint_task:
20+
env:
21+
CIRRUS_WORKING_DIR: "/go/src/github.com/containers/storage"
22+
container:
23+
- image: golang:1.15
24+
+ image: golang:1.19
25+
modules_cache:
26+
fingerprint_script: cat go.sum
27+
folder: $GOPATH/pkg/mod
28+
diff --git a/vendor/github.com/containers/storage/userns.go b/vendor/github.com/containers/storage/userns.go
29+
index 3ada41f..2a6298e 100644
30+
--- a/vendor/github.com/containers/storage/userns.go
31+
+++ b/vendor/github.com/containers/storage/userns.go
32+
@@ -1,18 +1,20 @@
33+
+//go:build linux
34+
package storage
35+
36+
import (
37+
"os"
38+
"os/user"
39+
- "path/filepath"
40+
"strconv"
41+
42+
drivers "github.com/containers/storage/drivers"
43+
"github.com/containers/storage/pkg/idtools"
44+
"github.com/containers/storage/pkg/unshare"
45+
"github.com/containers/storage/types"
46+
+ securejoin "github.com/cyphar/filepath-securejoin"
47+
libcontainerUser "github.com/opencontainers/runc/libcontainer/user"
48+
"github.com/pkg/errors"
49+
"github.com/sirupsen/logrus"
50+
+ "golang.org/x/sys/unix"
51+
)
52+
53+
// getAdditionalSubIDs looks up the additional IDs configured for
54+
@@ -78,43 +80,65 @@ func (s *store) getAvailableIDs() (*idSet, *idSet, error) {
55+
return u, g, nil
56+
}
57+
58+
+const nobodyUser = 65534
59+
+
60+
// parseMountedFiles returns the maximum UID and GID found in the /etc/passwd and
61+
// /etc/group files.
62+
func parseMountedFiles(containerMount, passwdFile, groupFile string) uint32 {
63+
+ var (
64+
+ passwd *os.File
65+
+ group *os.File
66+
+ size int
67+
+ err error
68+
+ )
69+
if passwdFile == "" {
70+
- passwdFile = filepath.Join(containerMount, "etc/passwd")
71+
- }
72+
- if groupFile == "" {
73+
- groupFile = filepath.Join(groupFile, "etc/group")
74+
+ passwd, err = secureOpen(containerMount, "/etc/passwd")
75+
+ } else {
76+
+ // User-specified override from a volume. Will not be in
77+
+ // container root.
78+
+ passwd, err = os.Open(passwdFile)
79+
}
80+
81+
- size := 0
82+
-
83+
- users, err := libcontainerUser.ParsePasswdFile(passwdFile)
84+
if err == nil {
85+
- for _, u := range users {
86+
- // Skip the "nobody" user otherwise we end up with 65536
87+
- // ids with most images
88+
- if u.Name == "nobody" {
89+
- continue
90+
- }
91+
- if u.Uid > size {
92+
- size = u.Uid
93+
- }
94+
- if u.Gid > size {
95+
- size = u.Gid
96+
+ defer passwd.Close()
97+
+
98+
+ users, err := libcontainerUser.ParsePasswd(passwd)
99+
+ if err == nil {
100+
+ for _, u := range users {
101+
+ // Skip the "nobody" user otherwise we end up with 65536
102+
+ // ids with most images
103+
+ if u.Name == "nobody" || u.Name == "nogroup" {
104+
+ continue
105+
+ }
106+
+ if u.Uid > size && u.Uid != nobodyUser {
107+
+ size = u.Uid + 1
108+
+ }
109+
+ if u.Gid > size && u.Gid != nobodyUser {
110+
+ size = u.Gid + 1
111+
+ }
112+
}
113+
}
114+
}
115+
116+
- groups, err := libcontainerUser.ParseGroupFile(groupFile)
117+
+ if groupFile == "" {
118+
+ group, err = secureOpen(containerMount, "/etc/group")
119+
+ } else {
120+
+ // User-specified override from a volume. Will not be in
121+
+ // container root.
122+
+ group, err = os.Open(groupFile)
123+
+ }
124+
if err == nil {
125+
- for _, g := range groups {
126+
- if g.Name == "nobody" {
127+
- continue
128+
- }
129+
- if g.Gid > size {
130+
- size = g.Gid
131+
+ defer group.Close()
132+
+
133+
+ groups, err := libcontainerUser.ParseGroup(group)
134+
+ if err == nil {
135+
+ for _, g := range groups {
136+
+ if g.Name == "nobody" || g.Name == "nogroup" {
137+
+ continue
138+
+ }
139+
+ if g.Gid > size && g.Gid != nobodyUser {
140+
+ size = g.Gid + 1
141+
+ }
142+
}
143+
}
144+
}
145+
@@ -300,3 +324,19 @@ func getAutoUserNSIDMappings(
146+
gidMap := append(availableGIDs.zip(requestedContainerGIDs), additionalGIDMappings...)
147+
return uidMap, gidMap, nil
148+
}
149+
+
150+
+// Securely open (read-only) a file in a container mount.
151+
+func secureOpen(containerMount, file string) (*os.File, error) {
152+
+ filePath, err := securejoin.SecureJoin(containerMount, file)
153+
+ if err != nil {
154+
+ return nil, err
155+
+ }
156+
+
157+
+ flags := unix.O_PATH | unix.O_CLOEXEC | unix.O_RDONLY
158+
+ fileHandle, err := os.OpenFile(filePath, flags, 0)
159+
+ if err != nil {
160+
+ return nil, err
161+
+ }
162+
+
163+
+ return fileHandle, nil
164+
+}
165+
diff --git a/vendor/github.com/containers/storage/userns_unsupported.go b/vendor/github.com/containers/storage/userns_unsupported.go
166+
new file mode 100644
167+
index 0000000..e37c18f
168+
--- /dev/null
169+
+++ b/vendor/github.com/containers/storage/userns_unsupported.go
170+
@@ -0,0 +1,14 @@
171+
+//go:build !linux
172+
+
173+
+package storage
174+
+
175+
+import (
176+
+ "errors"
177+
+
178+
+ "github.com/containers/storage/pkg/idtools"
179+
+ "github.com/containers/storage/types"
180+
+)
181+
+
182+
+func (s *store) getAutoUserNS(_ *types.AutoUserNsOptions, _ *Image, _ rwLayerStore, _ []roLayerStore) ([]idtools.IDMap, []idtools.IDMap, error) {
183+
+ return nil, nil, errors.New("user namespaces are not supported on this platform")
184+
+}
185+
--
186+
2.40.4
187+

SPECS/cri-o/cri-o.spec

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ Summary: OCI-based implementation of Kubernetes Container Runtime Interfa
2626
# Define macros for further referenced sources
2727
Name: cri-o
2828
Version: 1.22.3
29-
Release: 13%{?dist}
29+
Release: 14%{?dist}
3030
License: ASL 2.0
3131
Vendor: Microsoft Corporation
3232
Distribution: Mariner
@@ -76,6 +76,7 @@ Patch20: CVE-2023-6476.patch
7676
Patch21: CVE-2024-44337.patch
7777
Patch22: CVE-2025-27144.patch
7878
Patch23: CVE-2025-21614.patch
79+
Patch24: CVE-2024-9676.patch
7980
BuildRequires: btrfs-progs-devel
8081
BuildRequires: device-mapper-devel
8182
BuildRequires: fdupes
@@ -228,6 +229,9 @@ mkdir -p /opt/cni/bin
228229
%{_fillupdir}/sysconfig.kubelet
229230

230231
%changelog
232+
* Thu Apr 17 2025 Sean Dougherty <sdougherty@microsoft.com> - 1.22.3-14
233+
- Add patch for CVE-2024-9676.
234+
231235
* Fri Apr 04 2025 Henry Li <lihl@microsoft.com> - 1.22.3-13
232236
- Add patch for CVE-2025-21614
233237

0 commit comments

Comments
 (0)