9ae3a8
From 95b523f48df55dfd60229d2573385828a884aa7c Mon Sep 17 00:00:00 2001
9ae3a8
From: Jeff Cody <jcody@redhat.com>
9ae3a8
Date: Tue, 25 Mar 2014 14:23:25 +0100
9ae3a8
Subject: [PATCH 18/49] vhdx: Bounds checking for block_size and logical_sector_size (CVE-2014-0148)
9ae3a8
9ae3a8
RH-Author: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Message-id: <1395753835-7591-19-git-send-email-kwolf@redhat.com>
9ae3a8
Patchwork-id: n/a
9ae3a8
O-Subject: [virt-devel] [EMBARGOED RHEL-7.0 qemu-kvm PATCH 18/48] vhdx: Bounds checking for block_size and logical_sector_size (CVE-2014-0148)
9ae3a8
Bugzilla: 1079346
9ae3a8
RH-Acked-by: Jeff Cody <jcody@redhat.com>
9ae3a8
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
9ae3a8
RH-Acked-by: Paolo Bonzini <pbonzini@redhat.com>
9ae3a8
9ae3a8
From: Jeff Cody <jcody@redhat.com>
9ae3a8
9ae3a8
Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1079346
9ae3a8
Upstream status: Embargoed
9ae3a8
9ae3a8
Other variables (e.g. sectors_per_block) are calculated using these
9ae3a8
variables, and if not range-checked illegal values could be obtained
9ae3a8
causing infinite loops and other potential issues when calculating
9ae3a8
BAT entries.
9ae3a8
9ae3a8
The 1.00 VHDX spec requires BlockSize to be min 1MB, max 256MB.
9ae3a8
LogicalSectorSize is required to be either 512 or 4096 bytes.
9ae3a8
9ae3a8
Reported-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
Signed-off-by: Jeff Cody <jcody@redhat.com>
9ae3a8
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
9ae3a8
---
9ae3a8
 block/vhdx.c |   12 ++++++++++--
9ae3a8
 1 files changed, 10 insertions(+), 2 deletions(-)
9ae3a8
9ae3a8
diff --git a/block/vhdx.c b/block/vhdx.c
9ae3a8
index 1995778..66a25c9 100644
9ae3a8
--- a/block/vhdx.c
9ae3a8
+++ b/block/vhdx.c
9ae3a8
@@ -785,12 +785,20 @@ static int vhdx_parse_metadata(BlockDriverState *bs, BDRVVHDXState *s)
9ae3a8
     le32_to_cpus(&s->logical_sector_size);
9ae3a8
     le32_to_cpus(&s->physical_sector_size);
9ae3a8
 
9ae3a8
-    if (s->logical_sector_size == 0 || s->params.block_size == 0) {
9ae3a8
+    if (s->params.block_size < VHDX_BLOCK_SIZE_MIN ||
9ae3a8
+        s->params.block_size > VHDX_BLOCK_SIZE_MAX) {
9ae3a8
         ret = -EINVAL;
9ae3a8
         goto exit;
9ae3a8
     }
9ae3a8
 
9ae3a8
-    /* both block_size and sector_size are guaranteed powers of 2 */
9ae3a8
+    /* only 2 supported sector sizes */
9ae3a8
+    if (s->logical_sector_size != 512 && s->logical_sector_size != 4096) {
9ae3a8
+        ret = -EINVAL;
9ae3a8
+        goto exit;
9ae3a8
+    }
9ae3a8
+
9ae3a8
+    /* Both block_size and sector_size are guaranteed powers of 2, below.
9ae3a8
+       Due to range checks above, s->sectors_per_block can never be < 256 */
9ae3a8
     s->sectors_per_block = s->params.block_size / s->logical_sector_size;
9ae3a8
     s->chunk_ratio = (VHDX_MAX_SECTORS_PER_BLOCK) *
9ae3a8
                      (uint64_t)s->logical_sector_size /
9ae3a8
-- 
9ae3a8
1.7.1
9ae3a8