53 lines
1.8 KiB
Diff
53 lines
1.8 KiB
Diff
|
From: Kevin Wolf <kwolf@redhat.com>
|
||
|
Date: Wed, 26 Mar 2014 13:06:08 +0100
|
||
|
Subject: [PATCH] parallels: Fix catalog size integer overflow (CVE-2014-0143)
|
||
|
|
||
|
The first test case would cause a huge memory allocation, leading to a
|
||
|
qemu abort; the second one to a too small malloc() for the catalog
|
||
|
(smaller than s->catalog_size), which causes a read-only out-of-bounds
|
||
|
array access and on big endian hosts an endianess conversion for an
|
||
|
undefined memory area.
|
||
|
|
||
|
The sample image used here is not an original Parallels image. It was
|
||
|
created using an hexeditor on the basis of the struct that qemu uses.
|
||
|
Good enough for trying to crash the driver, but not for ensuring
|
||
|
compatibility.
|
||
|
|
||
|
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
||
|
Reviewed-by: Max Reitz <mreitz@redhat.com>
|
||
|
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
|
||
|
(cherry picked from commit afbcc40bee4ef51731102d7d4b499ee12fc182e1)
|
||
|
|
||
|
Conflicts:
|
||
|
tests/qemu-iotests/common
|
||
|
tests/qemu-iotests/group
|
||
|
---
|
||
|
block/parallels.c | 7 ++++++-
|
||
|
1 file changed, 6 insertions(+), 1 deletion(-)
|
||
|
|
||
|
diff --git a/block/parallels.c b/block/parallels.c
|
||
|
index 18b3ac0..bad47f4 100644
|
||
|
--- a/block/parallels.c
|
||
|
+++ b/block/parallels.c
|
||
|
@@ -49,7 +49,7 @@ typedef struct BDRVParallelsState {
|
||
|
CoMutex lock;
|
||
|
|
||
|
uint32_t *catalog_bitmap;
|
||
|
- int catalog_size;
|
||
|
+ unsigned int catalog_size;
|
||
|
|
||
|
int tracks;
|
||
|
} BDRVParallelsState;
|
||
|
@@ -93,6 +93,11 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags)
|
||
|
s->tracks = le32_to_cpu(ph.tracks);
|
||
|
|
||
|
s->catalog_size = le32_to_cpu(ph.catalog_entries);
|
||
|
+ if (s->catalog_size > INT_MAX / 4) {
|
||
|
+ fprintf(stderr, "Catalog too large");
|
||
|
+ ret = -EFBIG;
|
||
|
+ goto fail;
|
||
|
+ }
|
||
|
s->catalog_bitmap = g_malloc(s->catalog_size * 4);
|
||
|
|
||
|
ret = bdrv_pread(bs->file, 64, s->catalog_bitmap, s->catalog_size * 4);
|