[Date Prev][Date Next] [Thread Prev][Thread Next] [Date Index] [Thread Index]

Bug#655178: pu: package pidgin/2.7.3-1+squeeze1



On 01/14/2012 11:33 AM, Adam D. Barratt wrote:
Thanks.  Would it be possible to have an updated diff without the cruft?

New patch attached.

(fwiw, I'm also not quite sure what some other parts of that patch have
to do with fixing the crash; e.g.

The patch was taken directly from the upstream change, and I guess they didn't do a good job of separating the security fix from general cleanups.
diff --git a/debian/changelog b/debian/changelog
index 5406328..716ca65 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,16 @@
+pidgin (2.7.3-1+squeeze2) squeeze; urgency=medium
+
+  * CVE-2011-3594.patch:
+    - fix a SILC remote crash bug
+  * CVE-2011-4601.patch:
+    - fix an AIM/ICQ remote crash bug
+  * CVE-2011-4602.patch:
+    - fix an XMPP remote crash bug
+  * CVE-2011-4603.patch:
+    - fix a SILC remote crash bug
+
+ -- Ari Pollak <ari@debian.org>  Sat, 07 Jan 2012 21:47:12 -0500
+
 pidgin (2.7.3-1+squeeze1) squeeze; urgency=medium
 
   * baseXX_decode_error_handling_2.patch:
diff --git a/debian/patches/CVE-2011-3594.patch b/debian/patches/CVE-2011-3594.patch
new file mode 100644
index 0000000..98210d0
--- /dev/null
+++ b/debian/patches/CVE-2011-3594.patch
@@ -0,0 +1,28 @@
+Description: fix SILC remote crash
+#
+#
+# patch "libpurple/protocols/silc/ops.c"
+#  from [30ab18780af11a53b6564a44c4e8ebfc1a296d78]
+#    to [80bd9a7d3faf9e5ef28438647159fe19847e9839]
+#
+============================================================
+--- pidgin/libpurple/protocols/silc/ops.c	30ab18780af11a53b6564a44c4e8ebfc1a296d78
++++ pidgin/libpurple/protocols/silc/ops.c	80bd9a7d3faf9e5ef28438647159fe19847e9839
+@@ -408,9 +408,16 @@ silc_private_message(SilcClient client, 
+ 	}
+ 
+ 	if (flags & SILC_MESSAGE_FLAG_UTF8) {
+-		tmp = g_markup_escape_text((const char *)message, -1);
++		const char *msg = (const char *)message;
++		char *salvaged = NULL;
++		if (!g_utf8_validate((const char *)message, -1, NULL)) {
++			salvaged = purple_utf8_salvage((const char *)message);
++			msg = salvaged;
++		}
++		tmp = g_markup_escape_text(msg, -1);
+ 		/* Send to Purple */
+ 		serv_got_im(gc, sender->nickname, tmp, 0, time(NULL));
++		g_free(salvaged);
+ 		g_free(tmp);
+ 	}
+ }
diff --git a/debian/patches/CVE-2011-4601.patch b/debian/patches/CVE-2011-4601.patch
new file mode 100644
index 0000000..2e1c16f
--- /dev/null
+++ b/debian/patches/CVE-2011-4601.patch
@@ -0,0 +1,168 @@
+Description: fix AIM and ICQ remote crash
+#
+#
+# patch "libpurple/protocols/oscar/family_feedbag.c"
+#  from [8f80e2c5acd2b21acc88d54ba8e5ab43dbdaa3e2]
+#    to [ff8702078ba3a5c73ff1c86a206f09f7749c1314]
+#
+============================================================
+--- pidgin/libpurple/protocols/oscar/family_feedbag.c	8f80e2c5acd2b21acc88d54ba8e5ab43dbdaa3e2
++++ pidgin/libpurple/protocols/oscar/family_feedbag.c	ff8702078ba3a5c73ff1c86a206f09f7749c1314
+@@ -1650,18 +1650,35 @@ static int receiveauthgrant(OscarData *o
+ 	int ret = 0;
+ 	aim_rxcallback_t userfunc;
+ 	guint16 tmp;
+-	char *bn, *msg;
++	char *bn, *msg, *tmpstr;
+ 
+ 	/* Read buddy name */
+-	if ((tmp = byte_stream_get8(bs)))
+-		bn = byte_stream_getstr(bs, tmp);
+-	else
+-		bn = NULL;
++	tmp = byte_stream_get8(bs);
++	if (!tmp) {
++		purple_debug_warning("oscar", "Dropping auth grant SNAC "
++				"because username was empty\n");
++		return 0;
++	}
++	bn = byte_stream_getstr(bs, tmp);
++	if (!g_utf8_validate(bn, -1, NULL)) {
++		purple_debug_warning("oscar", "Dropping auth grant SNAC "
++				"because the username was not valid UTF-8\n");
++		g_free(bn);
++	}
+ 
+-	/* Read message (null terminated) */
+-	if ((tmp = byte_stream_get16(bs)))
++	/* Read message */
++	tmp = byte_stream_get16(bs);
++	if (tmp) {
+ 		msg = byte_stream_getstr(bs, tmp);
+-	else
++		if (!g_utf8_validate(msg, -1, NULL)) {
++			/* Ugh, msg isn't UTF8.  Let's salvage. */
++			purple_debug_warning("oscar", "Got non-UTF8 message in auth "
++					"grant from %s\n", bn);
++			tmpstr = purple_utf8_salvage(msg);
++			g_free(msg);
++			msg = tmpstr;
++		}
++	} else
+ 		msg = NULL;
+ 
+ 	/* Unknown */
+@@ -1724,18 +1741,35 @@ static int receiveauthrequest(OscarData 
+ 	int ret = 0;
+ 	aim_rxcallback_t userfunc;
+ 	guint16 tmp;
+-	char *bn, *msg;
++	char *bn, *msg, *tmpstr;
+ 
+ 	/* Read buddy name */
+-	if ((tmp = byte_stream_get8(bs)))
+-		bn = byte_stream_getstr(bs, tmp);
+-	else
+-		bn = NULL;
++	tmp = byte_stream_get8(bs);
++	if (!tmp) {
++		purple_debug_warning("oscar", "Dropping auth request SNAC "
++				"because username was empty\n");
++		return 0;
++	}
++	bn = byte_stream_getstr(bs, tmp);
++	if (!g_utf8_validate(bn, -1, NULL)) {
++		purple_debug_warning("oscar", "Dropping auth request SNAC "
++				"because the username was not valid UTF-8\n");
++		g_free(bn);
++	}
+ 
+-	/* Read message (null terminated) */
+-	if ((tmp = byte_stream_get16(bs)))
++	/* Read message */
++	tmp = byte_stream_get16(bs);
++	if (tmp) {
+ 		msg = byte_stream_getstr(bs, tmp);
+-	else
++		if (!g_utf8_validate(msg, -1, NULL)) {
++			/* Ugh, msg isn't UTF8.  Let's salvage. */
++			purple_debug_warning("oscar", "Got non-UTF8 message in auth "
++					"request from %s\n", bn);
++			tmpstr = purple_utf8_salvage(msg);
++			g_free(msg);
++			msg = tmpstr;
++		}
++	} else
+ 		msg = NULL;
+ 
+ 	/* Unknown */
+@@ -1808,21 +1842,38 @@ static int receiveauthreply(OscarData *o
+ 	aim_rxcallback_t userfunc;
+ 	guint16 tmp;
+ 	guint8 reply;
+-	char *bn, *msg;
++	char *bn, *msg, *tmpstr;
+ 
+ 	/* Read buddy name */
+-	if ((tmp = byte_stream_get8(bs)))
+-		bn = byte_stream_getstr(bs, tmp);
+-	else
+-		bn = NULL;
++	tmp = byte_stream_get8(bs);
++	if (!tmp) {
++		purple_debug_warning("oscar", "Dropping auth reply SNAC "
++				"because username was empty\n");
++		return 0;
++	}
++	bn = byte_stream_getstr(bs, tmp);
++	if (!g_utf8_validate(bn, -1, NULL)) {
++		purple_debug_warning("oscar", "Dropping auth reply SNAC "
++				"because the username was not valid UTF-8\n");
++		g_free(bn);
++	}
+ 
+ 	/* Read reply */
+ 	reply = byte_stream_get8(bs);
+ 
+-	/* Read message (null terminated) */
+-	if ((tmp = byte_stream_get16(bs)))
++	/* Read message */
++	tmp = byte_stream_get16(bs);
++	if (tmp) {
+ 		msg = byte_stream_getstr(bs, tmp);
+-	else
++		if (!g_utf8_validate(msg, -1, NULL)) {
++			/* Ugh, msg isn't UTF8.  Let's salvage. */
++			purple_debug_warning("oscar", "Got non-UTF8 message in auth "
++					"reply from %s\n", bn);
++			tmpstr = purple_utf8_salvage(msg);
++			g_free(msg);
++			msg = tmpstr;
++		}
++	} else
+ 		msg = NULL;
+ 
+ 	/* Unknown */
+@@ -1848,10 +1899,18 @@ static int receiveadded(OscarData *od, F
+ 	char *bn;
+ 
+ 	/* Read buddy name */
+-	if ((tmp = byte_stream_get8(bs)))
+-		bn = byte_stream_getstr(bs, tmp);
+-	else
+-		bn = NULL;
++	tmp = byte_stream_get8(bs);
++	if (!tmp) {
++		purple_debug_warning("oscar", "Dropping 'you were added' SNAC "
++				"because username was empty\n");
++		return 0;
++	}
++	bn = byte_stream_getstr(bs, tmp);
++	if (!g_utf8_validate(bn, -1, NULL)) {
++		purple_debug_warning("oscar", "Dropping 'you were added' SNAC "
++				"because the username was not valid UTF-8\n");
++		g_free(bn);
++	}
+ 
+ 	if ((userfunc = aim_callhandler(od, snac->family, snac->subtype)))
+ 		ret = userfunc(od, conn, frame, bn);
diff --git a/debian/patches/CVE-2011-4602.patch b/debian/patches/CVE-2011-4602.patch
new file mode 100644
index 0000000..a6d8edd
--- /dev/null
+++ b/debian/patches/CVE-2011-4602.patch
@@ -0,0 +1,258 @@
+Description: fix XMPP remote crash
+#
+#
+# patch "libpurple/protocols/jabber/jingle/jingle.c" from
+# [185980c698f1c26bad6f0f8a23e866c0645ea1d9] to
+# [2933cb6d81371155c69a5a4f97b6b3bf09aa5aa5]
+# 
+# patch "libpurple/protocols/jabber/jingle/rtp.c" from
+# [2656346b8bf03a7995ef995e7c2e154facdf905e] to
+# [dcacf06a52d80015f7bc1676b1ccbdb182276784]
+# 
+# patch "libpurple/protocols/jabber/jingle/session.c" from
+# [00e7dd7888866a805129a8f17a545159c7e6e378] to
+# [6f394c4ccad3d4ef658116e13e9db59d4b4a46fb]
+#
+Index: pidgin/libpurple/protocols/jabber/jingle/jingle.c
+===================================================================
+--- pidgin.orig/libpurple/protocols/jabber/jingle/jingle.c
++++ pidgin/libpurple/protocols/jabber/jingle/jingle.c
+@@ -119,7 +119,7 @@ jingle_handle_content_modify(JingleSessi
+ 		if (local_content != NULL) {
+ 			const gchar *senders = xmlnode_get_attrib(content, "senders");
+ 			gchar *local_senders = jingle_content_get_senders(local_content);
+-			if (strcmp(senders, local_senders))
++			if (!purple_strequal(senders, local_senders))
+ 				jingle_content_modify(local_content, senders);
+ 			g_free(local_senders);
+ 		} else {
+Index: pidgin/libpurple/protocols/jabber/jingle/rtp.c
+===================================================================
+--- pidgin.orig/libpurple/protocols/jabber/jingle/rtp.c
++++ pidgin/libpurple/protocols/jabber/jingle/rtp.c
+@@ -589,6 +589,16 @@ jingle_rtp_init_media(JingleContent *con
+ 	senders = jingle_content_get_senders(content);
+ 	transport = jingle_content_get_transport(content);
+ 
++	if (media_type == NULL) {
++		g_free(name);
++		g_free(remote_jid);
++		g_free(senders);
++		g_free(params);
++		g_object_unref(transport);
++		g_object_unref(session);
++		return FALSE;
++	}
++
+ 	if (JINGLE_IS_RAWUDP(transport))
+ 		transmitter = "rawudp";
+ 	else if (JINGLE_IS_ICEUDP(transport))
+@@ -597,24 +607,34 @@ jingle_rtp_init_media(JingleContent *con
+ 		transmitter = "notransmitter";
+ 	g_object_unref(transport);
+ 
+-	is_audio = !strcmp(media_type, "audio");
++	is_audio = g_str_equal(media_type, "audio");
+ 
+-	if (!strcmp(senders, "both"))
+-		type = is_audio == TRUE ? PURPLE_MEDIA_AUDIO
++	if (purple_strequal(senders, "both"))
++		type = is_audio ? PURPLE_MEDIA_AUDIO
+ 				: PURPLE_MEDIA_VIDEO;
+-	else if ((strcmp(senders, "initiator") == 0) ==
++	else if (purple_strequal(senders, "initiator") ==
+ 			jingle_session_is_initiator(session))
+-		type = is_audio == TRUE ? PURPLE_MEDIA_SEND_AUDIO
++		type = is_audio ? PURPLE_MEDIA_SEND_AUDIO
+ 				: PURPLE_MEDIA_SEND_VIDEO;
+ 	else
+-		type = is_audio == TRUE ? PURPLE_MEDIA_RECV_AUDIO
++		type = is_audio ? PURPLE_MEDIA_RECV_AUDIO
+ 				: PURPLE_MEDIA_RECV_VIDEO;
+ 
+ 	params = 
+ 		jingle_get_params(jingle_session_get_js(session), &num_params);
+ 
+ 	creator = jingle_content_get_creator(content);
+-	if (!strcmp(creator, "initiator"))
++	if (creator == NULL) {
++		g_free(name);
++		g_free(media_type);
++		g_free(remote_jid);
++		g_free(senders);
++		g_free(params);
++		g_object_unref(session);
++		return FALSE;
++	}
++
++	if (g_str_equal(creator, "initiator"))
+ 		is_creator = jingle_session_is_initiator(session);
+ 	else
+ 		is_creator = !jingle_session_is_initiator(session);
+@@ -623,6 +643,8 @@ jingle_rtp_init_media(JingleContent *con
+ 	if(!purple_media_add_stream(media, name, remote_jid,
+ 			type, is_creator, transmitter, num_params, params)) {
+ 		purple_media_end(media, NULL, NULL);
++		/* TODO: How much clean-up is necessary here? (does calling
++		         purple_media_end lead to cleaning up Jingle structs?) */
+ 		return FALSE;
+ 	}
+ 
+@@ -644,9 +666,22 @@ jingle_rtp_parse_codecs(xmlnode *descrip
+ 	const char *encoding_name,*id, *clock_rate;
+ 	PurpleMediaCodec *codec;
+ 	const gchar *media = xmlnode_get_attrib(description, "media");
+-	PurpleMediaSessionType type =
+-			!strcmp(media, "video") ? PURPLE_MEDIA_VIDEO :
+-			!strcmp(media, "audio") ? PURPLE_MEDIA_AUDIO : 0;
++	PurpleMediaSessionType type;
++
++	if (media == NULL) {
++		purple_debug_warning("jingle-rtp", "missing media type\n");
++		return NULL;
++	}
++
++	if (g_str_equal(media, "video")) {
++		type = PURPLE_MEDIA_VIDEO;
++	} else if (g_str_equal(media, "audio")) {
++		type = PURPLE_MEDIA_AUDIO;
++	} else {
++		purple_debug_warning("jingle-rtp", "unknown media type: %s\n",
++				media);
++		return NULL;
++	}
+ 
+ 	for (codec_element = xmlnode_get_child(description, "payload-type") ;
+ 		 codec_element ;
+@@ -767,19 +802,19 @@ jingle_rtp_handle_action_internal(Jingle
+ 	switch (action) {
+ 		case JINGLE_SESSION_ACCEPT:
+ 		case JINGLE_SESSION_INITIATE: {
+-			JingleSession *session = jingle_content_get_session(content);
+-			JingleTransport *transport = jingle_transport_parse(
+-					xmlnode_get_child(xmlcontent, "transport"));
+-			xmlnode *description = xmlnode_get_child(xmlcontent, "description");
+-			GList *candidates = jingle_rtp_transport_to_candidates(transport);
+-			GList *codecs = jingle_rtp_parse_codecs(description);
+-			gchar *name = jingle_content_get_name(content);
+-			gchar *remote_jid =
+-					jingle_session_get_remote_jid(session);
++			JingleSession *session;
++			JingleTransport *transport;
++			xmlnode *description;
++			GList *candidates;
++			GList *codecs;
++			gchar *name;
++			gchar *remote_jid;
+ 			PurpleMedia *media;
+ 
++			session = jingle_content_get_session(content);
++
+ 			if (action == JINGLE_SESSION_INITIATE &&
+-					jingle_rtp_init_media(content) == FALSE) {
++					!jingle_rtp_init_media(content)) {
+ 				/* XXX: send error */
+ 				jabber_iq_send(jingle_session_terminate_packet(
+ 						session, "general-error"));
+@@ -787,6 +822,14 @@ jingle_rtp_handle_action_internal(Jingle
+ 				break;
+ 			}
+ 
++			transport = jingle_transport_parse(
++					xmlnode_get_child(xmlcontent, "transport"));
++			description = xmlnode_get_child(xmlcontent, "description");
++			candidates = jingle_rtp_transport_to_candidates(transport);
++			codecs = jingle_rtp_parse_codecs(description);
++			name = jingle_content_get_name(content);
++			remote_jid = jingle_session_get_remote_jid(session);
++
+ 			media = jingle_rtp_get_media(session);
+ 			purple_media_set_remote_codecs(media,
+ 					name, remote_jid, codecs);
+Index: pidgin/libpurple/protocols/jabber/jingle/session.c
+===================================================================
+--- pidgin.orig/libpurple/protocols/jabber/jingle/session.c
++++ pidgin/libpurple/protocols/jabber/jingle/session.c
+@@ -284,7 +284,7 @@ jingle_session_create(JabberStream *js,
+ 	if (!js->sessions) {
+ 		purple_debug_info("jingle",
+ 				"Creating hash table for sessions\n");
+-		js->sessions = g_hash_table_new(g_str_hash, g_str_equal);
++		js->sessions = g_hash_table_new_full(g_str_hash, g_str_equal, g_free, NULL);
+ 	}
+ 	purple_debug_info("jingle",
+ 			"inserting session with key: %s into table\n", sid);
+@@ -407,27 +407,25 @@ jingle_add_jingle_packet(JingleSession *
+ 			xmlnode_new("jingle");
+ 	gchar *local_jid = jingle_session_get_local_jid(session);
+ 	gchar *remote_jid = jingle_session_get_remote_jid(session);
++	gchar *sid = jingle_session_get_sid(session);
+ 
+ 	xmlnode_set_namespace(jingle, JINGLE);
+ 	xmlnode_set_attrib(jingle, "action", jingle_get_action_name(action));
+ 
+ 	if (jingle_session_is_initiator(session)) {
+-		xmlnode_set_attrib(jingle, "initiator",
+-				jingle_session_get_local_jid(session));
+-		xmlnode_set_attrib(jingle, "responder",
+-				jingle_session_get_remote_jid(session));
++		xmlnode_set_attrib(jingle, "initiator", local_jid);
++		xmlnode_set_attrib(jingle, "responder", remote_jid);
+ 	} else {
+-		xmlnode_set_attrib(jingle, "initiator",
+-				jingle_session_get_remote_jid(session));
+-		xmlnode_set_attrib(jingle, "responder",
+-				jingle_session_get_local_jid(session));
++		xmlnode_set_attrib(jingle, "initiator", remote_jid);
++		xmlnode_set_attrib(jingle, "responder", local_jid);
+ 	}
+ 
++	xmlnode_set_attrib(jingle, "sid", sid);
++
+ 	g_free(local_jid);
+ 	g_free(remote_jid);
++	g_free(sid);
+ 
+-	xmlnode_set_attrib(jingle, "sid", jingle_session_get_sid(session));
+-	
+ 	return jingle;
+ }
+ 
+@@ -504,11 +502,16 @@ void jingle_session_handle_action(Jingle
+ JingleContent *
+ jingle_session_find_content(JingleSession *session, const gchar *name, const gchar *creator)
+ {
+-	GList *iter = session->priv->contents;
++	GList *iter;
++
++	if (name == NULL)
++		return NULL;
++
++	iter = session->priv->contents;
+ 	for (; iter; iter = g_list_next(iter)) {
+ 		JingleContent *content = iter->data;
+ 		gchar *cname = jingle_content_get_name(content);
+-		gboolean result = !strcmp(name, cname);
++		gboolean result = g_str_equal(name, cname);
+ 		g_free(cname);
+ 
+ 		if (creator != NULL) {
+@@ -526,11 +529,16 @@ jingle_session_find_content(JingleSessio
+ JingleContent *
+ jingle_session_find_pending_content(JingleSession *session, const gchar *name, const gchar *creator)
+ {
+-	GList *iter = session->priv->pending_contents;
++	GList *iter;
++
++	if (name == NULL)
++		return NULL;
++
++	iter = session->priv->pending_contents;
+ 	for (; iter; iter = g_list_next(iter)) {
+ 		JingleContent *content = iter->data;
+ 		gchar *cname = jingle_content_get_name(content);
+-		gboolean result = !strcmp(name, cname);
++		gboolean result = g_str_equal(name, cname);
+ 		g_free(cname);
+ 
+ 		if (creator != NULL) {
diff --git a/debian/patches/CVE-2011-4603.patch b/debian/patches/CVE-2011-4603.patch
new file mode 100644
index 0000000..c73a2d0
--- /dev/null
+++ b/debian/patches/CVE-2011-4603.patch
@@ -0,0 +1,29 @@
+Description: fix SILC remote crash
+#
+#
+# patch "libpurple/protocols/silc/ops.c"
+#  from [80bd9a7d3faf9e5ef28438647159fe19847e9839]
+#    to [e828291021afbdd6e6370738aa6224788bf885a3]
+#
+============================================================
+--- pidgin/libpurple/protocols/silc/ops.c	80bd9a7d3faf9e5ef28438647159fe19847e9839
++++ pidgin/libpurple/protocols/silc/ops.c	e828291021afbdd6e6370738aa6224788bf885a3
+@@ -332,10 +332,17 @@ silc_channel_message(SilcClient client, 
+ 	}
+ 
+ 	if (flags & SILC_MESSAGE_FLAG_UTF8) {
+-		tmp = g_markup_escape_text((const char *)message, -1);
++		const char *msg = (const char *)message;
++		char *salvaged = NULL;
++		if (!g_utf8_validate((const char *)message, -1, NULL)) {
++			salvaged = purple_utf8_salvage((const char *)message);
++			msg = salvaged;
++		}
++		tmp = g_markup_escape_text(msg, -1);
+ 		/* Send to Purple */
+ 		serv_got_chat_in(gc, purple_conv_chat_get_id(PURPLE_CONV_CHAT(convo)),
+ 				 sender->nickname, 0, tmp, time(NULL));
++		g_free(salvaged);
+ 		g_free(tmp);
+ 	}
+ }
diff --git a/debian/patches/series b/debian/patches/series
index f240bda..59a00a0 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -3,3 +3,7 @@ python26.patch
 libnssckbi_path.patch
 baseXX_decode_error_handling_2.patch
 cyrus_sasl_crash.patch
+CVE-2011-3594.patch
+CVE-2011-4601.patch
+CVE-2011-4602.patch
+CVE-2011-4603.patch

Reply to: