changeset 32796:5ae7e1f36b43

Fix a possible XMPP remote crash A series of specially crafted file transfer requests can cause clients to reference invalid memory. The user must have accepted one of the file transfer requests. The fix is to correctly cancel and free a SOCKS5 connection attempt so that it does not trigger an attempt to access invalid memory later. This was reported to us by Jos«± Valent«żn Guti«±rrez and this patch is written by Paul Aurich.
author Mark Doliner <mark@kingant.net>
date Mon, 07 May 2012 03:16:31 +0000
parents a359399cc0ce
children aacfb71133cc
files libpurple/proxy.c
diffstat 1 files changed, 19 insertions(+), 5 deletions(-) [+]
line wrap: on
line diff
--- a/libpurple/proxy.c	Sun May 06 17:52:46 2012 +0000
+++ b/libpurple/proxy.c	Mon May 07 03:16:31 2012 +0000
@@ -59,6 +59,8 @@
 	 */
 	GSList *hosts;
 
+	PurpleProxyConnectData *child;
+
 	/*
 	 * All of the following variables are used when establishing a
 	 * connection through a proxy.
@@ -559,6 +561,12 @@
 static void
 purple_proxy_connect_data_disconnect(PurpleProxyConnectData *connect_data, const gchar *error_message)
 {
+	if (connect_data->child != NULL)
+	{
+		purple_proxy_connect_cancel(connect_data->child);
+		connect_data->child = NULL;
+	}
+
 	if (connect_data->inpa > 0)
 	{
 		purple_input_remove(connect_data->inpa);
@@ -2417,12 +2425,19 @@
 	/* This is the PurpleProxyConnectData for the overall SOCKS5 connection */
 	PurpleProxyConnectData *connect_data = data;
 
+	purple_debug_error("proxy", "Connect Data is %p\n", connect_data);
+
 	/* Check that the overall SOCKS5 connection wasn't cancelled while we were
 	 * connecting to it (we don't have a way of associating the process of
 	 * connecting to the SOCKS5 server to the overall PurpleProxyConnectData)
 	 */
-	if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data))
+	if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) {
+		purple_debug_error("proxy", "Data had gone out of scope :(\n");
 		return;
+	}
+
+	/* Break the link between the two PurpleProxyConnectDatas  */
+	connect_data->child = NULL;
 
 	if (error_message != NULL) {
 		purple_debug_error("proxy", "Unable to connect to SOCKS5 host.\n");
@@ -2486,10 +2501,7 @@
 		return NULL;
 	}
 
-	/* The API doesn't really provide us with a way to cancel the specific
-	 * proxy connection attempt (account_proxy_conn_data) when the overall
-	 * SOCKS5 connection (connect_data) attempt is cancelled :(
-	 */
+	connect_data->child = account_proxy_conn_data;
 
 	handles = g_slist_prepend(handles, connect_data);
 
@@ -2499,6 +2511,8 @@
 void
 purple_proxy_connect_cancel(PurpleProxyConnectData *connect_data)
 {
+	g_return_if_fail(connect_data != NULL);
+
 	purple_proxy_connect_data_disconnect(connect_data, NULL);
 	purple_proxy_connect_data_destroy(connect_data);
 }