2017-06-26 12:10:20 +02:00
|
|
|
From 096703b0e4c619c6cd3015fcb105c65692b2ec56 Mon Sep 17 00:00:00 2001
|
2017-06-21 03:27:18 +02:00
|
|
|
From: Eric Blake <eblake@redhat.com>
|
|
|
|
Date: Fri, 26 May 2017 22:04:21 -0500
|
|
|
|
Subject: [PATCH] nbd: Fully initialize client in case of failed negotiation
|
|
|
|
|
|
|
|
If a non-NBD client connects to qemu-nbd, we would end up with
|
|
|
|
a SIGSEGV in nbd_client_put() because we were trying to
|
|
|
|
unregister the client's association to the export, even though
|
|
|
|
we skipped inserting the client into that list. Easy trigger
|
|
|
|
in two terminals:
|
|
|
|
|
|
|
|
$ qemu-nbd -p 30001 --format=raw file
|
|
|
|
$ nmap 127.0.0.1 -p 30001
|
|
|
|
|
|
|
|
nmap claims that it thinks it connected to a pago-services1
|
|
|
|
server (which probably means nmap could be updated to learn the
|
|
|
|
NBD protocol and give a more accurate diagnosis of the open
|
|
|
|
port - but that's not our problem), then terminates immediately,
|
|
|
|
so our call to nbd_negotiate() fails. The fix is to reorder
|
|
|
|
nbd_co_client_start() to ensure that all initialization occurs
|
|
|
|
before we ever try talking to a client in nbd_negotiate(), so
|
|
|
|
that the teardown sequence on negotiation failure doesn't fault
|
|
|
|
while dereferencing a half-initialized object.
|
|
|
|
|
|
|
|
While debugging this, I also noticed that nbd_update_server_watch()
|
|
|
|
called by nbd_client_closed() was still adding a channel to accept
|
|
|
|
the next client, even when the state was no longer RUNNING. That
|
|
|
|
is fixed by making nbd_can_accept() pay attention to the current
|
|
|
|
state.
|
|
|
|
|
|
|
|
Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
|
|
|
|
|
|
|
|
Signed-off-by: Eric Blake <eblake@redhat.com>
|
|
|
|
Message-Id: <20170527030421.28366-1-eblake@redhat.com>
|
|
|
|
Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
|
|
|
|
(cherry picked from commit df8ad9f128c15aa0a0ebc7b24e9a22c9775b67af)
|
|
|
|
[BR: BSC#1043808 CVE-2017-9524]
|
|
|
|
Signed-off-by: Bruce Rogers <brogers@suse.com>
|
|
|
|
---
|
|
|
|
nbd/server.c | 8 +++-----
|
|
|
|
qemu-nbd.c | 2 +-
|
|
|
|
2 files changed, 4 insertions(+), 6 deletions(-)
|
|
|
|
|
|
|
|
diff --git a/nbd/server.c b/nbd/server.c
|
|
|
|
index 924a1fe2db..edfda84d43 100644
|
|
|
|
--- a/nbd/server.c
|
|
|
|
+++ b/nbd/server.c
|
|
|
|
@@ -1376,16 +1376,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
|
|
|
|
|
|
|
|
if (exp) {
|
|
|
|
nbd_export_get(exp);
|
|
|
|
+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
|
|
|
|
}
|
|
|
|
+ qemu_co_mutex_init(&client->send_lock);
|
|
|
|
+
|
|
|
|
if (nbd_negotiate(data)) {
|
|
|
|
client_close(client);
|
|
|
|
goto out;
|
|
|
|
}
|
|
|
|
- qemu_co_mutex_init(&client->send_lock);
|
|
|
|
-
|
|
|
|
- if (exp) {
|
|
|
|
- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
|
|
|
|
- }
|
|
|
|
|
|
|
|
nbd_client_receive_next_request(client);
|
|
|
|
|
|
|
|
diff --git a/qemu-nbd.c b/qemu-nbd.c
|
|
|
|
index e080fb7c75..b44764eb87 100644
|
|
|
|
--- a/qemu-nbd.c
|
|
|
|
+++ b/qemu-nbd.c
|
|
|
|
@@ -324,7 +324,7 @@ out:
|
|
|
|
|
|
|
|
static int nbd_can_accept(void)
|
|
|
|
{
|
|
|
|
- return nb_fds < shared;
|
|
|
|
+ return state == RUNNING && nb_fds < shared;
|
|
|
|
}
|
|
|
|
|
|
|
|
static void nbd_export_closed(NBDExport *exp)
|