diff options
author | Eric Blake <eblake@redhat.com> | 2017-05-26 22:04:21 -0500 |
---|---|---|
committer | Michael Roth <mdroth@linux.vnet.ibm.com> | 2017-08-24 16:52:10 -0500 |
commit | ec49c8ac57885db3c9475d9fc9a80e2200dc26de (patch) | |
tree | 2d99df3c6b7bbfc78b093bf165570000d967a435 /qemu-nbd.c | |
parent | f28b8906dd38816ed4da5a98bdeb5ff797afae8a (diff) | |
download | qemu-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.c | 2 |
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) |