From: Jeff Cody <jcody@redhat.com>
To: Stefan Weil <sw@weilnetz.de>
Cc: Kevin Wolf <kwolf@redhat.com>,
pmatouse@redhat.com, qemu-devel@nongnu.org,
Stefan Hajnoczi <stefanha@redhat.com>,
qemu-stable@nongnu.org
Subject: Re: [Qemu-devel] [PATCH for-2.0 16/47] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144)
Date: Thu, 27 Mar 2014 14:52:42 -0400 [thread overview]
Message-ID: <20140327185242.GE21833@localhost.localdomain> (raw)
In-Reply-To: <53331AA9.5040506@weilnetz.de>
On Wed, Mar 26, 2014 at 07:21:29PM +0100, Stefan Weil wrote:
> Hi Stefan, hi Jeff,
>
> please cc me for future block/vdi.c related patches. See more comments
> below.
>
> Am 26.03.2014 13:05, schrieb Stefan Hajnoczi:
> > From: Jeff Cody <jcody@redhat.com>
> >
> > The maximum blocks_in_image is 0xffffffff / 4, which also limits the
> > maximum disk_size for a VDI image.
> >
> > Signed-off-by: Jeff Cody <jcody@redhat.com>
> > Signed-off-by: Kevin Wolf <kwolf@redhat.com>
> > ---
> > block/vdi.c | 28 +++++++++++++++++++++++++---
> > 1 file changed, 25 insertions(+), 3 deletions(-)
> >
> > diff --git a/block/vdi.c b/block/vdi.c
> > index ac9a025..718884d 100644
> > --- a/block/vdi.c
> > +++ b/block/vdi.c
> > @@ -120,6 +120,12 @@ typedef unsigned char uuid_t[16];
> >
> > #define VDI_IS_ALLOCATED(X) ((X) < VDI_DISCARDED)
> >
> > +#define VDI_BLOCK_SIZE (1 * MiB)
>
> There is already DEFAULT_CLUSTER_SIZE which should be used instead of
> VDI_BLOCK_SIZE.
>
OK, great.
> > +/* max blocks in image is (0xffffffff / 4) */
> > +#define VDI_BLOCKS_IN_IMAGE_MAX 0x3fffffff
>
> This looks wrong. I think it should be (SIZE_MAX / sizeof(uint32_t)). 64
> bit platforms with a 64 bit size_t allow more blocks.
>
I looked around, and I could not find a definitive source for a VDI
specification. Do you know if there is a specified max size for a VDI
image?
If we assume support for 64 bit size_t values, that may or may not be
within the VDI spec (I don't know). But I think there are practical
limits we need to set in place with our current driver implementation,
as we currently dynamically allocate the block cache based on
blocks_in_image * 4 * SECTOR_SIZE.
Of course, this needs to be tempered with the notion of not breaking
existing support for VDI images that are in-spec.
> > +#define VDI_DISK_SIZE_MAX ((uint64_t)VDI_BLOCKS_IN_IMAGE_MAX * \
> > + (uint64_t)VDI_BLOCK_SIZE)
> > +
>
> This macro cannot be used because the block size might have a non
> default value.
>
The VDI driver does not currently support non-default block sizes.
There is partial support for vdi image creation for variable block
sizes, but it is commented out (with a note saying it is untested).
But for image open, the vdi_open() function currently has a hard check
for header.block_size != 1MB.
So, the above macro is in line with what the VDI driver supports, I
believe.
This was meant to be a bug-fix only, so adding in new support for
non-default block sizes wasn't the original intent.
> > #if !defined(CONFIG_UUID)
> > static inline void uuid_generate(uuid_t out)
> > {
> > @@ -385,6 +391,11 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
> > vdi_header_print(&header);
> > #endif
> >
> > + if (header.disk_size > VDI_DISK_SIZE_MAX) {
>
> Here error_setg is missing. The style does not match the other checks.
> More changes are needed because VDI_DISK_SIZE_MAX cannot be used.
>
I agree error_setg could be useful here.
> > + ret = -EINVAL;
> > + goto fail;
> > + }
> > +
> > if (header.disk_size % SECTOR_SIZE != 0) {
> > /* 'VBoxManage convertfromraw' can create images with odd disk sizes.
> > We accept them but round the disk size to the next multiple of
> > @@ -420,9 +431,9 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
> > header.sector_size, SECTOR_SIZE);
> > ret = -ENOTSUP;
> > goto fail;
> > - } else if (header.block_size != 1 * MiB) {
> > + } else if (header.block_size != VDI_BLOCK_SIZE) {
> > error_setg(errp, "unsupported VDI image (sector size %u is not %u)",
>
> Here is a copy+paste bug which was recently introduced.
>
Yes, the error message should be modified: s/sector/block
> > - header.block_size, 1 * MiB);
> > + header.block_size, VDI_BLOCK_SIZE);
>
> Replace VDI_BLOCK_SIZE by the existing macro here.
>
OK
> > ret = -ENOTSUP;
> > goto fail;
> > } else if (header.disk_size >
> > @@ -441,6 +452,10 @@ static int vdi_open(BlockDriverState *bs, QDict *options, int flags,
> > error_setg(errp, "unsupported VDI image (non-NULL parent UUID)");
> > ret = -ENOTSUP;
> > goto fail;
> > + } else if (header.blocks_in_image > VDI_BLOCKS_IN_IMAGE_MAX) {
> > + error_setg(errp, "unsupported VDI image (too many blocks)");
>
> Fix test and improve error message (show limit) here.
>
> > + ret = -ENOTSUP;
> > + goto fail;
> > } > > > > bs->total_sectors = header.disk_size / SECTOR_SIZE;
> > @@ -689,11 +704,17 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
> > options++;
> > }
> >
> > + if (bytes > VDI_DISK_SIZE_MAX) {
>
> Dto.
>
> > + result = -EINVAL;
> > + goto exit;
> > + }
> > +
> > fd = qemu_open(filename,
> > O_WRONLY | O_CREAT | O_TRUNC | O_BINARY | O_LARGEFILE,
> > 0644);
> > if (fd < 0) {
> > - return -errno;
> > + result = -errno;
> > + goto exit;
> > }
> >
> > /* We need enough blocks to store the given disk size,
> > @@ -754,6 +775,7 @@ static int vdi_create(const char *filename, QEMUOptionParameter *options,
> > result = -errno;
> > }
> >
> > +exit:
>
> Is goto+label better than a simple return statement?
>
In this case, maybe not.
> > return result;
> > }
> >
> >
>
> Do we need this patch for QEMU 2.0? For 32 bit systems, the image size
> limit is 1000 TB, and that image would need 4 GB for the block cache in
> memory. Are such image sizes used anywhere? For 64 bit systems, the
> limit will be much higher.
>
I don't know what systems are in use in the wild. But since we
allocate block cache to fit the entire cache in RAM currently, that
does open us up to potentially allocating a lot of memory, based on
what the image file header specifies.
That is a reason to keep the maximum blocks_in_image size bounded to
the size of 0x3fffffff. With an unbound blocks_in_image size (except
to UINT32_MAX), the driver would potentially attempt to allocate 16GB
of RAM, if qemu attempts to open a VDI image file with such a header.
Of course, if the VDI spec allows for image sizes > 1000TB, then maybe
you are right and we should allow it, even if it means a lot of RAM
allocation. I don't know.
I think allowing blocks_in_images and block_size to be more variable
is probably a good idea, but I think that if we are going to allow
that, we should probably modify how we handle the block cache. And to
add that support in would seem more in line with a feature addition.
next prev parent reply other threads:[~2014-03-27 18:53 UTC|newest]
Thread overview: 104+ messages / expand[flat|nested] mbox.gz Atom feed top
2014-03-26 12:05 [Qemu-devel] [PATCH for-2.0 00/47] block: image format input validation fixes Stefan Hajnoczi
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 01/47] qemu-iotests: add ./check -cloop support Stefan Hajnoczi
2014-03-26 19:25 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 02/47] qemu-iotests: add cloop input validation tests Stefan Hajnoczi
2014-03-26 19:31 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 03/47] block/cloop: validate block_size header field (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 19:38 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 04/47] block/cloop: prevent offsets_size integer overflow (CVE-2014-0143) Stefan Hajnoczi
2014-03-26 19:41 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 05/47] block/cloop: refuse images with huge offsets arrays (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 19:43 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 06/47] block/cloop: refuse images with bogus offsets (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 19:48 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 07/47] block/cloop: fix offsets[] size off-by-one Stefan Hajnoczi
2014-03-26 19:51 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 08/47] qemu-iotests: Support for bochs format Stefan Hajnoczi
2014-03-26 19:58 ` Max Reitz
2014-04-01 17:01 ` Kevin Wolf
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 09/47] bochs: Unify header structs and make them QEMU_PACKED Stefan Hajnoczi
2014-03-26 19:59 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 10/47] bochs: Use unsigned variables for offsets and sizes (CVE-2014-0147) Stefan Hajnoczi
2014-03-26 20:02 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 11/47] bochs: Check catalog_size header field (CVE-2014-0143) Stefan Hajnoczi
2014-03-26 20:09 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 12/47] bochs: Check extent_size header field (CVE-2014-0142) Stefan Hajnoczi
2014-03-26 20:13 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 13/47] bochs: Fix bitmap offset calculation Stefan Hajnoczi
2014-03-26 20:14 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 14/47] vpc/vhd: add bounds check for max_table_entries and block_size (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:15 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 15/47] vpc: Validate block size (CVE-2014-0142) Stefan Hajnoczi
2014-03-26 20:22 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 16/47] vdi: add bounds checks for blocks_in_image and disk_size header fields (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 18:21 ` Stefan Weil
2014-03-27 18:52 ` Jeff Cody [this message]
2014-03-27 19:58 ` Stefan Weil
2014-03-28 9:07 ` Stefan Hajnoczi
2014-03-28 12:52 ` Jeff Cody
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 17/47] vhdx: Bounds checking for block_size and logical_sector_size (CVE-2014-0148) Stefan Hajnoczi
2014-03-26 20:26 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 18/47] curl: check data size before memcpy to local buffer. (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:29 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 19/47] qcow2: Check header_length (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:40 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 20/47] qcow2: Check backing_file_offset (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:46 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 21/47] qcow2: Check refcount table size (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:50 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 22/47] qcow2: Validate refcount table offset Stefan Hajnoczi
2014-03-26 20:52 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 23/47] qcow2: Validate snapshot table offset/size (CVE-2014-0144) Stefan Hajnoczi
2014-03-26 20:59 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 24/47] qcow2: Validate active L1 table offset and size (CVE-2014-0144) Stefan Hajnoczi
2014-03-28 22:36 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 25/47] qcow2: Fix backing file name length check Stefan Hajnoczi
2014-03-28 22:39 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 26/47] qcow2: Don't rely on free_cluster_index in alloc_refcount_block() (CVE-2014-0147) Stefan Hajnoczi
2014-03-28 17:06 ` [Qemu-devel] [PATCH v2 " Stefan Hajnoczi
2014-03-28 22:51 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 27/47] qcow2: Avoid integer overflow in get_refcount (CVE-2014-0143) Stefan Hajnoczi
2014-03-28 22:58 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 28/47] qcow2: Check new refcount table size on growth Stefan Hajnoczi
2014-03-28 23:00 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 29/47] qcow2: Fix types in qcow2_alloc_clusters and alloc_clusters_noref Stefan Hajnoczi
2014-03-28 23:04 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 30/47] qcow2: Protect against some integer overflows in bdrv_check Stefan Hajnoczi
2014-03-28 23:06 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 31/47] qcow2: Fix new L1 table size check (CVE-2014-0143) Stefan Hajnoczi
2014-03-28 23:07 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 32/47] dmg: coding style and indentation cleanup Stefan Hajnoczi
2014-03-28 23:08 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 33/47] dmg: prevent out-of-bounds array access on terminator Stefan Hajnoczi
2014-03-28 23:10 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 34/47] dmg: drop broken bdrv_pread() loop Stefan Hajnoczi
2014-03-28 23:10 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 35/47] dmg: use appropriate types when reading chunks Stefan Hajnoczi
2014-03-28 23:10 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 36/47] dmg: sanitize chunk length and sectorcount (CVE-2014-0145) Stefan Hajnoczi
2014-03-28 23:11 ` Max Reitz
2014-03-26 12:05 ` [Qemu-devel] [PATCH for-2.0 37/47] dmg: use uint64_t consistently for sectors and lengths Stefan Hajnoczi
2014-03-28 23:11 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 38/47] dmg: prevent chunk buffer overflow (CVE-2014-0145) Stefan Hajnoczi
2014-03-28 23:12 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 39/47] block: vdi bounds check qemu-io tests Stefan Hajnoczi
2014-03-28 23:22 ` Max Reitz
2014-03-29 0:26 ` Jeff Cody
2014-03-31 7:12 ` Stefan Hajnoczi
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 40/47] block: Limit request size (CVE-2014-0143) Stefan Hajnoczi
2014-03-28 23:24 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 41/47] qcow2: Fix copy_sectors() with VM state Stefan Hajnoczi
2014-03-28 23:33 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 42/47] qcow2: Fix NULL dereference in qcow2_open() error path (CVE-2014-0146) Stefan Hajnoczi
2014-03-28 23:35 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 43/47] qcow2: Fix L1 allocation size in qcow2_snapshot_load_tmp() (CVE-2014-0145) Stefan Hajnoczi
2014-03-28 23:38 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 44/47] qcow2: Check maximum L1 size in qcow2_snapshot_load_tmp() (CVE-2014-0143) Stefan Hajnoczi
2014-03-28 23:39 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 45/47] qcow2: Limit snapshot table size Stefan Hajnoczi
2014-03-28 23:41 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 46/47] parallels: Fix catalog size integer overflow (CVE-2014-0143) Stefan Hajnoczi
2014-03-28 23:45 ` Max Reitz
2014-03-26 12:06 ` [Qemu-devel] [PATCH for-2.0 47/47] parallels: Sanity check for s->tracks (CVE-2014-0142) Stefan Hajnoczi
2014-03-28 23:46 ` Max Reitz
2014-04-01 13:49 ` [Qemu-devel] [PATCH for-2.0 00/47] block: image format input validation fixes Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20140327185242.GE21833@localhost.localdomain \
--to=jcody@redhat.com \
--cc=kwolf@redhat.com \
--cc=pmatouse@redhat.com \
--cc=qemu-devel@nongnu.org \
--cc=qemu-stable@nongnu.org \
--cc=stefanha@redhat.com \
--cc=sw@weilnetz.de \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).