Skip to content

Commit

Permalink
io: remove io watch if TLS channel is closed during handshake
Browse files Browse the repository at this point in the history
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.

CVE-2023-3354
Reported-by: jiangyegen <jiangyegen@huawei.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
  • Loading branch information
berrange committed Aug 1, 2023
1 parent 8023418 commit 10be627
Show file tree
Hide file tree
Showing 2 changed files with 13 additions and 6 deletions.
1 change: 1 addition & 0 deletions include/io/channel-tls.h
Expand Up @@ -48,6 +48,7 @@ struct QIOChannelTLS {
QIOChannel *master;
QCryptoTLSSession *session;
QIOChannelShutdown shutdown;
guint hs_ioc_tag;
};

/**
Expand Down
18 changes: 12 additions & 6 deletions io/channel-tls.c
Expand Up @@ -198,12 +198,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);
}
}

Expand All @@ -218,6 +219,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);

Expand Down Expand Up @@ -378,6 +380,10 @@ static int qio_channel_tls_close(QIOChannel *ioc,
{
QIOChannelTLS *tioc = QIO_CHANNEL_TLS(ioc);

if (tioc->hs_ioc_tag) {
g_clear_handle_id(&tioc->hs_ioc_tag, g_source_remove);
}

return qio_channel_close(tioc->master, errp);
}

Expand Down

0 comments on commit 10be627

Please sign in to comment.