|
|
d76c62 |
From 1e3921f1065972dc236bc726f19be37492a145c6 Mon Sep 17 00:00:00 2001
|
|
|
d76c62 |
Message-Id: <1e3921f1065972dc236bc726f19be37492a145c6@dist-git>
|
|
|
d76c62 |
From: Peter Krempa <pkrempa@redhat.com>
|
|
|
d76c62 |
Date: Fri, 28 Feb 2020 10:24:43 +0100
|
|
|
d76c62 |
Subject: [PATCH] virStorageFileGetMetadataRecurse: Allow format probing under
|
|
|
d76c62 |
special circumstances
|
|
|
d76c62 |
MIME-Version: 1.0
|
|
|
d76c62 |
Content-Type: text/plain; charset=UTF-8
|
|
|
d76c62 |
Content-Transfer-Encoding: 8bit
|
|
|
d76c62 |
|
|
|
d76c62 |
Allow format probing to work around lazy clients which did not specify
|
|
|
d76c62 |
their format in the overlay. Format probing will be allowed only, if we
|
|
|
d76c62 |
are able to probe the image, the probing result was successful and the
|
|
|
d76c62 |
probed image does not have any backing or data file.
|
|
|
d76c62 |
|
|
|
d76c62 |
This relaxes the restrictions which were imposed in commit 3615e8b39bad
|
|
|
d76c62 |
in cases when we know that the image probing will not result in security
|
|
|
d76c62 |
issues or data corruption.
|
|
|
d76c62 |
|
|
|
d76c62 |
We perform the image format detection and in the case that we were able
|
|
|
d76c62 |
to probe the format and the format does not specify a backing store (or
|
|
|
d76c62 |
doesn't support backing store) we can use this format.
|
|
|
d76c62 |
|
|
|
d76c62 |
With pre-blockdev configurations this will restore the previous
|
|
|
d76c62 |
behaviour for the images mentioned above as qemu would probe the format
|
|
|
d76c62 |
anyways. It also improves error reporting compared to the old state as
|
|
|
d76c62 |
we now report that the backing chain will be broken in case when there
|
|
|
d76c62 |
is a backing file.
|
|
|
d76c62 |
|
|
|
d76c62 |
In blockdev configurations this ensures that libvirt will not cause data
|
|
|
d76c62 |
corruption by ending the chain prematurely without notifying the user,
|
|
|
d76c62 |
but still allows the old semantics when the users forgot to specify the
|
|
|
d76c62 |
format.
|
|
|
d76c62 |
|
|
|
d76c62 |
Users thus don't have to re-invent when image format detection is safe
|
|
|
d76c62 |
to do.
|
|
|
d76c62 |
|
|
|
d76c62 |
The price for this is that libvirt will need to keep the image format
|
|
|
d76c62 |
detector still current and working or replace it by invocation of
|
|
|
d76c62 |
qemu-img.
|
|
|
d76c62 |
|
|
|
d76c62 |
Signed-off-by: Peter Krempa <pkrempa@redhat.com>
|
|
|
d76c62 |
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
|
d76c62 |
(cherry picked from commit ae9e6c2a2b75d958995c661f7bb64ed4353a6404)
|
|
|
d76c62 |
|
|
|
d76c62 |
https://bugzilla.redhat.com/show_bug.cgi?id=1798148
|
|
|
d76c62 |
Message-Id: <77d1d21a0ce64fd49c501b1ed3667307cbab0b73.1582881363.git.pkrempa@redhat.com>
|
|
|
d76c62 |
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
|
d76c62 |
---
|
|
|
d76c62 |
src/util/virstoragefile.c | 52 ++++++++++++++++++++++-----------------
|
|
|
d76c62 |
1 file changed, 30 insertions(+), 22 deletions(-)
|
|
|
d76c62 |
|
|
|
d76c62 |
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
|
|
|
d76c62 |
index 0bfd9e16e9..b88763b267 100644
|
|
|
d76c62 |
--- a/src/util/virstoragefile.c
|
|
|
d76c62 |
+++ b/src/util/virstoragefile.c
|
|
|
d76c62 |
@@ -4986,6 +4986,7 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
|
|
|
d76c62 |
virHashTablePtr cycle,
|
|
|
d76c62 |
unsigned int depth)
|
|
|
d76c62 |
{
|
|
|
d76c62 |
+ virStorageFileFormat orig_format = src->format;
|
|
|
d76c62 |
size_t headerLen;
|
|
|
d76c62 |
int rv;
|
|
|
d76c62 |
g_autofree char *buf = NULL;
|
|
|
d76c62 |
@@ -4995,10 +4996,17 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
|
|
|
d76c62 |
NULLSTR(src->path), src->format,
|
|
|
d76c62 |
(unsigned int)uid, (unsigned int)gid);
|
|
|
d76c62 |
|
|
|
d76c62 |
+ if (src->format == VIR_STORAGE_FILE_AUTO_SAFE)
|
|
|
d76c62 |
+ src->format = VIR_STORAGE_FILE_AUTO;
|
|
|
d76c62 |
+
|
|
|
d76c62 |
/* exit if we can't load information about the current image */
|
|
|
d76c62 |
rv = virStorageFileSupportsBackingChainTraversal(src);
|
|
|
d76c62 |
- if (rv <= 0)
|
|
|
d76c62 |
+ if (rv <= 0) {
|
|
|
d76c62 |
+ if (orig_format == VIR_STORAGE_FILE_AUTO)
|
|
|
d76c62 |
+ return -2;
|
|
|
d76c62 |
+
|
|
|
d76c62 |
return rv;
|
|
|
d76c62 |
+ }
|
|
|
d76c62 |
|
|
|
d76c62 |
if (virStorageFileGetMetadataRecurseReadHeader(src, parent, uid, gid,
|
|
|
d76c62 |
&buf, &headerLen, cycle) < 0)
|
|
|
d76c62 |
@@ -5007,6 +5015,18 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
|
|
|
d76c62 |
if (virStorageFileGetMetadataInternal(src, buf, headerLen) < 0)
|
|
|
d76c62 |
return -1;
|
|
|
d76c62 |
|
|
|
d76c62 |
+ /* If we probed the format we MUST ensure that nothing else than the current
|
|
|
d76c62 |
+ * image (this includes both backing files and external data store) is
|
|
|
d76c62 |
+ * considered for security labelling and/or recursion. */
|
|
|
d76c62 |
+ if (orig_format == VIR_STORAGE_FILE_AUTO) {
|
|
|
d76c62 |
+ if (src->backingStoreRaw || src->externalDataStoreRaw) {
|
|
|
d76c62 |
+ src->format = VIR_STORAGE_FILE_RAW;
|
|
|
d76c62 |
+ VIR_FREE(src->backingStoreRaw);
|
|
|
d76c62 |
+ VIR_FREE(src->externalDataStoreRaw);
|
|
|
d76c62 |
+ return -2;
|
|
|
d76c62 |
+ }
|
|
|
d76c62 |
+ }
|
|
|
d76c62 |
+
|
|
|
d76c62 |
if (src->backingStoreRaw) {
|
|
|
d76c62 |
if ((rv = virStorageSourceNewFromBacking(src, &backingStore)) < 0)
|
|
|
d76c62 |
return -1;
|
|
|
d76c62 |
@@ -5015,33 +5035,21 @@ virStorageFileGetMetadataRecurse(virStorageSourcePtr src,
|
|
|
d76c62 |
if (rv == 1)
|
|
|
d76c62 |
return 0;
|
|
|
d76c62 |
|
|
|
d76c62 |
- if (backingStore->format == VIR_STORAGE_FILE_AUTO) {
|
|
|
d76c62 |
- /* Assuming the backing store to be raw can lead to failures. We do
|
|
|
d76c62 |
- * it only when we must not report an error to prevent losing VMs.
|
|
|
d76c62 |
- * Otherwise report an error.
|
|
|
d76c62 |
- */
|
|
|
d76c62 |
- if (report_broken) {
|
|
|
d76c62 |
+ if ((rv = virStorageFileGetMetadataRecurse(backingStore, parent,
|
|
|
d76c62 |
+ uid, gid,
|
|
|
d76c62 |
+ report_broken,
|
|
|
d76c62 |
+ cycle, depth + 1)) < 0) {
|
|
|
d76c62 |
+ if (!report_broken)
|
|
|
d76c62 |
+ return 0;
|
|
|
d76c62 |
+
|
|
|
d76c62 |
+ if (rv == -2) {
|
|
|
d76c62 |
virReportError(VIR_ERR_OPERATION_INVALID,
|
|
|
d76c62 |
_("format of backing image '%s' of image '%s' was not specified in the image metadata "
|
|
|
d76c62 |
"(See https://libvirt.org/kbase/backing_chains.html for troubleshooting)"),
|
|
|
d76c62 |
src->backingStoreRaw, NULLSTR(src->path));
|
|
|
d76c62 |
- return -1;
|
|
|
d76c62 |
}
|
|
|
d76c62 |
|
|
|
d76c62 |
- backingStore->format = VIR_STORAGE_FILE_RAW;
|
|
|
d76c62 |
- }
|
|
|
d76c62 |
-
|
|
|
d76c62 |
- if (backingStore->format == VIR_STORAGE_FILE_AUTO_SAFE)
|
|
|
d76c62 |
- backingStore->format = VIR_STORAGE_FILE_AUTO;
|
|
|
d76c62 |
-
|
|
|
d76c62 |
- if (virStorageFileGetMetadataRecurse(backingStore, parent,
|
|
|
d76c62 |
- uid, gid,
|
|
|
d76c62 |
- report_broken,
|
|
|
d76c62 |
- cycle, depth + 1) < 0) {
|
|
|
d76c62 |
- if (report_broken)
|
|
|
d76c62 |
- return -1;
|
|
|
d76c62 |
- else
|
|
|
d76c62 |
- return 0;
|
|
|
d76c62 |
+ return -1;
|
|
|
d76c62 |
}
|
|
|
d76c62 |
|
|
|
d76c62 |
backingStore->id = depth;
|
|
|
d76c62 |
--
|
|
|
d76c62 |
2.25.1
|
|
|
d76c62 |
|