Patchwork [1/2] qcow2: Fix qemu-img check segfault on corrupted images

login
register
mail settings
Submitter Kevin Wolf
Date June 22, 2010, 10:37 a.m.
Message ID <1277203075-8239-2-git-send-email-kwolf@redhat.com>
Download mbox | patch
Permalink /patch/56453/
State New
Headers show

Comments

Kevin Wolf - June 22, 2010, 10:37 a.m.
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>
---
 block/qcow2-refcount.c |   14 +++++++++++---
 1 files changed, 11 insertions(+), 3 deletions(-)

Patch

diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
index c2d0e61..cedf57e 100644
--- a/block/qcow2-refcount.c
+++ b/block/qcow2-refcount.c
@@ -1140,22 +1140,30 @@  int qcow2_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]);
             }
         }
     }