From 2d2d5cb5719024e47226e0c39138e9e99c20788d Mon Sep 17 00:00:00 2001 From: Stefan Hajnoczi Date: Tue, 25 Mar 2014 11:45:35 +0100 Subject: [PATCH 17/48] block/cloop: validate block_size header field (CVE-2014-0144) RH-Author: Kevin Wolf Message-id: <1395744364-16049-17-git-send-email-kwolf@redhat.com> Patchwork-id: n/a O-Subject: [EMBARGOED RHEL-6.6/6.5.z qemu-kvm PATCH v2 16/45] block/cloop: validate block_size header field (CVE-2014-0144) Bugzilla: 1079453 RH-Acked-by: Max Reitz RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Jeff Cody Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1079453 Upstream status: Embargoed Avoid unbounded s->uncompressed_block memory allocation by checking that the block_size header field has a reasonable value. Also enforce the assumption that the value is a non-zero multiple of 512. These constraints conform to cloop 2.639's code so we accept existing image files. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf Conflicts: tests/qemu-iotests/075 tests/qemu-iotests/075.out qerror_report() doesn't take a format string like error_setg() (it does use a format string for the JSON representation, but we want to use QERR_GENERIC_ERROR there), so changed error messages to static strings for RHEL 6. Signed-off-by: Kevin Wolf --- block/cloop.c | 21 +++++++++++++++++++++ 1 files changed, 21 insertions(+), 0 deletions(-) diff --git a/block/cloop.c b/block/cloop.c index 775f8a9..9caf7f0 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -26,6 +26,9 @@ #include "module.h" #include +/* Maximum compressed block size */ +#define MAX_BLOCK_SIZE (64 * 1024 * 1024) + typedef struct BDRVCloopState { CoMutex lock; uint32_t block_size; @@ -63,6 +66,24 @@ static int cloop_open(BlockDriverState *bs, int flags) goto cloop_close; } s->block_size = be32_to_cpu(s->block_size); + if (s->block_size % 512) { + qerror_report(QERR_GENERIC_ERROR, + "block_size must be a multiple of 512"); + return -EINVAL; + } + if (s->block_size == 0) { + qerror_report(QERR_GENERIC_ERROR, "block_size cannot be zero"); + return -EINVAL; + } + + /* cloop's create_compressed_fs.c warns about block sizes beyond 256 KB but + * we can accept more. Prevent ridiculous values like 4 GB - 1 since we + * need a buffer this big. + */ + if (s->block_size > MAX_BLOCK_SIZE) { + qerror_report(QERR_GENERIC_ERROR, "block_size too large"); + return -EINVAL; + } if (bdrv_pread(bs->file, 128 + 4, &s->n_blocks, 4) < 4) { goto cloop_close; -- 1.7.1