[From nobody Thu Mar 12 02:38:53 2009
X-Account-Key: account2
Received: from mail.cs.umass.edu ([128.119.243.168])
	by rwcrmxc24.comcast.net (rwcrmxc24) with ESMTP
	id &lt;20050131235923r24000avgre&gt;; Mon, 31 Jan 2005 23:59:23 +0000
X-Originating-IP: [128.119.243.168]
Received: from loki.cs.umass.edu
	(IDENT:zihP9Yo/w3cX83PQyN3Ipd2R81qM5d6J@localhost [127.0.0.1])
	by mail.cs.umass.edu (8.12.11/8.12.5) with ESMTP id j0VNxCwS023850
	(version=TLSv1/SSLv3 cipher=DHE-RSA-AES256-SHA bits=256 verify=NOT)
	for &lt;brendanburns@comcast.net&gt;; Mon, 31 Jan 2005 18:59:12 -0500
Received: from localhost (bburns@localhost)
	by loki.cs.umass.edu (8.12.11/8.12.5/Submit) with ESMTP id
	j0VNxCRg023847
	for &lt;brendanburns@comcast.net&gt;; Mon, 31 Jan 2005 18:59:12 -0500
Date: Mon, 31 Jan 2005 18:59:12 -0500 (EST)
From: Brendan Burns &lt;bburns@cs.umass.edu&gt;
To: brendanburns@comcast.net
Subject: Icculus quake2 - security patch (fwd)
Message-ID: &lt;Pine.LNX.4.44.0501311859010.23818-200000@loki.cs.umass.edu&gt;
MIME-Version: 1.0
Content-Type: MULTIPART/Mixed; BOUNDARY=------------000308040205070900090108
Content-ID: &lt;Pine.LNX.4.44.0501311859011.23818@loki.cs.umass.edu&gt;

  This message is in MIME format.  The first part should be readable text,
  while the remaining parts are likely unreadable without MIME-aware tools.
  Send mail to mime@docserver.cac.washington.edu for more info.

--------------000308040205070900090108
Content-Type: TEXT/PLAIN; CHARSET=US-ASCII; FORMAT=flowed
Content-ID: &lt;Pine.LNX.4.44.0501311859012.23818@loki.cs.umass.edu&gt;



---------- Forwarded message ----------
Date: Sun, 30 Jan 2005 00:58:41 +0300
From: Andrey Nazarov &lt;skuller-vidnoe@yandex.ru&gt;
To: bburns@icculus.org
Subject: Icculus quake2 - security patch

Hello,

First I would like to thank you for maintaining this linux quake2 port. 
I found the sources very useful as a starting point for porting my own 
quake2 client to linux. Keep up this good work!

I'm sending a patch for the latest version of Icculus Quake2 that fixes 
some important vulnerabilities found in quake2 engine, affecting both 
the server and client. Some of these vulnerabilities allow remote 
execution of arbitrary code, others allow denial-of-service attacks, so 
these fixes are essential.

I'm new to linux, and I'm currently running cvs/diff on my windows box, 
so I can't be sure if this patch applies correctly. Sorry if there is 
some kind of a problem.

-- 
Best regards,
Andrey Nazarov            mailto:skuller-vidnoe@yandex.ru

--------------000308040205070900090108
Content-Type: TEXT/PLAIN; NAME=&quot;security.patch&quot;
Content-ID: &lt;Pine.LNX.4.44.0501311859013.23818@loki.cs.umass.edu&gt;
Content-Description: 
Content-Disposition: INLINE; FILENAME=&quot;security.patch&quot;

Index: client/cl_parse.c
===================================================================
RCS file: /cvs/cvsroot/quake2/src/client/cl_parse.c,v
retrieving revision 1.3
diff -u -r1.3 cl_parse.c
--- client/cl_parse.c	24 Sep 2004 22:06:52 -0000	1.3
+++ client/cl_parse.c	29 Jan 2005 20:57:01 -0000
@@ -397,6 +397,9 @@
 	strncpy(ci-&gt;cinfo, s, sizeof(ci-&gt;cinfo));
 	ci-&gt;cinfo[sizeof(ci-&gt;cinfo)-1] = 0;
 
+	// sku - avoid potentional buffer overflow vulnerability
+	s = ci-&gt;cinfo;
+
 	// isolate the player's name
 	strncpy(ci-&gt;name, s, sizeof(ci-&gt;name));
 	ci-&gt;name[sizeof(ci-&gt;name)-1] = 0;
@@ -528,6 +531,7 @@
 	int		i;
 	char	*s;
 	char	olds[MAX_QPATH];
+	int		length;
 
 	i = MSG_ReadShort (&amp;net_message);
 	if (i &lt; 0 || i &gt;= MAX_CONFIGSTRINGS)
@@ -537,6 +541,12 @@
 	strncpy (olds, cl.configstrings[i], sizeof(olds));
 	olds[sizeof(olds) - 1] = 0;
 
+	// sku - avoid potentional buffer overflow vulnerability
+	length = strlen( s );
+	if( length &gt; sizeof( cl.configstrings ) - sizeof( cl.configstrings[0] ) * i - 1 ) {
+		Com_Error( ERR_DROP, &quot;CL_ParseConfigString: oversize configstring&quot; );
+	}
+
 	strcpy (cl.configstrings[i], s);
 
 	// do something apropriate 
Index: qcommon/cmd.c
===================================================================
RCS file: /cvs/cvsroot/quake2/src/qcommon/cmd.c,v
retrieving revision 1.2
diff -u -r1.2 cmd.c
--- qcommon/cmd.c	3 Jan 2002 05:10:14 -0000	1.2
+++ qcommon/cmd.c	29 Jan 2005 20:57:01 -0000
@@ -215,8 +215,11 @@
 			if (text[i] == '\n')
 				break;
 		}
-			
-				
+		
+		// sku - removed potentional buffer overflow vulnerability
+		if( i &gt; sizeof( line ) - 1 ) {
+			i = sizeof( line ) - 1;
+		}
 		memcpy (line, text, i);
 		line[i] = 0;
 		
@@ -657,7 +660,8 @@
 		{
 			int		l;
 
-			strcpy (cmd_args, text);
+			// sku - removed potentional buffer overflow vulnerability
+			strncpy( cmd_args, text, sizeof( cmd_args ) );
 
 			// strip off any trailing whitespace
 			l = strlen(cmd_args) - 1;
Index: qcommon/common.c
===================================================================
RCS file: /cvs/cvsroot/quake2/src/qcommon/common.c,v
retrieving revision 1.4
diff -u -r1.4 common.c
--- qcommon/common.c	30 Mar 2002 22:48:36 -0000	1.4
+++ qcommon/common.c	29 Jan 2005 20:57:02 -0000
@@ -797,7 +797,9 @@
 	l = 0;
 	do
 	{
-		c = MSG_ReadChar (msg_read);
+		// sku - replaced MSG_ReadChar with MSG_ReadByte to avoid
+		// potentional vulnerability
+		c = MSG_ReadByte (msg_read);
 		if (c == -1 || c == 0)
 			break;
 		string[l] = c;
@@ -817,7 +819,9 @@
 	l = 0;
 	do
 	{
-		c = MSG_ReadChar (msg_read);
+		// sku - replaced MSG_ReadChar with MSG_ReadByte to avoid
+		// potentional vulnerability
+		c = MSG_ReadByte (msg_read);
 		if (c == -1 || c == 0 || c == '\n')
 			break;
 		string[l] = c;
Index: server/sv_main.c
===================================================================
RCS file: /cvs/cvsroot/quake2/src/server/sv_main.c,v
retrieving revision 1.2
diff -u -r1.2 sv_main.c
--- server/sv_main.c	22 Mar 2002 00:24:37 -0000	1.2
+++ server/sv_main.c	29 Jan 2005 20:57:03 -0000
@@ -293,8 +293,9 @@
 
 	challenge = atoi(Cmd_Argv(3));
 
-	strncpy (userinfo, Cmd_Argv(4), sizeof(userinfo)-1);
-	userinfo[sizeof(userinfo) - 1] = 0;
+	// sku - reserve 32 bytes for the IP address
+	strncpy (userinfo, Cmd_Argv(4), sizeof(userinfo)-32);
+	userinfo[sizeof(userinfo) - 32] = 0;
 
 	// force the IP key/value pair so the game can filter based on ip
 	Info_SetValueForKey (userinfo, &quot;ip&quot;, NET_AdrToString(net_from));
@@ -317,8 +318,11 @@
 		{
 			if (NET_CompareBaseAdr (net_from, svs.challenges[i].adr))
 			{
-				if (challenge == svs.challenges[i].challenge)
+				// sku - ignore zero challenges
+				if( svs.challenges[i].challenge &amp;&amp; challenge == svs.challenges[i].challenge ) {
+					svs.challenges[i].challenge = 0;
 					break;		// good
+				}
 				Netchan_OutOfBandPrint (NS_SERVER, adr, &quot;print\nBad challenge.\n&quot;);
 				return;
 			}
@@ -342,6 +346,11 @@
 			&amp;&amp; ( cl-&gt;netchan.qport == qport 
 			|| adr.port == cl-&gt;netchan.remote_address.port ) )
 		{
+			// sku - avoid reusing slot of the client already connected
+			if( cl-&gt;state != cs_zombie ) {
+				Netchan_OutOfBandPrint( NS_SERVER, adr, &quot;print\nConnected client from this IP is already present.\n&quot; );
+				return;
+			}
 			if (!NET_IsLocalAddress (adr) &amp;&amp; (svs.realtime - cl-&gt;lastconnect) &lt; ((int)sv_reconnect_limit-&gt;value * 1000))
 			{
 				Com_DPrintf (&quot;%s:reconnect rejected : too soon\n&quot;, NET_AdrToString (adr));
Index: server/sv_user.c
===================================================================
RCS file: /cvs/cvsroot/quake2/src/server/sv_user.c,v
retrieving revision 1.2
diff -u -r1.2 sv_user.c
--- server/sv_user.c	21 Mar 2002 04:44:46 -0000	1.2
+++ server/sv_user.c	29 Jan 2005 20:57:04 -0000
@@ -142,6 +142,9 @@
 	}
 	
 	start = atoi(Cmd_Argv(2));
+	if( start &lt; 0 ) {
+		start = 0;	// sku - catch negative offsets
+	}
 
 	// write a packet full of data
 
@@ -150,9 +153,18 @@
 	{
 		if (sv.configstrings[start][0])
 		{
+			int length;
+
+			// sku - write configstrings that exceed MAX_QPATH in proper-sized chunks
+			length = strlen( sv.configstrings[start] );
+			if( length &gt; MAX_QPATH ) {
+				length = MAX_QPATH;
+			}
+
 			MSG_WriteByte (&amp;sv_client-&gt;netchan.message, svc_configstring);
 			MSG_WriteShort (&amp;sv_client-&gt;netchan.message, start);
-			MSG_WriteString (&amp;sv_client-&gt;netchan.message, sv.configstrings[start]);
+			SZ_Write (&amp;sv_client-&gt;netchan.message, sv.configstrings[start], length);
+			MSG_WriteByte (&amp;sv_client-&gt;netchan.message, 0);
 		}
 		start++;
 	}
@@ -199,6 +211,9 @@
 	}
 	
 	start = atoi(Cmd_Argv(2));
+	if( start &lt; 0 ) {
+		start = 0;
+	}
 
 	memset (&amp;nullstate, 0, sizeof(nullstate));
 
@@ -398,7 +413,7 @@
 */
 void SV_ShowServerinfo_f (void)
 {
-	Info_Print (Cvar_Serverinfo());
+//	Info_Print (Cvar_Serverinfo());
 }
 
 




--------------000308040205070900090108--

]