[glib-networking/wip/pwithnall/dtls: 3/18] gnutls: Fix leaking GTask on TLS close after implicit handshake



commit a0e14e8ca722a49f313658800993699d588e1cc7
Author: Philip Withnall <philip withnall collabora co uk>
Date:   Wed Sep 17 13:13:06 2014 +0100

    gnutls: Fix leaking GTask on TLS close after implicit handshake
    
    If a GTlsConnectionGnutls is created and an implicit handshake operation
    is started on it (e.g. via a read), if the handshake doesn’t complete
    and close() is called on the connection without any other operations
    being called first, the GTlsConnectionGnutls.implicit_handshake GTask
    will be leaked. Since it holds a reference to the GTlsConnectionGnutls
    connection as a whole, that object will be leaked too in a reference
    cycle.
    
    Fix this by explicitly clearing implicit_handshake when claiming
    OP_CLOSE, instead of ignoring it. Any errors from the handshake process
    are ignored as before, however.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=736809

 tls/gnutls/gtlsconnection-gnutls.c |   11 +++++++----
 1 files changed, 7 insertions(+), 4 deletions(-)
---
diff --git a/tls/gnutls/gtlsconnection-gnutls.c b/tls/gnutls/gtlsconnection-gnutls.c
index 8fc71f6..0a7b826 100644
--- a/tls/gnutls/gtlsconnection-gnutls.c
+++ b/tls/gnutls/gtlsconnection-gnutls.c
@@ -588,10 +588,10 @@ claim_op (GTlsConnectionGnutls    *gnutls,
       return FALSE;
     }
 
-  if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE &&
-      op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE)
+  if (op != G_TLS_CONNECTION_GNUTLS_OP_HANDSHAKE)
     {
-      if (gnutls->priv->need_handshake)
+      if (op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE &&
+          gnutls->priv->need_handshake)
        {
          gnutls->priv->need_handshake = FALSE;
          gnutls->priv->handshaking = TRUE;
@@ -615,12 +615,15 @@ claim_op (GTlsConnectionGnutls    *gnutls,
          g_clear_object (&gnutls->priv->implicit_handshake);
          g_mutex_lock (&gnutls->priv->op_mutex);
 
-         if (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error))
+         if (op != G_TLS_CONNECTION_GNUTLS_OP_CLOSE &&
+             (!success || g_cancellable_set_error_if_cancelled (cancellable, &my_error)))
            {
              g_propagate_error (error, my_error);
              g_mutex_unlock (&gnutls->priv->op_mutex);
              return FALSE;
            }
+
+          g_clear_error (&my_error);
        }
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]