From c5104a9f172e91c0fc2f7bb6d8fa45d5eccdc255 Mon Sep 17 00:00:00 2001 From: Rob Bradford Date: Wed, 1 Jul 2026 17:25:03 +0100 Subject: [PATCH] devices: fw_cfg: Correctly handle short and long reads Fill the target MMIO buffer with zeroes to handle reads with access sizes larger than the data and also check that the read access length does not exceed the size of the backing slice (previously it just checked the access size vs length not taking the offset into account). Assisted-by: Claude:Opus-4.8 Signed-off-by: Rob Bradford --- devices/src/legacy/fw_cfg.rs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/devices/src/legacy/fw_cfg.rs b/devices/src/legacy/fw_cfg.rs index 6006e8f20..3624e9490 100644 --- a/devices/src/legacy/fw_cfg.rs +++ b/devices/src/legacy/fw_cfg.rs @@ -722,16 +722,18 @@ impl FwCfg { } fn read_content(content: &FwCfgContent, offset: u32, data: &mut [u8], size: u32) -> Option { + // Zero fill rather than the usual 0xff fill for QEMU compatibility + data.fill(0); let start = offset as usize; let end = start + size as usize; match content { FwCfgContent::Bytes(b) => { - if b.len() >= size as usize { + if end <= b.len() { data.copy_from_slice(&b[start..end]); } } FwCfgContent::Slice(s) => { - if s.len() >= size as usize { + if end <= s.len() { data.copy_from_slice(&s[start..end]); } } @@ -740,7 +742,9 @@ impl FwCfg { } FwCfgContent::U32(n) => { let bytes = n.to_le_bytes(); - data.copy_from_slice(&bytes[start..end]); + if end <= bytes.len() { + data.copy_from_slice(&bytes[start..end]); + } } } Some(size as u8)