On 08.08.2022 14:07, Alexander Ivanov wrote:
> When an image is opened, data_end field in BDRVParallelsState
> is setted as the biggest offset in the BAT plus cluster size.
> If there is a corrupted offset pointing outside the image,
> the image size increase accordingly. It potentially leads
> to attempts to create a file size of petabytes.
>
> Set the data_end field with the original file size if the image
> was opened for checking and repairing purposes or raise an error.
>
> Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
> ---
> block/parallels.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/block/parallels.c b/block/parallels.c
> index 3cb5452613..72cf7499c1 100644
> --- a/block/parallels.c
> +++ b/block/parallels.c
> @@ -811,6 +811,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> BDRVParallelsState *s = bs->opaque;
> ParallelsHeader ph;
> int ret, size, i;
> + int64_t file_size;
> QemuOpts *opts = NULL;
> Error *local_err = NULL;
> char *buf;
> @@ -890,6 +891,22 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
> }
> }
>
> + file_size = bdrv_getlength(bs->file->bs);
> + if (file_size < 0) {
> + goto fail;
> + }
> +
> + file_size >>= BDRV_SECTOR_BITS;
> + if (s->data_end > file_size) {
> + if (flags & BDRV_O_CHECK) {
> + s->data_end = file_size;
> + } else {
> + error_setg(errp, "parallels: Offset in BAT is out of image");
> + ret = -EINVAL;
> + goto fail;
> + }
> + }
> +
> if (le32_to_cpu(ph.inuse) == HEADER_INUSE_MAGIC) {
> /* Image was not closed correctly. The check is mandatory */
> s->header_unclean = true;
for me it would be more logical to have this check inside the loop,
calculating data_offset. Though this is personal.