@@ -21,12 +21,18 @@
#include "io/channel-socket.h"
#include "io/net-listener.h"
+typedef struct NBDConn {
+ QIOChannelSocket *cioc;
+ QSLIST_ENTRY(NBDConn) next;
+} NBDConn;
+
typedef struct NBDServerData {
QIONetListener *listener;
QCryptoTLSCreds *tlscreds;
char *tlsauthz;
uint32_t max_connections;
uint32_t connections;
+ QSLIST_HEAD(, NBDConn) conns;
} NBDServerData;
static NBDServerData *nbd_server;
@@ -65,8 +71,13 @@ static void nbd_blockdev_client_closed(NBDClient *client, uint32_t cookie,
static void nbd_accept(QIONetListener *listener, QIOChannelSocket *cioc,
gpointer opaque)
{
+ NBDConn *conn = g_new0(NBDConn, 1);
+
assert(nbd_server);
nbd_server->connections++;
+ object_ref(OBJECT(cioc));
+ conn->cioc = cioc;
+ QSLIST_INSERT_HEAD(&nbd_server->conns, conn, next);
nbd_update_server_watch(nbd_server);
qio_channel_set_name(QIO_CHANNEL(cioc), "nbd-server");
@@ -89,8 +100,21 @@ static void nbd_server_free(NBDServerData *server)
return;
}
+ /*
+ * Forcefully close the listener socket, and any clients that have
+ * not yet disconnected on their own.
+ */
qio_net_listener_disconnect(server->listener);
object_unref(OBJECT(server->listener));
+ while (!QSLIST_EMPTY(&server->conns)) {
+ NBDConn *conn = QSLIST_FIRST(&server->conns);
+
+ qio_channel_close(QIO_CHANNEL(conn->cioc), NULL);
+ object_unref(OBJECT(conn->cioc));
+ QSLIST_REMOVE_HEAD(&server->conns, next);
+ g_free(conn);
+ }
if (server->tlscreds) {
object_unref(OBJECT(server->tlscreds));
}
--
2.45.2
A malicious client can attempt to connect to an NBD server, and then intentionally not progress in the handshake. This can form a resource leak for as long as the client wants, when the client does not catch our attention by failing to provide TLS credentials; although it can be bounded by max-connections per NBD server that does not use the default of unlimited. Better is to forcefully disconnect any remaining client sockets when the NBD server is shut down. While less severe than the issue fixed in the previous patch, this can still be considered defense against a potential denial of service attack, so it is still categorized under the same CVE. Signed-off-by: Eric Blake <eblake@redhat.com> --- I do not know if I need to worry about multi-threaded access (is it possible that more than one client trying to connect simultaneously means that I need to access nbd_server->conns atomically)? blockdev-nbd.c | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)