From af1d69a9ddff03db3bdee85b299c53c1ea62a9ed Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Sat, 28 Mar 2026 14:11:55 +0100 Subject: [PATCH] block: Reject discard requests with flags set The virtio spec v1.2 in 5.2.6.2 requires that the device MUST return VIRTIO_BLK_S_UNSUPP for discard commands if the unmap flag is set or if any unknown flag is set. The discard handler was not reading the flags field at all, silently accepting requests with arbitrary flags. Read and validate the flags, rejecting any non-zero value with VIRTIO_BLK_S_UNSUPP. Signed-off-by: Anatol Belski --- block/src/lib.rs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/block/src/lib.rs b/block/src/lib.rs index d62e2717b..912cf4401 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -610,6 +610,7 @@ impl Request { let mut discard_sector = [0u8; 8]; let mut discard_num_sectors = [0u8; 4]; + let mut discard_flags = [0u8; 4]; let sector_addr = data_addr.checked_add(DISCARD_WZ_SECTOR_OFFSET).unwrap(); mem.read_slice(&mut discard_sector, sector_addr) @@ -621,6 +622,17 @@ impl Request { mem.read_slice(&mut discard_num_sectors, num_sectors_addr) .map_err(ExecuteError::Read)?; + let flags_addr = data_addr.checked_add(DISCARD_WZ_FLAGS_OFFSET).unwrap(); + mem.read_slice(&mut discard_flags, flags_addr) + .map_err(ExecuteError::Read)?; + + let discard_flags = u32::from_le_bytes(discard_flags); + // Per virtio spec v1.2 reject discard if any flag is set, including unmap. + if discard_flags != 0 { + warn!("Unsupported flags {discard_flags:#x} in discard request"); + return Err(ExecuteError::Unsupported(VIRTIO_BLK_T_DISCARD)); + } + let discard_sector = u64::from_le_bytes(discard_sector); if discard_sector == 0 && disable_sector0_writes {