• E
    nbd: Fully initialize client in case of failed negotiation · df8ad9f1
    Eric Blake 提交于
    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=1451614Signed-off-by: NEric Blake <eblake@redhat.com>
    Message-Id: <20170527030421.28366-1-eblake@redhat.com>
    Signed-off-by: NPaolo Bonzini <pbonzini@redhat.com>
    df8ad9f1
server.c 38.7 KB