dm: virtio: reject requests that violate the virtio-block spec

VirtIO v1.0 spec 04 5.2.5:
- Protocol unit size is always 512 bytes.
- blk_size (logical block size) and physical_block_exp (physical block
  size) do not affect the units in the protocol, only performance.

VirtIO v1.0 spec 04 5.2.6.1:
- A driver MUST NOT submit a request which would cause a read or write
  beyond capacity.

Reject the requests that violate these terms.

v1 -> v2:
- add more comments for clarity

Tracked-On: #1422
Signed-off-by: Peter Fang <peter.fang@intel.com>
Acked-by: Yu Wang <yu1.wang@intel.com>
This commit is contained in:
Peter Fang 2018-10-09 15:51:19 -07:00 committed by Xie, Nanlin
parent ba4e72bd0a
commit 2202b7f578

View File

@ -254,10 +254,29 @@ virtio_blk_proc(struct virtio_blk *blk, struct virtio_vq_info *vq)
switch (type) {
case VBH_OP_READ:
err = blockif_read(blk->bc, &io->req);
break;
case VBH_OP_WRITE:
err = blockif_write(blk->bc, &io->req);
/*
* VirtIO v1.0 spec 04 5.2.5:
* - Protocol unit size is always 512 bytes.
* - blk_size (logical block size) and physical_block_exp
* (physical block size) do not affect the units in the
* protocol, only performance.
*
* VirtIO v1.0 spec 04 5.2.6.1:
* - A driver MUST NOT submit a request which would cause a
* read or write beyond capacity.
*/
if ((iolen & (DEV_BSIZE - 1)) ||
vbh->sector + iolen / DEV_BSIZE > blk->cfg.capacity) {
DPRINTF(("virtio_blk: invalid request, iolen = %ld, "
"sector = %lu, capacity = %lu\n\r", iolen,
vbh->sector, blk->cfg.capacity));
virtio_blk_done(&io->req, EINVAL);
return;
}
err = ((type == VBH_OP_READ) ? blockif_read : blockif_write)
(blk->bc, &io->req);
break;
case VBH_OP_FLUSH:
case VBH_OP_FLUSH_OUT: