From 26dad6065e17caa63ff13483f9285f00e37e0894 Mon Sep 17 00:00:00 2001 Message-Id: <26dad6065e17caa63ff13483f9285f00e37e0894.1378813438.git.minovotn@redhat.com> In-Reply-To: References: From: Jeffrey Cody Date: Wed, 28 Aug 2013 13:14:48 +0200 Subject: [PATCH 06/13] block/vpc.c: Detect too-large vpc file RH-Author: Jeffrey Cody Message-id: Patchwork-id: 53841 O-Subject: [RHEL6.5 qemu-kvm PATCH 06/13] block/vpc.c: Detect too-large vpc file Bugzilla: 999779 RH-Acked-by: Stefan Hajnoczi RH-Acked-by: Kevin Wolf RH-Acked-by: Fam Zheng From: "Serge E. Hallyn" VHD files technically can be up to 2Tb, but virtual pc is limited to 127G. Currently qemu-img refused to create vpc files > 127G, but it is failing to return error when converting from a non-vpc VHD file which is >127G. It returns success, but creates a truncated converted image. Also, qemu-img info claims the vpc file is 127G (and clean). This patch detects a too-large vpc file and returns -EFBIG. Without this patch, ============================================================= root@ip-10-38-123-242:~/qemu-fixed# qemu-img info /mnt/140g-dynamic.vhd image: /mnt/140g-dynamic.vhd file format: vpc virtual size: 127G (136899993600 bytes) disk size: 284K root@ip-10-38-123-242:~/qemu-fixed# qemu-img convert -f vpc -O raw /mnt/140g-dynamic.vhd /mnt/y root@ip-10-38-123-242:~/qemu-fixed# echo $? 0 root@ip-10-38-123-242:~/qemu-fixed# qemu-img info /mnt/y image: /mnt/y file format: raw virtual size: 127G (136899993600 bytes) disk size: 0 ============================================================= (The 140G image was truncated with no warning or error.) With the patch, I get: ============================================================= root@ip-10-38-123-242:~/qemu-fixed# ./qemu-img info /mnt/140g-dynamic.vhd qemu-img: Could not open '/mnt/140g-dynamic.vhd': File too large root@ip-10-38-123-242:~/qemu-fixed# ./qemu-img convert -f vpc -O raw /mnt/140g-dynamic.vhd /mnt/y qemu-img: Could not open '/mnt/140g-dynamic.vhd': File too large qemu-img: Could not open '/mnt/140g-dynamic.vhd' ============================================================= See https://bugs.launchpad.net/qemu/+bug/814222 for details. Signed-off-by: Serge Hallyn Signed-off-by: Kevin Wolf (cherry picked from commit efc8243d00ab4cf4fa05a9be93233cb883b7caa0) Signed-off-by: Jeff Cody --- block/vpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) Signed-off-by: Michal Novotny --- block/vpc.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/block/vpc.c b/block/vpc.c index a1e6142..75a2f23 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -157,6 +157,7 @@ static int vpc_open(BlockDriverState *bs, int flags) struct vhd_dyndisk_header* dyndisk_header; uint8_t buf[HEADER_SIZE]; uint32_t checksum; + int err = -1; if (bdrv_pread(bs->file, 0, s->footer_buf, HEADER_SIZE) != HEADER_SIZE) goto fail; @@ -180,6 +181,11 @@ static int vpc_open(BlockDriverState *bs, int flags) bs->total_sectors = (int64_t) be16_to_cpu(footer->cyls) * footer->heads * footer->secs_per_cyl; + if (bs->total_sectors >= 65535 * 16 * 255) { + err = -EFBIG; + goto fail; + } + if (bdrv_pread(bs->file, be64_to_cpu(footer->data_offset), buf, HEADER_SIZE) != HEADER_SIZE) goto fail; @@ -227,7 +233,7 @@ static int vpc_open(BlockDriverState *bs, int flags) qemu_co_mutex_init(&s->lock); return 0; fail: - return -1; + return err; } static int vpc_reopen_prepare(BDRVReopenState *state, -- 1.7.11.7