From nobody Fri Oct 24 13:14:18 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) 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; dkim=fail; spf=pass (zoho.com: domain of gnu.org designates 208.118.235.17 as permitted sender) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org Return-Path: Received: from lists.gnu.org (lists.gnu.org [208.118.235.17]) by mx.zohomail.com with SMTPS id 1519922302867477.20226770636475; Thu, 1 Mar 2018 08:38:22 -0800 (PST) Received: from localhost ([::1]:57987 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erRDj-0007Py-4b for importer@patchew.org; Thu, 01 Mar 2018 11:38:15 -0500 Received: from eggs.gnu.org ([2001:4830:134:3::10]:41350) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1erR46-0008BT-H3 for qemu-devel@nongnu.org; Thu, 01 Mar 2018 11:28:20 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1erR41-0004K5-GU for qemu-devel@nongnu.org; Thu, 01 Mar 2018 11:28:18 -0500 Received: from fanzine.igalia.com ([91.117.99.155]:54930) by eggs.gnu.org with esmtps (TLS1.0:RSA_AES_128_CBC_SHA1:16) (Exim 4.71) (envelope-from ) id 1erR40-0003uO-Tb; Thu, 01 Mar 2018 11:28:13 -0500 Received: from [194.100.51.2] (helo=perseus.local) by fanzine.igalia.com with esmtpsa (Cipher TLS1.2:ECDHE_RSA_AES_256_GCM_SHA384:256) (Exim) id 1erR3P-0003Dh-RY; Thu, 01 Mar 2018 17:27:35 +0100 Received: from berto by perseus.local with local (Exim 4.89) (envelope-from ) id 1erR36-0004Oh-VF; Thu, 01 Mar 2018 18:27:16 +0200 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=igalia.com; s=20170329; h=References:In-Reply-To:References:In-Reply-To:Message-Id:Date:Subject:Cc:To:From; bh=soRhI3HOwQgIzdDFduXWlQyyZejLosAlsFnasmofjXE=; b=BZFfbeG8EojCoh3QtPnegGwUcgT6Ke4KGw8TON/xed4uHzSggNAWmeXHbZdvV6PO1aagSsUrlIFYnvlbLTDjcQFYoiYszzlYS/hiFWfvsPjRxFEFpgX+EED5OuuQbsiYQVc4pXXbo1RiwcfKytM24rDBSvv5KPicrHfAFSaZgSV7krUedpcGvZr0sbKJqi3rBs+ZTaBezwbk5LziZlihsNWqQUuDm8v2/5iV07HVh1T4OG57CxQnPzYJrPNqm7kitroNpO6uVRO4Cv4LvUwmpcegHDk1jjtQcUmPpI7JpfqKNlXtboShNAedex6GbrnUHJo1iVpAq8S3J402J1XLmw==; From: Alberto Garcia To: qemu-devel@nongnu.org Date: Thu, 1 Mar 2018 18:27:13 +0200 Message-Id: X-Mailer: git-send-email 2.11.0 In-Reply-To: References: In-Reply-To: References: X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x (no timestamps) [generic] [fuzzy] X-Received-From: 91.117.99.155 Subject: [Qemu-devel] [PATCH 7/7] qcow2: Make qemu-img check detect corrupted L1 tables in snapshots 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 , Alberto Garcia , qemu-block@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZohoMail: RDKM_2 RSF_0 Z_629925259 SPT_0 Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" 'qemu-img check' cannot detect if a snapshot's L1 table is corrupted. This patch checks the table's offset and size and reports corruption if the values are not valid. This patch doesn't add code to fix that corruption yet, only to detect and report it. Signed-off-by: Alberto Garcia Reviewed-by: Eric Blake --- block/qcow2-refcount.c | 14 ++++++++++++++ tests/qemu-iotests/080 | 2 ++ tests/qemu-iotests/080.out | 20 ++++++++++++++++++++ 3 files changed, 36 insertions(+) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index dcb96e2b16..b1828d6fce 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -2019,6 +2019,20 @@ static int calculate_refcounts(BlockDriverState *bs,= BdrvCheckResult *res, /* snapshots */ for (i =3D 0; i < s->nb_snapshots; i++) { sn =3D s->snapshots + i; + if (offset_into_cluster(s, sn->l1_table_offset)) { + fprintf(stderr, "ERROR snapshot %s (%s) l1_offset=3D%#" PRIx64= ": " + "L1 table is not cluster aligned; snapshot table entry= " + "corrupted\n", sn->id_str, sn->name, sn->l1_table_offs= et); + res->corruptions++; + continue; + } + if (sn->l1_size > QCOW_MAX_L1_SIZE / sizeof(uint64_t)) { + fprintf(stderr, "ERROR snapshot %s (%s) l1_size=3D%#" PRIx32 "= : " + "L1 table is too large; snapshot table entry corrupted= \n", + sn->id_str, sn->name, sn->l1_size); + res->corruptions++; + continue; + } ret =3D check_refcounts_l1(bs, res, refcount_table, nb_clusters, sn->l1_table_offset, sn->l1_size, 0, fix); if (ret < 0) { diff --git a/tests/qemu-iotests/080 b/tests/qemu-iotests/080 index f8e7d6f4df..4dbe68e950 100755 --- a/tests/qemu-iotests/080 +++ b/tests/qemu-iotests/080 @@ -182,6 +182,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_offset" "\x00\x= 00\x00\x00\x00\x40\x02\x0 -c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir { $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir { $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir +_check_test_img =20 echo echo "=3D=3D Invalid snapshot L1 table size =3D=3D" @@ -195,6 +196,7 @@ poke_file "$TEST_IMG" "$offset_snap1_l1_size" "\x10\x00= \x00\x00" -c 'write 0 4k'; } 2>&1 | _filter_qemu_io | _filter_testdir { $QEMU_IMG snapshot -a test $TEST_IMG; } 2>&1 | _filter_testdir { $QEMU_IMG snapshot -d test $TEST_IMG; } 2>&1 | _filter_testdir +_check_test_img =20 # success, all done echo "*** done" diff --git a/tests/qemu-iotests/080.out b/tests/qemu-iotests/080.out index f16fd59053..2dad7f46a0 100644 --- a/tests/qemu-iotests/080.out +++ b/tests/qemu-iotests/080.out @@ -69,6 +69,16 @@ Failed to flush the refcount block cache: Invalid argume= nt write failed: Invalid argument qemu-img: Could not apply snapshot 'test': Failed to load snapshot: Invali= d argument qemu-img: Could not delete snapshot 'test': Snapshot L1 table offset inval= id +ERROR snapshot 1 (test) l1_offset=3D0x400200: L1 table is not cluster alig= ned; snapshot table entry corrupted +Leaked cluster 4 refcount=3D2 reference=3D1 +Leaked cluster 5 refcount=3D2 reference=3D1 +Leaked cluster 6 refcount=3D1 reference=3D0 + +1 errors were found on the image. +Data may be corrupted, or further writes to the image may corrupt it. + +3 leaked clusters were found on the image. +This means waste of disk space, but no harm to data. =20 =3D=3D Invalid snapshot L1 table size =3D=3D Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D67108864 @@ -80,4 +90,14 @@ Failed to flush the refcount block cache: File too large write failed: File too large qemu-img: Could not apply snapshot 'test': Failed to load snapshot: File t= oo large qemu-img: Could not delete snapshot 'test': Snapshot L1 table too large +ERROR snapshot 1 (test) l1_size=3D0x10000000: L1 table is too large; snaps= hot table entry corrupted +Leaked cluster 4 refcount=3D2 reference=3D1 +Leaked cluster 5 refcount=3D2 reference=3D1 +Leaked cluster 6 refcount=3D1 reference=3D0 + +1 errors were found on the image. +Data may be corrupted, or further writes to the image may corrupt it. + +3 leaked clusters were found on the image. +This means waste of disk space, but no harm to data. *** done --=20 2.11.0