[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-stable] [PATCH 2/3] block/qcow2: fix the corruption when rebasing
From: |
Maxim Levitsky |
Subject: |
[Qemu-stable] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files |
Date: |
Fri, 6 Sep 2019 20:32:00 +0300 |
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 <address@hidden>
---
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;
}
--
2.17.2
[Qemu-stable] [PATCH 2/3] block/qcow2: fix the corruption when rebasing luks encrypted files,
Maxim Levitsky <=
[Qemu-stable] [PATCH 3/3] qemu-iotests: test for bz #1745922, Maxim Levitsky, 2019/09/06
Re: [Qemu-stable] [Qemu-devel] [PATCH 0/3] Fix qcow2+luks corruption introduced by commit 8ac0f15f335, Maxim Levitsky, 2019/09/06