Sophie

Sophie

distrib > Scientific%20Linux > 5x > x86_64 > by-pkgid > 340e01248478ba8b78a6d4d1809b1eff > files > 653

kvm-83-270.el5_11.src.rpm

From 2fc8b6b9b3526fedfda629bea7eb60e62caca518 Mon Sep 17 00:00:00 2001
From: Kevin Wolf <kwolf@redhat.com>
Date: Thu, 24 Jun 2010 14:47:58 -0300
Subject: [PATCH 2/5] qcow2: Fix qemu-img check segfault on corrupted images

RH-Author: Kevin Wolf <kwolf@redhat.com>
Message-id: <1277390879-11484-2-git-send-email-kwolf@redhat.com>
Patchwork-id: 10184
O-Subject: [RHEL-5.6 KVM PATCH 1/2] qcow2: Fix qemu-img check segfault on
	corrupted images
Bugzilla: 606434
RH-Acked-by: Eduardo Habkost <ehabkost@redhat.com>
RH-Acked-by: Christoph Hellwig <chellwig@redhat.com>
RH-Acked-by: Jes Sorensen <Jes.Sorensen@redhat.com>

Bugzilla: 606434
Upstream commit: 6882c8fa78dcc4882640d3e11232d995fda7d5c4

With corrupted images, we can easily get an cluster index that exceeds the
array size of the temporary refcount table.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 qemu/block-qcow2.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

Signed-off-by: Eduardo Habkost <ehabkost@redhat.com>
---
 qemu/block-qcow2.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/qemu/block-qcow2.c b/qemu/block-qcow2.c
index 5647350..4556a6b 100644
--- a/qemu/block-qcow2.c
+++ b/qemu/block-qcow2.c
@@ -3360,22 +3360,30 @@ static int check_refcounts(BlockDriverState *bs)
                   s->refcount_table_offset,
                   s->refcount_table_size * sizeof(uint64_t));
     for(i = 0; i < s->refcount_table_size; i++) {
-        int64_t offset;
+        uint64_t offset, cluster;
         offset = s->refcount_table[i];
+        cluster = offset >> s->cluster_bits;
 
         /* Refcount blocks are cluster aligned */
         if (offset & (s->cluster_size - 1)) {
             fprintf(stderr, "ERROR refcount block %d is not "
                 "cluster aligned; refcount table entry corrupted\n", i);
             errors++;
+            continue;
+        }
+
+        if (cluster >= nb_clusters) {
+            fprintf(stderr, "ERROR refcount block %d is outside image\n", i);
+            errors++;
+            continue;
         }
 
         if (offset != 0) {
             errors += inc_refcounts(bs, refcount_table, nb_clusters,
                           offset, s->cluster_size);
-            if (refcount_table[offset / s->cluster_size] != 1) {
+            if (refcount_table[cluster] != 1) {
                 fprintf(stderr, "ERROR refcount block %d refcount=%d\n",
-                    i, refcount_table[offset / s->cluster_size]);
+                    i, refcount_table[cluster]);
             }
         }
     }
-- 
1.7.0.3