comparison libpurple/protocols/oscar/family_icbm.c @ 30702:6829b27ee4c8

This patch attempts to fix four bugs in the oscar protocol plugin that were introduced with the X-Status code in Pidgin 2.7.0. Problem #1 (the remotely-triggerable crash): The crash happens when a buddy sets an xstatus message containing <desc> but no closing </desc>, or <title> but no closing </title>. The fix is to check the result of strstr(closing_tag_name) and do nothing if it is NULL. This is CVE-2010-2528. Problem #2: Fixes potential incorrect parsing of the xstatus string that could result in an incorrect message being displayed to the libpurple user. Happens if an xstatus message contains </desc> before <desc>, or </title> before <title>. The fix is to start looking for the closing tag at the end of the beginning tag rather than at the beginning of the xstatus xml. Probably not a security problem, but definitely a bug. Problem #3: Fixes potential incorrect parsing of the xstatus string that could result in the title not being shown to the libpurple user. Happens if the close title tag appears after the desc tag in the xstatus xml, because we add a null character at the beginning of the close title tag, so strstr() for the desc tag would stop searching there. Probably not a security problem, but definitely a bug. Problem #4: Fixes potential incorrect display of the xstatus string that could result in an incorrect message being displayed to the libpurple user. Happens because we reusing the 'xml' string when preparing the string for the user, but we copy values from xml to xml. If those values overlap with themselves or with each other then an incorrect value could be displayed. Probably not a security problem, but definitely a bug.
author Mark Doliner <mark@kingant.net>
date Wed, 21 Jul 2010 02:49:23 +0000
parents 62f7ea77feb3
children 2f96590b7b40 8e9b04071e79
comparison
equal deleted inserted replaced
30701:9a46847fad1b 30702:6829b27ee4c8
246 buf = g_strdup_printf(_("Unable to send message to %s: %s"), 246 buf = g_strdup_printf(_("Unable to send message to %s: %s"),
247 bn ? bn : "(unknown)", reason_str); 247 bn ? bn : "(unknown)", reason_str);
248 purple_notify_error(od->gc, NULL, buf, reason_str); 248 purple_notify_error(od->gc, NULL, buf, reason_str);
249 } 249 }
250 g_free(buf); 250 g_free(buf);
251
252
253
254 251
255 g_free(snac2->data); 252 g_free(snac2->data);
256 g_free(snac2); 253 g_free(snac2);
257 254
258 return 1; 255 return 1;
2685 guint8 bnlen; 2682 guint8 bnlen;
2686 char *xml = NULL; 2683 char *xml = NULL;
2687 guint16 hdrlen; 2684 guint16 hdrlen;
2688 int curpos; 2685 int curpos;
2689 guint16 num1, num2; 2686 guint16 num1, num2;
2690 char *desc, *title, *temp;
2691 PurpleAccount *account; 2687 PurpleAccount *account;
2692 PurpleBuddy *buddy; 2688 PurpleBuddy *buddy;
2693 PurplePresence *presence; 2689 PurplePresence *presence;
2694 PurpleStatus *status; 2690 PurpleStatus *status;
2695 2691
2712 byte_stream_advance(bs, 86); 2708 byte_stream_advance(bs, 86);
2713 curpos = byte_stream_curpos(bs); 2709 curpos = byte_stream_curpos(bs);
2714 xml = byte_stream_getstr(bs, bs->len - curpos); 2710 xml = byte_stream_getstr(bs, bs->len - curpos);
2715 purple_debug_misc("oscar", "X-Status: Received XML reply\n"); 2711 purple_debug_misc("oscar", "X-Status: Received XML reply\n");
2716 if (xml) { 2712 if (xml) {
2717 /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", xml); */ 2713 GString *xstatus;
2718 desc = strstr(xml, "&lt;desc&gt;"); 2714 char *tmp1, *tmp2;
2719 if (desc != NULL) { 2715
2720 temp = strstr(xml, "&lt;/desc&gt;"); 2716 /* purple_debug_misc("oscar", "X-Status: XML reply: %s\n", xml); */
2721 temp[0] = 0; 2717
2722 desc = desc + 12; 2718 xstatus = g_string_new(NULL);
2719
2720 tmp1 = strstr(xml, "&lt;title&gt;");
2721 if (tmp1 != NULL) {
2722 tmp1 += 13;
2723 tmp2 = strstr(tmp1, "&lt;/title&gt;");
2724 if (tmp2 != NULL)
2725 g_string_append_len(xstatus, tmp1, tmp2 - tmp1);
2723 } 2726 }
2724 title = strstr(xml, "&lt;title&gt;"); 2727 tmp1 = strstr(xml, "&lt;desc&gt;");
2725 if (title != NULL) { 2728 if (tmp1 != NULL) {
2726 temp = strstr(xml, "&lt;/title&gt;"); 2729 tmp1 += 12;
2727 temp[0] = 0; 2730 tmp2 = strstr(tmp1, "&lt;/desc&gt;");
2728 title = title + 13; 2731 if (tmp2 != NULL) {
2729 } else { 2732 if (xstatus->len > 0)
2730 title = ""; 2733 g_string_append(xstatus, " - ");
2734 g_string_append_len(xstatus, tmp1, tmp2 - tmp1);
2735 }
2731 } 2736 }
2732 strcpy(xml,title); 2737 if (xstatus->len > 0) {
2733 if (desc) { 2738 purple_debug_misc("oscar", "X-Status reply: %s\n", xstatus->str);
2734 strcat(xml, " - "); 2739 account = purple_connection_get_account(od->gc);
2735 strcat(xml, desc); 2740 buddy = purple_find_buddy(account, bn);
2741 presence = purple_buddy_get_presence(buddy);
2742 status = purple_presence_get_active_status(presence);
2743 purple_prpl_got_user_status(account, bn,
2744 purple_status_get_id(status),
2745 "message", xstatus->str, NULL);
2736 } 2746 }
2737 purple_debug_misc("oscar", "X-Status reply: %s\n", xml); 2747 g_string_free(xstatus, TRUE);
2738 account = purple_connection_get_account(od->gc);
2739 buddy = purple_find_buddy(account, bn);
2740 presence = purple_buddy_get_presence(buddy);
2741 status = purple_presence_get_active_status(presence);
2742 purple_prpl_got_user_status(account, bn,
2743 purple_status_get_id(status), "message", xml, NULL);
2744 } else { 2748 } else {
2745 purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n"); 2749 purple_debug_misc("oscar", "X-Status: Can't get XML reply string\n");
2746 } 2750 }
2747 } else { 2751 } else {
2748 purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n"); 2752 purple_debug_misc("oscar", "X-Status: 0x0004, 0x000b not an xstatus reply\n");