<feed xmlns='http://www.w3.org/2005/Atom'>
<title>qemu/nbd, branch master</title>
<subtitle>QEMU development tree</subtitle>
<id>https://git.zx2c4.com/qemu/atom/nbd?h=master</id>
<link rel='self' href='https://git.zx2c4.com/qemu/atom/nbd?h=master'/>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/'/>
<updated>2024-08-08T21:25:33Z</updated>
<entry>
<title>nbd/server: CVE-2024-7409: Drop non-negotiating clients</title>
<updated>2024-08-08T21:25:33Z</updated>
<author>
<name>Eric Blake</name>
<email>eblake@redhat.com</email>
</author>
<published>2024-08-08T21:05:08Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=b9b72cb3ce15b693148bd09cef7e50110566d8a0'/>
<id>urn:sha1:b9b72cb3ce15b693148bd09cef7e50110566d8a0</id>
<content type='text'>
A client that opens a socket but does not negotiate is merely hogging
qemu's resources (an open fd and a small amount of memory); and a
malicious client that can access the port where NBD is listening can
attempt a denial of service attack by intentionally opening and
abandoning lots of unfinished connections.  The previous patch put a
default bound on the number of such ongoing connections, but once that
limit is hit, no more clients can connect (including legitimate ones).
The solution is to insist that clients complete handshake within a
reasonable time limit, defaulting to 10 seconds.  A client that has
not successfully completed NBD_OPT_GO by then (including the case of
where the client didn't know TLS credentials to even reach the point
of NBD_OPT_GO) is wasting our time and does not deserve to stay
connected.  Later patches will allow fine-tuning the limit away from
the default value (including disabling it for doing integration
testing of the handshake process itself).

Note that this patch in isolation actually makes it more likely to see
qemu SEGV after nbd-server-stop, as any client socket still connected
when the server shuts down will now be closed after 10 seconds rather
than at the client's whims.  That will be addressed in the next patch.

For a demo of this patch in action:
$ qemu-nbd -f raw -r -t -e 10 file &amp;
$ nbdsh --opt-mode -c '
H = list()
for i in range(20):
  print(i)
  H.insert(i, nbd.NBD())
  H[i].set_opt_mode(True)
  H[i].connect_uri("nbd://localhost")
'
$ kill $!

where later connections get to start progressing once earlier ones are
forcefully dropped for taking too long, rather than hanging.

Suggested-by: Daniel P. Berrangé &lt;berrange@redhat.com&gt;
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
Message-ID: &lt;20240807174943.771624-13-eblake@redhat.com&gt;
Reviewed-by: Daniel P. Berrangé &lt;berrange@redhat.com&gt;
[eblake: rebase to changes earlier in series, reduce scope of timer]
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: Plumb in new args to nbd_client_add()</title>
<updated>2024-08-08T20:05:27Z</updated>
<author>
<name>Eric Blake</name>
<email>eblake@redhat.com</email>
</author>
<published>2024-08-07T13:50:01Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=fb1c2aaa981e0a2fa6362c9985f1296b74f055ac'/>
<id>urn:sha1:fb1c2aaa981e0a2fa6362c9985f1296b74f055ac</id>
<content type='text'>
Upcoming patches to fix a CVE need to track an opaque pointer passed
in by the owner of a client object, as well as request for a time
limit on how fast negotiation must complete.  Prepare for that by
changing the signature of nbd_client_new() and adding an accessor to
get at the opaque pointer, although for now the two servers
(qemu-nbd.c and blockdev-nbd.c) do not change behavior even though
they pass in a new default timeout value.

Suggested-by: Vladimir Sementsov-Ogievskiy &lt;vsementsov@yandex-team.ru&gt;
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
Message-ID: &lt;20240807174943.771624-11-eblake@redhat.com&gt;
Reviewed-by: Daniel P. Berrangé &lt;berrange@redhat.com&gt;
[eblake: s/LIMIT/MAX_SECS/ as suggested by Dan]
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd: Minor style and typo fixes</title>
<updated>2024-08-08T15:18:22Z</updated>
<author>
<name>Eric Blake</name>
<email>eblake@redhat.com</email>
</author>
<published>2024-08-01T21:49:20Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=c719573d71afd38e3ac774e5a331fbaa0fc9f3da'/>
<id>urn:sha1:c719573d71afd38e3ac774e5a331fbaa0fc9f3da</id>
<content type='text'>
Touch up a comment with the wrong type name, and an over-long line,
both noticed while working on upcoming patches.

Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
Message-ID: &lt;20240807174943.771624-10-eblake@redhat.com&gt;
Reviewed-by: Daniel P. Berrangé &lt;berrange@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: Mark negotiation functions as coroutine_fn</title>
<updated>2024-04-25T17:59:19Z</updated>
<author>
<name>Eric Blake</name>
<email>eblake@redhat.com</email>
</author>
<published>2024-04-08T16:00:44Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=4fa333e08dd96395a99ea8dd9e4c73a29dd23344'/>
<id>urn:sha1:4fa333e08dd96395a99ea8dd9e4c73a29dd23344</id>
<content type='text'>
nbd_negotiate() is already marked coroutine_fn.  And given the fix in
the previous patch to have nbd_negotiate_handle_starttls not create
and wait on a g_main_loop (as that would violate coroutine
constraints), it is worth marking the rest of the related static
functions reachable only during option negotiation as also being
coroutine_fn.

Suggested-by: Vladimir Sementsov-Ogievskiy &lt;vsementsov@yandex-team.ru&gt;
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
Message-ID: &lt;20240408160214.1200629-6-eblake@redhat.com&gt;
Reviewed-by: Vladimir Sementsov-Ogievskiy &lt;vsementsov@yandex-team.ru&gt;
[eblake: drop one spurious coroutine_fn marking]
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: do not poll within a coroutine context</title>
<updated>2024-04-25T12:56:16Z</updated>
<author>
<name>Zhu Yangyang</name>
<email>zhuyangyang14@huawei.com</email>
</author>
<published>2024-04-08T16:00:43Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=ae6d91a7e9b77abb029ed3fa9fad461422286942'/>
<id>urn:sha1:ae6d91a7e9b77abb029ed3fa9fad461422286942</id>
<content type='text'>
Coroutines are not supposed to block. Instead, they should yield.

The client performs TLS upgrade outside of an AIOContext, during
synchronous handshake; this still requires g_main_loop.  But the
server responds to TLS upgrade inside a coroutine, so a nested
g_main_loop is wrong.  Since the two callbacks no longer share more
than the setting of data.complete and data.error, it's just as easy to
use static helpers instead of trying to share a common code path.  It
is also possible to add assertions that no other code is interfering
with the eventual path to qio reaching the callback, whether or not it
required a yield or main loop.

Fixes: f95910f ("nbd: implement TLS support in the protocol negotiation")
Signed-off-by: Zhu Yangyang &lt;zhuyangyang14@huawei.com&gt;
[eblake: move callbacks to their use point, add assertions]
Signed-off-by: Eric Blake &lt;eblake@redhat.com&gt;
Message-ID: &lt;20240408160214.1200629-5-eblake@redhat.com&gt;
Reviewed-by: Vladimir Sementsov-Ogievskiy &lt;vsementsov@yandex-team.ru&gt;
</content>
</entry>
<entry>
<title>nbd/server: Fix race in draining the export</title>
<updated>2024-03-18T11:38:02Z</updated>
<author>
<name>Kevin Wolf</name>
<email>kwolf@redhat.com</email>
</author>
<published>2024-03-14T16:58:24Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=9c707525cbb1dd1e56876e45c70c0c08f2876d41'/>
<id>urn:sha1:9c707525cbb1dd1e56876e45c70c0c08f2876d41</id>
<content type='text'>
When draining an NBD export, nbd_drained_begin() first sets
client-&gt;quiescing so that nbd_client_receive_next_request() won't start
any new request coroutines. Then nbd_drained_poll() tries to makes sure
that we wait for any existing request coroutines by checking that
client-&gt;nb_requests has become 0.

However, there is a small window between creating a new request
coroutine and increasing client-&gt;nb_requests. If a coroutine is in this
state, it won't be waited for and drain returns too early.

In the context of switching to a different AioContext, this means that
blk_aio_attached() will see client-&gt;recv_coroutine != NULL and fail its
assertion.

Fix this by increasing client-&gt;nb_requests immediately when starting the
coroutine. Doing this after the checks if we should create a new
coroutine is okay because client-&gt;lock is held.

Cc: qemu-stable@nongnu.org
Fixes: fd6afc501a01 ("nbd/server: Use drained block ops to quiesce the server")
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
Message-ID: &lt;20240314165825.40261-2-kwolf@redhat.com&gt;
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: introduce NBDClient-&gt;lock to protect fields</title>
<updated>2023-12-21T20:59:10Z</updated>
<author>
<name>Stefan Hajnoczi</name>
<email>stefanha@redhat.com</email>
</author>
<published>2023-12-21T19:24:52Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=7075d235114b40b30524cf1c5b61906c0bbf5f4d'/>
<id>urn:sha1:7075d235114b40b30524cf1c5b61906c0bbf5f4d</id>
<content type='text'>
NBDClient has a number of fields that are accessed by both the export
AioContext and the main loop thread. When the AioContext lock is removed
these fields will need another form of protection.

Add NBDClient-&gt;lock and protect fields that are accessed by both
threads. Also add assertions where possible and otherwise add doc
comments stating assumptions about which thread and lock holding.

Note this patch moves the client-&gt;recv_coroutine assertion from
nbd_co_receive_request() to nbd_trip() where client-&gt;lock is held.

Signed-off-by: Stefan Hajnoczi &lt;stefanha@redhat.com&gt;
Message-ID: &lt;20231221192452.1785567-7-stefanha@redhat.com&gt;
Reviewed-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: only traverse NBDExport-&gt;clients from main loop thread</title>
<updated>2023-12-21T20:59:07Z</updated>
<author>
<name>Stefan Hajnoczi</name>
<email>stefanha@redhat.com</email>
</author>
<published>2023-12-21T19:24:51Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=f816310d0c32c8482e56807ea0f9faa8d1b5f696'/>
<id>urn:sha1:f816310d0c32c8482e56807ea0f9faa8d1b5f696</id>
<content type='text'>
The NBD clients list is currently accessed from both the export
AioContext and the main loop thread. When the AioContext lock is removed
there will be nothing protecting the clients list.

Adding a lock around the clients list is tricky because NBDClient
structs are refcounted and may be freed from the export AioContext or
the main loop thread. nbd_export_request_shutdown() -&gt; client_close() -&gt;
nbd_client_put() is also tricky because the list lock would be held
while indirectly dropping references to NDBClients.

A simpler approach is to only allow nbd_client_put() and client_close()
calls from the main loop thread. Then the NBD clients list is only
accessed from the main loop thread and no fancy locking is needed.

nbd_trip() just needs to reschedule itself in the main loop AioContext
before calling nbd_client_put() and client_close(). This costs more CPU
cycles per NBD request so add nbd_client_put_nonzero() to optimize the
common case where more references to NBDClient remain.

Note that nbd_client_get() can still be called from either thread, so
make NBDClient-&gt;refcount atomic.

Signed-off-by: Stefan Hajnoczi &lt;stefanha@redhat.com&gt;
Message-ID: &lt;20231221192452.1785567-6-stefanha@redhat.com&gt;
Reviewed-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
</content>
</entry>
<entry>
<title>nbd/server: avoid per-NBDRequest nbd_client_get/put()</title>
<updated>2023-12-21T20:59:03Z</updated>
<author>
<name>Stefan Hajnoczi</name>
<email>stefanha@redhat.com</email>
</author>
<published>2023-12-21T19:24:50Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=efade66d5872e3bfb906944105145007ff2e26a3'/>
<id>urn:sha1:efade66d5872e3bfb906944105145007ff2e26a3</id>
<content type='text'>
nbd_trip() processes a single NBD request from start to finish and holds
an NBDClient reference throughout. NBDRequest does not outlive the scope
of nbd_trip(). Therefore it is unnecessary to ref/unref NBDClient for
each NBDRequest.

Removing these nbd_client_get()/nbd_client_put() calls will make
thread-safety easier in the commits that follow.

Signed-off-by: Stefan Hajnoczi &lt;stefanha@redhat.com&gt;
Reviewed-by: Paolo Bonzini &lt;pbonzini@redhat.com&gt;
Message-ID: &lt;20231221192452.1785567-5-stefanha@redhat.com&gt;
Reviewed-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
</content>
</entry>
<entry>
<title>block: Mark bdrv_filter_or_cow_bs() and callers GRAPH_RDLOCK</title>
<updated>2023-11-07T18:14:19Z</updated>
<author>
<name>Kevin Wolf</name>
<email>kwolf@redhat.com</email>
</author>
<published>2023-10-27T15:53:15Z</published>
<link rel='alternate' type='text/html' href='https://git.zx2c4.com/qemu/commit/?id=372b69f503d47eb6619a98cac2ab5a6a569e3483'/>
<id>urn:sha1:372b69f503d47eb6619a98cac2ab5a6a569e3483</id>
<content type='text'>
This adds GRAPH_RDLOCK annotations to declare that callers of
bdrv_filter_or_cow_bs() need to hold a reader lock for the graph because
it calls bdrv_filter_or_cow_child(), which accesses bs-&gt;file/backing.

Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
Message-ID: &lt;20231027155333.420094-7-kwolf@redhat.com&gt;
Reviewed-by: Eric Blake &lt;eblake@redhat.com&gt;
Signed-off-by: Kevin Wolf &lt;kwolf@redhat.com&gt;
</content>
</entry>
</feed>
