COMMAND

    TetriNet daemon (Tetrix)

SYSTEMS AFFECTED

    Linux

PROBLEM

    Steven Hodges  found a  buffer overflow  in a  TetriNet daemon for
    Linux  called  "Tetrix".   To  exploit  this  bug, you will need a
    hostname longer than 122 characters, and any method of  connecting
    to the  host on  port 31457  (nc).   Once you  are connected,  the
    overflow should take place.

SOLUTION

    Here is the patch:

    diff -ru tetrinetx-1.13.16.orig/src/main.c tetrinetx-1.13.16/src/main.c
    --- tetrinetx-1.13.16.orig/src/main.c   Thu Dec 24 00:24:50 1998
    +++ tetrinetx-1.13.16/src/main.c        Sun Feb 14 16:22:45 1999
    @@ -2561,7 +2562,7 @@
     /* Someone has just connected. So lets answer them */
     void net_telnet(struct net_t *n, char *buf)
       {
    -    unsigned long ip; int k,l; char s[121]; char strg[121];
    +    unsigned long ip; int k,l; char s[UHOSTLEN]; char strg[121];
	 char n1[4], n2[4], n3[4], n4[4];
	 struct channel_t *chan, *ochan;
	 struct net_t *net;
    diff -ru tetrinetx-1.13.16.orig/src/main.h tetrinetx-1.13.16/src/main.h
    --- tetrinetx-1.13.16.orig/src/main.h   Thu Dec 24 00:24:50 1998
    +++ tetrinetx-1.13.16/src/main.h        Sun Feb 14 16:19:06 1999
    @@ -48,9 +48,8 @@
     #define SERVERBUILD "16"               /* What build we are at */
     #define NICKLEN 30                     /* Maximum length of Nickname */
     #define VERLEN 10                      /* Maximum length of Tetrinet version */
    -#define UHOSTLEN 30                    /* Maximum length of Hostname */
    +#define UHOSTLEN 256                   /* Maximum length of Hostname */
     #define TEAMLEN NICKLEN                        /* Maximum length of teamname */
    -/*#define MAXNET 80*/                  /* Maximum network sockets */
     #define MAXWINLIST 100                 /* Maximum entries on Winlist */
     #define TELNET_PORT 31457              /* Telnet port to listen on */
     #define QUERY_PORT 31456               /* Query port to listen on */
    diff -ru tetrinetx-1.13.16.orig/src/net.c tetrinetx-1.13.16/src/net.c
    --- tetrinetx-1.13.16.orig/src/net.c    Thu Dec 24 00:24:50 1998
    +++ tetrinetx-1.13.16/src/net.c Sun Feb 14 16:22:11 1999
    @@ -250,15 +250,17 @@
     unsigned long ip;
     {
       struct hostent *hp; unsigned long addr=ip;
    -  unsigned char *p; static char s[121];
    -/*  alarm(10);*/
    +  unsigned char *p; static char s[UHOSTLEN];
    +
       hp=gethostbyaddr((char *)&addr,sizeof(addr),AF_INET); /*alarm(0);*/
       if (hp==NULL) {
	 p=(unsigned char *)&addr;
	 sprintf(s,"%u.%u.%u.%u",p[0],p[1],p[2],p[3]);
	 return s;
       }
    -  strcpy(s,hp->h_name); return s;
    +  strncpy(s,hp->h_name,(UHOSTLEN-1));
    +  s[strlen(s)]='\0';
    +  return s;
     }
     /* short routine to answer a connect received on a socket made previously

    According to Pavel  Machek s[strlen(s)]='\0'; will  not help it  -
    because  strlen()  looks  for  \0.   s[UHOSTLEN-1]='\0';  would be
    correct.