- accel/tcg: fix race in cpu_exec_step_atomic (bug 1863025) - pci: assert configuration access is within bounds - io: remove io watch if TLS channel is closed during handshake Signed-off-by: Jiabo Feng <fengjiabo1@huawei.com>
88 lines
3.0 KiB
Diff
88 lines
3.0 KiB
Diff
From 3eca3cc3ce4c5553680ca3bab533443460c570d6 Mon Sep 17 00:00:00 2001
|
|
From: =?UTF-8?q?Daniel=20P=2E=20Berrang=C3=A9?= <berrange@redhat.com>
|
|
Date: Tue, 20 Jun 2023 09:45:34 +0100
|
|
Subject: [PATCH] io: remove io watch if TLS channel is closed during handshake
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
The TLS handshake make take some time to complete, during which time an
|
|
I/O watch might be registered with the main loop. If the owner of the
|
|
I/O channel invokes qio_channel_close() while the handshake is waiting
|
|
to continue the I/O watch must be removed. Failing to remove it will
|
|
later trigger the completion callback which the owner is not expecting
|
|
to receive. In the case of the VNC server, this results in a SEGV as
|
|
vnc_disconnect_start() tries to shutdown a client connection that is
|
|
already gone / NULL.
|
|
|
|
---------------------------------------------------------------------
|
|
Note: g_clear_handle_id is not available before glibc-2.56, modify it.
|
|
|
|
CVE-2023-3354
|
|
Reported-by: jiangyegen <jiangyegen@huawei.com>
|
|
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
|
|
---
|
|
include/io/channel-tls.h | 1 +
|
|
io/channel-tls.c | 19 +++++++++++++------
|
|
2 files changed, 14 insertions(+), 6 deletions(-)
|
|
|
|
diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
|
|
index fdbdf12feb..e49e2831a2 100644
|
|
--- a/include/io/channel-tls.h
|
|
+++ b/include/io/channel-tls.h
|
|
@@ -49,6 +49,7 @@ struct QIOChannelTLS {
|
|
QIOChannel *master;
|
|
QCryptoTLSSession *session;
|
|
QIOChannelShutdown shutdown;
|
|
+ guint hs_ioc_tag;
|
|
};
|
|
|
|
/**
|
|
diff --git a/io/channel-tls.c b/io/channel-tls.c
|
|
index 7ec8ceff2f..b0bdbd428f 100644
|
|
--- a/io/channel-tls.c
|
|
+++ b/io/channel-tls.c
|
|
@@ -194,12 +194,13 @@ static void qio_channel_tls_handshake_task(QIOChannelTLS *ioc,
|
|
}
|
|
|
|
trace_qio_channel_tls_handshake_pending(ioc, status);
|
|
- qio_channel_add_watch_full(ioc->master,
|
|
- condition,
|
|
- qio_channel_tls_handshake_io,
|
|
- data,
|
|
- NULL,
|
|
- context);
|
|
+ ioc->hs_ioc_tag =
|
|
+ qio_channel_add_watch_full(ioc->master,
|
|
+ condition,
|
|
+ qio_channel_tls_handshake_io,
|
|
+ data,
|
|
+ NULL,
|
|
+ context);
|
|
}
|
|
}
|
|
|
|
@@ -214,6 +215,7 @@ static gboolean qio_channel_tls_handshake_io(QIOChannel *ioc,
|
|
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(
|
|
qio_task_get_source(task));
|
|
|
|
+ tioc->hs_ioc_tag = 0;
|
|
g_free(data);
|
|
qio_channel_tls_handshake_task(tioc, task, context);
|
|
|
|
@@ -371,6 +373,11 @@ static int qio_channel_tls_close(QIOChannel *ioc,
|
|
{
|
|
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);
|
|
|
|
+ if (tioc->hs_ioc_tag) {
|
|
+ g_source_remove(tioc->hs_ioc_tag);
|
|
+ tioc->hs_ioc_tag = 0;
|
|
+ }
|
|
+
|
|
return qio_channel_close(tioc->master, errp);
|
|
}
|
|
|
|
--
|
|
2.41.0.windows.1
|
|
|