mirror of
https://gitlab.com/qemu-project/qemu
synced 2024-09-06 18:05:37 +00:00
dmg: sanitize chunk length and sectorcount (CVE-2014-0145)
Chunk length and sectorcount are used for decompression buffers as well as the bdrv_pread() count argument. Ensure that they have reasonable values so neither memory allocation nor conversion from uint64_t to int will cause problems. Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com> Signed-off-by: Kevin Wolf <kwolf@redhat.com> Reviewed-by: Max Reitz <mreitz@redhat.com> Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
This commit is contained in:
parent
eb71803b04
commit
c165f77580
24
block/dmg.c
24
block/dmg.c
|
@ -27,6 +27,14 @@
|
|||
#include "qemu/module.h"
|
||||
#include <zlib.h>
|
||||
|
||||
enum {
|
||||
/* Limit chunk sizes to prevent unreasonable amounts of memory being used
|
||||
* or truncating when converting to 32-bit types
|
||||
*/
|
||||
DMG_LENGTHS_MAX = 64 * 1024 * 1024, /* 64 MB */
|
||||
DMG_SECTORCOUNTS_MAX = DMG_LENGTHS_MAX / 512,
|
||||
};
|
||||
|
||||
typedef struct BDRVDMGState {
|
||||
CoMutex lock;
|
||||
/* each chunk contains a certain number of sectors,
|
||||
|
@ -208,6 +216,14 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
|
|||
}
|
||||
offset += 8;
|
||||
|
||||
if (s->sectorcounts[i] > DMG_SECTORCOUNTS_MAX) {
|
||||
error_report("sector count %" PRIu64 " for chunk %u is "
|
||||
"larger than max (%u)",
|
||||
s->sectorcounts[i], i, DMG_SECTORCOUNTS_MAX);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
ret = read_uint64(bs, offset, &s->offsets[i]);
|
||||
if (ret < 0) {
|
||||
goto fail;
|
||||
|
@ -221,6 +237,14 @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
|
|||
}
|
||||
offset += 8;
|
||||
|
||||
if (s->lengths[i] > DMG_LENGTHS_MAX) {
|
||||
error_report("length %" PRIu64 " for chunk %u is larger "
|
||||
"than max (%u)",
|
||||
s->lengths[i], i, DMG_LENGTHS_MAX);
|
||||
ret = -EINVAL;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (s->lengths[i] > max_compressed_size) {
|
||||
max_compressed_size = s->lengths[i];
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue