Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
151 changes: 151 additions & 0 deletions SPECS/kubevirt/CVE-2025-64324.patch
Original file line number Diff line number Diff line change
@@ -0,0 +1,151 @@
From 65d9983cddb566e34b5f910c47cf7b230f7be412 Mon Sep 17 00:00:00 2001
From: AllSpark <[email protected]>
Date: Mon, 24 Nov 2025 06:07:26 +0000
Subject: [PATCH] host-disk: only chown when file is created; make Create use
pointer receiver; add failure ownership manager for tests; adjust storage
tests for non-qemu ownership

Signed-off-by: Azure Linux Security Servicing Account <[email protected]>
Upstream-reference: AI Backport of https://github.com/kubevirt/kubevirt/pull/15037.diff
---
pkg/ephemeral-disk-utils/utils.go | 18 ++++++++++++++++--
pkg/host-disk/host-disk.go | 14 +++++++-------
pkg/host-disk/host-disk_test.go | 11 ++++++++++-
tests/storage/storage.go | 19 +++++++++++++++----
4 files changed, 48 insertions(+), 14 deletions(-)

diff --git a/pkg/ephemeral-disk-utils/utils.go b/pkg/ephemeral-disk-utils/utils.go
index fc1a07b..3a2f493 100644
--- a/pkg/ephemeral-disk-utils/utils.go
+++ b/pkg/ephemeral-disk-utils/utils.go
@@ -44,14 +44,28 @@ 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..fb44104 100644
--- a/pkg/host-disk/host-disk_test.go
+++ b/pkg/host-disk/host-disk_test.go
@@ -40,6 +40,8 @@ import (
v1 "kubevirt.io/api/core/v1"
"kubevirt.io/client-go/kubecli"

+ ephemeraldiskutils "kubevirt.io/kubevirt/pkg/ephemeral-disk-utils"
+
libvmistatus "kubevirt.io/kubevirt/pkg/libvmi/status"

"kubevirt.io/kubevirt/pkg/testutils"
@@ -289,7 +291,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")
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

6 changes: 5 additions & 1 deletion SPECS/kubevirt/kubevirt.spec
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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
Expand Down Expand Up @@ -270,6 +271,9 @@ install -p -m 0644 cmd/virt-launcher/qemu.conf %{buildroot}%{_datadir}/kube-virt
%{_bindir}/virt-tests

%changelog
* Mon Nov 24 2025 Azure Linux Security Servicing Account <[email protected]> - 1.5.0-7
- Patch for CVE-2025-64324

* Tue Nov 18 2025 Azure Linux Security Servicing Account <[email protected]> - 1.5.0-6
- Patch for CVE-2025-47913

Expand Down
Loading