Sign Up
Log In
Log In
or
Sign Up
Places
All Projects
Status Monitor
Collapse sidebar
SUSE:SLE-12-SP2:Update
qemu-linux-user
0240-nbd-Fully-initialize-client-in-case.patch
Overview
Repositories
Revisions
Requests
Users
Attributes
Meta
File 0240-nbd-Fully-initialize-client-in-case.patch of Package qemu-linux-user
From: Eric Blake <eblake@redhat.com> Date: Fri, 26 May 2017 22:04:21 -0500 Subject: 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) [FL: BSC#1043808 CVE-2017-9524] Signed-off-by: Fei Li <fli@suse.com> --- nbd/server.c | 8 ++++---- qemu-nbd.c | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/nbd/server.c b/nbd/server.c index 8639ecbe9270e5463ecd05a27bbd..493e8421b7f1e853ccdccef2b79a 100644 --- a/nbd/server.c +++ b/nbd/server.c @@ -1257,17 +1257,17 @@ 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); + nbd_set_handlers(client); - if (exp) { - QTAILQ_INSERT_TAIL(&exp->clients, client, next); - } out: g_free(data); } diff --git a/qemu-nbd.c b/qemu-nbd.c index 6dea6d69d23b264d5ee277d674c2..946ea9d6c7168258d064d6ea7dd1 100644 --- a/qemu-nbd.c +++ b/qemu-nbd.c @@ -309,7 +309,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)
Locations
Projects
Search
Status Monitor
Help
OpenBuildService.org
Documentation
API Documentation
Code of Conduct
Contact
Support
@OBShq
Terms
openSUSE Build Service is sponsored by
The Open Build Service is an
openSUSE project
.
Sign Up
Log In
Places
Places
All Projects
Status Monitor