From: "Denis V. Lunev" <[email protected]>

The chunk size is an int and is shifted left by 3 before the result is
widened, so a chunk size of 1 << 28 or above overflows.

parallels passes s->cluster_size, which parallels_open() lets reach
2 GiB. With a bitmap needing two L1 entries the bogus limit makes the
"bm_size - offset" in parallels_load_bitmap_data() underflow; both
wrong values slip past the assertions in serialization_chunk() and the
resulting index lands outside the hbitmap, so a 128 KiB image memsets
unrelated memory through hbitmap_deserialize_ones().

Widen the shift. qcow2, the only other caller, never exceeds a 2 MiB
cluster.

Fixes: 35f428ba3971 ("qcow2-bitmap: make bytes_covered_by_bitmap_cluster() 
public")
Cc: Eric Blake <[email protected]>
Cc: Vladimir Sementsov-Ogievskiy <[email protected]>
Cc: Stefan Hajnoczi <[email protected]>
Cc: Thomas Huth <[email protected]>
Signed-off-by: Denis V. Lunev <[email protected]>
Message-ID: <[email protected]>
Reviewed-by: Vladimir Sementsov-Ogievskiy <[email protected]>
Signed-off-by: Vladimir Sementsov-Ogievskiy <[email protected]>
---
 block/dirty-bitmap.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/block/dirty-bitmap.c b/block/dirty-bitmap.c
index 13a1979755d..9fda3a4b983 100644
--- a/block/dirty-bitmap.c
+++ b/block/dirty-bitmap.c
@@ -612,7 +612,7 @@ uint64_t bdrv_dirty_bitmap_serialization_coverage(int 
serialized_chunk_size,
                                                   const BdrvDirtyBitmap 
*bitmap)
 {
     uint64_t granularity = bdrv_dirty_bitmap_granularity(bitmap);
-    uint64_t limit = granularity * (serialized_chunk_size << 3);
+    uint64_t limit = granularity * ((uint64_t)serialized_chunk_size << 3);
 
     assert(QEMU_IS_ALIGNED(limit,
                            bdrv_dirty_bitmap_serialization_align(bitmap)));
-- 
2.43.0


Reply via email to