Fix a possible XMPP remote crash release-2.x.y
authorMark Doliner <markdoliner@pidgin.im>
Mon, 07 May 2012 03:16:31 +0000
branchrelease-2.x.y
changeset5f9d676cefdb pushlog
parent 7da03a4db8b9
child 4d6bcb4f4ea4
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.
libpurple/proxy.c
     1.1 --- a/libpurple/proxy.c
     1.2 +++ b/libpurple/proxy.c
     1.3 @@ -59,6 +59,8 @@
     1.4  	 */
     1.5  	GSList *hosts;
     1.6  
     1.7 +	PurpleProxyConnectData *child;
     1.8 +
     1.9  	/*
    1.10  	 * All of the following variables are used when establishing a
    1.11  	 * connection through a proxy.
    1.12 @@ -559,6 +561,12 @@
    1.13  static void
    1.14  purple_proxy_connect_data_disconnect(PurpleProxyConnectData *connect_data, const gchar *error_message)
    1.15  {
    1.16 +	if (connect_data->child != NULL)
    1.17 +	{
    1.18 +		purple_proxy_connect_cancel(connect_data->child);
    1.19 +		connect_data->child = NULL;
    1.20 +	}
    1.21 +
    1.22  	if (connect_data->inpa > 0)
    1.23  	{
    1.24  		purple_input_remove(connect_data->inpa);
    1.25 @@ -2417,12 +2425,19 @@
    1.26  	/* This is the PurpleProxyConnectData for the overall SOCKS5 connection */
    1.27  	PurpleProxyConnectData *connect_data = data;
    1.28  
    1.29 +	purple_debug_error("proxy", "Connect Data is %p\n", connect_data);
    1.30 +
    1.31  	/* Check that the overall SOCKS5 connection wasn't cancelled while we were
    1.32  	 * connecting to it (we don't have a way of associating the process of
    1.33  	 * connecting to the SOCKS5 server to the overall PurpleProxyConnectData)
    1.34  	 */
    1.35 -	if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data))
    1.36 +	if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) {
    1.37 +		purple_debug_error("proxy", "Data had gone out of scope :(\n");
    1.38  		return;
    1.39 +	}
    1.40 +
    1.41 +	/* Break the link between the two PurpleProxyConnectDatas  */
    1.42 +	connect_data->child = NULL;
    1.43  
    1.44  	if (error_message != NULL) {
    1.45  		purple_debug_error("proxy", "Unable to connect to SOCKS5 host.\n");
    1.46 @@ -2486,10 +2501,7 @@
    1.47  		return NULL;
    1.48  	}
    1.49  
    1.50 -	/* The API doesn't really provide us with a way to cancel the specific
    1.51 -	 * proxy connection attempt (account_proxy_conn_data) when the overall
    1.52 -	 * SOCKS5 connection (connect_data) attempt is cancelled :(
    1.53 -	 */
    1.54 +	connect_data->child = account_proxy_conn_data;
    1.55  
    1.56  	handles = g_slist_prepend(handles, connect_data);
    1.57  
    1.58 @@ -2499,6 +2511,8 @@
    1.59  void
    1.60  purple_proxy_connect_cancel(PurpleProxyConnectData *connect_data)
    1.61  {
    1.62 +	g_return_if_fail(connect_data != NULL);
    1.63 +
    1.64  	purple_proxy_connect_data_disconnect(connect_data, NULL);
    1.65  	purple_proxy_connect_data_destroy(connect_data);
    1.66  }