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. */