From 758e15a22395fda98bc4cf0c10c328ee0e663f47 Mon Sep 17 00:00:00 2001 From: Azure Linux Security Servicing Account Date: Tue, 16 Dec 2025 08:55:49 +0000 Subject: [PATCH 1/2] Patch kubevirt for CVE-2025-64324 --- SPECS/kubevirt/CVE-2025-64324.patch | 174 ++++++++++++++++++++++++++++ SPECS/kubevirt/kubevirt.spec | 6 +- 2 files changed, 179 insertions(+), 1 deletion(-) create mode 100644 SPECS/kubevirt/CVE-2025-64324.patch diff --git a/SPECS/kubevirt/CVE-2025-64324.patch b/SPECS/kubevirt/CVE-2025-64324.patch new file mode 100644 index 00000000000..0928b691c06 --- /dev/null +++ b/SPECS/kubevirt/CVE-2025-64324.patch @@ -0,0 +1,174 @@ +From 2ffeb78c9f8bb39fa2fed114d1887d04ec507523 Mon Sep 17 00:00:00 2001 +From: Jed Lejosne +Date: Wed, 25 Jun 2025 09:19:41 -0400 +Subject: [PATCH 1/2] host-path: only chown files we created + +Signed-off-by: Jed Lejosne +(cherry picked from commit a1d1e58bce65afecdaa59941cf28ac3f0528d926) +Signed-off-by: Jed Lejosne +--- + pkg/ephemeral-disk-utils/utils.go | 19 +++++++++++++++++-- + pkg/host-disk/host-disk.go | 12 ++++++------ + pkg/host-disk/host-disk_test.go | 17 +++++++++++------ + 3 files changed, 34 insertions(+), 14 deletions(-) + +diff --git a/pkg/ephemeral-disk-utils/utils.go b/pkg/ephemeral-disk-utils/utils.go +index fc1a07b..863b267 100644 +--- a/pkg/ephemeral-disk-utils/utils.go ++++ b/pkg/ephemeral-disk-utils/utils.go +@@ -44,14 +44,29 @@ func MockDefaultOwnershipManager() { + type nonOpManager struct { + } + +-func (no *nonOpManager) UnsafeSetFileOwnership(file string) error { ++func (no *nonOpManager) UnsafeSetFileOwnership(_ string) error { + return nil + } + +-func (no *nonOpManager) SetFileOwnership(file *safepath.Path) error { ++func (no *nonOpManager) SetFileOwnership(_ *safepath.Path) error { + return nil + } + ++func MockDefaultOwnershipManagerWithFailure() { ++ DefaultOwnershipManager = &failureManager{} ++} ++ ++type failureManager struct { ++} ++ ++func (no *failureManager) UnsafeSetFileOwnership(_ string) error { ++ panic("unexpected call to UnsafeSetFileOwnership") ++} ++ ++func (no *failureManager) SetFileOwnership(_ *safepath.Path) error { ++ panic("unexpected call to SetFileOwnership") ++} ++ + type OwnershipManager struct { + user string + } +diff --git a/pkg/host-disk/host-disk.go b/pkg/host-disk/host-disk.go +index 3575005..416b700 100644 +--- a/pkg/host-disk/host-disk.go ++++ b/pkg/host-disk/host-disk.go +@@ -235,7 +235,7 @@ func (hdc *DiskImgCreator) setlessPVCSpaceToleration(toleration int) { + hdc.lessPVCSpaceToleration = toleration + } + +-func (hdc DiskImgCreator) Create(vmi *v1.VirtualMachineInstance) error { ++func (hdc *DiskImgCreator) Create(vmi *v1.VirtualMachineInstance) error { + for _, volume := range vmi.Spec.Volumes { + if hostDisk := volume.VolumeSource.HostDisk; shouldMountHostDisk(hostDisk) { + if err := hdc.mountHostDiskAndSetOwnership(vmi, volume.Name, hostDisk); err != nil { +@@ -271,11 +271,11 @@ func (hdc *DiskImgCreator) mountHostDiskAndSetOwnership(vmi *v1.VirtualMachineIn + if err != nil { + return err + } +- } +- // Change file ownership to the qemu user. +- if err := ephemeraldiskutils.DefaultOwnershipManager.SetFileOwnership(diskPath); err != nil { +- log.Log.Reason(err).Errorf("Couldn't set Ownership on %s: %v", diskPath, err) +- return err ++ // Change file ownership to the qemu user. ++ if err := ephemeraldiskutils.DefaultOwnershipManager.SetFileOwnership(diskPath); err != nil { ++ log.Log.Reason(err).Errorf("Couldn't set Ownership on %s: %v", diskPath, err) ++ return err ++ } + } + return nil + } +diff --git a/pkg/host-disk/host-disk_test.go b/pkg/host-disk/host-disk_test.go +index 8b8f3da..4ca6aff 100644 +--- a/pkg/host-disk/host-disk_test.go ++++ b/pkg/host-disk/host-disk_test.go +@@ -34,15 +34,13 @@ import ( + "k8s.io/apimachinery/pkg/api/resource" + "k8s.io/client-go/kubernetes/fake" + "k8s.io/client-go/tools/record" +- +- "kubevirt.io/kubevirt/pkg/libvmi" +- "kubevirt.io/kubevirt/pkg/safepath" +- + v1 "kubevirt.io/api/core/v1" + "kubevirt.io/client-go/kubecli" + ++ ephemeraldiskutils "kubevirt.io/kubevirt/pkg/ephemeral-disk-utils" ++ "kubevirt.io/kubevirt/pkg/libvmi" + libvmistatus "kubevirt.io/kubevirt/pkg/libvmi/status" +- ++ "kubevirt.io/kubevirt/pkg/safepath" + "kubevirt.io/kubevirt/pkg/testutils" + ) + +@@ -300,7 +298,14 @@ var _ = Describe("HostDisk", func() { + }) + }) + Context("With existing disk.img", func() { +- It("Should not re-create disk.img", func() { ++ AfterEach(func() { ++ By("Switching back to the regular mock ownership manager") ++ ephemeraldiskutils.MockDefaultOwnershipManager() ++ }) ++ ++ It("Should not re-create or chown disk.img", func() { ++ By("Switching to an ownership manager that panics when called") ++ ephemeraldiskutils.MockDefaultOwnershipManagerWithFailure() + By("Creating a disk.img before adding a HostDisk volume") + tmpDiskImg := createTempDiskImg("volume1") + By("Creating a new VMI with a HostDisk volumes") +-- +2.45.4 + + +From 279812e35d9d2bb91c34db48566f05208d19edf4 Mon Sep 17 00:00:00 2001 +From: Jed Lejosne +Date: Tue, 1 Jul 2025 09:09:14 -0400 +Subject: [PATCH 2/2] tests: adjust host-path test according to previous fix + +Signed-off-by: Jed Lejosne +(cherry picked from commit 7fbfe8a2e2d422472ce6b80bd75ed1e5532a0934) +Signed-off-by: Jed Lejosne +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://patch-diff.githubusercontent.com/raw/kubevirt/kubevirt/pull/15990.patch +--- + tests/storage/storage.go | 19 +++++++++++++++---- + 1 file changed, 15 insertions(+), 4 deletions(-) + +diff --git a/tests/storage/storage.go b/tests/storage/storage.go +index dfec79f..974c724 100644 +--- a/tests/storage/storage.go ++++ b/tests/storage/storage.go +@@ -254,14 +254,25 @@ var _ = SIGDescribe("Storage", func() { + // Start the VirtualMachineInstance with the PVC attached + vmi = newVMI(pvcName) + +- vmi = libvmops.RunVMIAndExpectLaunch(vmi, 180) ++ if imageOwnedByQEMU { ++ vmi = libvmops.RunVMIAndExpectLaunch(vmi, 180) + +- By(checkingVMInstanceConsoleOut) +- Expect(console.LoginToAlpine(vmi)).To(Succeed()) ++ By(checkingVMInstanceConsoleOut) ++ Expect(console.LoginToAlpine(vmi)).To(Succeed()) ++ } else { ++ By("Starting a VirtualMachineInstance") ++ createdVMI := libvmops.RunVMIAndExpectScheduling(vmi, 60) ++ ++ By(fmt.Sprintf("Checking that VirtualMachineInstance start failed: starting at %v", time.Now())) ++ ctx, cancel := context.WithCancel(context.Background()) ++ defer cancel() ++ event := watcher.New(createdVMI).Timeout(60*time.Second).SinceWatchedObjectResourceVersion().WaitFor(ctx, watcher.WarningEvent, "SyncFailed") ++ Expect(event.Message).To(ContainSubstring("Could not open '/var/run/kubevirt-private/vmi-disks/disk0/disk.img': Permission denied"), "VMI should not be started") ++ } + }, + Entry("[test_id:3130]with Disk PVC", newRandomVMIWithPVC, true), + Entry("[test_id:3131]with CDRom PVC", newRandomVMIWithCDRom, true), +- Entry("hostpath disk image file not owned by qemu", newRandomVMIWithPVC, false), ++ Entry("unless hostpath disk image file not owned by qemu", newRandomVMIWithPVC, false), + ) + }) + +-- +2.45.4 + diff --git a/SPECS/kubevirt/kubevirt.spec b/SPECS/kubevirt/kubevirt.spec index b553e356be3..187aebbf525 100644 --- a/SPECS/kubevirt/kubevirt.spec +++ b/SPECS/kubevirt/kubevirt.spec @@ -20,7 +20,7 @@ Summary: Container native virtualization Name: kubevirt Version: 1.5.3 -Release: 2%{?dist} +Release: 3%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -31,6 +31,7 @@ Source0: https://github.com/kubevirt/kubevirt/archive/refs/tags/v%{versio # Nexus team needs these to-be-upstreamed patches for the operator Edge to work # correctly. Patch0: CVE-2025-47913.patch +Patch1: CVE-2025-64324.patch %global debug_package %{nil} BuildRequires: swtpm-tools @@ -268,6 +269,9 @@ install -p -m 0644 cmd/virt-launcher/qemu.conf %{buildroot}%{_datadir}/kube-virt %{_bindir}/virt-tests %changelog +* Tue Dec 16 2025 Azure Linux Security Servicing Account - 1.5.3-3 +- Patch for CVE-2025-64324 + * Mon Nov 24 2025 Andrew Phelps - 1.5.3-2 - Bump to rebuild with updated glibc From dac5fc96760e7b805aebf039595e1b1ba525029b Mon Sep 17 00:00:00 2001 From: Kanishk Bansal Date: Tue, 16 Dec 2025 09:12:06 +0000 Subject: [PATCH 2/2] remove unused patch --- SPECS/kubevirt/CVE-2025-22872.patch | 42 ----------------------------- 1 file changed, 42 deletions(-) delete mode 100644 SPECS/kubevirt/CVE-2025-22872.patch diff --git a/SPECS/kubevirt/CVE-2025-22872.patch b/SPECS/kubevirt/CVE-2025-22872.patch deleted file mode 100644 index 8e0d348b32b..00000000000 --- a/SPECS/kubevirt/CVE-2025-22872.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 49deeee2f3c9277aa729e4d0698ab9f297b0c38a Mon Sep 17 00:00:00 2001 -From: Sreenivasulu Malavathula -Date: Thu, 24 Apr 2025 18:37:02 -0500 -Subject: [PATCH] Address CVE-2025-22872 -Upstream Patch Reference: https://github.com/golang/net/commit/e1fcd82abba34df74614020343be8eb1fe85f0d9 - ---- - vendor/golang.org/x/net/html/token.go | 18 ++++++++++++++++-- - 1 file changed, 16 insertions(+), 2 deletions(-) - -diff --git a/vendor/golang.org/x/net/html/token.go b/vendor/golang.org/x/net/html/token.go -index de67f93..9bbdf7d 100644 ---- a/vendor/golang.org/x/net/html/token.go -+++ b/vendor/golang.org/x/net/html/token.go -@@ -839,8 +839,22 @@ func (z *Tokenizer) readStartTag() TokenType { - if raw { - z.rawTag = strings.ToLower(string(z.buf[z.data.start:z.data.end])) - } -- // Look for a self-closing token like "
". -- if z.err == nil && z.buf[z.raw.end-2] == '/' { -+ // Look for a self-closing token (e.g.
). -+ // -+ // Originally, we did this by just checking that the last character of the -+ // tag (ignoring the closing bracket) was a solidus (/) character, but this -+ // is not always accurate. -+ // -+ // We need to be careful that we don't misinterpret a non-self-closing tag -+ // as self-closing, as can happen if the tag contains unquoted attribute -+ // values (i.e.

). -+ // -+ // To avoid this, we check that the last non-bracket character of the tag -+ // (z.raw.end-2) isn't the same character as the last non-quote character of -+ // the last attribute of the tag (z.pendingAttr[1].end-1), if the tag has -+ // attributes. -+ nAttrs := len(z.attr) -+ if z.err == nil && z.buf[z.raw.end-2] == '/' && (nAttrs == 0 || z.raw.end-2 != z.attr[nAttrs-1][1].end-1) { - return SelfClosingTagToken - } - return StartTagToken --- -2.45.2 -