Skip to content

Commit

Permalink
vhdx: Handle failure for potentially large allocations
Browse files Browse the repository at this point in the history
Some code in the block layer makes potentially huge allocations. Failure
is not completely unexpected there, so avoid aborting qemu and handle
out-of-memory situations gracefully.

This patch addresses the allocations in the vhdx block driver.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
  • Loading branch information
kevmw committed Aug 15, 2014
1 parent 17cce73 commit a67e128
Show file tree
Hide file tree
Showing 2 changed files with 17 additions and 3 deletions.
7 changes: 6 additions & 1 deletion block/vhdx-log.c
Expand Up @@ -352,7 +352,12 @@ static int vhdx_log_read_desc(BlockDriverState *bs, BDRVVHDXState *s,
}

desc_sectors = vhdx_compute_desc_sectors(hdr.descriptor_count);
desc_entries = qemu_blockalign(bs, desc_sectors * VHDX_LOG_SECTOR_SIZE);
desc_entries = qemu_try_blockalign(bs->file,
desc_sectors * VHDX_LOG_SECTOR_SIZE);
if (desc_entries == NULL) {
ret = -ENOMEM;
goto exit;
}

ret = vhdx_log_read_sectors(bs, log, &sectors_read, desc_entries,
desc_sectors, false);
Expand Down
13 changes: 11 additions & 2 deletions block/vhdx.c
Expand Up @@ -958,7 +958,12 @@ static int vhdx_open(BlockDriverState *bs, QDict *options, int flags,
}

/* s->bat is freed in vhdx_close() */
s->bat = qemu_blockalign(bs, s->bat_rt.length);
s->bat = qemu_try_blockalign(bs->file, s->bat_rt.length);
if (s->bat == NULL) {
ret = -ENOMEM;
goto fail;
}

ret = bdrv_pread(bs->file, s->bat_offset, s->bat, s->bat_rt.length);
if (ret < 0) {
goto fail;
Expand Down Expand Up @@ -1587,7 +1592,11 @@ static int vhdx_create_bat(BlockDriverState *bs, BDRVVHDXState *s,
use_zero_blocks ||
bdrv_has_zero_init(bs) == 0) {
/* for a fixed file, the default BAT entry is not zero */
s->bat = g_malloc0(length);
s->bat = g_try_malloc0(length);
if (length && s->bat != NULL) {
ret = -ENOMEM;
goto exit;
}
block_state = type == VHDX_TYPE_FIXED ? PAYLOAD_BLOCK_FULLY_PRESENT :
PAYLOAD_BLOCK_NOT_PRESENT;
block_state = use_zero_blocks ? PAYLOAD_BLOCK_ZERO : block_state;
Expand Down

0 comments on commit a67e128

Please sign in to comment.