From 5dae6e30c531feb31eed99f9039b52bf70832ce3 Mon Sep 17 00:00:00 2001 From: Kevin Wolf Date: Wed, 26 Mar 2014 13:06:07 +0100 Subject: qcow2: Limit snapshot table size Even with a limit of 64k snapshots, each snapshot could have a filename and an ID with up to 64k, which would still lead to pretty large allocations, which could potentially lead to qemu aborting. Limit the total size of the snapshot table to an average of 1k per entry when the limit of 64k snapshots is fully used. This should be plenty for any reasonable user. This also fixes potential integer overflows of s->snapshot_size. Suggested-by: Max Reitz Signed-off-by: Kevin Wolf Reviewed-by: Max Reitz Signed-off-by: Stefan Hajnoczi --- block/qcow2-snapshot.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'block/qcow2-snapshot.c') diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index 5db4f30c82..0aa9defbe2 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -116,8 +116,14 @@ int qcow2_read_snapshots(BlockDriverState *bs) } offset += name_size; sn->name[name_size] = '\0'; + + if (offset - s->snapshots_offset > QCOW_MAX_SNAPSHOTS_SIZE) { + ret = -EFBIG; + goto fail; + } } + assert(offset - s->snapshots_offset <= INT_MAX); s->snapshots_size = offset - s->snapshots_offset; return 0; @@ -138,7 +144,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) uint32_t nb_snapshots; uint64_t snapshots_offset; } QEMU_PACKED header_data; - int64_t offset, snapshots_offset; + int64_t offset, snapshots_offset = 0; int ret; /* compute the size of the snapshots */ @@ -150,7 +156,14 @@ static int qcow2_write_snapshots(BlockDriverState *bs) offset += sizeof(extra); offset += strlen(sn->id_str); offset += strlen(sn->name); + + if (offset > QCOW_MAX_SNAPSHOTS_SIZE) { + ret = -EFBIG; + goto fail; + } } + + assert(offset <= INT_MAX); snapshots_size = offset; /* Allocate space for the new snapshot list */ -- cgit v1.2.3