From f0f6bce3f2d2f269f45d985d8eed3bebfac0e4eb Mon Sep 17 00:00:00 2001
From: Christoph Hellwig <chellwig@redhat.com>
Date: Tue, 26 Apr 2011 12:55:36 -0300
Subject: [RHEL6 qemu-kvm PATCH 1/2] virtio-blk: fail unaligned requests

RH-Author: Christoph Hellwig <chellwig@redhat.com>
Message-id: <1303822536.25531.7.camel@rocky.lst.de>
Patchwork-id: 22838
O-Subject: [PATCH qemu RHEL6.1] virtio-blk: fail unaligned requests
Bugzilla: 698910
RH-Acked-by: Kevin Wolf <kwolf@redhat.com>
RH-Acked-by: Petr Matousek <pmatouse@redhat.com>
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>

Like all block drivers virtio-blk should not allow small than block size
granularity access.  But given that the protocol specifies a
byte unit length field we currently accept such requests, which cause
qemu to abort() in lower layers.  Add checks to the main read and
write handlers to catch them early.

Reported-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Tested-by: Conor Murphy <conor_murphy_virt@hotmail.com>
Signed-off-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Stefan Hajnoczi <stefanha@linux.vnet.ibm.com>
Signed-off-by: Kevin Wolf <kwolf@redhat.com>

Upstream commit 52c050236eaa4f0b5e1d160cd66dc18106445c4d
BZ: 698910

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 hw/virtio-blk.c |    8 ++++++++
 1 files changed, 8 insertions(+), 0 deletions(-)

diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c
index cff21a9..6737c6b 100644
--- a/hw/virtio-blk.c
+++ b/hw/virtio-blk.c
@@ -292,6 +292,10 @@ static void virtio_blk_handle_write(BlockRequest *blkreq, int *num_writes,
         *num_writes = 0;
         *old_bs = req->dev->bs;
     }
+    if (req->qiov.size % req->dev->conf->logical_block_size) {
+        virtio_blk_rw_complete(req, -EIO);
+        return;
+    }
 
     blkreq[*num_writes].sector = req->out->sector;
     blkreq[*num_writes].nb_sectors = req->qiov.size / 512;
@@ -311,6 +315,10 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req)
         virtio_blk_rw_complete(req, -EIO);
         return;
     }
+    if (req->qiov.size % req->dev->conf->logical_block_size) {
+        virtio_blk_rw_complete(req, -EIO);
+        return;
+    }
 
     acb = bdrv_aio_readv(req->dev->bs, req->out->sector, &req->qiov,
                          req->qiov.size / 512, virtio_blk_rw_complete, req);
-- 
1.7.3.2

