From patchwork Mon Jul 25 18:34:35 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: "Serge E. Hallyn" X-Patchwork-Id: 106736 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from lists.gnu.org (lists.gnu.org [140.186.70.17]) (using TLSv1 with cipher AES256-SHA (256/256 bits)) (Client did not present a certificate) by ozlabs.org (Postfix) with ESMTPS id 7BC06B6FAF for ; Tue, 26 Jul 2011 05:11:53 +1000 (EST) Received: from localhost ([::1]:44204 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlQZC-0000X7-VT for incoming@patchwork.ozlabs.org; Mon, 25 Jul 2011 15:11:50 -0400 Received: from eggs.gnu.org ([140.186.70.92]:52876) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlQZ7-0000Wp-LR for qemu-devel@nongnu.org; Mon, 25 Jul 2011 15:11:46 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1QlQZ4-00077g-Sv for qemu-devel@nongnu.org; Mon, 25 Jul 2011 15:11:45 -0400 Received: from 50-56-35-84.static.cloud-ips.com ([50.56.35.84]:43475 helo=mail) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1QlQZ4-00077N-QM for qemu-devel@nongnu.org; Mon, 25 Jul 2011 15:11:42 -0400 Received: by mail (Postfix, from userid 1000) id 439C8100EE3; Mon, 25 Jul 2011 18:34:35 +0000 (UTC) Date: Mon, 25 Jul 2011 18:34:35 +0000 From: "Serge E. Hallyn" To: qemu-devel@nongnu.org Message-ID: <20110725183435.GA26649@hallyn.com> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.20 (2009-06-14) X-detected-operating-system: by eggs.gnu.org: Genre and OS details not recognized. X-Received-From: 50.56.35.84 Subject: [Qemu-devel] [PATCH 1/1] block/vpc.c: Detect too-large vpc file X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.14 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org 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 --- block/vpc.c | 8 +++++++- 1 files changed, 7 insertions(+), 1 deletions(-) diff --git a/block/vpc.c b/block/vpc.c index 56865da..fdd5236 100644 --- a/block/vpc.c +++ b/block/vpc.c @@ -156,6 +156,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; @@ -176,6 +177,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; @@ -222,7 +228,7 @@ static int vpc_open(BlockDriverState *bs, int flags) return 0; fail: - return -1; + return err; } /*