|
|
56fe68 |
diff -up pidgin-2.10.7/libpurple/protocols/yahoo/libymsg.c.CVE-2013-6481 pidgin-2.10.7/libpurple/protocols/yahoo/libymsg.c
|
|
|
56fe68 |
--- pidgin-2.10.7/libpurple/protocols/yahoo/libymsg.c.CVE-2013-6481 2014-01-27 10:20:14.473648650 -0500
|
|
|
56fe68 |
+++ pidgin-2.10.7/libpurple/protocols/yahoo/libymsg.c 2014-01-28 20:57:13.990365865 -0500
|
|
|
56fe68 |
@@ -2720,7 +2720,7 @@ static void yahoo_p2p_read_pkt_cb(gpoint
|
|
|
56fe68 |
int pos = 0;
|
|
|
56fe68 |
int pktlen;
|
|
|
56fe68 |
struct yahoo_packet *pkt;
|
|
|
56fe68 |
- guchar *start = NULL;
|
|
|
56fe68 |
+ guchar *start;
|
|
|
56fe68 |
struct yahoo_p2p_data *p2p_data;
|
|
|
56fe68 |
YahooData *yd;
|
|
|
56fe68 |
|
|
|
56fe68 |
@@ -2742,19 +2742,29 @@ static void yahoo_p2p_read_pkt_cb(gpoint
|
|
|
56fe68 |
return;
|
|
|
56fe68 |
}
|
|
|
56fe68 |
|
|
|
56fe68 |
+ /* TODO: It looks like there's a bug here (and above) where an incorrect
|
|
|
56fe68 |
+ * assumtion is being made that the buffer will be added to when this
|
|
|
56fe68 |
+ * is next called, but that's not really the case! */
|
|
|
56fe68 |
if(len < YAHOO_PACKET_HDRLEN)
|
|
|
56fe68 |
return;
|
|
|
56fe68 |
|
|
|
56fe68 |
- if(strncmp((char *)buf, "YMSG", MIN(4, len)) != 0) {
|
|
|
56fe68 |
+ if(strncmp((char *)buf, "YMSG", 4) != 0) {
|
|
|
56fe68 |
/* Not a YMSG packet */
|
|
|
56fe68 |
- purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n");
|
|
|
56fe68 |
+ purple_debug_warning("yahoo", "p2p: Got something other than YMSG packet\n");
|
|
|
56fe68 |
|
|
|
56fe68 |
- start = memchr(buf + 1, 'Y', len - 1);
|
|
|
56fe68 |
- if (start == NULL)
|
|
|
56fe68 |
+ start = (guchar *) g_strstr_len((char *) buf + 1, len - 1 ,"YMSG");
|
|
|
56fe68 |
+ if (start == NULL) {
|
|
|
56fe68 |
+ /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
|
|
|
56fe68 |
+ if (g_hash_table_lookup(yd->peers, p2p_data->host_username))
|
|
|
56fe68 |
+ g_hash_table_remove(yd->peers, p2p_data->host_username);
|
|
|
56fe68 |
+ else
|
|
|
56fe68 |
+ yahoo_p2p_disconnect_destroy_data(data);
|
|
|
56fe68 |
return;
|
|
|
56fe68 |
+ }
|
|
|
56fe68 |
+ purple_debug_warning("yahoo","p2p: Got something other than YMSG packet\n");
|
|
|
56fe68 |
|
|
|
56fe68 |
- g_memmove(buf, start, len - (start - buf));
|
|
|
56fe68 |
- len -= start - buf;
|
|
|
56fe68 |
+ len -= (start - buf);
|
|
|
56fe68 |
+ g_memmove(buf, start, len);
|
|
|
56fe68 |
}
|
|
|
56fe68 |
|
|
|
56fe68 |
pos += 4; /* YMSG */
|
|
|
56fe68 |
@@ -2762,7 +2772,17 @@ static void yahoo_p2p_read_pkt_cb(gpoint
|
|
|
56fe68 |
pos += 2;
|
|
|
56fe68 |
|
|
|
56fe68 |
pktlen = yahoo_get16(buf + pos); pos += 2;
|
|
|
56fe68 |
- purple_debug_misc("yahoo", "p2p: %d bytes to read\n", len);
|
|
|
56fe68 |
+ if (len < (YAHOO_PACKET_HDRLEN + pktlen)) {
|
|
|
56fe68 |
+ purple_debug_error("yahoo", "p2p: packet length(%d) > buffer length(%d)\n",
|
|
|
56fe68 |
+ pktlen, (len - pos));
|
|
|
56fe68 |
+ /* remove from p2p connection lists, also calls yahoo_p2p_disconnect_destroy_data */
|
|
|
56fe68 |
+ if (g_hash_table_lookup(yd->peers, p2p_data->host_username))
|
|
|
56fe68 |
+ g_hash_table_remove(yd->peers, p2p_data->host_username);
|
|
|
56fe68 |
+ else
|
|
|
56fe68 |
+ yahoo_p2p_disconnect_destroy_data(data);
|
|
|
56fe68 |
+ return;
|
|
|
56fe68 |
+ } else
|
|
|
56fe68 |
+ purple_debug_misc("yahoo", "p2p: %d bytes to read\n", pktlen);
|
|
|
56fe68 |
|
|
|
56fe68 |
pkt = yahoo_packet_new(0, 0, 0);
|
|
|
56fe68 |
pkt->service = yahoo_get16(buf + pos); pos += 2;
|