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 <anbelski@linux.microsoft.com>
This commit is contained in:
Anatol Belski
2026-03-28 14:11:55 +01:00
committed by Rob Bradford
parent ca58685f4c
commit af1d69a9dd

View File

@@ -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 {