Message ID | 20210914122454.141075-7-vsementsov@virtuozzo.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
Series | qcow2 check: check some reserved bits and subcluster bitmaps | expand |
On Tue, Sep 14, 2021 at 03:24:50PM +0300, Vladimir Sementsov-Ogievskiy wrote: > Check subcluster bitmap of the l2 entry for different types of > clusters: > > - for compressed it must be zero > - for allocated check consistency of two parts of the bitmap > - for unallocated all subclusters should be unallocated > (or zero-plain) > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > Tested-by: Kirill Tkhai <ktkhai@virtuozzo.com> > --- > block/qcow2-refcount.c | 28 ++++++++++++++++++++++++++-- > 1 file changed, 26 insertions(+), 2 deletions(-) > Reviewed-by: Eric Blake <eblake@redhat.com>
14.09.2021 17:25, Eric Blake wrote: > On Tue, Sep 14, 2021 at 03:24:50PM +0300, Vladimir Sementsov-Ogievskiy wrote: >> Check subcluster bitmap of the l2 entry for different types of >> clusters: >> >> - for compressed it must be zero >> - for allocated check consistency of two parts of the bitmap >> - for unallocated all subclusters should be unallocated >> (or zero-plain) >> >> Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> >> Tested-by: Kirill Tkhai <ktkhai@virtuozzo.com> >> --- >> block/qcow2-refcount.c | 28 ++++++++++++++++++++++++++-- >> 1 file changed, 26 insertions(+), 2 deletions(-) >> > > Reviewed-by: Eric Blake <eblake@redhat.com> > Thanks!
On 14.09.21 14:24, Vladimir Sementsov-Ogievskiy wrote: > Check subcluster bitmap of the l2 entry for different types of > clusters: > > - for compressed it must be zero > - for allocated check consistency of two parts of the bitmap > - for unallocated all subclusters should be unallocated > (or zero-plain) > > Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com> > Tested-by: Kirill Tkhai <ktkhai@virtuozzo.com> > --- > block/qcow2-refcount.c | 28 ++++++++++++++++++++++++++-- > 1 file changed, 26 insertions(+), 2 deletions(-) Reviewed-by: Hanna Reitz <hreitz@redhat.com>
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index f48c5e1b5d..9a5ae3cac4 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1661,7 +1661,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, int flags, BdrvCheckMode fix, bool active) { BDRVQcow2State *s = bs->opaque; - uint64_t l2_entry; + uint64_t l2_entry, l2_bitmap; uint64_t next_contiguous_offset = 0; int i, ret; size_t l2_size_bytes = s->l2_size * l2_entry_size(s); @@ -1681,6 +1681,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, uint64_t coffset; int csize; l2_entry = get_l2_entry(s, l2_table, i); + l2_bitmap = get_l2_bitmap(s, l2_table, i); switch (qcow2_get_cluster_type(bs, l2_entry)) { case QCOW2_CLUSTER_COMPRESSED: @@ -1700,6 +1701,14 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, break; } + if (l2_bitmap) { + fprintf(stderr, "ERROR compressed cluster %d with non-zero " + "subcluster allocation bitmap, entry=0x%" PRIx64 "\n", + i, l2_entry); + res->corruptions++; + break; + } + /* Mark cluster as used */ qcow2_parse_compressed_l2_entry(bs, l2_entry, &coffset, &csize); ret = qcow2_inc_refcounts_imrt( @@ -1727,13 +1736,19 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, { uint64_t offset = l2_entry & L2E_OFFSET_MASK; + if ((l2_bitmap >> 32) & l2_bitmap) { + res->corruptions++; + fprintf(stderr, "ERROR offset=%" PRIx64 ": Allocated " + "cluster has corrupted subcluster allocation bitmap\n", + offset); + } + /* Correct offsets are cluster aligned */ if (offset_into_cluster(s, offset)) { bool contains_data; res->corruptions++; if (has_subclusters(s)) { - uint64_t l2_bitmap = get_l2_bitmap(s, l2_table, i); contains_data = (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC); } else { contains_data = !(l2_entry & QCOW_OFLAG_ZERO); @@ -1799,7 +1814,16 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res, } case QCOW2_CLUSTER_ZERO_PLAIN: + /* Impossible when image has subclusters */ + assert(!l2_bitmap); + break; + case QCOW2_CLUSTER_UNALLOCATED: + if (l2_bitmap & QCOW_L2_BITMAP_ALL_ALLOC) { + res->corruptions++; + fprintf(stderr, "ERROR: Unallocated " + "cluster has non-zero subcluster allocation map\n"); + } break; default: