Pablo Greco e6a3ae
From 14768fe9b44d6c89c066ebf597b9be79f7d43f30 Mon Sep 17 00:00:00 2001
Pablo Greco e6a3ae
From: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Date: Wed, 14 Aug 2019 11:28:11 +0100
Pablo Greco e6a3ae
Subject: [PATCH 3/3] qemu-img: fix regression copying secrets during convert
Pablo Greco e6a3ae
MIME-Version: 1.0
Pablo Greco e6a3ae
Content-Type: text/plain; charset=UTF-8
Pablo Greco e6a3ae
Content-Transfer-Encoding: 8bit
Pablo Greco e6a3ae
Pablo Greco e6a3ae
RH-Author: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Message-id: <20190814112811.28642-2-kwolf@redhat.com>
Pablo Greco e6a3ae
Patchwork-id: 89987
Pablo Greco e6a3ae
O-Subject: [RHEL-8.1.0 qemu-kvm PATCH 1/1] qemu-img: fix regression copying secrets during convert
Pablo Greco e6a3ae
Bugzilla: 1727821
Pablo Greco e6a3ae
RH-Acked-by: Max Reitz <mreitz@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: John Snow <jsnow@redhat.com>
Pablo Greco e6a3ae
RH-Acked-by: Thomas Huth <thuth@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
From: Daniel P. Berrangé <berrange@redhat.com>
Pablo Greco e6a3ae
Pablo Greco e6a3ae
When the convert command is creating an output file that needs
Pablo Greco e6a3ae
secrets, we need to ensure those secrets are passed to both the
Pablo Greco e6a3ae
blk_new_open and bdrv_create API calls.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
This is done by qemu-img extracting all opts matching the name
Pablo Greco e6a3ae
suffix "key-secret". Unfortunately the code doing this was run after the
Pablo Greco e6a3ae
call to bdrv_create(), which meant the QemuOpts it was extracting
Pablo Greco e6a3ae
secrets from was now empty.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Previously this worked by luks as a bug meant the "key-secret"
Pablo Greco e6a3ae
parameters were not purged from the QemuOpts. This bug was fixed in
Pablo Greco e6a3ae
Pablo Greco e6a3ae
  commit b76b4f604521e59f857d6177bc55f6f2e41fd392
Pablo Greco e6a3ae
  Author: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
  Date:   Thu Jan 11 16:18:08 2018 +0100
Pablo Greco e6a3ae
Pablo Greco e6a3ae
    qcow2: Use visitor for options in qcow2_create()
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Exposing the latent bug in qemu-img. This fix simply moves the copying
Pablo Greco e6a3ae
of secrets to before the bdrv_create() call.
Pablo Greco e6a3ae
Pablo Greco e6a3ae
Cc: qemu-stable@nongnu.org
Pablo Greco e6a3ae
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
(cherry picked from commit 8d65a3ccfd5db7f0436e095cd952f5d0c3a873ba)
Pablo Greco e6a3ae
Signed-off-by: Kevin Wolf <kwolf@redhat.com>
Pablo Greco e6a3ae
Signed-off-by: Danilo C. L. de Paula <ddepaula@redhat.com>
Pablo Greco e6a3ae
---
Pablo Greco e6a3ae
 qemu-img.c | 32 +++++++++++++++-----------------
Pablo Greco e6a3ae
 1 file changed, 15 insertions(+), 17 deletions(-)
Pablo Greco e6a3ae
Pablo Greco e6a3ae
diff --git a/qemu-img.c b/qemu-img.c
Pablo Greco e6a3ae
index f42750a..fa0cbd7 100644
Pablo Greco e6a3ae
--- a/qemu-img.c
Pablo Greco e6a3ae
+++ b/qemu-img.c
Pablo Greco e6a3ae
@@ -348,21 +348,6 @@ static int img_add_key_secrets(void *opaque,
Pablo Greco e6a3ae
     return 0;
Pablo Greco e6a3ae
 }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
-static BlockBackend *img_open_new_file(const char *filename,
Pablo Greco e6a3ae
-                                       QemuOpts *create_opts,
Pablo Greco e6a3ae
-                                       const char *fmt, int flags,
Pablo Greco e6a3ae
-                                       bool writethrough, bool quiet,
Pablo Greco e6a3ae
-                                       bool force_share)
Pablo Greco e6a3ae
-{
Pablo Greco e6a3ae
-    QDict *options = NULL;
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-    options = qdict_new();
Pablo Greco e6a3ae
-    qemu_opt_foreach(create_opts, img_add_key_secrets, options, &error_abort);
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
-    return img_open_file(filename, options, fmt, flags, writethrough, quiet,
Pablo Greco e6a3ae
-                         force_share);
Pablo Greco e6a3ae
-}
Pablo Greco e6a3ae
-
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
 static BlockBackend *img_open(bool image_opts,
Pablo Greco e6a3ae
                               const char *filename,
Pablo Greco e6a3ae
@@ -1994,6 +1979,7 @@ static int img_convert(int argc, char **argv)
Pablo Greco e6a3ae
     BlockDriverState *out_bs;
Pablo Greco e6a3ae
     QemuOpts *opts = NULL, *sn_opts = NULL;
Pablo Greco e6a3ae
     QemuOptsList *create_opts = NULL;
Pablo Greco e6a3ae
+    QDict *open_opts = NULL;
Pablo Greco e6a3ae
     char *options = NULL;
Pablo Greco e6a3ae
     Error *local_err = NULL;
Pablo Greco e6a3ae
     bool writethrough, src_writethrough, quiet = false, image_opts = false,
Pablo Greco e6a3ae
@@ -2342,6 +2328,16 @@ static int img_convert(int argc, char **argv)
Pablo Greco e6a3ae
         }
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
 
Pablo Greco e6a3ae
+    /*
Pablo Greco e6a3ae
+     * The later open call will need any decryption secrets, and
Pablo Greco e6a3ae
+     * bdrv_create() will purge "opts", so extract them now before
Pablo Greco e6a3ae
+     * they are lost.
Pablo Greco e6a3ae
+     */
Pablo Greco e6a3ae
+    if (!skip_create) {
Pablo Greco e6a3ae
+        open_opts = qdict_new();
Pablo Greco e6a3ae
+        qemu_opt_foreach(opts, img_add_key_secrets, open_opts, &error_abort);
Pablo Greco e6a3ae
+    }
Pablo Greco e6a3ae
+
Pablo Greco e6a3ae
     if (!skip_create) {
Pablo Greco e6a3ae
         /* Create the new image */
Pablo Greco e6a3ae
         ret = bdrv_create(drv, out_filename, opts, &local_err);
Pablo Greco e6a3ae
@@ -2368,8 +2364,9 @@ static int img_convert(int argc, char **argv)
Pablo Greco e6a3ae
          * That has to wait for bdrv_create to be improved
Pablo Greco e6a3ae
          * to allow filenames in option syntax
Pablo Greco e6a3ae
          */
Pablo Greco e6a3ae
-        s.target = img_open_new_file(out_filename, opts, out_fmt,
Pablo Greco e6a3ae
-                                     flags, writethrough, quiet, false);
Pablo Greco e6a3ae
+        s.target = img_open_file(out_filename, open_opts, out_fmt,
Pablo Greco e6a3ae
+                                 flags, writethrough, quiet, false);
Pablo Greco e6a3ae
+        open_opts = NULL; /* blk_new_open will have freed it */
Pablo Greco e6a3ae
     }
Pablo Greco e6a3ae
     if (!s.target) {
Pablo Greco e6a3ae
         ret = -1;
Pablo Greco e6a3ae
@@ -2437,6 +2434,7 @@ out:
Pablo Greco e6a3ae
     qemu_opts_del(opts);
Pablo Greco e6a3ae
     qemu_opts_free(create_opts);
Pablo Greco e6a3ae
     qemu_opts_del(sn_opts);
Pablo Greco e6a3ae
+    qobject_unref(open_opts);
Pablo Greco e6a3ae
     blk_unref(s.target);
Pablo Greco e6a3ae
     if (s.src) {
Pablo Greco e6a3ae
         for (bs_i = 0; bs_i < s.src_num; bs_i++) {
Pablo Greco e6a3ae
-- 
Pablo Greco e6a3ae
1.8.3.1
Pablo Greco e6a3ae