From 7ccd9eeea3f5cba44df5caddc298929f9f252ef4 Mon Sep 17 00:00:00 2001 From: Kevin Wolf <kwolf@redhat.com> Date: Thu, 24 Jun 2010 14:47:58 -0300 Subject: [PATCH 1/4] qcow2: Fix qemu-img check segfault on corrupted images RH-Author: Kevin Wolf <kwolf@redhat.com> Message-id: <patch-10184-clone-for-rhel55-rhel55> Patchwork-id: 10240 O-Subject: [RHEL-5.6 KVM PATCH 1/2] qcow2: Fix qemu-img check segfault on corrupted images Bugzilla: 610342 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