Mercurial > pidgin
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 |