From: Stefan Hajnoczi Date: Wed, 26 Mar 2014 13:05:28 +0100 Subject: [PATCH] block/cloop: refuse images with bogus offsets (CVE-2014-0144) The offsets[] array allows efficient seeking and tells us the maximum compressed data size. If the offsets are bogus the maximum compressed data size will be unrealistic. This could cause g_malloc() to abort and bogus offsets mean the image is broken anyway. Therefore we should refuse such images. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi (cherry picked from commit f56b9bc3ae20fc93815b34aa022be919941406ce) Conflicts: tests/qemu-iotests/075 tests/qemu-iotests/075.out --- block/cloop.c | 34 +++++++++++++++++++++++++++++----- 1 file changed, 29 insertions(+), 5 deletions(-) diff --git a/block/cloop.c b/block/cloop.c index cf81c61..5c9c085 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -123,12 +123,36 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags) } for(i=0;in_blocks;i++) { + uint64_t size; + s->offsets[i] = be64_to_cpu(s->offsets[i]); - if (i > 0) { - uint32_t size = s->offsets[i] - s->offsets[i - 1]; - if (size > max_compressed_block_size) { - max_compressed_block_size = size; - } + if (i == 0) { + continue; + } + + if (s->offsets[i] < s->offsets[i - 1]) { + fprintf(stderr, "offsets not monotonically increasing at " + "index %u, image file is corrupt", i); + ret = -EINVAL; + goto fail; + } + + size = s->offsets[i] - s->offsets[i - 1]; + + /* Compressed blocks should be smaller than the uncompressed block size + * but maybe compression performed poorly so the compressed block is + * actually bigger. Clamp down on unrealistic values to prevent + * ridiculous s->compressed_block allocation. + */ + if (size > 2 * MAX_BLOCK_SIZE) { + fprintf(stderr, "invalid compressed block size at index %u, " + "image file is corrupt", i); + ret = -EINVAL; + goto fail; + } + + if (size > max_compressed_block_size) { + max_compressed_block_size = size; } }