From c79f3acfabf352af75f8b2081768503812a5127a Mon Sep 17 00:00:00 2001 From: Anatol Belski Date: Fri, 20 Mar 2026 23:25:29 +0100 Subject: [PATCH] block: Validate sector range for DISCARD and WRITE_ZEROES requests Add range validation for DISCARD and WRITE_ZEROES, matching the existing check in the read/write path. Per virtio spec section 5.2.6.1, a driver must not submit a request which would cause a read or write beyond capacity. Use checked_add to guard against overflow, then compare against disk_nsectors. Without this, requests beyond device capacity pass through to the host punch_hole/write_zeroes calls, relying on backend specific behavior rather than returning VIRTIO_BLK_S_IOERR consistently. Signed-off-by: Anatol Belski --- block/src/lib.rs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/block/src/lib.rs b/block/src/lib.rs index b6c083cef..81b3f27c0 100644 --- a/block/src/lib.rs +++ b/block/src/lib.rs @@ -625,6 +625,13 @@ impl Request { let discard_num_sectors = u32::from_le_bytes(discard_num_sectors); + let top = discard_sector + .checked_add(discard_num_sectors as u64) + .ok_or(ExecuteError::BadRequest(Error::InvalidOffset))?; + if top > disk_nsectors { + return Err(ExecuteError::BadRequest(Error::InvalidOffset)); + } + let discard_offset = discard_sector * SECTOR_SIZE; let discard_length = (discard_num_sectors as u64) * SECTOR_SIZE; @@ -672,6 +679,14 @@ impl Request { if wz_offset == 0 && disable_sector0_writes { return Err(ExecuteError::BadRequest(Error::InvalidOffset)); } + + let top = wz_sector + .checked_add(wz_num_sectors as u64) + .ok_or(ExecuteError::BadRequest(Error::InvalidOffset))?; + if top > disk_nsectors { + return Err(ExecuteError::BadRequest(Error::InvalidOffset)); + } + let wz_length = (wz_num_sectors as u64) * SECTOR_SIZE; if wz_flags & VIRTIO_BLK_WRITE_ZEROES_FLAG_UNMAP != 0 {