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);