From patchwork Fri Sep 6 17:32:00 2019 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Maxim Levitsky X-Patchwork-Id: 1159159 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (mailfrom) smtp.mailfrom=nongnu.org (client-ip=209.51.188.17; helo=lists.gnu.org; envelope-from=qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=fail (p=none dis=none) header.from=redhat.com Received: from lists.gnu.org (lists.gnu.org [209.51.188.17]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 46Q4TM3tl2z9s3Z for ; Sat, 7 Sep 2019 03:35:35 +1000 (AEST) Received: from localhost ([::1]:58952 helo=lists1p.gnu.org) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i6I8z-00073v-BP for incoming@patchwork.ozlabs.org; Fri, 06 Sep 2019 13:35:33 -0400 Received: from eggs.gnu.org ([2001:470:142:3::10]:46370) by lists.gnu.org with esmtp (Exim 4.90_1) (envelope-from ) id 1i6I60-0003qI-SW for qemu-devel@nongnu.org; Fri, 06 Sep 2019 13:32:30 -0400 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1i6I5y-0003D2-QI for qemu-devel@nongnu.org; Fri, 06 Sep 2019 13:32:28 -0400 Received: from mx1.redhat.com ([209.132.183.28]:38754) by eggs.gnu.org with esmtps (TLS1.0:DHE_RSA_AES_256_CBC_SHA1:32) (Exim 4.71) (envelope-from ) id 1i6I5q-00033u-04; Fri, 06 Sep 2019 13:32:19 -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 49A45189DACE; Fri, 6 Sep 2019 17:32:14 +0000 (UTC) Received: from maximlenovopc.usersys.redhat.com (unknown [10.35.206.83]) by smtp.corp.redhat.com (Postfix) with ESMTP id EA13A5D9CA; Fri, 6 Sep 2019 17:32:08 +0000 (UTC) From: Maxim Levitsky To: qemu-devel@nongnu.org Date: Fri, 6 Sep 2019 20:32:00 +0300 Message-Id: <20190906173201.7926-3-mlevitsk@redhat.com> In-Reply-To: <20190906173201.7926-1-mlevitsk@redhat.com> References: <20190906173201.7926-1-mlevitsk@redhat.com> X-Scanned-By: MIMEDefang 2.79 on 10.5.11.14 X-Greylist: Sender IP whitelisted, not delayed by milter-greylist-4.6.2 (mx1.redhat.com [10.5.110.63]); Fri, 06 Sep 2019 17:32:14 +0000 (UTC) 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] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files X-BeenThere: qemu-devel@nongnu.org X-Mailman-Version: 2.1.23 Precedence: list List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Cc: Kevin Wolf , Vladimir Sementsov-Ogievskiy , =?utf-8?q?Daniel_P_=2E_Berrang=C3=A9?= , qemu-block@nongnu.org, qemu-stable , Maxim Levitsky , Max Reitz Errors-To: qemu-devel-bounces+incoming=patchwork.ozlabs.org@nongnu.org Sender: "Qemu-devel" This fixes subltle corruption introduced by luks threaded encryption in commit 8ac0f15f335 Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=1745922 The corruption happens when we do * write to two or more unallocated clusters at once * write doesn't fully cover nether first nor last cluster In this case, when allocating the new clusters we COW both area prior to the write and after the write, and we encrypt them. The above mentioned commit accidently made it so, we encrypt the second COW are using the physical cluster offset of the first area. Fix this by: * remove the offset_in_cluster parameter of do_perform_cow_encrypt since it is misleading. That offset can be larger that cluster size. instead just add the start and end COW are offsets to both host and guest offsets that do_perform_cow_encrypt receives. * in do_perform_cow_encrypt, remove the cluster offset from the host_offset And thus pass correctly to the qcow2_co_encrypt, the host cluster offset and full guest offset Signed-off-by: Maxim Levitsky --- block/qcow2-cluster.c | 26 +++++++++++++++----------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c index b95e64c237..32477f0156 100644 --- a/block/qcow2-cluster.c +++ b/block/qcow2-cluster.c @@ -463,20 +463,20 @@ static int coroutine_fn do_perform_cow_read(BlockDriverState *bs, } static bool coroutine_fn do_perform_cow_encrypt(BlockDriverState *bs, - uint64_t guest_cluster_offset, - uint64_t host_cluster_offset, - unsigned offset_in_cluster, + uint64_t guest_offset, + uint64_t host_offset, uint8_t *buffer, unsigned bytes) { if (bytes && bs->encrypted) { BDRVQcow2State *s = bs->opaque; - assert((offset_in_cluster & ~BDRV_SECTOR_MASK) == 0); + assert((guest_offset & ~BDRV_SECTOR_MASK) == 0); + assert((host_offset & ~BDRV_SECTOR_MASK) == 0); assert((bytes & ~BDRV_SECTOR_MASK) == 0); assert(s->crypto); - if (qcow2_co_encrypt(bs, host_cluster_offset, - guest_cluster_offset + offset_in_cluster, - buffer, bytes) < 0) { + + if (qcow2_co_encrypt(bs, start_of_cluster(s, host_offset), + guest_offset, buffer, bytes) < 0) { return false; } } @@ -890,11 +890,15 @@ static int perform_cow(BlockDriverState *bs, QCowL2Meta *m) /* Encrypt the data if necessary before writing it */ if (bs->encrypted) { - if (!do_perform_cow_encrypt(bs, m->offset, m->alloc_offset, - start->offset, start_buffer, + if (!do_perform_cow_encrypt(bs, + m->offset + start->offset, + m->alloc_offset + start->offset, + start_buffer, start->nb_bytes) || - !do_perform_cow_encrypt(bs, m->offset, m->alloc_offset, - end->offset, end_buffer, end->nb_bytes)) { + !do_perform_cow_encrypt(bs, + m->offset + end->offset, + m->alloc_offset + end->offset, + end_buffer, end->nb_bytes)) { ret = -EIO; goto fail; }