Fix for CVE-2010-3711. Properly validate the return value from
authorDaniel Atallah <datallah@pidgin.im>
Sun, 17 Oct 2010 03:55:04 +0000
changeset1a7e2da2ab01 pushlog
parent f227121c8561
child abc600ff8ae2
Fix for CVE-2010-3711. Properly validate the return value from
purple_base64_decode() (the CVE issue) and purple_base16_decode() (just a bug).
Coincidentally, this should also fix #12614.


committer: John Bailey <rekkanoryo@rekkanoryo.org>
libpurple/ntlm.c
libpurple/plugins/perl/common/Util.xs
libpurple/protocols/jabber/auth_digest_md5.c
libpurple/protocols/msn/slp.c
libpurple/protocols/myspace/message.c
libpurple/protocols/oscar/clientlogin.c
libpurple/protocols/qq/im.c
libpurple/protocols/yahoo/libymsg.c
     1.1 --- a/libpurple/ntlm.c
     1.2 +++ b/libpurple/ntlm.c
     1.3 @@ -152,9 +152,14 @@
     1.4  	static guint8 nonce[8];
     1.5  
     1.6  	tmsg = (struct type2_message*)purple_base64_decode(type2, &retlen);
     1.7 -	memcpy(nonce, tmsg->nonce, 8);
     1.8 -	if (flags != NULL)
     1.9 -		*flags = GUINT16_FROM_LE(tmsg->flags);
    1.10 +	if (tmsg != NULL && retlen >= (sizeof(struct type2_message) - 1)) {
    1.11 +		memcpy(nonce, tmsg->nonce, 8);
    1.12 +		if (flags != NULL)
    1.13 +			*flags = GUINT16_FROM_LE(tmsg->flags);
    1.14 +	} else {
    1.15 +		purple_debug_error("ntlm", "Unable to parse type2 message - returning empty nonce.\n");
    1.16 +		memset(nonce, 0, 8);
    1.17 +	}
    1.18  	g_free(tmsg);
    1.19  
    1.20  	return nonce;
     2.1 --- a/libpurple/plugins/perl/common/Util.xs
     2.2 +++ b/libpurple/plugins/perl/common/Util.xs
     2.3 @@ -238,7 +238,7 @@
     2.4  	guchar *ret;
     2.5  	CODE:
     2.6  		ret = purple_base16_decode(str, &len);
     2.7 -		if(len) {
     2.8 +		if(ret && len > 0) {
     2.9  			RETVAL = newSVpv((gchar *)ret, len);
    2.10  		} else {
    2.11  			g_free(ret);
    2.12 @@ -256,7 +256,7 @@
    2.13  	guchar *ret;
    2.14  	CODE:
    2.15  		ret = purple_base64_decode(str, &len);
    2.16 -		if(len) {
    2.17 +		if(ret && len > 0) {
    2.18  			RETVAL = newSVpv((gchar *)ret, len);
    2.19  		} else {
    2.20  			g_free(ret);
     3.1 --- a/libpurple/protocols/jabber/auth_digest_md5.c
     3.2 +++ b/libpurple/protocols/jabber/auth_digest_md5.c
     3.3 @@ -182,7 +182,9 @@
     3.4  
     3.5  	dec_in = (char *)purple_base64_decode(enc_in, NULL);
     3.6  	purple_debug_misc("jabber", "decoded challenge (%"
     3.7 -			G_GSIZE_FORMAT "): %s\n", strlen(dec_in), dec_in);
     3.8 +			G_GSIZE_FORMAT "): %s\n",
     3.9 +			dec_in != NULL ? strlen(dec_in) : 0,
    3.10 +			dec_in != NULL  ? dec_in : "(null)");
    3.11  
    3.12  	parts = parse_challenge(dec_in);
    3.13  
     4.1 --- a/libpurple/protocols/msn/slp.c
     4.2 +++ b/libpurple/protocols/msn/slp.c
     4.3 @@ -554,7 +554,7 @@
     4.4  							 slpcall->slplink->remote_user);
     4.5  
     4.6  		header = (MsnFileContext *)purple_base64_decode(context, &bin_len);
     4.7 -		if (bin_len >= sizeof(MsnFileContext) - 1 &&
     4.8 +		if (header != NULL && bin_len >= sizeof(MsnFileContext) - 1 &&
     4.9  			(header->version == 2 ||
    4.10  			 (header->version == 3 && header->length == sizeof(MsnFileContext) + 63))) {
    4.11  			file_size = GUINT64_FROM_LE(header->file_size);
     5.1 --- a/libpurple/protocols/myspace/message.c
     5.2 +++ b/libpurple/protocols/myspace/message.c
     5.3 @@ -1363,7 +1363,7 @@
     5.4  			 *
     5.5  			 */
     5.6  			*binary_data = (gchar *)purple_base64_decode((const gchar *)elem->data, binary_length);
     5.7 -			return TRUE;
     5.8 +			return ((*binary_data) != NULL);
     5.9  
    5.10  		case MSIM_TYPE_BINARY:
    5.11  			gs = (GString *)elem->data;
     6.1 --- a/libpurple/protocols/oscar/clientlogin.c
     6.2 +++ b/libpurple/protocols/oscar/clientlogin.c
     6.3 @@ -272,7 +272,7 @@
     6.4  	char *tls_certname = NULL;
     6.5  	unsigned short port;
     6.6  	guint8 *cookiedata;
     6.7 -	gsize cookiedata_len;
     6.8 +	gsize cookiedata_len = 0;
     6.9  
    6.10  	od = user_data;
    6.11  	gc = od->gc;
     7.1 --- a/libpurple/protocols/qq/im.c
     7.2 +++ b/libpurple/protocols/qq/im.c
     7.3 @@ -547,7 +547,6 @@
     7.4  	const gchar *start, *end, *last;
     7.5  	GData *attribs;
     7.6  	gchar *tmp;
     7.7 -	unsigned char *rgb;
     7.8  
     7.9  	g_return_val_if_fail(msg != NULL, NULL);
    7.10  
    7.11 @@ -570,8 +569,11 @@
    7.12  
    7.13  		tmp = g_datalist_get_data(&attribs, "color");
    7.14  		if (tmp && strlen(tmp) > 1) {
    7.15 -			rgb = purple_base16_decode(tmp + 1, NULL);
    7.16 -			g_memmove(fmt->rgb, rgb, 3);
    7.17 +			unsigned char *rgb;
    7.18 +			gsize rgb_len;
    7.19 +			rgb = purple_base16_decode(tmp + 1, &rgb_len);
    7.20 +			if (rgb != NULL && rgb_len >= 3)
    7.21 +				g_memmove(fmt->rgb, rgb, 3);
    7.22  			g_free(rgb);
    7.23  		}
    7.24  
     8.1 --- a/libpurple/protocols/yahoo/libymsg.c
     8.2 +++ b/libpurple/protocols/yahoo/libymsg.c
     8.3 @@ -317,7 +317,7 @@
     8.4  
     8.5  			if (pair->value) {
     8.6  				decoded = purple_base64_decode(pair->value, &len);
     8.7 -				if (len) {
     8.8 +				if (decoded && len > 0) {
     8.9  					tmp = purple_str_binary_to_ascii(decoded, len);
    8.10  					purple_debug_info("yahoo", "Got key 197, value = %s\n", tmp);
    8.11  					g_free(tmp);
    8.12 @@ -2863,15 +2863,17 @@
    8.13  	if (base64) {
    8.14  		guint32 ip;
    8.15  		YahooFriend *f;
    8.16 -		char *host_ip;
    8.17 +		char *host_ip, *tmp;
    8.18  		struct yahoo_p2p_data *p2p_data;
    8.19  
    8.20  		decoded = purple_base64_decode(base64, &len);
    8.21 -		if (len) {
    8.22 -			char *tmp = purple_str_binary_to_ascii(decoded, len);
    8.23 -			purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp);
    8.24 -			g_free(tmp);
    8.25 +		if (decoded == NULL) {
    8.26 +			purple_debug_info("yahoo","p2p: Unable to decode base64 IP (%s) \n", base64);
    8.27 +			return;
    8.28  		}
    8.29 +		tmp = purple_str_binary_to_ascii(decoded, len);
    8.30 +		purple_debug_info("yahoo", "Got P2P service packet (from server): who = %s, ip = %s\n", who, tmp);
    8.31 +		g_free(tmp);
    8.32  
    8.33  		ip = strtol((gchar *)decoded, NULL, 10);
    8.34  		g_free(decoded);