Skip to content

Commit 1cdb253

Browse files
[AUTO-CHERRYPICK] Fix CVE-2024-21626 by patching vendored runc in kubernetes, kubevirt, cri-tools - branch main (#7903)
Co-authored-by: rikenm1 <rmaharjan@microsoft.com>
1 parent 8acb776 commit 1cdb253

6 files changed

Lines changed: 988 additions & 7 deletions

File tree

Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
diff -urN b/cri-tools-1.28.0/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go a/cri-tools-1.28.0/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go
2+
--- cri-tools-1.28.0/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go 2023-08-11 06:45:27.000000000 -0700
3+
+++ cri-tools-1.28.0/vendor/github.com/opencontainers/runc/libcontainer/utils/utils_unix.go 2024-02-13 15:41:56.671537200 -0800
4+
@@ -7,6 +7,7 @@
5+
"fmt"
6+
"os"
7+
"strconv"
8+
+ _ "unsafe" // for go:linkname
9+
10+
"golang.org/x/sys/unix"
11+
)
12+
@@ -23,9 +24,11 @@
13+
return nil
14+
}
15+
16+
-// CloseExecFrom applies O_CLOEXEC to all file descriptors currently open for
17+
-// the process (except for those below the given fd value).
18+
-func CloseExecFrom(minFd int) error {
19+
+type fdFunc func(fd int)
20+
+
21+
+// fdRangeFrom calls the passed fdFunc for each file descriptor that is open in
22+
+// the current process.
23+
+func fdRangeFrom(minFd int, fn fdFunc) error {
24+
fdDir, err := os.Open("/proc/self/fd")
25+
if err != nil {
26+
return err
27+
@@ -50,15 +53,60 @@
28+
if fd < minFd {
29+
continue
30+
}
31+
- // Intentionally ignore errors from unix.CloseOnExec -- the cases where
32+
- // this might fail are basically file descriptors that have already
33+
- // been closed (including and especially the one that was created when
34+
- // os.ReadDir did the "opendir" syscall).
35+
- unix.CloseOnExec(fd)
36+
+ // Ignore the file descriptor we used for readdir, as it will be closed
37+
+ // when we return.
38+
+ if uintptr(fd) == fdDir.Fd() {
39+
+ continue
40+
+ }
41+
+ // Run the closure.
42+
+ fn(fd)
43+
}
44+
return nil
45+
}
46+
47+
+// CloseExecFrom sets the O_CLOEXEC flag on all file descriptors greater or
48+
+// equal to minFd in the current process.
49+
+func CloseExecFrom(minFd int) error {
50+
+ return fdRangeFrom(minFd, unix.CloseOnExec)
51+
+}
52+
+
53+
+//go:linkname runtime_IsPollDescriptor internal/poll.IsPollDescriptor
54+
+
55+
+// In order to make sure we do not close the internal epoll descriptors the Go
56+
+// runtime uses, we need to ensure that we skip descriptors that match
57+
+// "internal/poll".IsPollDescriptor. Yes, this is a Go runtime internal thing,
58+
+// unfortunately there's no other way to be sure we're only keeping the file
59+
+// descriptors the Go runtime needs. Hopefully nothing blows up doing this...
60+
+func runtime_IsPollDescriptor(fd uintptr) bool //nolint:revive
61+
+
62+
+// UnsafeCloseFrom closes all file descriptors greater or equal to minFd in the
63+
+// current process, except for those critical to Go's runtime (such as the
64+
+// netpoll management descriptors).
65+
+//
66+
+// NOTE: That this function is incredibly dangerous to use in most Go code, as
67+
+// closing file descriptors from underneath *os.File handles can lead to very
68+
+// bad behaviour (the closed file descriptor can be re-used and then any
69+
+// *os.File operations would apply to the wrong file). This function is only
70+
+// intended to be called from the last stage of runc init.
71+
+func UnsafeCloseFrom(minFd int) error {
72+
+ // We must not close some file descriptors.
73+
+ return fdRangeFrom(minFd, func(fd int) {
74+
+ if runtime_IsPollDescriptor(uintptr(fd)) {
75+
+ // These are the Go runtimes internal netpoll file descriptors.
76+
+ // These file descriptors are operated on deep in the Go scheduler,
77+
+ // and closing those files from underneath Go can result in panics.
78+
+ // There is no issue with keeping them because they are not
79+
+ // executable and are not useful to an attacker anyway. Also we
80+
+ // don't have any choice.
81+
+ return
82+
+ }
83+
+ // There's nothing we can do about errors from close(2), and the
84+
+ // only likely error to be seen is EBADF which indicates the fd was
85+
+ // already closed (in which case, we got what we wanted).
86+
+ _ = unix.Close(fd)
87+
+ })
88+
+}
89+
+
90+
// NewSockPair returns a new unix socket pair
91+
func NewSockPair(name string) (parent *os.File, child *os.File, err error) {
92+
fds, err := unix.Socketpair(unix.AF_LOCAL, unix.SOCK_STREAM|unix.SOCK_CLOEXEC, 0)
93+
Binary files b/v1.28.0.tar.gz and a/v1.28.0.tar.gz differ

SPECS/cri-tools/cri-tools.spec

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
Summary: CRI tools
88
Name: cri-tools
99
Version: 1.28.0
10-
Release: 4%{?dist}
10+
Release: 5%{?dist}
1111
License: Apache-2.0
1212
Vendor: Microsoft Corporation
1313
Distribution: Mariner
1414
Group: Development/Tools
1515
URL: https://github.com/kubernetes-sigs/cri-tools
1616
Source0: https://github.com/kubernetes-sigs/cri-tools/archive/v%{version}.tar.gz#/%{name}-%{version}.tar.gz
17+
Patch0: CVE-2024-21626.patch
1718
BuildRequires: glib-devel
1819
BuildRequires: glibc-devel
1920
BuildRequires: golang
@@ -44,9 +45,12 @@ install -p -m 755 -t %{buildroot}%{_bindir} "${BUILD_FOLDER}/critest"
4445
%{_bindir}/critest
4546

4647
%changelog
47-
* Fri Feb 02 2024 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 1.28.0-4
48+
* Thu Feb 15 2024 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 1.28.0-5
4849
- Bump release to rebuild with go 1.21.6
4950

51+
* Wed Feb 14 2024 Riken Maharjan <rmaharjan@microsoft.com> - 1.28.0-4
52+
- Patch runc for CVE-2024-21626
53+
5054
* Mon Oct 16 2023 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 1.28.0-3
5155
- Bump release to rebuild with go 1.20.9
5256

0 commit comments

Comments
 (0)