Blame SOURCES/0010-sasl-Rework-memory-handling-in-spice_channel_perform.patch

dfc2f2
From a79e780c83ed9d31115d18b642bee4ef889602cd Mon Sep 17 00:00:00 2001
dfc2f2
From: Christophe Fergeau <cfergeau@redhat.com>
dfc2f2
Date: Fri, 11 Oct 2013 19:56:25 +0200
dfc2f2
Subject: [PATCH] sasl: Rework memory handling in
dfc2f2
 spice_channel_perform_auth_sasl()
dfc2f2
dfc2f2
While looking at the SASL code, I noticed some memory leaks in error paths.
dfc2f2
This commit adds a cleanup: block to free some of the memory dynamically
dfc2f2
allocated in that function, and remove the corresponding g_free() from
dfc2f2
the regular code flow. This should ensure that both the regular path
dfc2f2
and the error paths free the same memory.
dfc2f2
dfc2f2
This fixes at least this 'mechlist' leak which I got during regular SASL
dfc2f2
PLAIN authentication:
dfc2f2
==3452== 6 bytes in 1 blocks are definitely lost in loss record 140 of 11,706
dfc2f2
==3452==    at 0x4A0645D: malloc (in /usr/lib64/valgrind/vgpreload_memcheck-amd64-linux.s
dfc2f2
==3452==    by 0x35BAC4EE6E: g_malloc (gmem.c:104)
dfc2f2
==3452==    by 0x5BF7CAA: spice_channel_perform_auth_sasl (spice-channel.c:1440)
dfc2f2
==3452==    by 0x5BF9033: spice_channel_recv_link_msg (spice-channel.c:1727)
dfc2f2
==3452==    by 0x5BFAECD: spice_channel_coroutine (spice-channel.c:2348)
dfc2f2
==3452==    by 0x5C35D6D: coroutine_trampoline (coroutine_ucontext.c:63)
dfc2f2
==3452==    by 0x5C35A1B: continuation_trampoline (continuation.c:51)
dfc2f2
==3452==    by 0x31342479BF: ??? (in /usr/lib64/libc-2.18.so)
dfc2f2
==3452==    by 0x75F2940591224CFF: ???
dfc2f2
==3452==    by 0xE756E5F: ???
dfc2f2
==3452==    by 0xE7589BF: ???
dfc2f2
==3452==    by 0xFFEFFF78F: ???
dfc2f2
==3452==    by 0x5BFCD92: g_io_wait_helper (gio-coroutine.c:43)
dfc2f2
=
dfc2f2
dfc2f2
Related: rhbz#1097338
dfc2f2
dfc2f2
(cherry picked from commit 76724d7cb6089b0b91b1cb19ca06f4f6ac145db7)
dfc2f2
---
dfc2f2
 gtk/spice-channel.c | 21 +++++++++++----------
dfc2f2
 1 file changed, 11 insertions(+), 10 deletions(-)
dfc2f2
dfc2f2
diff --git a/gtk/spice-channel.c b/gtk/spice-channel.c
dfc2f2
index f101c3a..1fa42c0 100644
dfc2f2
--- a/gtk/spice-channel.c
dfc2f2
+++ b/gtk/spice-channel.c
dfc2f2
@@ -1330,7 +1330,7 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel)
dfc2f2
     };
dfc2f2
     sasl_interact_t *interact = NULL;
dfc2f2
     guint32 len;
dfc2f2
-    char *mechlist;
dfc2f2
+    char *mechlist = NULL;
dfc2f2
     const char *mechname;
dfc2f2
     gboolean ret = FALSE;
dfc2f2
     GSocketAddress *addr = NULL;
dfc2f2
@@ -1385,8 +1385,6 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel)
dfc2f2
                           saslcb,
dfc2f2
                           SASL_SUCCESS_DATA,
dfc2f2
                           &saslconn);
dfc2f2
-    g_free(localAddr);
dfc2f2
-    g_free(remoteAddr);
dfc2f2
 
dfc2f2
     if (err != SASL_OK) {
dfc2f2
         g_critical("Failed to create SASL client context: %d (%s)",
dfc2f2
@@ -1435,8 +1433,6 @@ static gboolean spice_channel_perform_auth_sasl(SpiceChannel *channel)
dfc2f2
     spice_channel_read(channel, mechlist, len);
dfc2f2
     mechlist[len] = '\0';
dfc2f2
     if (c->has_error) {
dfc2f2
-        g_free(mechlist);
dfc2f2
-        mechlist = NULL;
dfc2f2
         goto error;
dfc2f2
     }
dfc2f2
 
dfc2f2
@@ -1452,8 +1448,6 @@ restart:
dfc2f2
     if (err != SASL_OK && err != SASL_CONTINUE && err != SASL_INTERACT) {
dfc2f2
         g_critical("Failed to start SASL negotiation: %d (%s)",
dfc2f2
                    err, sasl_errdetail(saslconn));
dfc2f2
-        g_free(mechlist);
dfc2f2
-        mechlist = NULL;
dfc2f2
         goto error;
dfc2f2
     }
dfc2f2
 
dfc2f2
@@ -1639,15 +1633,22 @@ complete:
dfc2f2
      * is defined to be sent unencrypted, and setting saslconn turns
dfc2f2
      * on the SSF layer encryption processing */
dfc2f2
     c->sasl_conn = saslconn;
dfc2f2
-    return ret;
dfc2f2
+    goto cleanup;
dfc2f2
 
dfc2f2
 error:
dfc2f2
-    g_clear_object(&addr);
dfc2f2
     if (saslconn)
dfc2f2
         sasl_dispose(&saslconn);
dfc2f2
     emit_main_context(channel, SPICE_CHANNEL_EVENT, SPICE_CHANNEL_ERROR_AUTH);
dfc2f2
     c->has_error = TRUE; /* force disconnect */
dfc2f2
-    return FALSE;
dfc2f2
+    ret = FALSE;
dfc2f2
+
dfc2f2
+cleanup:
dfc2f2
+    g_free(localAddr);
dfc2f2
+    g_free(remoteAddr);
dfc2f2
+    g_free(mechlist);
dfc2f2
+    g_free(serverin);
dfc2f2
+    g_clear_object(&addr);
dfc2f2
+    return ret;
dfc2f2
 }
dfc2f2
 #endif /* HAVE_SASL */
dfc2f2