comparison libpurple/proxy.c @ 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 9f26efb70c67
children fa666e7f747e 6fa0e854cfc6
comparison
equal deleted inserted replaced
32795:a359399cc0ce 32796:5ae7e1f36b43
57 * This contains alternating length/char* values. The char* 57 * This contains alternating length/char* values. The char*
58 * values need to be freed when removed from the linked list. 58 * values need to be freed when removed from the linked list.
59 */ 59 */
60 GSList *hosts; 60 GSList *hosts;
61 61
62 PurpleProxyConnectData *child;
63
62 /* 64 /*
63 * All of the following variables are used when establishing a 65 * All of the following variables are used when establishing a
64 * connection through a proxy. 66 * connection through a proxy.
65 */ 67 */
66 guchar *write_buffer; 68 guchar *write_buffer;
557 * connection was successful then pass in null. 559 * connection was successful then pass in null.
558 */ 560 */
559 static void 561 static void
560 purple_proxy_connect_data_disconnect(PurpleProxyConnectData *connect_data, const gchar *error_message) 562 purple_proxy_connect_data_disconnect(PurpleProxyConnectData *connect_data, const gchar *error_message)
561 { 563 {
564 if (connect_data->child != NULL)
565 {
566 purple_proxy_connect_cancel(connect_data->child);
567 connect_data->child = NULL;
568 }
569
562 if (connect_data->inpa > 0) 570 if (connect_data->inpa > 0)
563 { 571 {
564 purple_input_remove(connect_data->inpa); 572 purple_input_remove(connect_data->inpa);
565 connect_data->inpa = 0; 573 connect_data->inpa = 0;
566 } 574 }
2415 static void socks5_connected_to_proxy(gpointer data, gint source, 2423 static void socks5_connected_to_proxy(gpointer data, gint source,
2416 const gchar *error_message) { 2424 const gchar *error_message) {
2417 /* This is the PurpleProxyConnectData for the overall SOCKS5 connection */ 2425 /* This is the PurpleProxyConnectData for the overall SOCKS5 connection */
2418 PurpleProxyConnectData *connect_data = data; 2426 PurpleProxyConnectData *connect_data = data;
2419 2427
2428 purple_debug_error("proxy", "Connect Data is %p\n", connect_data);
2429
2420 /* Check that the overall SOCKS5 connection wasn't cancelled while we were 2430 /* Check that the overall SOCKS5 connection wasn't cancelled while we were
2421 * connecting to it (we don't have a way of associating the process of 2431 * connecting to it (we don't have a way of associating the process of
2422 * connecting to the SOCKS5 server to the overall PurpleProxyConnectData) 2432 * connecting to the SOCKS5 server to the overall PurpleProxyConnectData)
2423 */ 2433 */
2424 if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) 2434 if (!PURPLE_PROXY_CONNECT_DATA_IS_VALID(connect_data)) {
2425 return; 2435 purple_debug_error("proxy", "Data had gone out of scope :(\n");
2436 return;
2437 }
2438
2439 /* Break the link between the two PurpleProxyConnectDatas */
2440 connect_data->child = NULL;
2426 2441
2427 if (error_message != NULL) { 2442 if (error_message != NULL) {
2428 purple_debug_error("proxy", "Unable to connect to SOCKS5 host.\n"); 2443 purple_debug_error("proxy", "Unable to connect to SOCKS5 host.\n");
2429 connect_data->connect_cb(connect_data->data, source, error_message); 2444 connect_data->connect_cb(connect_data->data, source, error_message);
2430 return; 2445 return;
2484 purple_debug_error("proxy", "Unable to initiate connection to account proxy.\n"); 2499 purple_debug_error("proxy", "Unable to initiate connection to account proxy.\n");
2485 purple_proxy_connect_data_destroy(connect_data); 2500 purple_proxy_connect_data_destroy(connect_data);
2486 return NULL; 2501 return NULL;
2487 } 2502 }
2488 2503
2489 /* The API doesn't really provide us with a way to cancel the specific 2504 connect_data->child = account_proxy_conn_data;
2490 * proxy connection attempt (account_proxy_conn_data) when the overall
2491 * SOCKS5 connection (connect_data) attempt is cancelled :(
2492 */
2493 2505
2494 handles = g_slist_prepend(handles, connect_data); 2506 handles = g_slist_prepend(handles, connect_data);
2495 2507
2496 return connect_data; 2508 return connect_data;
2497 } 2509 }
2498 2510
2499 void 2511 void
2500 purple_proxy_connect_cancel(PurpleProxyConnectData *connect_data) 2512 purple_proxy_connect_cancel(PurpleProxyConnectData *connect_data)
2501 { 2513 {
2514 g_return_if_fail(connect_data != NULL);
2515
2502 purple_proxy_connect_data_disconnect(connect_data, NULL); 2516 purple_proxy_connect_data_disconnect(connect_data, NULL);
2503 purple_proxy_connect_data_destroy(connect_data); 2517 purple_proxy_connect_data_destroy(connect_data);
2504 } 2518 }
2505 2519
2506 void 2520 void