summaryrefslogtreecommitdiffstats
path: root/block
diff options
context:
space:
mode:
authorKevin Wolf <kwolf@redhat.com>2014-07-03 14:43:32 +0200
committerKevin Wolf <kwolf@redhat.com>2014-07-14 12:03:20 +0200
commit44deba5a52576508f27edadf953e435141e2a76a (patch)
treef5e5cb9b5360d0060b78a72dda44c0f40316097d /block
parent33f461e0c5d8efa21ef7e746be561fc57a1df106 (diff)
downloadhqemu-44deba5a52576508f27edadf953e435141e2a76a.zip
hqemu-44deba5a52576508f27edadf953e435141e2a76a.tar.gz
qcow2: Make qiov match request size until backing file EOF
If a qcow2 image has a shorter backing file and a read request to unallocated clusters goes across EOF of the backing file, the backing file sees a shortened request and the rest is filled with zeros. However, the original too long qiov was used with the shortened 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> Reviewed-by: Max Reitz <mreitz@redhat.com>
Diffstat (limited to 'block')
-rw-r--r--block/qcow2.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/block/qcow2.c b/block/qcow2.c
index 67e55c9..b0faa69 100644
--- a/block/qcow2.c
+++ b/block/qcow2.c
@@ -1020,11 +1020,20 @@ static coroutine_fn int qcow2_co_readv(BlockDriverState *bs, int64_t sector_num,
n1 = qcow2_backing_read1(bs->backing_hd, &hd_qiov,
sector_num, cur_nr_sectors);
if (n1 > 0) {
+ QEMUIOVector local_qiov;
+
+ qemu_iovec_init(&local_qiov, hd_qiov.niov);
+ qemu_iovec_concat(&local_qiov, &hd_qiov, 0,
+ n1 * BDRV_SECTOR_SIZE);
+
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
qemu_co_mutex_unlock(&s->lock);
ret = bdrv_co_readv(bs->backing_hd, sector_num,
- n1, &hd_qiov);
+ n1, &local_qiov);
qemu_co_mutex_lock(&s->lock);
+
+ qemu_iovec_destroy(&local_qiov);
+
if (ret < 0) {
goto fail;
}
OpenPOWER on IntegriCloud