From 23673249846dc263607681b9b8db42dfa68e6cde Mon Sep 17 00:00:00 2001 From: Dan Winship Date: Mon, 4 Apr 2011 11:09:15 -0400 Subject: [PATCH] gnutls: fix leaks GTlsConnections were never being freed, due to circular refs. Additionally, certificates seen during handshaking, and a GSocketAddress used in the session cache code were being leaked. --- tls/gnutls/gtlsclientconnection-gnutls.c | 1 + tls/gnutls/gtlsconnection-gnutls.c | 2 ++ tls/gnutls/gtlsinputstream-gnutls.c | 25 ++++++++++++++++++++----- tls/gnutls/gtlsoutputstream-gnutls.c | 25 ++++++++++++++++++++----- 4 files changed, 43 insertions(+), 10 deletions(-) diff --git a/tls/gnutls/gtlsclientconnection-gnutls.c b/tls/gnutls/gtlsclientconnection-gnutls.c index 245fc09..2710e9c 100644 --- a/tls/gnutls/gtlsclientconnection-gnutls.c +++ b/tls/gnutls/gtlsclientconnection-gnutls.c @@ -156,6 +156,7 @@ g_tls_client_connection_gnutls_constructed (GObject *object) gnutls->priv->session_id = g_strdup_printf ("%s/%d", addrstr, port); g_free (addrstr); } + g_object_unref (remote_addr); } g_object_unref (base_conn); diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c index c0fb898..b741184 100644 --- a/tls/gnutls/gtlsconnection-gnutls.c +++ b/tls/gnutls/gtlsconnection-gnutls.c @@ -846,6 +846,8 @@ handshake_internal (GTlsConnectionGnutls *gnutls, for (i = num_certs - 1; i >= 0; i--) { cert = g_tls_certificate_gnutls_new (&certs[i], chain); + if (chain) + g_object_unref (chain); chain = cert; } } diff --git a/tls/gnutls/gtlsinputstream-gnutls.c b/tls/gnutls/gtlsinputstream-gnutls.c index dd22be5..6970883 100644 --- a/tls/gnutls/gtlsinputstream-gnutls.c +++ b/tls/gnutls/gtlsinputstream-gnutls.c @@ -38,14 +38,18 @@ struct _GTlsInputStreamGnutlsPrivate }; static void -g_tls_input_stream_gnutls_finalize (GObject *object) +g_tls_input_stream_gnutls_dispose (GObject *object) { GTlsInputStreamGnutls *stream = G_TLS_INPUT_STREAM_GNUTLS (object); if (stream->priv->conn) - g_object_unref (stream->priv->conn); + { + g_object_remove_weak_pointer (G_OBJECT (stream->priv->conn), + (gpointer *)&stream->priv->conn); + stream->priv->conn = NULL; + } - G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->finalize (object); + G_OBJECT_CLASS (g_tls_input_stream_gnutls_parent_class)->dispose (object); } static gssize @@ -57,6 +61,8 @@ g_tls_input_stream_gnutls_read (GInputStream *stream, { GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (stream); + g_return_val_if_fail (tls_stream->priv->conn != NULL, -1); + return g_tls_connection_gnutls_read (tls_stream->priv->conn, buffer, count, TRUE, cancellable, error); @@ -117,6 +123,8 @@ g_tls_input_stream_gnutls_read_async (GInputStream *stream, GError *error = NULL; GSource *source; + g_return_if_fail (tls_stream->priv->conn != NULL); + simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_tls_input_stream_gnutls_read_async); nread = g_tls_connection_gnutls_read (tls_stream->priv->conn, @@ -168,6 +176,8 @@ g_tls_input_stream_gnutls_pollable_is_readable (GPollableInputStream *pollable) { GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable); + g_return_val_if_fail (tls_stream->priv->conn != NULL, FALSE); + return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_IN); } @@ -177,6 +187,8 @@ g_tls_input_stream_gnutls_pollable_create_source (GPollableInputStream *pollable { GTlsInputStreamGnutls *tls_stream = G_TLS_INPUT_STREAM_GNUTLS (pollable); + g_return_val_if_fail (tls_stream->priv->conn != NULL, NULL); + return g_tls_connection_gnutls_create_source (tls_stream->priv->conn, G_IO_IN, cancellable); @@ -203,7 +215,7 @@ g_tls_input_stream_gnutls_class_init (GTlsInputStreamGnutlsClass *klass) g_type_class_add_private (klass, sizeof (GTlsInputStreamGnutlsPrivate)); - gobject_class->finalize = g_tls_input_stream_gnutls_finalize; + gobject_class->dispose = g_tls_input_stream_gnutls_dispose; input_stream_class->read_fn = g_tls_input_stream_gnutls_read; input_stream_class->read_async = g_tls_input_stream_gnutls_read_async; @@ -230,6 +242,9 @@ g_tls_input_stream_gnutls_new (GTlsConnectionGnutls *conn) GTlsInputStreamGnutls *tls_stream; tls_stream = g_object_new (G_TYPE_TLS_INPUT_STREAM_GNUTLS, NULL); - tls_stream->priv->conn = g_object_ref (conn); + tls_stream->priv->conn = conn; + g_object_add_weak_pointer (G_OBJECT (conn), + (gpointer *)&tls_stream->priv->conn); + return G_INPUT_STREAM (tls_stream); } diff --git a/tls/gnutls/gtlsoutputstream-gnutls.c b/tls/gnutls/gtlsoutputstream-gnutls.c index 462d74e..2e101e4 100644 --- a/tls/gnutls/gtlsoutputstream-gnutls.c +++ b/tls/gnutls/gtlsoutputstream-gnutls.c @@ -38,14 +38,18 @@ struct _GTlsOutputStreamGnutlsPrivate }; static void -g_tls_output_stream_gnutls_finalize (GObject *object) +g_tls_output_stream_gnutls_dispose (GObject *object) { GTlsOutputStreamGnutls *stream = G_TLS_OUTPUT_STREAM_GNUTLS (object); if (stream->priv->conn) - g_object_unref (stream->priv->conn); + { + g_object_remove_weak_pointer (G_OBJECT (stream->priv->conn), + (gpointer *)&stream->priv->conn); + stream->priv->conn = NULL; + } - G_OBJECT_CLASS (g_tls_output_stream_gnutls_parent_class)->finalize (object); + G_OBJECT_CLASS (g_tls_output_stream_gnutls_parent_class)->dispose (object); } static gssize @@ -57,6 +61,8 @@ g_tls_output_stream_gnutls_write (GOutputStream *stream, { GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (stream); + g_return_val_if_fail (tls_stream->priv->conn != NULL, -1); + return g_tls_connection_gnutls_write (tls_stream->priv->conn, buffer, count, TRUE, cancellable, error); @@ -117,6 +123,8 @@ g_tls_output_stream_gnutls_write_async (GOutputStream *stream, GError *error = NULL; GSource *source; + g_return_if_fail (tls_stream->priv->conn != NULL); + simple = g_simple_async_result_new (G_OBJECT (stream), callback, user_data, g_tls_output_stream_gnutls_write_async); nwrote = g_tls_connection_gnutls_write (tls_stream->priv->conn, @@ -168,6 +176,8 @@ g_tls_output_stream_gnutls_pollable_is_writable (GPollableOutputStream *pollable { GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable); + g_return_val_if_fail (tls_stream->priv->conn != NULL, FALSE); + return g_tls_connection_gnutls_check (tls_stream->priv->conn, G_IO_OUT); } @@ -177,6 +187,8 @@ g_tls_output_stream_gnutls_pollable_create_source (GPollableOutputStream *pollab { GTlsOutputStreamGnutls *tls_stream = G_TLS_OUTPUT_STREAM_GNUTLS (pollable); + g_return_val_if_fail (tls_stream->priv->conn != NULL, NULL); + return g_tls_connection_gnutls_create_source (tls_stream->priv->conn, G_IO_OUT, cancellable); @@ -203,7 +215,7 @@ g_tls_output_stream_gnutls_class_init (GTlsOutputStreamGnutlsClass *klass) g_type_class_add_private (klass, sizeof (GTlsOutputStreamGnutlsPrivate)); - gobject_class->finalize = g_tls_output_stream_gnutls_finalize; + gobject_class->dispose = g_tls_output_stream_gnutls_dispose; output_stream_class->write_fn = g_tls_output_stream_gnutls_write; output_stream_class->write_async = g_tls_output_stream_gnutls_write_async; @@ -230,6 +242,9 @@ g_tls_output_stream_gnutls_new (GTlsConnectionGnutls *conn) GTlsOutputStreamGnutls *tls_stream; tls_stream = g_object_new (G_TYPE_TLS_OUTPUT_STREAM_GNUTLS, NULL); - tls_stream->priv->conn = g_object_ref (conn); + tls_stream->priv->conn = conn; + g_object_add_weak_pointer (G_OBJECT (conn), + (gpointer *)&tls_stream->priv->conn); + return G_OUTPUT_STREAM (tls_stream); } -- 2.7.4