96825 2003-03-25 18:45 /9 rader/ <caf@guarana.org> Importerad: 2003-03-25 18:45 av Brevbäraren Extern mottagare: Timo Sirainen <tss@iki.fi> Mottagare: Bugtraq (import) <4151> Kommentar till text 94152 av Timo Sirainen <tss@iki.fi> Ärende: Re: Buffer overflows in ircII-based clients ------------------------------------------------------------ Attached is a set of official-ish patches to the BitchX 1.0c19 release to cover the mentioned buffer mishandling. Alternatively, you can upgrade to the latest CVS revision of BitchX. - caf. (96825) / <caf@guarana.org>/------------------------ Bilaga (text/plain) i text 96826 96826 2003-03-25 18:45 /273 rader/ <caf@guarana.org> Importerad: 2003-03-25 18:45 av Brevbäraren Extern mottagare: Timo Sirainen <tss@iki.fi> Mottagare: Bugtraq (import) <4152> Bilaga (text/plain) till text 96825 Ärende: Bilaga till: Re: Buffer overflows in ircII-based clients ------------------------------------------------------------ diff -ur BitchX.orig/source/banlist.c BitchX/source/banlist.c --- BitchX.orig/source/banlist.c Thu Feb 28 15:22:46 2002 +++ BitchX/source/banlist.c Wed Mar 26 01:47:23 2003 @@ -264,9 +264,9 @@ char * ban_it(char *nick, char *user, char *host, char *ip) { static char banstr[BIG_BUFFER_SIZE/4+1]; -char *tmpstr = NULL; char *t = user; char *t1 = user; +char *tmp; *banstr = 0; while (strlen(t1)>9) @@ -277,32 +277,40 @@ case 7: if (ip) { - sprintf(banstr, "*!*@%s", cluster(ip)); + snprintf(banstr, sizeof banstr, "*!*@%s", + cluster(ip)); break; } case 2: /* Better */ - sprintf(banstr, "*!*%s@%s", t1, cluster(host)); + snprintf(banstr, sizeof banstr, "*!*%s@%s", t1, + cluster(host)); break; case 3: /* Host */ - sprintf(banstr, "*!*@%s", host); + snprintf(banstr, sizeof banstr, "*!*@%s", host); break; case 4: /* Domain */ - sprintf(banstr, "*!*@*%s", strrchr(host, '.')); - break; + tmp = strrchr(host, '.'); + if (tmp) { + snprintf(banstr, sizeof banstr, "*!*@*%s", + tmp); + } else { + snprintf(banstr, sizeof banstr, "*!*@%s", + host); + } + break; case 5: /* User */ - sprintf(banstr, "*!%s@%s", t, cluster(host)); + snprintf(banstr, sizeof banstr, "*!%s@%s", t, + cluster(host)); break; case 6: /* Screw */ - malloc_sprintf(&tmpstr, "*!*%s@%s", t1, host); - strcpy(banstr, screw(tmpstr)); - new_free(&tmpstr); + snprintf(banstr, sizeof banstr, "*!*%s@%s", t1, host); + screw(banstr); break; case 1: /* Normal */ default: - { - sprintf(banstr, "%s!*%s@%s", nick, t1, host); + snprintf(banstr, sizeof banstr, "%s!*%s@%s", nick, t1, + host); break; - } } return banstr; } Only in BitchX/source: banlist.c.orig diff -ur BitchX.orig/source/ctcp.c BitchX/source/ctcp.c --- BitchX.orig/source/ctcp.c Thu Feb 28 15:22:47 2002 +++ BitchX/source/ctcp.c Wed Mar 26 01:49:52 2003 @@ -1482,6 +1482,10 @@ *putbuf2; int len; len = IRCD_BUFFER_SIZE - (12 + strlen(to)); + + if (len < strlen(ctcp_cmd[datatag].name) + 3) + return; + putbuf2 = alloca(len); if (format) diff -ur BitchX.orig/source/misc.c BitchX/source/misc.c --- BitchX.orig/source/misc.c Sun Mar 24 20:31:07 2002 +++ BitchX/source/misc.c Wed Mar 26 01:57:44 2003 @@ -3110,42 +3110,47 @@ static char result[IRCD_BUFFER_SIZE/4 + 1]; char temphost[BIG_BUFFER_SIZE + 1]; char *host; + char *atsign; if (!hostname) return NULL; - host = temphost; - *result = 0; - memset(result, 0, sizeof(result)); - memset(temphost, 0, sizeof(temphost)); - if (strchr(hostname, '@')) - { - if (*hostname == '~') - hostname++; - strcpy(result, hostname); - *strchr(result, '@') = '\0'; - if (strlen(result) > 9) - { - result[8] = '*'; - result[9] = '\0'; + + atsign = strchr(hostname, '@'); + if (atsign) { + if (*hostname == '~') { + strcpy(result, "~*@"); + } else { + size_t ident_len = atsign - hostname; + + if (ident_len <= 9) { + /* copy ident@ */ + strmcpy(result, hostname, ident_len + 1); + } else { + strmcpy(result, hostname, 8); + result[8] = '*'; + result[9] = '@'; + result[10] = '\0'; + } } - strcat(result, "@"); - if (!(hostname = strchr(hostname, '@'))) - return NULL; - hostname++; + hostname = atsign + 1; + } else { + *result = 0; } - strcpy(host, hostname); - if (*host && isdigit(*(host + strlen(host) - 1))) + strlcpy(temphost, hostname, sizeof temphost); + host = temphost; + + if (*host && isdigit((unsigned char)*(host + strlen(host) - 1))) { /* Thanks icebreak for this small patch which fixes this function */ int i; char *tmp; - char count=0; + char count = 0; tmp = host; - while((tmp-host)<strlen(host)) + while((tmp - host) < strlen(host)) { - if((tmp=strchr(tmp,'.'))==NULL) + if((tmp = strchr(tmp,'.')) == NULL) break; count++; tmp++; @@ -3154,8 +3159,8 @@ for (i = 0; i < count; i++) tmp = strchr(tmp, '.') + 1; *tmp = '\0'; - strcat(result, host); - strcat(result, "*"); + strlcat(result, host, sizeof result); + strlcat(result, "*", sizeof result); } else { @@ -3177,16 +3182,17 @@ else return (char *) NULL; } + + /* We don't need strlcat for these first two, because + * at this point the maximum length of the string in + * result is 10 */ strcat(result, "*"); if (my_stricmp(host, temphost)) strcat(result, "."); - strcat(result, host); + strlcat(result, host, sizeof result); } return result; } - - - struct _sock_manager { Only in BitchX/source: misc.c.orig Only in BitchX/source: misc.c.rej diff -ur BitchX.orig/source/names.c BitchX/source/names.c --- BitchX.orig/source/names.c Tue Mar 26 07:47:30 2002 +++ BitchX/source/names.c Wed Mar 26 01:58:54 2003 @@ -572,7 +572,7 @@ *nmodes = 0; *nargs = 0; - for (; *modes; modes++) + for (; *modes && (strlen(nmodes) + 2) < sizeof nmodes; modes++) { isbanned = isopped = isvoiced = 0; switch (*modes) @@ -742,7 +742,7 @@ /* modes which can be done multiple times are added here */ - for (tucm = ucm; tucm; tucm = tucm->next) + for (tucm = ucm; tucm && (strlen(nmodes) + 2) < sizeof nmodes; tucm = tucm->next) { if (tucm->o_ed) { diff -ur BitchX.orig/source/notice.c BitchX/source/notice.c --- BitchX.orig/source/notice.c Thu Feb 28 15:22:50 2002 +++ BitchX/source/notice.c Wed Mar 26 01:59:44 2003 @@ -425,7 +425,7 @@ int conn = !strncmp(line+7, "connect", 7) ? 1 : 0; int dalnet = 0, ircnet = 0; - if (*(line+18) == ':') + if (strlen(line) >= 19 && line[18] == ':') q = NULL; else dalnet = (q == NULL); diff -ur BitchX.orig/source/numbers.c BitchX/source/numbers.c --- BitchX.orig/source/numbers.c Thu Feb 28 15:22:50 2002 +++ BitchX/source/numbers.c Wed Mar 26 02:02:35 2003 @@ -354,26 +354,29 @@ set_display_target(chan, LOG_CURRENT); PasteArgs(ArgList, 0); - strcpy(buffer, ArgList[0]); + strlcpy(buffer, ArgList[0], sizeof buffer); switch(-current_numeric) { case 437: - strcat(buffer, " (Channel is temporarily unavailable)"); + strlcat(buffer, + " (Channel is temporarily unavailable)", + sizeof buffer); break; case 471: - strcat(buffer, " (Channel is full)"); + strlcat(buffer, " (Channel is full)", sizeof buffer); break; case 473: - strcat(buffer, " (You must be invited)"); + strlcat(buffer, " (You must be invited)", + sizeof buffer); break; case 474: - strcat(buffer, " (You are banned)"); + strlcat(buffer, " (You are banned)", sizeof buffer); break; case 475: - strcat(buffer, " (Bad channel key)"); + strlcat(buffer, " (Bad channel key)", sizeof buffer); break; case 476: - strcat(buffer, " (Bad channel mask)"); + strlcat(buffer, " (Bad channel mask)", sizeof buffer); break; default: return; @@ -384,7 +387,6 @@ put_it("%s %s", numeric_banner(), buffer); reset_display_target(); } - int handle_server_stats(char *from, char **ArgList, int comm) { (96826) / <caf@guarana.org>/------------------------