diff mbox

[1/4] block: Make qiov match the request size until EOF

Message ID 1404489305-8750-2-git-send-email-kwolf@redhat.com
State New
Headers show

Commit Message

Kevin Wolf July 4, 2014, 3:55 p.m. UTC
If a read request goes across EOF, the block driver sees a shortened
request that stops at EOF (the rest is memsetted in block.c), however
the original qiov was used for this request.

This patch makes the qiov size match the request size, avoiding a
potential buffer overflow in raw-posix.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block.c | 11 ++++++++++-
 1 file changed, 10 insertions(+), 1 deletion(-)

Comments

Max Reitz July 5, 2014, 7:19 p.m. UTC | #1
On 04.07.2014 17:55, Kevin Wolf wrote:
> If a read request goes across EOF, the block driver sees a shortened
> request that stops at EOF (the rest is memsetted in block.c), however
> the original qiov was used for this request.
>
> This patch makes the qiov size match the request size, avoiding a
> potential buffer overflow in raw-posix.
>
> Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> ---
>   block.c | 11 ++++++++++-
>   1 file changed, 10 insertions(+), 1 deletion(-)

Reviewed-by: Max Reitz <mreitz@redhat.com>
diff mbox

Patch

diff --git a/block.c b/block.c
index 159a31e..ac4a037 100644
--- a/block.c
+++ b/block.c
@@ -3060,8 +3060,17 @@  static int coroutine_fn bdrv_aligned_preadv(BlockDriverState *bs,
         max_nb_sectors = ROUND_UP(MAX(0, total_sectors - sector_num),
                                   align >> BDRV_SECTOR_BITS);
         if (max_nb_sectors > 0) {
+            QEMUIOVector local_qiov;
+
+            qemu_iovec_init(&local_qiov, qiov->niov);
+            qemu_iovec_concat(&local_qiov, qiov, 0,
+                              max_nb_sectors * BDRV_SECTOR_SIZE);
+
             ret = drv->bdrv_co_readv(bs, sector_num,
-                                     MIN(nb_sectors, max_nb_sectors), qiov);
+                                     MIN(nb_sectors, max_nb_sectors),
+                                     &local_qiov);
+
+            qemu_iovec_destroy(&local_qiov);
         } else {
             ret = 0;
         }