|
|
9ae3a8 |
From cd10207e755b1b0470503c72c78a8d927f87a37a Mon Sep 17 00:00:00 2001
|
|
|
9ae3a8 |
From: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Date: Sat, 13 Jun 2015 16:21:58 +0200
|
|
|
9ae3a8 |
Subject: [PATCH 04/42] qcow2: Catch !*host_offset for data allocation
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Message-id: <1434212556-3927-5-git-send-email-mreitz@redhat.com>
|
|
|
9ae3a8 |
Patchwork-id: 66023
|
|
|
9ae3a8 |
O-Subject: [RHEL-7.2 qemu-kvm PATCH 04/42] qcow2: Catch !*host_offset for data allocation
|
|
|
9ae3a8 |
Bugzilla: 1129893
|
|
|
9ae3a8 |
RH-Acked-by: Jeffrey Cody <jcody@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Fam Zheng <famz@redhat.com>
|
|
|
9ae3a8 |
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
BZ: 1129893
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
qcow2_alloc_cluster_offset() uses host_offset == 0 as "no preferred
|
|
|
9ae3a8 |
offset" for the (data) cluster range to be allocated. However, this
|
|
|
9ae3a8 |
offset is actually valid and may be allocated on images with a corrupted
|
|
|
9ae3a8 |
refcount table or first refcount block.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
In this case, the corruption prevention should normally catch that
|
|
|
9ae3a8 |
write anyway (because it would overwrite the image header). But since 0
|
|
|
9ae3a8 |
is a special value here, the function assumes that nothing has been
|
|
|
9ae3a8 |
allocated at all which it asserts against.
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Because this condition is not qemu's fault but rather that of a broken
|
|
|
9ae3a8 |
image, it shouldn't throw an assertion but rather mark the image corrupt
|
|
|
9ae3a8 |
and show an appropriate message, which this patch does by calling the
|
|
|
9ae3a8 |
corruption check earlier than it would be called normally (before the
|
|
|
9ae3a8 |
assertion).
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Reviewed-by: Eric Blake <eblake@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
|
|
|
9ae3a8 |
(cherry picked from commit ff52aab2df5c5e10f231481961b88d25a3021724)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
Signed-off-by: Max Reitz <mreitz@redhat.com>
|
|
|
9ae3a8 |
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
|
|
|
9ae3a8 |
---
|
|
|
9ae3a8 |
block/qcow2-cluster.c | 11 +++++++++++
|
|
|
9ae3a8 |
1 file changed, 11 insertions(+)
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
diff --git a/block/qcow2-cluster.c b/block/qcow2-cluster.c
|
|
|
9ae3a8 |
index 1b9609f..f2f1170 100644
|
|
|
9ae3a8 |
--- a/block/qcow2-cluster.c
|
|
|
9ae3a8 |
+++ b/block/qcow2-cluster.c
|
|
|
9ae3a8 |
@@ -1089,6 +1089,17 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
|
|
|
9ae3a8 |
return 0;
|
|
|
9ae3a8 |
}
|
|
|
9ae3a8 |
|
|
|
9ae3a8 |
+ /* !*host_offset would overwrite the image header and is reserved for "no
|
|
|
9ae3a8 |
+ * host offset preferred". If 0 was a valid host offset, it'd trigger the
|
|
|
9ae3a8 |
+ * following overlap check; do that now to avoid having an invalid value in
|
|
|
9ae3a8 |
+ * *host_offset. */
|
|
|
9ae3a8 |
+ if (!alloc_cluster_offset) {
|
|
|
9ae3a8 |
+ ret = qcow2_pre_write_overlap_check(bs, 0, alloc_cluster_offset,
|
|
|
9ae3a8 |
+ nb_clusters * s->cluster_size);
|
|
|
9ae3a8 |
+ assert(ret < 0);
|
|
|
9ae3a8 |
+ goto fail;
|
|
|
9ae3a8 |
+ }
|
|
|
9ae3a8 |
+
|
|
|
9ae3a8 |
/*
|
|
|
9ae3a8 |
* Save info needed for meta data update.
|
|
|
9ae3a8 |
*
|
|
|
9ae3a8 |
--
|
|
|
9ae3a8 |
1.8.3.1
|
|
|
9ae3a8 |
|