changeset 29466:69077f3993f6

Fix CVE-2010-0277, a possible remote crash when parsing an incoming SLP message. Discovered by Fabian Yamaguchi.
author Mark Doliner <mark@kingant.net>
date Tue, 16 Feb 2010 08:54:07 +0000
parents 1eeeb20f0b9f
children 40623dd0bba0
files ChangeLog libpurple/protocols/msn/slp.c libpurple/protocols/msn/slpcall.c libpurple/protocols/msn/slplink.c libpurple/protocols/msn/slpmsg.h
diffstat 5 files changed, 24 insertions(+), 9 deletions(-) [+]
line wrap: on
line diff
--- a/ChangeLog	Tue Feb 16 08:50:49 2010 +0000
+++ b/ChangeLog	Tue Feb 16 08:54:07 2010 +0000
@@ -26,6 +26,8 @@
 	  Previously only icons between 48x48 and 50x50 were allowed.
 
 	MSN:
+	* Fix CVE-2010-0277, a possible remote crash when parsing an incoming
+	  SLP message.  Discovered by Fabian Yamaguchi.
 	* File transfer requests will no longer cause a crash if you delete the
 	  file before the other side accepts.
 	* Received files will no longer hold an extra lock after completion,
--- a/libpurple/protocols/msn/slp.c	Tue Feb 16 08:50:49 2010 +0000
+++ b/libpurple/protocols/msn/slp.c	Tue Feb 16 08:54:07 2010 +0000
@@ -741,11 +741,10 @@
 	if (!strncmp(body, "INVITE", strlen("INVITE")))
 	{
 		char *branch;
+		char *call_id;
 		char *content;
 		char *content_type;
 
-		slpcall = msn_slpcall_new(slplink);
-
 		/* From: <msnmsgr:buddy@hotmail.com> */
 #if 0
 		slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
@@ -753,7 +752,7 @@
 
 		branch = get_token(body, ";branch={", "}");
 
-		slpcall->id = get_token(body, "Call-ID: {", "}");
+		call_id = get_token(body, "Call-ID: {", "}");
 
 #if 0
 		long content_len = -1;
@@ -767,13 +766,15 @@
 
 		content = get_token(body, "\r\n\r\n", NULL);
 
-		if (branch && content_type && content)
+		if (branch && call_id && content_type && content)
 		{
+			slpcall = msn_slpcall_new(slplink);
+			slpcall->id = call_id;
 			got_invite(slpcall, branch, content_type, content);
 		}
 		else
 		{
-			msn_slpcall_destroy(slpcall);
+			g_free(call_id);
 			slpcall = NULL;
 		}
 
--- a/libpurple/protocols/msn/slpcall.c	Tue Feb 16 08:50:49 2010 +0000
+++ b/libpurple/protocols/msn/slpcall.c	Tue Feb 16 08:54:07 2010 +0000
@@ -199,7 +199,7 @@
 
 	slpcall = NULL;
 	body = slpmsg->buffer;
-	body_len = slpmsg->size;
+	body_len = slpmsg->offset;
 
 	if (slpmsg->flags == 0x0 || slpmsg->flags == 0x1000000)
 	{
--- a/libpurple/protocols/msn/slplink.c	Tue Feb 16 08:50:49 2010 +0000
+++ b/libpurple/protocols/msn/slplink.c	Tue Feb 16 08:54:07 2010 +0000
@@ -585,15 +585,16 @@
 	}
 	else if (slpmsg->size && slpmsg->buffer)
 	{
-		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
+		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size || slpmsg->offset != offset)
 		{
 			purple_debug_error("msn",
 				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
 				slpmsg->size, offset, len);
 			g_return_if_reached();
+		} else {
+			memcpy(slpmsg->buffer + offset, data, len);
+			slpmsg->offset += len;
 		}
-		else
-			memcpy(slpmsg->buffer + offset, data, len);
 	}
 
 	if ((slpmsg->flags == 0x20 ||
--- a/libpurple/protocols/msn/slpmsg.h	Tue Feb 16 08:50:49 2010 +0000
+++ b/libpurple/protocols/msn/slpmsg.h	Tue Feb 16 08:54:07 2010 +0000
@@ -57,7 +57,18 @@
 	gboolean ft;
 	PurpleStoredImage *img;
 	guchar *buffer;
+
+	/**
+	 * For outgoing messages this is the number of bytes from buffer that
+	 * have already been sent out.  For incoming messages this is the
+	 * number of bytes that have been written to buffer.
+	 */
 	long long offset;
+
+	/**
+	 * This is the size of buffer, unless this is an outgoing file transfer,
+	 * in which case this is the size of the file.
+	 */
 	long long size;
 
 	GList *msgs; /**< The real messages. */