diff --git a/SPECS/kubevirt/CVE-2025-64324.patch b/SPECS/kubevirt/CVE-2025-64324.patch new file mode 100644 index 00000000000..b7e18ddfc83 --- /dev/null +++ b/SPECS/kubevirt/CVE-2025-64324.patch @@ -0,0 +1,174 @@ +From 98b37526dcf3018cbdf0f9bc39b83ffcb61b43da 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 +--- + pkg/ephemeral-disk-utils/utils.go | 19 +++++++++++++++++-- + pkg/host-disk/host-disk.go | 14 +++++++------- + pkg/host-disk/host-disk_test.go | 17 +++++++++++------ + 3 files changed, 35 insertions(+), 15 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 0d13301..02daaa1 100644 +--- a/pkg/host-disk/host-disk.go ++++ b/pkg/host-disk/host-disk.go +@@ -226,7 +226,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 { +@@ -249,14 +249,14 @@ func (hdc *DiskImgCreator) mountHostDiskAndSetOwnership(vmi *v1.VirtualMachineIn + return err + } + if !fileExists { +- if err := hdc.handleRequestedSizeAndCreateSparseRaw(vmi, diskDir, diskPath, hostDisk); err != nil { ++ if err = hdc.handleRequestedSizeAndCreateSparseRaw(vmi, diskDir, diskPath, hostDisk); err != nil { ++ return err ++ } ++ // Change file ownership to the qemu user. ++ if err = ephemeraldiskutils.DefaultOwnershipManager.UnsafeSetFileOwnership(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.UnsafeSetFileOwnership(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 2b04fa5..b4261d1 100644 +--- a/pkg/host-disk/host-disk_test.go ++++ b/pkg/host-disk/host-disk_test.go +@@ -33,15 +33,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" + ) + +@@ -289,7 +287,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 cc5039fe0bb3d92e2f4e4911efd653a60a5605da 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 +Signed-off-by: Azure Linux Security Servicing Account +Upstream-reference: https://patch-diff.githubusercontent.com/raw/kubevirt/kubevirt/pull/15037.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 b28efdd..1646dde 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 d31769ebb95..8867fd4d308 100644 --- a/SPECS/kubevirt/kubevirt.spec +++ b/SPECS/kubevirt/kubevirt.spec @@ -20,7 +20,7 @@ Summary: Container native virtualization Name: kubevirt Version: 1.5.0 -Release: 6%{?dist} +Release: 7%{?dist} License: ASL 2.0 Vendor: Microsoft Corporation Distribution: Azure Linux @@ -33,6 +33,7 @@ Source0: https://github.com/kubevirt/kubevirt/archive/refs/tags/v%{versio Patch0: CVE-2025-22869.patch Patch1: CVE-2025-22872.patch Patch2: CVE-2025-47913.patch +Patch3: CVE-2025-64324.patch %global debug_package %{nil} BuildRequires: swtpm-tools @@ -270,6 +271,9 @@ install -p -m 0644 cmd/virt-launcher/qemu.conf %{buildroot}%{_datadir}/kube-virt %{_bindir}/virt-tests %changelog +* Tue Dec 09 2025 Azure Linux Security Servicing Account - 1.5.0-7 +- Patch for CVE-2025-64324 + * Tue Nov 18 2025 Azure Linux Security Servicing Account - 1.5.0-6 - Patch for CVE-2025-47913