diff options
author | Kevin Wolf <kwolf@redhat.com> | 2014-05-20 13:28:14 +0200 |
---|---|---|
committer | Kevin Wolf <kwolf@redhat.com> | 2014-08-15 15:07:15 +0200 |
commit | b546a944749f963c5b4e27765354df10ac531853 (patch) | |
tree | 96d972bc43dfea082f6a9f2a521595bdff876a76 /block/dmg.c | |
parent | 8dc7a7725bd6db2aa7e3c09b49bc21a1a25f40cb (diff) | |
download | qemu-b546a944749f963c5b4e27765354df10ac531853.tar.gz qemu-b546a944749f963c5b4e27765354df10ac531853.tar.bz2 qemu-b546a944749f963c5b4e27765354df10ac531853.zip |
dmg: Handle failure for potentially large allocations
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 dmg block driver.
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
Reviewed-by: Benoit Canet <benoit@irqsave.net>
Diffstat (limited to 'block/dmg.c')
-rw-r--r-- | block/dmg.c | 19 |
1 files changed, 13 insertions, 6 deletions
diff --git a/block/dmg.c b/block/dmg.c index 1e153cd76d..e455886d2b 100644 --- a/block/dmg.c +++ b/block/dmg.c @@ -284,8 +284,15 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags, } /* initialize zlib engine */ - s->compressed_chunk = g_malloc(max_compressed_size + 1); - s->uncompressed_chunk = g_malloc(512 * max_sectors_per_chunk); + s->compressed_chunk = qemu_try_blockalign(bs->file, + max_compressed_size + 1); + s->uncompressed_chunk = qemu_try_blockalign(bs->file, + 512 * max_sectors_per_chunk); + if (s->compressed_chunk == NULL || s->uncompressed_chunk == NULL) { + ret = -ENOMEM; + goto fail; + } + if (inflateInit(&s->zstream) != Z_OK) { ret = -EINVAL; goto fail; @@ -302,8 +309,8 @@ fail: g_free(s->lengths); g_free(s->sectors); g_free(s->sectorcounts); - g_free(s->compressed_chunk); - g_free(s->uncompressed_chunk); + qemu_vfree(s->compressed_chunk); + qemu_vfree(s->uncompressed_chunk); return ret; } @@ -426,8 +433,8 @@ static void dmg_close(BlockDriverState *bs) g_free(s->lengths); g_free(s->sectors); g_free(s->sectorcounts); - g_free(s->compressed_chunk); - g_free(s->uncompressed_chunk); + qemu_vfree(s->compressed_chunk); + qemu_vfree(s->uncompressed_chunk); inflateEnd(&s->zstream); } |