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