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