summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorKevin Wolf2014-04-14 15:39:36 +0200
committerKevin Wolf2014-04-22 11:57:02 +0200
commitda15ee5134f715adb07e3688a1c6e8b42cb6ac94 (patch)
tree5f33a291e25b374e131f2c4f375a3524183accf3
parentblock: Limit size to INT_MAX in bdrv_check_byte_request() (diff)
downloadqemu-da15ee5134f715adb07e3688a1c6e8b42cb6ac94.tar.gz
qemu-da15ee5134f715adb07e3688a1c6e8b42cb6ac94.tar.xz
qemu-da15ee5134f715adb07e3688a1c6e8b42cb6ac94.zip
block: Catch integer overflow in bdrv_rw_co()
Insanely large requests could cause an integer overflow in bdrv_rw_co() while converting sectors to bytes. This patch catches the problem and returns an error (if we hadn't overflown the integer here, bdrv_check_byte_request() would have rejected the request, so we're not breaking anything that was supposed to work before). We actually do have a test case that triggers behaviour where we accidentally let such a request pass, so that it would return success, but read 0 bytes instead of the requested 4 GB. It fails now like it should. If the vdi block driver wants to be able to deal with huge images, it can't read the whole block bitmap at once into memory like it does today, but needs to use a metadata cache like qcow2 does. Signed-off-by: Kevin Wolf <kwolf@redhat.com>
-rw-r--r--block.c4
-rw-r--r--tests/qemu-iotests/084.out5
2 files changed, 5 insertions, 4 deletions
diff --git a/block.c b/block.c
index 5a0b421655..ec3fa503df 100644
--- a/block.c
+++ b/block.c
@@ -2690,6 +2690,10 @@ static int bdrv_rw_co(BlockDriverState *bs, int64_t sector_num, uint8_t *buf,
.iov_len = nb_sectors * BDRV_SECTOR_SIZE,
};
+ if (nb_sectors < 0 || nb_sectors > INT_MAX / BDRV_SECTOR_SIZE) {
+ return -EINVAL;
+ }
+
qemu_iovec_init_external(&qiov, &iov, 1);
return bdrv_prwv_co(bs, sector_num << BDRV_SECTOR_BITS,
&qiov, is_write, flags);
diff --git a/tests/qemu-iotests/084.out b/tests/qemu-iotests/084.out
index e681924b85..c7120d9b0b 100644
--- a/tests/qemu-iotests/084.out
+++ b/tests/qemu-iotests/084.out
@@ -4,10 +4,7 @@ QA output created by 084
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Test 1: Maximum size (1024 TB):
-image: TEST_DIR/t.IMGFMT
-file format: IMGFMT
-virtual size: 1024T (1125899905794048 bytes)
-cluster_size: 1048576
+qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'TEST_DIR/t.IMGFMT': Invalid argument
Test 2: Size too large (1024TB + 1)
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Unsupported VDI image size (size is 0x3fffffff10000, max supported is 0x3fffffff00000)