Blame SOURCES/kvm-nbd-client-Add-meta-contexts-to-nbd_receive_export_l.patch

7711c0
From 1c6d308e59fe4d6f50a0664eea5c0d09b8075f20 Mon Sep 17 00:00:00 2001
7711c0
From: John Snow <jsnow@redhat.com>
7711c0
Date: Wed, 27 Mar 2019 17:22:52 +0100
7711c0
Subject: [PATCH 114/163] nbd/client: Add meta contexts to
7711c0
 nbd_receive_export_list()
7711c0
7711c0
RH-Author: John Snow <jsnow@redhat.com>
7711c0
Message-id: <20190327172308.31077-40-jsnow@redhat.com>
7711c0
Patchwork-id: 85199
7711c0
O-Subject: [RHEL-7.7 qemu-kvm-rhev PATCH 39/55] nbd/client: Add meta contexts to nbd_receive_export_list()
7711c0
Bugzilla: 1691009
7711c0
RH-Acked-by: Stefan Hajnoczi <stefanha@redhat.com>
7711c0
RH-Acked-by: Max Reitz <mreitz@redhat.com>
7711c0
RH-Acked-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
7711c0
From: Eric Blake <eblake@redhat.com>
7711c0
7711c0
We want to be able to detect whether a given qemu NBD server is
7711c0
exposing the right export(s) and dirty bitmaps, at least for
7711c0
regression testing.  We could use 'nbd-client -l' from the upstream
7711c0
NBD project to list exports, but it's annoying to rely on
7711c0
out-of-tree binaries; furthermore, nbd-client doesn't necessarily
7711c0
know about all of the qemu NBD extensions.  Thus, we plan on adding
7711c0
a new mode to qemu-nbd that merely sniffs all possible information
7711c0
from the server during handshake phase, then disconnects and dumps
7711c0
the information.
7711c0
7711c0
This patch continues the work of the previous patch, by adding the
7711c0
ability to track the list of available meta contexts into
7711c0
NBDExportInfo.  It benefits from the recent refactoring patches
7711c0
with a new nbd_list_meta_contexts() that reuses much of the same
7711c0
framework as setting a meta context.
7711c0
7711c0
Note: a malicious server could exhaust memory of a client by feeding
7711c0
an unending loop of contexts; perhaps we could place a limit on how
7711c0
many we are willing to receive. But this is no different from our
7711c0
earlier analysis on a server sending an unending list of exports,
7711c0
and the death of a client due to memory exhaustion when the client
7711c0
was going to exit soon anyways is not really a denial of service
7711c0
attack.
7711c0
7711c0
Signed-off-by: Eric Blake <eblake@redhat.com>
7711c0
Reviewed-by: Richard W.M. Jones <rjones@redhat.com>
7711c0
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7711c0
Message-Id: <20190117193658.16413-19-eblake@redhat.com>
7711c0
(cherry picked from commit 0b576b6bfb56291bb13db0a54d99adf2f3706030)
7711c0
Signed-off-by: John Snow <jsnow@redhat.com>
7711c0
Signed-off-by: Miroslav Rezanina <mrezanin@redhat.com>
7711c0
---
7711c0
 include/block/nbd.h |  2 ++
7711c0
 nbd/client.c        | 41 +++++++++++++++++++++++++++++++++++++++--
7711c0
 2 files changed, 41 insertions(+), 2 deletions(-)
7711c0
7711c0
diff --git a/include/block/nbd.h b/include/block/nbd.h
7711c0
index 19332b4..4faf394 100644
7711c0
--- a/include/block/nbd.h
7711c0
+++ b/include/block/nbd.h
7711c0
@@ -284,6 +284,8 @@ struct NBDExportInfo {
7711c0
 
7711c0
     /* Set by server results during nbd_receive_export_list() */
7711c0
     char *description;
7711c0
+    int n_contexts;
7711c0
+    char **contexts;
7711c0
 };
7711c0
 typedef struct NBDExportInfo NBDExportInfo;
7711c0
 
7711c0
diff --git a/nbd/client.c b/nbd/client.c
7711c0
index 8a32169..798b82f 100644
7711c0
--- a/nbd/client.c
7711c0
+++ b/nbd/client.c
7711c0
@@ -818,6 +818,36 @@ static int nbd_negotiate_simple_meta_context(QIOChannel *ioc,
7711c0
 }
7711c0
 
7711c0
 /*
7711c0
+ * nbd_list_meta_contexts:
7711c0
+ * Request the server to list all meta contexts for export @info->name.
7711c0
+ * return 0 if list is complete (even if empty),
7711c0
+ *        -1 with errp set for any error
7711c0
+ */
7711c0
+static int nbd_list_meta_contexts(QIOChannel *ioc,
7711c0
+                                  NBDExportInfo *info,
7711c0
+                                  Error **errp)
7711c0
+{
7711c0
+    int ret;
7711c0
+
7711c0
+    if (nbd_send_meta_query(ioc, NBD_OPT_LIST_META_CONTEXT,
7711c0
+                            info->name, NULL, errp) < 0) {
7711c0
+        return -1;
7711c0
+    }
7711c0
+
7711c0
+    while (1) {
7711c0
+        char *context;
7711c0
+
7711c0
+        ret = nbd_receive_one_meta_context(ioc, NBD_OPT_LIST_META_CONTEXT,
7711c0
+                                           &context, NULL, errp);
7711c0
+        if (ret <= 0) {
7711c0
+            return ret;
7711c0
+        }
7711c0
+        info->contexts = g_renew(char *, info->contexts, ++info->n_contexts);
7711c0
+        info->contexts[info->n_contexts - 1] = context;
7711c0
+    }
7711c0
+}
7711c0
+
7711c0
+/*
7711c0
  * nbd_start_negotiate:
7711c0
  * Start the handshake to the server.  After a positive return, the server
7711c0
  * is ready to accept additional NBD_OPT requests.
7711c0
@@ -1066,7 +1096,7 @@ int nbd_receive_negotiate(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
7711c0
 /* Clean up result of nbd_receive_export_list */
7711c0
 void nbd_free_export_list(NBDExportInfo *info, int count)
7711c0
 {
7711c0
-    int i;
7711c0
+    int i, j;
7711c0
 
7711c0
     if (!info) {
7711c0
         return;
7711c0
@@ -1075,6 +1105,10 @@ void nbd_free_export_list(NBDExportInfo *info, int count)
7711c0
     for (i = 0; i < count; i++) {
7711c0
         g_free(info[i].name);
7711c0
         g_free(info[i].description);
7711c0
+        for (j = 0; j < info[i].n_contexts; j++) {
7711c0
+            g_free(info[i].contexts[j]);
7711c0
+        }
7711c0
+        g_free(info[i].contexts);
7711c0
     }
7711c0
     g_free(info);
7711c0
 }
7711c0
@@ -1144,7 +1178,10 @@ int nbd_receive_export_list(QIOChannel *ioc, QCryptoTLSCreds *tlscreds,
7711c0
                 break;
7711c0
             }
7711c0
 
7711c0
-            /* TODO: Grab meta contexts */
7711c0
+            if (result == 3 &&
7711c0
+                nbd_list_meta_contexts(ioc, &array[i], errp) < 0) {
7711c0
+                goto out;
7711c0
+            }
7711c0
         }
7711c0
 
7711c0
         /* Send NBD_OPT_ABORT as a courtesy before hanging up */
7711c0
-- 
7711c0
1.8.3.1
7711c0