|
| 1 | +From 50838ec94696282406d9cee47f41ca7c11f68694 Mon Sep 17 00:00:00 2001 |
| 2 | +From: Michael Catanzaro <mcatanzaro@redhat.com> |
| 3 | +Date: Wed, 14 Jan 2026 11:39:18 -0600 |
| 4 | +Subject: [PATCH] server-connection: check for cancellation in handshake |
| 5 | + callback |
| 6 | + |
| 7 | +If the SoupServerConnection is destroyed before the TLS handshake |
| 8 | +completes, then we have a use after free of the SoupServerConnection in |
| 9 | +tls_connection_handshake_ready_cb(). |
| 10 | + |
| 11 | +Spotted in #YWH-PGM9867-161. (I have not created a libsoup issue report |
| 12 | +for -161 because it was rejected by our triagers due to errors.) |
| 13 | + |
| 14 | +Signed-off-by: Azure Linux Security Servicing Account <azurelinux-security@microsoft.com> |
| 15 | +Upstream-reference: https://gitlab.gnome.org/GNOME/libsoup/-/merge_requests/495.patch |
| 16 | +--- |
| 17 | + libsoup/server/soup-server-connection.c | 12 +++++++++--- |
| 18 | + 1 file changed, 9 insertions(+), 3 deletions(-) |
| 19 | + |
| 20 | +diff --git a/libsoup/server/soup-server-connection.c b/libsoup/server/soup-server-connection.c |
| 21 | +index cac4eaa..7d4064a 100644 |
| 22 | +--- a/libsoup/server/soup-server-connection.c |
| 23 | ++++ b/libsoup/server/soup-server-connection.c |
| 24 | +@@ -62,6 +62,7 @@ typedef struct { |
| 25 | + gboolean advertise_http2; |
| 26 | + SoupHTTPVersion http_version; |
| 27 | + SoupServerMessageIO *io_data; |
| 28 | ++ GCancellable *cancellable; |
| 29 | + |
| 30 | + GSocketAddress *local_addr; |
| 31 | + GSocketAddress *remote_addr; |
| 32 | +@@ -86,6 +87,7 @@ soup_server_connection_init (SoupServerConnection *conn) |
| 33 | + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); |
| 34 | + |
| 35 | + priv->http_version = SOUP_HTTP_1_1; |
| 36 | ++ priv->cancellable = g_cancellable_new (); |
| 37 | + } |
| 38 | + |
| 39 | + static void |
| 40 | +@@ -109,6 +111,9 @@ soup_server_connection_finalize (GObject *object) |
| 41 | + SoupServerConnection *conn = SOUP_SERVER_CONNECTION (object); |
| 42 | + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); |
| 43 | + |
| 44 | ++ g_cancellable_cancel (priv->cancellable); |
| 45 | ++ g_clear_object (&priv->cancellable); |
| 46 | ++ |
| 47 | + if (priv->conn) { |
| 48 | + disconnect_internal (conn); |
| 49 | + } else { |
| 50 | +@@ -428,8 +433,9 @@ tls_connection_handshake_ready_cb (GTlsConnection *tls_conn, |
| 51 | + SoupServerConnection *conn) |
| 52 | + { |
| 53 | + SoupServerConnectionPrivate *priv = soup_server_connection_get_instance_private (conn); |
| 54 | ++ GError *error = NULL; |
| 55 | + |
| 56 | +- if (g_tls_connection_handshake_finish (tls_conn, result, NULL)) { |
| 57 | ++ if (g_tls_connection_handshake_finish (tls_conn, result, &error)) { |
| 58 | + const char *protocol = g_tls_connection_get_negotiated_protocol (tls_conn); |
| 59 | + |
| 60 | + if (g_strcmp0 (protocol, "h2") == 0) |
| 61 | +@@ -440,7 +446,7 @@ tls_connection_handshake_ready_cb (GTlsConnection *tls_conn, |
| 62 | + priv->http_version = SOUP_HTTP_1_1; |
| 63 | + |
| 64 | + soup_server_connection_connected (conn); |
| 65 | +- } else { |
| 66 | ++ } else if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_CANCELLED)) { |
| 67 | + soup_server_connection_disconnect (conn); |
| 68 | + } |
| 69 | + } |
| 70 | +@@ -518,7 +524,7 @@ soup_server_connection_accepted (SoupServerConnection *conn) |
| 71 | + conn, G_CONNECT_SWAPPED); |
| 72 | + |
| 73 | + g_tls_connection_handshake_async (G_TLS_CONNECTION (priv->conn), |
| 74 | +- G_PRIORITY_DEFAULT, NULL, |
| 75 | ++ G_PRIORITY_DEFAULT, priv->cancellable, |
| 76 | + (GAsyncReadyCallback)tls_connection_handshake_ready_cb, |
| 77 | + conn); |
| 78 | + return; |
| 79 | +-- |
| 80 | +2.45.4 |
| 81 | + |
0 commit comments