[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [PATCH v4 5/7] nbd/server: CVE-2024-7409: Close stray client sockets
From: |
Eric Blake |
Subject: |
Re: [PATCH v4 5/7] nbd/server: CVE-2024-7409: Close stray client sockets at shutdown |
Date: |
Wed, 7 Aug 2024 16:30:09 -0500 |
User-agent: |
NeoMutt/20240425 |
On Wed, Aug 07, 2024 at 07:29:25PM GMT, Daniel P. Berrangé wrote:
> On Wed, Aug 07, 2024 at 12:43:31PM -0500, Eric Blake wrote:
> > A malicious client can attempt to connect to an NBD server, and then
> > intentionally delay progress in the handshake, including if it does
> > not know the TLS secrets. Although this behavior can be bounded by
> > the max-connections parameter, the QMP nbd-server-start currently
> > defaults to unlimited incoming client connections. Worse, if the
I need to touch that sentence up to match the earlier patches. (The
curse of rebasing late at night...)
> > client waits to close the socket until after the QMP nbd-server-stop
> > command is executed, qemu will then SEGV when trying to dereference
> > the NULL nbd_server global which is no longer present, which amounts
> > to a denial of service attack. If another NBD server is started
> > before the malicious client disconnects, I cannot rule out additional
> > adverse effects when the old client interferes with the connection
> > count of the new server.
I _think_ the effect is most likely to be an assertion failure
(nbd_server->connections > 0), since we recommend compiling qemu with
assertions enabled. But "most likely" is not the same as "certainty".
> >
> > For environments without this patch, the CVE can be mitigated by
> > ensuring (such as via a firewall) that only trusted clients can
> > connect to an NBD server. Note that using frameworks like libvirt
> > that ensure that TLS is used and that nbd-server-stop is not executed
> > while any trusted clients are still connected will only help if there
> > is also no possibility for an untrusted client to open a connection
> > but then stall on the NBD handshake.
> >
> > Given the previous patches, it would be possible to guarantee that no
> > clients remain connected by having nbd-server-stop sleep for longer
> > than the default handshake deadline before finally freeing the global
> > nbd_server object, but that could make QMP non-responsive for a long
> > time. So intead, this patch fixes the problem by tracking all client
> > sockets opened while the server is running, and forcefully closing any
> > such sockets remaining without a completed handshake at the time of
> > nbd-server-stop, then waiting until the coroutines servicing those
> > sockets notice the state change. nbd-server-stop now has a second
> > AIO_WAIT_WHILE_UNLOCKED (the first is indirectly through the
> > blk_exp_close_all_type() that disconnects all clients that completed
> > handshakes), but forced socket shutdown is enough to progress the
> > coroutines and quickly tear down all clients before the server is
> > freed, thus finally fixing the CVE.
> >
> > This patch relies heavily on the fact that nbd/server.c guarantees
> > that it only calls nbd_blockdev_client_closed() from the main loop
> > (see the assertion in nbd_client_put() and the hoops used in
> > nbd_client_put_nonzero() to achieve that); if we did not have that
> > guarantee, we would also need a mutex protecting our accesses of the
> > list of connections to survive re-entrancy from independent iothreads.
> >
> > Although I did not actually try to test old builds, it looks like this
> > problem has existed since at least commit 862172f45c (v2.12.0, 2017) -
> > even back when that patch started using a QIONetListener to handle
> > listening on multiple sockets, nbd_server_free() was already unaware
> > that the nbd_blockdev_client_closed callback can be reached later by a
> > client thread that has not completed handshakes (and therefore the
> > client's socket never got added to the list closed in
> > nbd_export_close_all), despite that patch intentionally tearing down
> > the QIONetListener to prevent new clients.
> >
> > Reported-by: Alexander Ivanov <alexander.ivanov@virtuozzo.com>
> > Fixes: CVE-2024-7409
> > Signed-off-by: Eric Blake <eblake@redhat.com>
> > ---
> > blockdev-nbd.c | 35 ++++++++++++++++++++++++++++++++++-
> > 1 file changed, 34 insertions(+), 1 deletion(-)
>
> Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
Thanks for a speedy review.
--
Eric Blake, Principal Software Engineer
Red Hat, Inc.
Virtualization: qemu.org | libguestfs.org
- Re: [PATCH v4 2/7] nbd/server: Plumb in new args to nbd_client_add(), (continued)
- [PATCH v4 1/7] nbd: Minor style fixes, Eric Blake, 2024/08/07
- [PATCH v4 3/7] nbd/server: CVE-2024-7409: Change default max-connections to 100, Eric Blake, 2024/08/07
- [PATCH v4 4/7] nbd/server: CVE-2024-7409: Drop non-negotiating clients, Eric Blake, 2024/08/07
- [PATCH v4 5/7] nbd/server: CVE-2024-7409: Close stray client sockets at shutdown, Eric Blake, 2024/08/07
- [PATCH v4 6/7] qemu-nbd: Allow users to adjust handshake limit, Eric Blake, 2024/08/07
- [PATCH v4 7/7] nbd/server: Allow users to adjust handshake limit in QMP, Eric Blake, 2024/08/07
- Re: [PATCH for-9.1 v4 0/7] CVE-2024-7409, Denis V. Lunev, 2024/08/22