The total_sectors is computed as n_blocks * sectors_per_block where both operands are uint32_t. The multiplication is performed in 32-bit arithmetic and can overflow when the product exceeds UINT32_MAX, producing a value much smaller than the true image size. The result is assigned to int64_t total_sectors but the 32-bit multiplication has already wrapped around, and the zero-extension to 64-bit does not recover the correct value.
This causes the block layer to reject valid I/O requests (DoS) when the reported total_sectors is smaller than the actual image. Use 64-bit arithmetic by casting one operand to uint64_t so the multiplication is performed in 64-bit precision. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/3972 Signed-off-by: Ma Like <[email protected]> --- block/cloop.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/block/cloop.c b/block/cloop.c index 443af1444e..a16f08e6ef 100644 --- a/block/cloop.c +++ b/block/cloop.c @@ -202,7 +202,8 @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags, s->current_block = s->n_blocks; s->sectors_per_block = s->block_size/512; - bs->total_sectors = s->n_blocks * s->sectors_per_block; + /* Cast to uint64_t to prevent uint32_t overflow */ + bs->total_sectors = (uint64_t)s->n_blocks * s->sectors_per_block; qemu_co_mutex_init(&s->lock); return 0; -- 2.25.1
