On Wed, Jul 5, 2023 at 10:20 PM Daniel P. Berrangé <berra...@redhat.com>
wrote:

> 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 <jiangye...@huawei.com>
> Signed-off-by: Daniel P. Berrangé <berra...@redhat.com>
>



> ---
>  include/io/channel-tls.h |  1 +
>  io/channel-tls.c         | 18 ++++++++++++------
>  2 files changed, 13 insertions(+), 6 deletions(-)
>
> diff --git a/include/io/channel-tls.h b/include/io/channel-tls.h
> index 5672479e9e..26c67f17e2 100644
> --- a/include/io/channel-tls.h
> +++ b/include/io/channel-tls.h
> @@ -48,6 +48,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 9805dd0a3f..e327e6a5c2 100644
> --- a/io/channel-tls.c
> +++ b/io/channel-tls.c
> @@ -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);
>      }
>  }
>
> @@ -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);
>
> @@ -378,6 +380,10 @@ 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);
>

set it to 0 ?
or
g_clear_handle_id(&tios->hs_ioc_tag, g_source_remove);


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

-- 
Marc-André Lureau

Reply via email to