[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PULL 24/33] nbd: Fully initialize client in case of failed
From: |
Paolo Bonzini |
Subject: |
[Qemu-devel] [PULL 24/33] nbd: Fully initialize client in case of failed negotiation |
Date: |
Thu, 1 Jun 2017 14:41:42 +0200 |
From: Eric Blake <address@hidden>
If a non-NBD client connects to qemu-nbd, we would end up with
a SIGSEGV in nbd_cilent_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 <address@hidden>
Message-Id: <address@hidden>
Signed-off-by: Paolo Bonzini <address@hidden>
---
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 ee59e5d..49b55f6 100644
--- a/nbd/server.c
+++ b/nbd/server.c
@@ -1358,16 +1358,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 f60842f..651f85e 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -325,7 +325,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)
--
1.8.3.1
- Re: [Qemu-devel] [PULL 17/33] vhost-user-scsi: Introduce vhost-user-scsi host device, (continued)
[Qemu-devel] [PULL 19/33] target/i386: enable A20 automatically in system management mode, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 18/33] vhost-user-scsi: Introduce a vhost-user-scsi sample application, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 21/33] i386: fix read/write cr with icount option, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 20/33] target/i386: use multiple CPU AddressSpaces, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 23/33] exec: fix address_space_get_iotlb_entry page mask, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 24/33] nbd: Fully initialize client in case of failed negotiation,
Paolo Bonzini <=
[Qemu-devel] [PULL 22/33] sockets: improve error reporting if UNIX socket path is too long, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 26/33] kvmclock: update system_time_msr address forcibly, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 25/33] qtest: add rtc periodic timer test, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 27/33] linuxboot_dma: compile for i486, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 28/33] edu: fix memory leak on msi_broken platforms, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 30/33] target/i386: Add GDB XML description for SSE registers, Paolo Bonzini, 2017/06/01
[Qemu-devel] [PULL 31/33] hw/core: nmi.c can be compiled as common-obj nowadays, Paolo Bonzini, 2017/06/01