summaryrefslogtreecommitdiff
path: root/qemu-nbd.c
diff options
context:
space:
mode:
authorEric Blake <eblake@redhat.com>2017-05-26 22:04:21 -0500
committerMichael Roth <mdroth@linux.vnet.ibm.com>2017-08-24 16:52:10 -0500
commitec49c8ac57885db3c9475d9fc9a80e2200dc26de (patch)
tree2d99df3c6b7bbfc78b093bf165570000d967a435 /qemu-nbd.c
parentf28b8906dd38816ed4da5a98bdeb5ff797afae8a (diff)
downloadqemu-ec49c8ac57885db3c9475d9fc9a80e2200dc26de.tar.gz
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) Signed-off-by: Michael Roth <mdroth@linux.vnet.ibm.com>
Diffstat (limited to 'qemu-nbd.c')
-rw-r--r--qemu-nbd.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/qemu-nbd.c b/qemu-nbd.c
index e4f00e26dd..14e7947a4c 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)