From 47410d806fcfaed605450c2e9c75a09652e3b574 Mon Sep 17 00:00:00 2001 From: recht Date: Tue, 27 Jan 2004 01:24:51 +0000 Subject: 12 vulnerabilities were found in the instant messenger GAIM that allow remote compromise. The 12 identified problems range from simple standard stack overflows, over heap overflows to an integer overflow that can be abused to cause a heap overflow. Due to the nature of instant messaging some of these bugs require man-in-the-middle attacks between client and server. But the underlying protocols are easy to implement and MIM attacks on ordinary TCP sessions is afairly simple task. Please see http://security.e-matters.de/advisories/012004.html for more details. Apply the fix posted in that advisory (originally by the FreeBSD security team) and bump PKGREVISION to 1. --- chat/gaim/Makefile | 3 +- chat/gaim/distinfo | 5 +- chat/gaim/patches/patch-aa | 2 +- chat/gaim/patches/patch-ab | 176 +++++++++++++++++++++++++++++++++++++++++++++ chat/gaim/patches/patch-ac | 13 ++++ chat/gaim/patches/patch-ad | 136 +++++++++++++++++++++++++++++++++++ 6 files changed, 332 insertions(+), 3 deletions(-) create mode 100644 chat/gaim/patches/patch-ab create mode 100644 chat/gaim/patches/patch-ac create mode 100644 chat/gaim/patches/patch-ad (limited to 'chat') diff --git a/chat/gaim/Makefile b/chat/gaim/Makefile index c47ecb2bb98..849ea569516 100644 --- a/chat/gaim/Makefile +++ b/chat/gaim/Makefile @@ -1,7 +1,8 @@ -# $NetBSD: Makefile,v 1.50 2004/01/22 07:49:20 grant Exp $ +# $NetBSD: Makefile,v 1.51 2004/01/27 01:24:51 recht Exp $ # DISTNAME= gaim-0.75 +PKGREVISION= 1 CATEGORIES= chat x11 MASTER_SITES= ${MASTER_SITE_SOURCEFORGE:=gaim/} EXTRACT_SUFX= .tar.bz2 diff --git a/chat/gaim/distinfo b/chat/gaim/distinfo index 9229b0732fa..fe9ef139352 100644 --- a/chat/gaim/distinfo +++ b/chat/gaim/distinfo @@ -1,5 +1,8 @@ -$NetBSD: distinfo,v 1.37 2004/01/11 20:54:07 jmmv Exp $ +$NetBSD: distinfo,v 1.38 2004/01/27 01:24:52 recht Exp $ SHA1 (gaim-0.75.tar.bz2) = 20a7ccadf276d9db6b74ae3d07d90601d805a4a9 Size (gaim-0.75.tar.bz2) = 3370977 bytes SHA1 (patch-aa) = 90d7bbc5c9ab5c6ffeba30a6c782e66cb1e3d861 +SHA1 (patch-ab) = aff902959e96d00c0712ac88b235aa918ba082d6 +SHA1 (patch-ac) = 803423543063b5838139dfad4c80172d6bfb4d70 +SHA1 (patch-ad) = 02f5d4d7b6cf2bc49043eba09b079ce2530552dc diff --git a/chat/gaim/patches/patch-aa b/chat/gaim/patches/patch-aa index bb00bd79433..c00d5ae2940 100644 --- a/chat/gaim/patches/patch-aa +++ b/chat/gaim/patches/patch-aa @@ -1,4 +1,4 @@ -$NetBSD: patch-aa,v 1.16 2004/01/11 20:54:08 jmmv Exp $ +$NetBSD: patch-aa,v 1.17 2004/01/27 01:24:52 recht Exp $ --- src/protocols/oscar/ft.c.orig 2004-01-05 02:34:04.000000000 +0100 +++ src/protocols/oscar/ft.c diff --git a/chat/gaim/patches/patch-ab b/chat/gaim/patches/patch-ab new file mode 100644 index 00000000000..09b7568e0b0 --- /dev/null +++ b/chat/gaim/patches/patch-ab @@ -0,0 +1,176 @@ +$NetBSD: patch-ab,v 1.6 2004/01/27 01:24:52 recht Exp $ + +--- src/protocols/yahoo/yahoo.c.orig 2004-01-10 06:04:09.000000000 +0100 ++++ src/protocols/yahoo/yahoo.c +@@ -20,6 +20,7 @@ + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + */ ++#include + #include "internal.h" + + #include "account.h" +@@ -131,8 +132,15 @@ static void yahoo_packet_read(struct yah + while (pos + 1 < len) { + if (data[pos] == 0xc0 && data[pos + 1] == 0x80) + break; ++ if (x >= sizeof(key)-1) { ++ x++; ++ continue; ++ ++ } + key[x++] = data[pos++]; + } ++ if (x >= sizeof(key)-1) ++ x = 0; + key[x] = 0; + pos += 2; + pair->key = strtol(key, NULL, 10); +@@ -868,32 +876,66 @@ static void yahoo_process_contact(GaimCo + } + } + ++ ++static void octal(const char **p, const char *end, unsigned char *n) ++{ ++ int i, c; ++ ++ for (i = 0, c = 0; i < 3 && *p < end; ++i, ++*p) { ++ c <<= 3; ++ switch (**p) { ++ case '0': break; ++ case '1': c += 1; break; ++ case '2': c += 2; break; ++ case '3': c += 3; break; ++ case '4': c += 4; break; ++ case '5': c += 5; break; ++ case '6': c += 6; break; ++ case '7': c += 7; break; ++ default: ++ if (i == 0) { ++ *n = **p; ++ ++*p; ++ return; ++ } ++ c >>= 3; ++ goto done; ++ } ++ } ++done: ++ *n = (c > UCHAR_MAX) ? '?' : c; ++ return; ++} ++ + #define OUT_CHARSET "utf-8" + + static char *yahoo_decode(const char *text) + { + char *converted; +- char *p, *n, *new; +- +- n = new = g_malloc(strlen (text) + 1); +- +- for (p = (char *)text; *p; p++, n++) { ++ unsigned char *n, *new; ++ size_t len; ++ const char *p, *end; ++ ++ len = strlen (text); ++ p = text; ++ end = &text[len]; ++ n = new = g_malloc(len + 1); ++ while (p < end) { + if (*p == '\\') { +- sscanf(p + 1, "%3o\n", (int *)n); +- p += 3; +- } +- else +- *n = *p; ++ ++p; ++ octal(&p, end, n); ++ } else ++ *n = *p++; ++ ++n; + } +- + *n = '\0'; +- + converted = g_convert(new, n - new, OUT_CHARSET, "iso-8859-1", NULL, NULL, NULL); + g_free(new); + + return converted; + } + ++ + static void yahoo_process_mail(GaimConnection *gc, struct yahoo_packet *pkt) + { + GaimAccount *account = gaim_connection_get_account(gc); +@@ -1903,32 +1945,30 @@ static void yahoo_got_web_connected(gpoi + + static void yahoo_web_pending(gpointer data, gint source, GaimInputCondition cond) + { ++ static const char http302[] = "HTTP/1.0 302"; ++ static const char setcookie[] = "Set-Cookie: "; + GaimConnection *gc = data; + GaimAccount *account = gaim_connection_get_account(gc); + struct yahoo_data *yd = gc->proto_data; +- char buf[1024], buf2[256], *i = buf, *r = buf2; +- int len, o = 0; ++ char buf[1024], *i = buf; ++ int len; ++ GString *s; + + len = read(source, buf, sizeof(buf)); +- if (len <= 0 || strncmp(buf, "HTTP/1.0 302", strlen("HTTP/1.0 302"))) { ++ if (len <= 0 || (len >= sizeof(http302)-1 && ++ memcmp(http302, buf, sizeof(http302)-1) != 0)) { + gaim_connection_error(gc, _("Unable to read")); + return; + } +- +- while ((i = strstr(i, "Set-Cookie: ")) && 0 < 2) { +- i += strlen("Set-Cookie: "); +- for (;*i != ';'; r++, i++) { +- *r = *i; +- } +- *r=';'; +- r++; +- *r=' '; +- r++; +- o++; +- } +- /* Get rid of that "; " */ +- *(r-2) = '\0'; +- yd->auth = g_strdup(buf2); ++ s = g_string_sized_new(len); ++ buf[len] = '\0'; ++ while ((i = strstr(i, setcookie)) != NULL) { ++ i += sizeof(setcookie)-1; ++ for (;*i != ';'; i++) ++ g_string_append_c(s, *i); ++ g_string_append(s, "; "); ++ } ++ yd->auth = g_string_free(s, FALSE); + gaim_input_remove(gc->inpa); + close(source); + /* Now we have our cookies to login with. I'll go get the milk. */ +@@ -1974,15 +2014,17 @@ static GHashTable *yahoo_login_page_hash + const char *c = buf; + char *d; + char name[64], value[64]; ++ int count = sizeof(name)-1; + while ((c < (buf + len)) && (c = strstr(c, "') < d) + break; +- for (c = d, d = value; *c!='"'; c++, d++) ++ for (c = d, d = value; *c!='"' && count; c++, d++, count--) + *d = *c; + *d = '\0'; + g_hash_table_insert(hash, g_strdup(name), g_strdup(value)); diff --git a/chat/gaim/patches/patch-ac b/chat/gaim/patches/patch-ac new file mode 100644 index 00000000000..cc5cae22770 --- /dev/null +++ b/chat/gaim/patches/patch-ac @@ -0,0 +1,13 @@ +$NetBSD: patch-ac,v 1.5 2004/01/27 01:24:52 recht Exp $ + +--- src/proxy.c.orig 2004-01-10 05:04:56.000000000 +0100 ++++ src/proxy.c +@@ -974,7 +974,7 @@ http_canread(gpointer data, gint source, + + gaim_input_remove(phb->inpa); + +- while ((nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { ++ while ((pos < sizeof(inputline)-1) && (nlc != 2) && (read(source, &inputline[pos++], 1) == 1)) { + if (inputline[pos - 1] == '\n') + nlc++; + else if (inputline[pos - 1] != '\r') diff --git a/chat/gaim/patches/patch-ad b/chat/gaim/patches/patch-ad new file mode 100644 index 00000000000..0c4ea64cf1c --- /dev/null +++ b/chat/gaim/patches/patch-ad @@ -0,0 +1,136 @@ +$NetBSD: patch-ad,v 1.1 2004/01/27 01:24:52 recht Exp $ + +--- src/util.c.orig 2004-01-10 05:04:56.000000000 +0100 ++++ src/util.c +@@ -247,24 +247,71 @@ gaim_base64_decode(const char *text, cha + /************************************************************************** + * Quoted Printable Functions + **************************************************************************/ +-void +-gaim_quotedp_decode(const char *str, char **ret_str, int *ret_len) ++static void hex(const char **p, const char *end, unsigned char *n) + { +- char *p, *n, *new; ++ int i, c; + +- n = new = g_malloc(strlen (str) + 1); ++ for (i = 0, c = 0; i < 2 && *p < end; ++i, ++*p) { ++ c <<= 4; ++ switch (**p) { ++ case '0': break; ++ case '1': c += 1; break; ++ case '2': c += 2; break; ++ case '3': c += 3; break; ++ case '4': c += 4; break; ++ case '5': c += 5; break; ++ case '6': c += 6; break; ++ case '7': c += 7; break; ++ case '8': c += 8; break; ++ case '9': c += 9; break; ++ case 'a': c += 10; break; ++ case 'b': c += 11; break; ++ case 'c': c += 12; break; ++ case 'd': c += 13; break; ++ case 'e': c += 14; break; ++ case 'f': c += 15; break; ++ case 'A': c += 10; break; ++ case 'B': c += 11; break; ++ case 'C': c += 12; break; ++ case 'D': c += 13; break; ++ case 'E': c += 14; break; ++ case 'F': c += 15; break; ++ default: ++ if (i == 0) { ++ *n = **p; ++ ++*p; ++ return; ++ } ++ c >>= 4; ++ goto done; ++ } ++ } ++done: ++ *n = (c > UCHAR_MAX) ? '?' : c; ++ return; ++} + +- for (p = (char *)str; *p; p++, n++) { ++void ++gaim_quotedp_decode(const char *str, char **ret_str, int *ret_len) ++{ ++ const char *p, *end; ++ unsigned char *n, *new; ++ size_t len; ++ ++ len = strlen (str); ++ n = new = g_malloc(len + 1); ++ p = str; ++ end = &p[len]; ++ while (p < end) { + if (*p == '=') { +- sscanf(p + 1, "%2x\n", (int *)n); +- p += 2; +- } +- else if (*p == '_') ++ ++p; ++ hex(&p, end, n); ++ } else if (*p == '_') + *n = ' '; + else + *n = *p; ++ ++n; + } +- + *n = '\0'; + + if (ret_len) +@@ -1962,7 +2009,7 @@ gaim_url_parse(const char *url, char **r + char **ret_path) + { + char scan_info[255]; +- char port_str[5]; ++ char port_str[6]; + int f; + const char *turl; + char host[256], path[256]; +@@ -1982,16 +2029,21 @@ gaim_url_parse(const char *url, char **r + } + + g_snprintf(scan_info, sizeof(scan_info), +- "%%[%s]:%%[%s]/%%[%s]", addr_ctrl, port_ctrl, page_ctrl); ++ "%%255[%s]:%%5[%s]/%%255[%s]", addr_ctrl, port_ctrl, page_ctrl); ++ addr_ctrl[sizeof(addr_ctrl)-1] = '\0'; ++ port_ctrl[sizeof(port_ctrl)-1] = '\0'; ++ page_ctrl[sizeof(page_ctrl)-1] = '\0'; + + f = sscanf(url, scan_info, host, port_str, path); + + if (f == 1) + { + g_snprintf(scan_info, sizeof(scan_info), +- "%%[%s]/%%[%s]", ++ "%%255[%s]/%%255[%s]", + addr_ctrl, page_ctrl); + f = sscanf(url, scan_info, host, path); ++ addr_ctrl[sizeof(addr_ctrl)-1] = '\0'; ++ page_ctrl[sizeof(page_ctrl)-1] = '\0'; + g_snprintf(port_str, sizeof(port_str), "80"); + } + +@@ -2081,9 +2133,14 @@ parse_redirect(const char *data, size_t + static size_t + parse_content_len(const char *data, size_t data_len) + { +- size_t content_len = 0; ++ int content_len = 0; ++ char *tmp; + +- sscanf(data, "Content-Length: %d", (int *)&content_len); ++ tmp = g_malloc(data_len + 1); ++ memcpy(tmp, data, data_len); ++ tmp[data_len] = '\0'; ++ sscanf(tmp, "Content-Length: %d", &content_len); ++ g_free(tmp); + + return content_len; + } -- cgit v1.2.3