From nobody Thu Dec 18 13:18:45 2025 Delivered-To: importer@patchew.org Received-SPF: temperror (zoho.com: Error in retrieving data from DNS) client-ip=209.51.188.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; dmarc=fail(p=none dis=none) header.from=redhat.com ARC-Seal: i=1; a=rsa-sha256; t=1557242460; cv=none; d=zoho.com; s=zohoarc; b=VJv7E0bMsTD1v5Pmhm1+Z5rtbB4z3+RfL9pSCQ+lZxEeljDi0I5A8Cxt59XKjk4T/CBKDPWnzegvj7ERop39IqwNGJgUGj0t5ytDjObFF7P3IEkKIq6C3xeb+vI5arA1zbOg3GMw3fN2DfoXT4LNzbUaWy4XgJm8O2Tbin1wUgA= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zoho.com; s=zohoarc; t=1557242460; h=Content-Transfer-Encoding:Cc:Date:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Archive:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:To:ARC-Authentication-Results; bh=OgEhsAhPGch+NlaeYQpmJfZqtVqXy66OXWyC+Unbl/M=; b=dUGEKKx0LeGtoLB8ir8d57YGrqNjvsoKnCVUQv3812QlwiHgjPuO8pLEsKV4AbKrYSCDtPpBLbu9d8rxiqp/pszkXVPd9QeSmk3j/xpeEAmbFpG7lAzQ2ZzB95VkgxWtwxiykGnhGe2IFpJv5WMoTnVDPZDeADenPjq8LSuAryk= ARC-Authentication-Results: i=1; mx.zoho.com; spf=temperror (zoho.com: Error in retrieving data from DNS) smtp.mailfrom=qemu-devel-bounces+importer=patchew.org@nongnu.org; dmarc=fail header.from= (p=none dis=none) header.from= Return-Path: Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) by mx.zohomail.com with SMTPS id 1557242460022887.7182562630652; Tue, 7 May 2019 08:21:00 -0700 (PDT) Received: from localhost ([127.0.0.1]:48481 helo=lists.gnu.org) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hO1tY-0000Zu-RS for importer@patchew.org; Tue, 07 May 2019 11:20:40 -0400 Received: from eggs.gnu.org ([209.51.188.92]:58167) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1hO1rX-0007s1-MT for qemu-devel@nongnu.org; Tue, 07 May 2019 11:18:36 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1hO1rW-0003u1-E1 for qemu-devel@nongnu.org; Tue, 07 May 2019 11:18:35 -0400 Received: from mx1.redhat.com ([209.132.183.28]:39430) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1hO1rQ-0003oX-KH; Tue, 07 May 2019 11:18:30 -0400 Received: from smtp.corp.redhat.com (int-mx04.intmail.prod.int.phx2.redhat.com [10.5.11.14]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by mx1.redhat.com (Postfix) with ESMTPS id CBBC9C04FFF1; Tue, 7 May 2019 15:18:26 +0000 (UTC) Received: from localhost (unknown [10.40.205.217]) by smtp.corp.redhat.com (Postfix) with ESMTPS id 6356F5D9CC; Tue, 7 May 2019 15:18:26 +0000 (UTC) From: Max Reitz To: qemu-block@nongnu.org Date: Tue, 7 May 2019 17:18:10 +0200 Message-Id: <20190507151819.17401-3-mreitz@redhat.com> In-Reply-To: <20190507151819.17401-1-mreitz@redhat.com> References: <20190507151819.17401-1-mreitz@redhat.com> MIME-Version: 1.0 X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.5.16 (mx1.redhat.com [10.5.110.31]); Tue, 07 May 2019 15:18:26 +0000 (UTC) Content-Transfer-Encoding: quoted-printable X-detected-operating-system: by eggs.gnu.org: GNU/Linux 2.2.x-3.x [generic] X-Received-From: 209.132.183.28 Subject: [Qemu-devel] [PULL 02/11] qcow2-refcount: avoid eating RAM 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 , qemu-devel@nongnu.org, Max Reitz Errors-To: qemu-devel-bounces+importer=patchew.org@nongnu.org Sender: "Qemu-devel" Content-Type: text/plain; charset="utf-8" From: Vladimir Sementsov-Ogievskiy qcow2_inc_refcounts_imrt() (through realloc_refcount_array()) can eat an unpredictable amount of memory on corrupted table entries, which are referencing regions far beyond the end of file. Prevent this, by skipping such regions from further processing. Interesting that iotest 138 checks exactly the behavior which we fix here. So, change the test appropriately. Signed-off-by: Vladimir Sementsov-Ogievskiy Reviewed-by: Max Reitz Message-id: 20190227131433.197063-3-vsementsov@virtuozzo.com Signed-off-by: Max Reitz --- block/qcow2-refcount.c | 19 +++++++++++++++++++ tests/qemu-iotests/138 | 12 +++++------- tests/qemu-iotests/138.out | 5 ++++- 3 files changed, 28 insertions(+), 8 deletions(-) diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c index ed3d8ebd57..21e50dacf4 100644 --- a/block/qcow2-refcount.c +++ b/block/qcow2-refcount.c @@ -1520,12 +1520,31 @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, = BdrvCheckResult *res, { BDRVQcow2State *s =3D bs->opaque; uint64_t start, last, cluster_offset, k, refcount; + int64_t file_len; int ret; =20 if (size <=3D 0) { return 0; } =20 + file_len =3D bdrv_getlength(bs->file->bs); + if (file_len < 0) { + return file_len; + } + + /* + * Last cluster of qcow2 image may be semi-allocated, so it may be OK = to + * reference some space after file end but it should be less than one + * cluster. + */ + if (offset + size - file_len >=3D s->cluster_size) { + fprintf(stderr, "ERROR: counting reference for region exceeding th= e " + "end of the file by one cluster or more: offset 0x%" PRIx64 + " size 0x%" PRIx64 "\n", offset, size); + res->corruptions++; + return 0; + } + start =3D start_of_cluster(s, offset); last =3D start_of_cluster(s, offset + size - 1); for(cluster_offset =3D start; cluster_offset <=3D last; diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138 index f353ac8219..6a731370db 100755 --- a/tests/qemu-iotests/138 +++ b/tests/qemu-iotests/138 @@ -54,15 +54,13 @@ $QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io # Put the data cluster at a multiple of 2 TB, resulting in the image appar= ently # having a multiple of 2^32 clusters # (To be more specific: It is at 32 PB) -poke_file "$TEST_IMG" 2048 "\x80\x80\x00\x00\x00\x00\x00\x00" +poke_file "$TEST_IMG" $((2048 + 8)) "\x00\x80\x00\x00\x00\x00\x00\x00" =20 # An offset of 32 PB results in qemu-img check having to allocate an in-me= mory -# refcount table of 128 TB (16 bit refcounts, 512 byte clusters). -# This should be generally too much for any system and thus fail. -# What this test is checking is that the qcow2 driver actually tries to al= locate -# such a large amount of memory (and is consequently aborting) instead of = having -# truncated the cluster count somewhere (which would result in much less m= emory -# being allocated and then a segfault occurring). +# refcount table of 128 TB (16 bit refcounts, 512 byte clusters), if qemu-= img +# don't check that referenced data cluster is far beyond the end of file. +# But starting from 4.0, qemu-img does this check, and instead of "Cannot +# allocate memory", we have an error showing that l2 entry is invalid. _check_test_img =20 # success, all done diff --git a/tests/qemu-iotests/138.out b/tests/qemu-iotests/138.out index 3fe911f85a..aca7d47a80 100644 --- a/tests/qemu-iotests/138.out +++ b/tests/qemu-iotests/138.out @@ -5,5 +5,8 @@ QA output created by 138 Formatting 'TEST_DIR/t.IMGFMT', fmt=3DIMGFMT size=3D512 wrote 512/512 bytes at offset 0 512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) -qemu-img: Check failed: Cannot allocate memory +ERROR: counting reference for region exceeding the end of the file by one = cluster or more: offset 0x80000000000000 size 0x200 + +1 errors were found on the image. +Data may be corrupted, or further writes to the image may corrupt it. *** done --=20 2.20.1