qcow2: qemu-img check fixes
cover qcow2: qemu-img check fixes
Kevin Wolf (2):
qcow2: Fix qemu-img check segfault on corrupted images
qcow2: Don't try to check tables that couldn't be loaded
block/qcow2-refcount.c | 15 ++++++++++++--- 1 files changed, 12 insertions(+), 3 deletions(-)
PATCH 1/2 qcow2: Fix qemu-img check segfault on corrupted images
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 <[email protected]>
--- block/qcow2-refcount.c | 14 +++++++++++--- 1 files changed, 11 insertions(+), 3 deletions(-)
block/qcow2-refcount.c +11 -3
@@ -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]); } } }
Signature · 1 line
1.6.6.1
PATCH 2/2 qcow2: Don't try to check tables that couldn't be loaded
In reply to Kevin WolfTrying to check them leads to a second error message which is more confusing than helpful:
Can't get refcount for cluster 0: Invalid argument ERROR cluster 0 refcount=-22 reference=1
Signed-off-by Kevin Wolf <[email protected]>
--- block/qcow2-refcount.c | 1 + 1 files changed, 1 insertions(+), 0 deletions(-)
block/qcow2-refcount.c +1 -0
@@ -1174,6 +1174,7 @@ int qcow2_check_refcounts(BlockDriverState *bs)if (refcount1 <0 ) {fprintf (stderr,"Can't get refcount for cluster %d: %s\n" , i,strerror (-refcount1)); +continue ; } refcount2 = refcount_table[i];
Signature · 1 line
1.6.6.1