From nobody Tue Feb 10 19:14:44 2026 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=208.118.235.17; envelope-from=qemu-devel-bounces+importer=patchew.org@nongnu.org; helo=lists.gnu.org; Authentication-Results: mx.zohomail.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (208.118.235.17 [208.118.235.17]) by mx.zohomail.com with SMTPS id 1510680419841431.64964990331964; Tue, 14 Nov 2017 09:26:59 -0800 (PST) Received: from localhost ([::1]:60988 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEeyl-0007Qe-3U for importer@patchew.org; Tue, 14 Nov 2017 12:26:31 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:53518) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1eEewn-0005Om-Ex for qemu-devel@nongnu.org; Tue, 14 Nov 2017 12:24:30 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1eEewm-00047Y-9S for qemu-devel@nongnu.org; Tue, 14 Nov 2017 12:24:29 -0500 Received: from mx1.redhat.com ([209.132.183.28]:46314) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1eEewh-00043F-Rs; Tue, 14 Nov 2017 12:24:24 -0500 Received: from smtp.corp.redhat.com (int-mx06.intmail.prod.int.phx2.redhat.com [10.5.11.16]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id 08BF6C047B8C; Tue, 14 Nov 2017 17:24:23 +0000 (UTC) Received: from localhost (unknown [10.40.205.72]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 891E04C7; Tue, 14 Nov 2017 17:24:22 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Tue, 14 Nov 2017 18:23:58 +0100 Message-Id: <20171114172417.7654-2-mreitz@redhat.com> In-Reply-To: <20171114172417.7654-1-mreitz@redhat.com> References: <20171114172417.7654-1-mreitz@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.16 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 14 Nov 2017 17:24:23 +0000 (UTC) X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] [fuzzy] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 01/20] qcow2: Prevent allocating refcount blocks at offset 0 X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.21 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Peter Maydell , Alberto Garcia , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail: RSF_6 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" From: Alberto Garcia Each entry in the qcow2 cache contains an offset field indicating the location of the data in the qcow2 image. If the offset is 0 then it means that the entry contains no data and is available to be used when needed. Because of that it is not possible to store in the cache the first cluster of the qcow2 image (offset =3D 0). This is not a problem because that cluster always contains the qcow2 header and we're not using this cache for that. However, if the qcow2 image is corrupted it can happen that we try to allocate a new refcount block at offset 0, triggering this assertion and crashing QEMU: qcow2_cache_entry_mark_dirty: Assertion `c->entries[i].offset !=3D 0' fai= led This patch adds an explicit check for this scenario and a new test case. This problem was originally reported here: https://bugs.launchpad.net/qemu/+bug/1728615 Reported-by: R.Nageswara Sastry Signed-off-by: Alberto Garcia Reviewed-by: Max Reitz Message-id: 92a2fadd10d58b423f269c1d1a309af161cdc73f.1509718618.git.berto@i= galia.com Signed-off-by: Max Reitz --- block/qcow2-refcount.c | 7 +++++++ tests/qemu-iotests/060 | 11 +++++++++++ tests/qemu-iotests/060.out | 8 ++++++++ 3 files changed, 26 insertions(+) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index aa3fd6cf17..9059996c4b 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -367,6 +367,13 @@ static int alloc_refcount_block(BlockDriverState *bs, return new_block; } =20 + /* If we're allocating the block at offset 0 then something is wrong */ + if (new_block =3D=3D 0) { + qcow2_signal_corruption(bs, true, -1, -1, "Preventing invalid " + "allocation of refcount block at offset 0"= ); + return -EIO; + } + #ifdef DEBUG_ALLOC2 fprintf(stderr, "qcow2: Allocate refcount block %d for %" PRIx64 " at %" PRIx64 "\n", diff --git a/tests/qemu-iotests/060 b/tests/qemu-iotests/060 index 8e95c450eb..dead26aeaf 100755 --- a/tests/qemu-iotests/060 +++ b/tests/qemu-iotests/060 @@ -242,6 +242,17 @@ poke_file "$TEST_IMG" "$(($l2_offset+8))" "\x80\x00\x0= 0\x00\x00\x06\x2a\x00" # Should emit two error messages $QEMU_IO -c "discard 0 64k" -c "read 64k 64k" "$TEST_IMG" | _filter_qemu_io =20 +echo +echo "=3D=3D=3D Testing empty refcount table with valid L1 and L2 tables = =3D=3D=3D" +echo +_make_test_img 64M +$QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io +poke_file "$TEST_IMG" "$rt_offset" "\x00\x00\x00\x00\x00\x00\x00\x0= 0" +# Since the first data cluster is already allocated this triggers an +# allocation with an explicit offset (using qcow2_alloc_clusters_at()) +# causing a refcount block to be allocated at offset 0 +$QEMU_IO -c "write 0 128k" "$TEST_IMG" | _filter_qemu_io + # success, all done echo "*** done" rm -f $seq.full diff --git a/tests/qemu-iotests/060.out b/tests/qemu-iotests/060.out index 5ca3af491f..872719009c 100644 --- a/tests/qemu-iotests/060.out +++ b/tests/qemu-iotests/060.out @@ -181,4 +181,12 @@ qcow2: Marking image as corrupt: Cluster allocation of= fset 0x62a00 unaligned (L2 discard 65536/65536 bytes at offset 0 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) read failed: Input/output error + +=3D=3D=3D Testing empty refcount table with valid L1 and L2 tables =3D=3D= =3D + +Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 +wrote 65536/65536 bytes at offset 0 +64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) +qcow2: Marking image as corrupt: Preventing invalid allocation of refcount= block at offset 0; further corruption events will be suppressed +write failed: Input/output error *** done --=20 2.13.6