Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
parallels: Out of image offset in BAT leads to image inflation
data_end field in BDRVParallelsState is set to the biggest offset present
in BAT. If this offset is outside of the image, any further write will
create the cluster at this offset and/or the image will be truncated to
this offset on close. This is definitely not correct.

Raise an error in parallels_open() if data_end points outside the image
and it is not a check (let the check to repaire the image). Set data_end
to the end of the cluster with the last correct offset.

Signed-off-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
Message-Id: <20230424093147.197643-2-alexander.ivanov@virtuozzo.com>
Reviewed-by: Hanna Czenczek <hreitz@redhat.com>
Signed-off-by: Hanna Czenczek <hreitz@redhat.com>
  • Loading branch information
AlexanderIvanov-Virtuozzo authored and XanClic committed Jun 5, 2023
1 parent d7e1905 commit f5e715d
Showing 1 changed file with 17 additions and 0 deletions.
17 changes: 17 additions & 0 deletions block/parallels.c
Expand Up @@ -733,6 +733,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
BDRVParallelsState *s = bs->opaque;
ParallelsHeader ph;
int ret, size, i;
int64_t file_nb_sectors;
QemuOpts *opts = NULL;
Error *local_err = NULL;
char *buf;
Expand All @@ -742,6 +743,11 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
return ret;
}

file_nb_sectors = bdrv_nb_sectors(bs->file->bs);
if (file_nb_sectors < 0) {
return -EINVAL;
}

ret = bdrv_pread(bs->file, 0, sizeof(ph), &ph, 0);
if (ret < 0) {
goto fail;
Expand Down Expand Up @@ -806,6 +812,17 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,

for (i = 0; i < s->bat_size; i++) {
int64_t off = bat2sect(s, i);
if (off >= file_nb_sectors) {
if (flags & BDRV_O_CHECK) {
continue;
}
error_setg(errp, "parallels: Offset %" PRIi64 " in BAT[%d] entry "
"is larger than file size (%" PRIi64 ")",
off << BDRV_SECTOR_BITS, i,
file_nb_sectors << BDRV_SECTOR_BITS);
ret = -EINVAL;
goto fail;
}
if (off >= s->data_end) {
s->data_end = off + s->tracks;
}
Expand Down

0 comments on commit f5e715d

Please sign in to comment.