parallels_load_bitmap_data() unconditionally calls bdrv_dirty_bitmap_deserialize_finish() even when there is nothing to deserialize, which hits an assertion in hbitmap (hbitmap_iter_init: 'pos < hb->size') when the bitmap itself has zero size, i.e. the disk is a zero-sector image.
Skip allocating, populating and loading the L1 table entirely when l1_size == 0. This is safe only because the previous commit already guarantees l1_size == 0 exclusively means the disk has 0 size. Signed-off-by: Denis V. Lunev <[email protected]> CC: Thomas Huth <[email protected]> CC: Stefan Hajnoczi <[email protected]> --- block/parallels-ext.c | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/block/parallels-ext.c b/block/parallels-ext.c index 97744c9696..704e16e1de 100644 --- a/block/parallels-ext.c +++ b/block/parallels-ext.c @@ -168,14 +168,17 @@ parallels_load_bitmap(BlockDriverState *bs, uint8_t *data, size_t data_size, goto fail; } - l1_table = g_new(uint64_t, bf.l1_size); - for (i = 0; i < bf.l1_size; i++, data += sizeof(uint64_t)) { - l1_table[i] = ldq_le_p(data); - } + if (bf.l1_size != 0) { + l1_table = g_new(uint64_t, bf.l1_size); + for (i = 0; i < bf.l1_size; i++, data += sizeof(uint64_t)) { + l1_table[i] = ldq_le_p(data); + } - ret = parallels_load_bitmap_data(bs, l1_table, bf.l1_size, bitmap, errp); - if (ret < 0) { - goto fail; + ret = parallels_load_bitmap_data(bs, l1_table, bf.l1_size, bitmap, + errp); + if (ret < 0) { + goto fail; + } } /* We support format extension only for RO parallels images. */ -- 2.53.0
