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.