From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41454) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X4Z6i-0004jI-NF for qemu-devel@nongnu.org; Tue, 08 Jul 2014 13:24:06 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1X4Z6A-0000kl-2n for qemu-devel@nongnu.org; Tue, 08 Jul 2014 13:23:08 -0400 Received: from e32.co.us.ibm.com ([32.97.110.150]:38923) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1X4Z69-0000i3-Eo for qemu-devel@nongnu.org; Tue, 08 Jul 2014 13:22:33 -0400 Received: from /spool/local by e32.co.us.ibm.com with IBM ESMTP SMTP Gateway: Authorized Use Only! Violators will be prosecuted for from ; Tue, 8 Jul 2014 11:22:33 -0600 From: Michael Roth Date: Tue, 8 Jul 2014 12:18:17 -0500 Message-Id: <1404839947-1086-107-git-send-email-mdroth@linux.vnet.ibm.com> In-Reply-To: <1404839947-1086-1-git-send-email-mdroth@linux.vnet.ibm.com> References: <1404839947-1086-1-git-send-email-mdroth@linux.vnet.ibm.com> Subject: [Qemu-devel] [PATCH 106/156] dmg: sanitize chunk length and sectorcount (CVE-2014-0145) List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: qemu-stable@nongnu.org From: Stefan Hajnoczi Chunk length and sectorcount are used for decompression buffers as well as the bdrv_pread() count argument. Ensure that they have reasonable values so neither memory allocation nor conversion from uint64_t to int will cause problems. Signed-off-by: Stefan Hajnoczi Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi (cherry picked from commit c165f7758009a4f793c1fc19ebb69cf55313450b) Signed-off-by: Michael Roth --- block/dmg.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/block/dmg.c b/block/dmg.c index f98c94d..ad253fe 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -27,6 +27,14 @@ #include "qemu/module.h" #include +enum { + /* Limit chunk sizes to prevent unreasonable amounts of memory being used + * or truncating when converting to 32-bit types + */ + DMG_LENGTHS_MAX = 64 * 1024 * 1024, /* 64 MB */ + DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512, +}; + typedef struct BDRVDMGState { CoMutex lock; /* each chunk contains a certain number of sectors, @@ -208,6 +216,14 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, } offset += 8; + if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) { + error_report("sector count %" PRIu64 " for chunk %u is " + "larger than max (%u)", + s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX); + ret = -EINVAL; + goto fail; + } + ret = read_uint64(bs, offset, &s->offsets[i]); if (ret < 0) { goto fail; @@ -221,6 +237,14 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, } offset += 8; + if (s->lengths[i] > DMG_LENGTHS_MAX) { + error_report("length %" PRIu64 " for chunk %u is larger " + "than max (%u)", + s->lengths[i], i, DMG_LENGTHS_MAX); + ret = -EINVAL; + goto fail; + } + if (s->lengths[i] > max_compressed_size) { max_compressed_size = s->lengths[i]; } -- 1.9.1