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.
This commit is contained in:
recht 2004-01-27 01:24:51 +00:00
parent 18a916d5e6
commit 3805856b73
6 changed files with 332 additions and 3 deletions

View file

@ -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

View file

@ -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

View file

@ -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

176
chat/gaim/patches/patch-ab Normal file
View file

@ -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 <limits.h>
#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, "<input "))) {
c = strstr(c, "name=\"") + strlen("name=\"");
- for (d = name; *c!='"'; c++, d++)
+ for (d = name; *c!='"' && count; c++, d++, count--)
*d = *c;
*d = '\0';
+ count = sizeof(value)-1;
d = strstr(c, "value=\"") + strlen("value=\"");
if (strchr(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));

View file

@ -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')

136
chat/gaim/patches/patch-ad Normal file
View file

@ -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;
}