Fix CVE-2010-0277, a possible remote crash when parsing an incoming
authorMark Doliner <markdoliner@pidgin.im>
Tue, 16 Feb 2010 08:54:07 +0000
changeset9a3f73531905 pushlog
parent f9ce7935574c
child 6c8add94b5a4
Fix CVE-2010-0277, a possible remote crash when parsing an incoming
SLP message. Discovered by Fabian Yamaguchi.
ChangeLog
libpurple/protocols/msn/slp.c
libpurple/protocols/msn/slpcall.c
libpurple/protocols/msn/slplink.c
libpurple/protocols/msn/slpmsg.h
      1.1 --- a/ChangeLog
      1.2 +++ b/ChangeLog
      1.3 @@ -26,6 +26,8 @@
      1.4  	  Previously only icons between 48x48 and 50x50 were allowed.
      1.5  
      1.6  	MSN:
      1.7 +	* Fix CVE-2010-0277, a possible remote crash when parsing an incoming
      1.8 +	  SLP message.  Discovered by Fabian Yamaguchi.
      1.9  	* File transfer requests will no longer cause a crash if you delete the
     1.10  	  file before the other side accepts.
     1.11  	* Received files will no longer hold an extra lock after completion,
      2.1 --- a/libpurple/protocols/msn/slp.c
      2.2 +++ b/libpurple/protocols/msn/slp.c
      2.3 @@ -741,11 +741,10 @@
      2.4  	if (!strncmp(body, "INVITE", strlen("INVITE")))
      2.5  	{
      2.6  		char *branch;
      2.7 +		char *call_id;
      2.8  		char *content;
      2.9  		char *content_type;
     2.10  
     2.11 -		slpcall = msn_slpcall_new(slplink);
     2.12 -
     2.13  		/* From: <msnmsgr:buddy@hotmail.com> */
     2.14  #if 0
     2.15  		slpcall->remote_user = get_token(body, "From: <msnmsgr:", ">\r\n");
     2.16 @@ -753,7 +752,7 @@
     2.17  
     2.18  		branch = get_token(body, ";branch={", "}");
     2.19  
     2.20 -		slpcall->id = get_token(body, "Call-ID: {", "}");
     2.21 +		call_id = get_token(body, "Call-ID: {", "}");
     2.22  
     2.23  #if 0
     2.24  		long content_len = -1;
     2.25 @@ -767,13 +766,15 @@
     2.26  
     2.27  		content = get_token(body, "\r\n\r\n", NULL);
     2.28  
     2.29 -		if (branch && content_type && content)
     2.30 +		if (branch && call_id && content_type && content)
     2.31  		{
     2.32 +			slpcall = msn_slpcall_new(slplink);
     2.33 +			slpcall->id = call_id;
     2.34  			got_invite(slpcall, branch, content_type, content);
     2.35  		}
     2.36  		else
     2.37  		{
     2.38 -			msn_slpcall_destroy(slpcall);
     2.39 +			g_free(call_id);
     2.40  			slpcall = NULL;
     2.41  		}
     2.42  
      3.1 --- a/libpurple/protocols/msn/slpcall.c
      3.2 +++ b/libpurple/protocols/msn/slpcall.c
      3.3 @@ -199,7 +199,7 @@
      3.4  
      3.5  	slpcall = NULL;
      3.6  	body = slpmsg->buffer;
      3.7 -	body_len = slpmsg->size;
      3.8 +	body_len = slpmsg->offset;
      3.9  
     3.10  	if (slpmsg->flags == 0x0 || slpmsg->flags == 0x1000000)
     3.11  	{
      4.1 --- a/libpurple/protocols/msn/slplink.c
      4.2 +++ b/libpurple/protocols/msn/slplink.c
      4.3 @@ -585,15 +585,16 @@
      4.4  	}
      4.5  	else if (slpmsg->size && slpmsg->buffer)
      4.6  	{
      4.7 -		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size)
      4.8 +		if (G_MAXSIZE - len < offset || (offset + len) > slpmsg->size || slpmsg->offset != offset)
      4.9  		{
     4.10  			purple_debug_error("msn",
     4.11  				"Oversized slpmsg - msgsize=%lld offset=%" G_GUINT64_FORMAT " len=%" G_GSIZE_FORMAT "\n",
     4.12  				slpmsg->size, offset, len);
     4.13  			g_return_if_reached();
     4.14 +		} else {
     4.15 +			memcpy(slpmsg->buffer + offset, data, len);
     4.16 +			slpmsg->offset += len;
     4.17  		}
     4.18 -		else
     4.19 -			memcpy(slpmsg->buffer + offset, data, len);
     4.20  	}
     4.21  
     4.22  	if ((slpmsg->flags == 0x20 ||
      5.1 --- a/libpurple/protocols/msn/slpmsg.h
      5.2 +++ b/libpurple/protocols/msn/slpmsg.h
      5.3 @@ -57,7 +57,18 @@
      5.4  	gboolean ft;
      5.5  	PurpleStoredImage *img;
      5.6  	guchar *buffer;
      5.7 +
      5.8 +	/**
      5.9 +	 * For outgoing messages this is the number of bytes from buffer that
     5.10 +	 * have already been sent out.  For incoming messages this is the
     5.11 +	 * number of bytes that have been written to buffer.
     5.12 +	 */
     5.13  	long long offset;
     5.14 +
     5.15 +	/**
     5.16 +	 * This is the size of buffer, unless this is an outgoing file transfer,
     5.17 +	 * in which case this is the size of the file.
     5.18 +	 */
     5.19  	long long size;
     5.20  
     5.21  	GList *msgs; /**< The real messages. */