# HG changeset patch # User Mark Doliner # Date 1266310447 0 # Node ID 69077f3993f61f0a55d3292467f6020e984a45ee # Parent 1eeeb20f0b9f44141c4575a5432add8c8c76b1fd Fix CVE-2010-0277, a possible remote crash when parsing an incoming SLP message. Discovered by Fabian Yamaguchi. diff -r 1eeeb20f0b9f -r 69077f3993f6 ChangeLog --- 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, diff -r 1eeeb20f0b9f -r 69077f3993f6 libpurple/protocols/msn/slp.c --- 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: */ #if 0 slpcall->remote_user = get_token(body, "From: \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; } diff -r 1eeeb20f0b9f -r 69077f3993f6 libpurple/protocols/msn/slpcall.c --- 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) { diff -r 1eeeb20f0b9f -r 69077f3993f6 libpurple/protocols/msn/slplink.c --- 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 || diff -r 1eeeb20f0b9f -r 69077f3993f6 libpurple/protocols/msn/slpmsg.h --- 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. */