Skip to content

Commit 15c43ca

Browse files
CBL-Mariner-Botazurelinux-securityKanishk-Bansaljslobodzian
authored
[AUTO-CHERRYPICK] [AutoPR- Security] Patch cloud-hypervisor for CVE-2026-27211 [CRITICAL] - branch 3.0-dev (#15995)
Co-authored-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> Co-authored-by: Kanishk Bansal <103916909+Kanishk-Bansal@users.noreply.github.com> Co-authored-by: jslobodzian <joslobo@microsoft.com>
1 parent 20df47c commit 15c43ca

File tree

2 files changed

+276
-4
lines changed

2 files changed

+276
-4
lines changed
Lines changed: 267 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,267 @@
1+
From 9049e95ce8e99bea5d863f029bfa0ddf356f39f8 Mon Sep 17 00:00:00 2001
2+
From: Rob Bradford <rbradford@meta.com>
3+
Date: Sun, 8 Feb 2026 21:14:28 +0000
4+
Subject: [PATCH] vmm: Add option to control backing files
5+
6+
Backing files (e.g. for QCOW2) interact badly with landlock since they
7+
are not obvious from the initial VM configuration. Only enable their use
8+
with an explicit option.
9+
10+
Signed-off-by: Rob Bradford <rbradford@meta.com>
11+
Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com>
12+
Upstream-reference: https://github.com/microsoft/cloud-hypervisor/commit/69e16ca82cdcd7ad3c4361223a4754cc8ce7f672.patch
13+
---
14+
block/src/lib.rs | 1 +
15+
block/src/qcow_sync.rs | 14 ++++++++++----
16+
tests/integration.rs | 39 +++++++++++++++++++++++++++------------
17+
vmm/src/config.rs | 13 +++++++++++--
18+
vmm/src/device_manager.rs | 6 +++++-
19+
vmm/src/vm_config.rs | 2 ++
20+
6 files changed, 56 insertions(+), 19 deletions(-)
21+
22+
diff --git a/block/src/lib.rs b/block/src/lib.rs
23+
index 5599258..ef8c05b 100644
24+
--- a/block/src/lib.rs
25+
+++ b/block/src/lib.rs
26+
@@ -790,6 +790,7 @@ pub trait AsyncAdaptor {
27+
}
28+
}
29+
30+
+#[derive(PartialEq, Eq, Debug)]
31+
pub enum ImageType {
32+
FixedVhd,
33+
Qcow2,
34+
diff --git a/block/src/qcow_sync.rs b/block/src/qcow_sync.rs
35+
index cd6a1fb..a05022f 100644
36+
--- a/block/src/qcow_sync.rs
37+
+++ b/block/src/qcow_sync.rs
38+
@@ -20,10 +20,16 @@ pub struct QcowDiskSync {
39+
}
40+
41+
impl QcowDiskSync {
42+
- pub fn new(file: File, direct_io: bool) -> QcowResult<Self> {
43+
- Ok(QcowDiskSync {
44+
- qcow_file: QcowFile::from(RawFile::new(file, direct_io))?,
45+
- })
46+
+ pub fn new(file: File, direct_io: bool, backing_files: bool) -> QcowResult<Self> {
47+
+ if backing_files {
48+
+ Ok(QcowDiskSync {
49+
+ qcow_file: QcowFile::from(RawFile::new(file, direct_io))?,
50+
+ })
51+
+ } else {
52+
+ Ok(QcowDiskSync {
53+
+ qcow_file: QcowFile::from_with_nesting_depth(RawFile::new(file, direct_io), 0)?,
54+
+ })
55+
+ }
56+
}
57+
}
58+
59+
diff --git a/tests/integration.rs b/tests/integration.rs
60+
index cf20554..f6c8755 100644
61+
--- a/tests/integration.rs
62+
+++ b/tests/integration.rs
63+
@@ -3631,6 +3631,7 @@ mod common_parallel {
64+
disable_io_uring: bool,
65+
disable_aio: bool,
66+
verify_os_disk: bool,
67+
+ backing_files: bool,
68+
) {
69+
let disk_config = UbuntuDiskConfig::new(image_name.to_string());
70+
let guest = Guest::new(Box::new(disk_config));
71+
@@ -3653,8 +3654,9 @@ mod common_parallel {
72+
.args([
73+
"--disk",
74+
format!(
75+
- "path={}",
76+
- guest.disk_config.disk(DiskType::OperatingSystem).unwrap()
77+
+ "path={},backing_files={}",
78+
+ guest.disk_config.disk(DiskType::OperatingSystem).unwrap(),
79+
+ if backing_files { "on"} else {"off"}
80+
)
81+
.as_str(),
82+
format!(
83+
@@ -3741,17 +3743,17 @@ mod common_parallel {
84+
85+
#[test]
86+
fn test_virtio_block_io_uring() {
87+
- _test_virtio_block(FOCAL_IMAGE_NAME, false, true, false);
88+
+ _test_virtio_block(FOCAL_IMAGE_NAME, false, true, false, false);
89+
}
90+
91+
#[test]
92+
fn test_virtio_block_aio() {
93+
- _test_virtio_block(FOCAL_IMAGE_NAME, true, false, false);
94+
+ _test_virtio_block(FOCAL_IMAGE_NAME, true, false, false, false);
95+
}
96+
97+
#[test]
98+
fn test_virtio_block_sync() {
99+
- _test_virtio_block(FOCAL_IMAGE_NAME, true, true, false);
100+
+ _test_virtio_block(FOCAL_IMAGE_NAME, true, true, false, false);
101+
}
102+
103+
fn run_qemu_img(path: &std::path::Path, args: &[&str]) -> std::process::Output {
104+
@@ -3927,22 +3929,28 @@ mod common_parallel {
105+
106+
#[test]
107+
fn test_virtio_block_qcow2() {
108+
- _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2, false, false, true);
109+
+ _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2, false, false, true, false);
110+
}
111+
112+
#[test]
113+
fn test_virtio_block_qcow2_zlib() {
114+
- _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_ZLIB, false, false, true);
115+
+ _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_ZLIB, false, false, true, false);
116+
}
117+
118+
#[test]
119+
fn test_virtio_block_qcow2_zstd() {
120+
- _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_ZSTD, false, false, true);
121+
+ _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_ZSTD, false, false, true, false);
122+
}
123+
124+
#[test]
125+
fn test_virtio_block_qcow2_backing_zstd_file() {
126+
- _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_BACKING_ZSTD_FILE, false, false, true);
127+
+ _test_virtio_block(
128+
+ JAMMY_IMAGE_NAME_QCOW2_BACKING_ZSTD_FILE,
129+
+ false,
130+
+ false,
131+
+ true,
132+
+ true,
133+
+ );
134+
}
135+
136+
#[test]
137+
@@ -3952,12 +3960,19 @@ mod common_parallel {
138+
false,
139+
false,
140+
true,
141+
+ true,
142+
);
143+
}
144+
145+
#[test]
146+
fn test_virtio_block_qcow2_backing_raw_file() {
147+
- _test_virtio_block(JAMMY_IMAGE_NAME_QCOW2_BACKING_RAW_FILE, false, false, true);
148+
+ _test_virtio_block(
149+
+ JAMMY_IMAGE_NAME_QCOW2_BACKING_RAW_FILE,
150+
+ false,
151+
+ false,
152+
+ true,
153+
+ true,
154+
+ );
155+
}
156+
157+
#[test]
158+
@@ -3982,7 +3997,7 @@ mod common_parallel {
159+
.output()
160+
.expect("Expect generating VHD image from RAW image");
161+
162+
- _test_virtio_block(FOCAL_IMAGE_NAME_VHD, false, false, false);
163+
+ _test_virtio_block(FOCAL_IMAGE_NAME_VHD, false, false, false, false);
164+
}
165+
166+
#[test]
167+
@@ -4006,7 +4021,7 @@ mod common_parallel {
168+
.output()
169+
.expect("Expect generating dynamic VHDx image from RAW image");
170+
171+
- _test_virtio_block(FOCAL_IMAGE_NAME_VHDX, false, false, true);
172+
+ _test_virtio_block(FOCAL_IMAGE_NAME_VHDX, false, false, true, false);
173+
}
174+
175+
#[test]
176+
diff --git a/vmm/src/config.rs b/vmm/src/config.rs
177+
index 196956a..f4d201f 100644
178+
--- a/vmm/src/config.rs
179+
+++ b/vmm/src/config.rs
180+
@@ -1091,7 +1091,7 @@ impl DiskConfig {
181+
ops_size=<io_ops>,ops_one_time_burst=<io_ops>,ops_refill_time=<ms>,\
182+
id=<device_id>,pci_segment=<segment_id>,rate_limit_group=<group_id>,\
183+
queue_affinity=<list_of_queue_indices_with_their_associated_cpuset>,\
184+
- serial=<serial_number>";
185+
+ serial=<serial_number>,backing_files=on|off";
186+
187+
pub fn parse(disk: &str) -> Result<Self> {
188+
let mut parser = OptionParser::new();
189+
@@ -1116,7 +1116,8 @@ impl DiskConfig {
190+
.add("pci_segment")
191+
.add("serial")
192+
.add("rate_limit_group")
193+
- .add("queue_affinity");
194+
+ .add("queue_affinity")
195+
+ .add("backing_files");
196+
parser.parse(disk).map_err(Error::ParseDisk)?;
197+
198+
let path = parser.get("path").map(PathBuf::from);
199+
@@ -1201,6 +1202,12 @@ impl DiskConfig {
200+
})
201+
.collect()
202+
});
203+
+ let backing_files = parser
204+
+ .convert::<Toggle>("backing_files")
205+
+ .map_err(Error::ParseDisk)?
206+
+ .unwrap_or(Toggle(false))
207+
+ .0;
208+
+
209+
let bw_tb_config = if bw_size != 0 && bw_refill_time != 0 {
210+
Some(TokenBucketConfig {
211+
size: bw_size,
212+
@@ -1245,6 +1252,7 @@ impl DiskConfig {
213+
pci_segment,
214+
serial,
215+
queue_affinity,
216+
+ backing_files,
217+
})
218+
}
219+
220+
@@ -3425,6 +3433,7 @@ mod tests {
221+
pci_segment: 0,
222+
serial: None,
223+
queue_affinity: None,
224+
+ backing_files: false,
225+
}
226+
}
227+
228+
diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs
229+
index d47c461..b26dfea 100644
230+
--- a/vmm/src/device_manager.rs
231+
+++ b/vmm/src/device_manager.rs
232+
@@ -2706,6 +2706,10 @@ impl DeviceManager {
233+
let image_type =
234+
detect_image_type(&mut file).map_err(DeviceManagerError::DetectImageType)?;
235+
236+
+ if image_type != ImageType::Qcow2 && disk_cfg.backing_files {
237+
+ warn!("Enabling backing_files option only applies for QCOW2 files");
238+
+ }
239+
+
240+
let image = match image_type {
241+
ImageType::FixedVhd => {
242+
// Use asynchronous backend relying on io_uring if the
243+
@@ -2759,7 +2763,7 @@ impl DeviceManager {
244+
ImageType::Qcow2 => {
245+
info!("Using synchronous QCOW2 disk file");
246+
Box::new(
247+
- QcowDiskSync::new(file, disk_cfg.direct)
248+
+ QcowDiskSync::new(file, disk_cfg.direct, disk_cfg.backing_files)
249+
.map_err(DeviceManagerError::CreateQcowDiskSync)?,
250+
) as Box<dyn DiskFile>
251+
}
252+
diff --git a/vmm/src/vm_config.rs b/vmm/src/vm_config.rs
253+
index 61f194e..9722e4e 100644
254+
--- a/vmm/src/vm_config.rs
255+
+++ b/vmm/src/vm_config.rs
256+
@@ -278,6 +278,8 @@ pub struct DiskConfig {
257+
pub serial: Option<String>,
258+
#[serde(default)]
259+
pub queue_affinity: Option<Vec<VirtQueueAffinity>>,
260+
+ #[serde(default)]
261+
+ pub backing_files: bool,
262+
}
263+
264+
impl ApplyLandlock for DiskConfig {
265+
--
266+
2.45.4
267+

SPECS/cloud-hypervisor/cloud-hypervisor.spec

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
Name: cloud-hypervisor
66
Summary: Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on top of the KVM hypervisor and the Microsoft Hypervisor (MSHV).
77
Version: 48.0.246
8-
Release: 2%{?dist}
8+
Release: 3%{?dist}
99
License: ASL 2.0 OR BSD-3-clause
1010
Vendor: Microsoft Corporation
1111
Distribution: Azure Linux
@@ -20,6 +20,7 @@ Source0: https://github.com/microsoft/cloud-hypervisor/archive/refs/tags/
2020
# cargo vendor > config.toml
2121
# tar -czf %%{name}-%%{version}-vendor.tar.gz vendor/
2222
Source1: %{name}-%{version}-vendor.tar.gz
23+
Patch0: CVE-2026-27211.patch
2324
%endif
2425

2526
BuildRequires: binutils
@@ -72,6 +73,7 @@ Cloud Hypervisor is an open source Virtual Machine Monitor (VMM) that runs on to
7273
%prep
7374

7475
%setup -q -n cloud-hypervisor-%{version}
76+
%patch 0 -p1
7577
%if 0%{?using_vendored_crates}
7678
tar xf %{SOURCE1}
7779
%endif
@@ -137,9 +139,12 @@ cargo build --release --target=%{rust_musl_target} %{cargo_pkg_feature_opts} %{c
137139
%license LICENSES/CC-BY-4.0.txt
138140

139141
%changelog
140-
* Mon Feb 02 2026 Archana Shettigar <v-shettigara@microsoft.com> - 48.0.246-2
142+
* Thu Feb 26 2026 Archana Shettigar <v-shettigara@microsoft.com> - 48.0.246-3
141143
- Bump release to rebuild with rust
142144

145+
* Wed Feb 25 2026 Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> - 48.0.246-2
146+
- Patch for CVE-2026-27211
147+
143148
* Fri Jan 23 2026 CBL-Mariner Servicing Account <cblmargh@microsoft.com> - 48.0.246-1
144149
- Auto-upgrade to 48.0.246
145150

@@ -233,10 +238,10 @@ cargo build --release --target=%{rust_musl_target} %{cargo_pkg_feature_opts} %{c
233238
* Wed Aug 17 2022 Anatol Belski <anbelski@linux.microsoft.com> - 26.0-1
234239
- Pull release 26.0 for Mariner from upstream
235240

236-
* Tue May 16 2022 Anatol Belski <anbelski@linux.microsoft.com> - 23.1-0
241+
* Mon May 16 2022 Anatol Belski <anbelski@linux.microsoft.com> - 23.1-0
237242
- Initial import 23.1 for Mariner from upstream
238243

239-
* Thu Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
244+
* Wed Apr 13 2022 Rob Bradford <robert.bradford@intel.com> 23.0-0
240245
- Update to 23.0
241246

242247
* Thu Mar 03 2022 Rob Bradford <robert.bradford@intel.com> 22.0-0

0 commit comments

Comments
 (0)