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.

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, "[EMAIL PROTECTED]", cluster(ip));
+                               snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]",
+                                       cluster(ip));
                                break;
                        }
                case 2: /* Better       */
-                       sprintf(banstr, "[EMAIL PROTECTED]", t1, cluster(host));
+                       snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", t1, 
+                               cluster(host));
                        break;
                case 3: /* Host         */
-                       sprintf(banstr, "[EMAIL PROTECTED]", host);
+                       snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", host);
                        break;
                case 4: /* Domain       */
-                       sprintf(banstr, "[EMAIL PROTECTED]", strrchr(host, '.'));
-                       break;
+                       tmp = strrchr(host, '.');
+                       if (tmp) {
+                               snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]",
+                                       tmp);
+                       } else {
+                               snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", 
+                                       host);
+                       }
+                       break;  
                case 5: /* User         */
-                       sprintf(banstr, "[EMAIL PROTECTED]", t, cluster(host));
+                       snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", t, 
+                               cluster(host));
                        break;
                case 6: /* Screw        */
-                       malloc_sprintf(&tmpstr, "[EMAIL PROTECTED]", t1, host);
-                       strcpy(banstr, screw(tmpstr));
-                       new_free(&tmpstr);
+                       snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", t1, host);
+                       screw(banstr);
                        break;
                case 1: /* Normal       */
                default:
-               {
-                       sprintf(banstr, "[EMAIL PROTECTED]", nick, t1, host);
+                       snprintf(banstr, sizeof banstr, "[EMAIL PROTECTED]", 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)
 {

Reply via email to