]> git.proxmox.com Git - pve-qemu.git/blame - debian/patches/extra/0018-nbd-Fully-initialize-client-in-case-of-failed-negoti.patch
bump version to 2.9.0-5
[pve-qemu.git] / debian / patches / extra / 0018-nbd-Fully-initialize-client-in-case-of-failed-negoti.patch
CommitLineData
e74c0f31
WB
1From 4dbc47f9d71b8a17b174ffed314988aa99dc4775 Mon Sep 17 00:00:00 2001
2From: Eric Blake <eblake@redhat.com>
3Date: Fri, 26 May 2017 22:04:21 -0500
4Subject: [PATCH 18/23] nbd: Fully initialize client in case of failed
5 negotiation
6
7If a non-NBD client connects to qemu-nbd, we would end up with
8a SIGSEGV in nbd_client_put() because we were trying to
9unregister the client's association to the export, even though
10we skipped inserting the client into that list. Easy trigger
11in two terminals:
12
13$ qemu-nbd -p 30001 --format=raw file
14$ nmap 127.0.0.1 -p 30001
15
16nmap claims that it thinks it connected to a pago-services1
17server (which probably means nmap could be updated to learn the
18NBD protocol and give a more accurate diagnosis of the open
19port - but that's not our problem), then terminates immediately,
20so our call to nbd_negotiate() fails. The fix is to reorder
21nbd_co_client_start() to ensure that all initialization occurs
22before we ever try talking to a client in nbd_negotiate(), so
23that the teardown sequence on negotiation failure doesn't fault
24while dereferencing a half-initialized object.
25
26While debugging this, I also noticed that nbd_update_server_watch()
27called by nbd_client_closed() was still adding a channel to accept
28the next client, even when the state was no longer RUNNING. That
29is fixed by making nbd_can_accept() pay attention to the current
30state.
31
32Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1451614
33
34Signed-off-by: Eric Blake <eblake@redhat.com>
35Message-Id: <20170527030421.28366-1-eblake@redhat.com>
36Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
37---
38 nbd/server.c | 8 +++-----
39 qemu-nbd.c | 2 +-
40 2 files changed, 4 insertions(+), 6 deletions(-)
41
42diff --git a/nbd/server.c b/nbd/server.c
43index 924a1fe2db..edfda84d43 100644
44--- a/nbd/server.c
45+++ b/nbd/server.c
46@@ -1376,16 +1376,14 @@ static coroutine_fn void nbd_co_client_start(void *opaque)
47
48 if (exp) {
49 nbd_export_get(exp);
50+ QTAILQ_INSERT_TAIL(&exp->clients, client, next);
51 }
52+ qemu_co_mutex_init(&client->send_lock);
53+
54 if (nbd_negotiate(data)) {
55 client_close(client);
56 goto out;
57 }
58- qemu_co_mutex_init(&client->send_lock);
59-
60- if (exp) {
61- QTAILQ_INSERT_TAIL(&exp->clients, client, next);
62- }
63
64 nbd_client_receive_next_request(client);
65
66diff --git a/qemu-nbd.c b/qemu-nbd.c
67index e080fb7c75..b44764eb87 100644
68--- a/qemu-nbd.c
69+++ b/qemu-nbd.c
70@@ -324,7 +324,7 @@ out:
71
72 static int nbd_can_accept(void)
73 {
74- return nb_fds < shared;
75+ return state == RUNNING && nb_fds < shared;
76 }
77
78 static void nbd_export_closed(NBDExport *exp)
79--
802.11.0
81