Blame SOURCES/kvm-crypto.c-cleanup-created-file-when-block_crypto_co_c.patch

ddf19c
From 043decff5812c1f46ed44dd0f82099e3b8bb6a28 Mon Sep 17 00:00:00 2001
ddf19c
From: Maxim Levitsky <mlevitsk@redhat.com>
ddf19c
Date: Sun, 31 May 2020 16:40:35 +0100
ddf19c
Subject: [PATCH 7/7] crypto.c: cleanup created file when
ddf19c
 block_crypto_co_create_opts_luks fails
ddf19c
ddf19c
RH-Author: Maxim Levitsky <mlevitsk@redhat.com>
ddf19c
Message-id: <20200531164035.34188-4-mlevitsk@redhat.com>
ddf19c
Patchwork-id: 97060
ddf19c
O-Subject: [RHEL-AV-8.2.1 qemu-kvm PATCH 3/3] crypto.c: cleanup created file when block_crypto_co_create_opts_luks fails
ddf19c
Bugzilla: 1827630
ddf19c
RH-Acked-by: Sergio Lopez Pascual <slp@redhat.com>
ddf19c
RH-Acked-by: John Snow <jsnow@redhat.com>
ddf19c
RH-Acked-by: Eric Blake <eblake@redhat.com>
ddf19c
ddf19c
From: Daniel Henrique Barboza <danielhb413@gmail.com>
ddf19c
ddf19c
When using a non-UTF8 secret to create a volume using qemu-img, the
ddf19c
following error happens:
ddf19c
ddf19c
$ qemu-img create -f luks --object secret,id=vol_1_encrypt0,file=vol_resize_pool.vol_1.secret.qzVQrI -o key-secret=vol_1_encrypt0 /var/tmp/pool_target/vol_1 10240K
ddf19c
ddf19c
Formatting '/var/tmp/pool_target/vol_1', fmt=luks size=10485760 key-secret=vol_1_encrypt0
ddf19c
qemu-img: /var/tmp/pool_target/vol_1: Data from secret vol_1_encrypt0 is not valid UTF-8
ddf19c
ddf19c
However, the created file '/var/tmp/pool_target/vol_1' is left behind in the
ddf19c
file system after the failure. This behavior can be observed when creating
ddf19c
the volume using Libvirt, via 'virsh vol-create', and then getting "volume
ddf19c
target path already exist" errors when trying to re-create the volume.
ddf19c
ddf19c
The volume file is created inside block_crypto_co_create_opts_luks(), in
ddf19c
block/crypto.c. If the bdrv_create_file() call is successful but any
ddf19c
succeeding step fails*, the existing 'fail' label does not take into
ddf19c
account the created file, leaving it behind.
ddf19c
ddf19c
This patch changes block_crypto_co_create_opts_luks() to delete
ddf19c
'filename' in case of failure. A failure in this point means that
ddf19c
the volume is now truncated/corrupted, so even if 'filename' was an
ddf19c
existing volume before calling qemu-img, it is now unusable. Deleting
ddf19c
the file it is not much worse than leaving it in the filesystem in
ddf19c
this scenario, and we don't have to deal with checking the file
ddf19c
pre-existence in the code.
ddf19c
ddf19c
* in our case, block_crypto_co_create_generic calls qcrypto_block_create,
ddf19c
which calls qcrypto_block_luks_create, and this function fails when
ddf19c
calling qcrypto_secret_lookup_as_utf8.
ddf19c
ddf19c
Reported-by: Srikanth Aithal <bssrikanth@in.ibm.com>
ddf19c
Suggested-by: Kevin Wolf <kwolf@redhat.com>
ddf19c
Signed-off-by: Daniel Henrique Barboza <danielhb413@gmail.com>
ddf19c
Message-Id: <20200130213907.2830642-4-danielhb413@gmail.com>
ddf19c
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
ddf19c
(cherry picked from commit 1bba30da24e1124ceeb0693c81382a0d77e20ca5)
ddf19c
Signed-off-by: Maxim Levitsky <mlevitsk@redhat.com>
ddf19c
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
ddf19c
---
ddf19c
 block/crypto.c | 18 ++++++++++++++++++
ddf19c
 1 file changed, 18 insertions(+)
ddf19c
ddf19c
diff --git a/block/crypto.c b/block/crypto.c
ddf19c
index 970d463..5e3b15c 100644
ddf19c
--- a/block/crypto.c
ddf19c
+++ b/block/crypto.c
ddf19c
@@ -30,6 +30,7 @@
ddf19c
 #include "qapi/error.h"
ddf19c
 #include "qemu/module.h"
ddf19c
 #include "qemu/option.h"
ddf19c
+#include "qemu/cutils.h"
ddf19c
 #include "crypto.h"
ddf19c
 
ddf19c
 typedef struct BlockCrypto BlockCrypto;
ddf19c
@@ -597,6 +598,23 @@ static int coroutine_fn block_crypto_co_create_opts_luks(BlockDriver *drv,
ddf19c
 
ddf19c
     ret = 0;
ddf19c
 fail:
ddf19c
+    /*
ddf19c
+     * If an error occurred, delete 'filename'. Even if the file existed
ddf19c
+     * beforehand, it has been truncated and corrupted in the process.
ddf19c
+     */
ddf19c
+    if (ret && bs) {
ddf19c
+        Error *local_delete_err = NULL;
ddf19c
+        int r_del = bdrv_co_delete_file(bs, &local_delete_err);
ddf19c
+        /*
ddf19c
+         * ENOTSUP will happen if the block driver doesn't support
ddf19c
+         * the 'bdrv_co_delete_file' interface. This is a predictable
ddf19c
+         * scenario and shouldn't be reported back to the user.
ddf19c
+         */
ddf19c
+        if ((r_del < 0) && (r_del != -ENOTSUP)) {
ddf19c
+            error_report_err(local_delete_err);
ddf19c
+        }
ddf19c
+    }
ddf19c
+
ddf19c
     bdrv_unref(bs);
ddf19c
     qapi_free_QCryptoBlockCreateOptions(create_opts);
ddf19c
     qobject_unref(cryptoopts);
ddf19c
-- 
ddf19c
1.8.3.1
ddf19c