[SCM] Quake 3 engine branch, master, updated. debian/1.36+svn1946-3-3-gb3edd54

Simon McVittie smcv at debian.org
Thu Jul 28 13:34:49 UTC 2011


The following commit has been merged in the master branch:
commit 098df1ac41512b418ccee2492fa660370e41fd2e
Author: Simon McVittie <smcv at debian.org>
Date:   Mon Jul 25 22:23:37 2011 +0100

    Security fixes
    
    * Apply upstream r2097 to fix arbitrary code execution by a malicious
      server. CVE-2011-1412
    * Apply upstream r2098 to fix arbitrary code execution by malicious QVM
      bytecode (mitigation: only if native code is enabled), which could be
      auto-downloaded from a malicious server if enabled. CVE-2011-2764

diff --git a/debian/changelog b/debian/changelog
index 531b417..e96f77a 100644
--- a/debian/changelog
+++ b/debian/changelog
@@ -1,3 +1,15 @@
+ioquake3 (1.36+svn1946-4) UNRELEASED; urgency=low
+
+  * Apply upstream r2092 to fix failover between xmessage, zenity and kdialog
+    if the preferred implementation is missing, so that r2097 can be applied
+  * Apply upstream r2097 to fix arbitrary code execution by a malicious
+    server. CVE-2011-1412
+  * Apply upstream r2098 to fix arbitrary code execution by malicious QVM
+    bytecode (mitigation: only if native code is enabled), which could be
+    auto-downloaded from a malicious server if enabled. CVE-2011-2764
+
+ -- Simon McVittie <smcv at debian.org>  Mon, 25 Jul 2011 21:51:49 +0100
+
 ioquake3 (1.36+svn1946-3) unstable; urgency=low
 
   * (ioquake3 1.36+svn1946-2 was never in Debian, due to problems with the
diff --git a/debian/patches/0001-Fix-extension-name-comparison-for-DLL-files.patch b/debian/patches/0001-Fix-extension-name-comparison-for-DLL-files.patch
new file mode 100644
index 0000000..21b2b25
--- /dev/null
+++ b/debian/patches/0001-Fix-extension-name-comparison-for-DLL-files.patch
@@ -0,0 +1,77 @@
+From: Thilo Schulz <thilo>
+Date: Sun, 24 Jul 2011 22:12:21 +0000
+Subject: Fix extension name comparison for DLL files
+
+[This might make it possible for gamecode to write out a malicious DLL file
+which would be executed if vm_game = 0. Present in r1499, so v1.36 was
+already vulnerable. This is a backport to r1946 -smcv]
+
+Origin: upstream, commit:2098
+Applied-upstream: 1.37
+Bug-CVE: CVE-2011-2764
+---
+ code/qcommon/files.c    |    2 +-
+ code/qcommon/q_shared.c |   24 ++++++++++++++++++++++++
+ code/qcommon/q_shared.h |    1 +
+ 3 files changed, 26 insertions(+), 1 deletions(-)
+
+diff --git a/code/qcommon/files.c b/code/qcommon/files.c
+index f6d8e3d..db6d86e 100644
+--- a/code/qcommon/files.c
++++ b/code/qcommon/files.c
+@@ -538,7 +538,7 @@ static void FS_CheckFilenameIsNotExecutable( const char *filename,
+ 		const char *function )
+ {
+ 	// Check if the filename ends with the library extension
+-	if( !Q_stricmp( COM_GetExtension( filename ), DLL_EXT ) )
++	if(COM_CompareExtension(filename, DLL_EXT))
+ 	{
+ 		Com_Error( ERR_FATAL, "%s: Not allowed to manipulate '%s' due "
+ 			"to %s extension\n", function, filename, DLL_EXT );
+diff --git a/code/qcommon/q_shared.c b/code/qcommon/q_shared.c
+index 3626133..8f206e1 100644
+--- a/code/qcommon/q_shared.c
++++ b/code/qcommon/q_shared.c
+@@ -96,6 +96,30 @@ void COM_StripExtension( const char *in, char *out, int destsize ) {
+ 		out[length] = 0;
+ }
+ 
++/*
++============
++COM_CompareExtension
++
++string compare the end of the strings and return qtrue if strings match
++============
++*/
++qboolean COM_CompareExtension(const char *in, const char *ext)
++{
++	int inlen, extlen;
++	
++	inlen = strlen(in);
++	extlen = strlen(ext);
++	
++	if(extlen <= inlen)
++	{
++		in += inlen - extlen;
++		
++		if(!Q_stricmp(in, ext))
++			return qtrue;
++	}
++	
++	return qfalse;
++}
+ 
+ /*
+ ==================
+diff --git a/code/qcommon/q_shared.h b/code/qcommon/q_shared.h
+index 190791e..5db3144 100644
+--- a/code/qcommon/q_shared.h
++++ b/code/qcommon/q_shared.h
+@@ -639,6 +639,7 @@ float Com_Clamp( float min, float max, float value );
+ char	*COM_SkipPath( char *pathname );
+ const char	*COM_GetExtension( const char *name );
+ void	COM_StripExtension(const char *in, char *out, int destsize);
++qboolean COM_CompareExtension(const char *in, const char *ext);
+ void	COM_DefaultExtension( char *path, int maxSize, const char *extension );
+ 
+ void	COM_BeginParseSession( const char *name );
diff --git a/debian/patches/0001-Fix-various-issues-with-unix-Sys_Dialog.patch b/debian/patches/0001-Fix-various-issues-with-unix-Sys_Dialog.patch
new file mode 100644
index 0000000..b07378a
--- /dev/null
+++ b/debian/patches/0001-Fix-various-issues-with-unix-Sys_Dialog.patch
@@ -0,0 +1,138 @@
+From: Tim Angus <tma>
+Date: Mon, 18 Jul 2011 19:32:25 +0000
+Subject: Fix various issues with unix Sys_Dialog
+
+[This fixes failover between zenity, kdialog and xmessage if the first one
+tried does not actually exist. This is a backport onto r1946; security
+fix r2097 relies on this restructuring having been done and I'd rather not
+reimplement all this. -smcv]
+
+Origin: upstream, commit:2092
+Applied-upstream: 1.37
+---
+ code/sys/sys_unix.c |   43 ++++++++++++++++++++++---------------------
+ 1 files changed, 22 insertions(+), 21 deletions(-)
+
+diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c
+index a6b1931..b5ba5df 100644
+--- a/code/sys/sys_unix.c
++++ b/code/sys/sys_unix.c
+@@ -579,10 +579,10 @@ void Sys_ErrorDialog( const char *error )
+ Sys_ZenityCommand
+ ==============
+ */
+-static int Sys_ZenityCommand( dialogType_t type, const char *message, const char *title )	
++static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title,
++		char *command, size_t commandSize )
+ {
+ 	const char *options = "";
+-	char       command[ 1024 ];
+ 
+ 	switch( type )
+ 	{
+@@ -594,10 +594,8 @@ static int Sys_ZenityCommand( dialogType_t type, const char *message, const char
+ 		case DT_OK_CANCEL: options = "--question --ok-label=\"OK\" --cancel-label=\"Cancel\""; break;
+ 	}
+ 
+-	Com_sprintf( command, sizeof( command ), "zenity %s --text=\"%s\" --title=\"%s\"",
++	Com_sprintf( command, commandSize, "zenity %s --text=\"%s\" --title=\"%s\" >/dev/null 2>/dev/null",
+ 		options, message, title );
+-
+-	return system( command );
+ }
+ 
+ /*
+@@ -605,10 +603,10 @@ static int Sys_ZenityCommand( dialogType_t type, const char *message, const char
+ Sys_KdialogCommand
+ ==============
+ */
+-static int Sys_KdialogCommand( dialogType_t type, const char *message, const char *title )
++static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title,
++		char *command, size_t commandSize )
+ {
+ 	const char *options = "";
+-	char       command[ 1024 ];
+ 
+ 	switch( type )
+ 	{
+@@ -620,10 +618,8 @@ static int Sys_KdialogCommand( dialogType_t type, const char *message, const cha
+ 		case DT_OK_CANCEL: options = "--warningcontinuecancel"; break;
+ 	}
+ 
+-	Com_sprintf( command, sizeof( command ), "kdialog %s \"%s\" --title \"%s\"",
++	Com_sprintf( command, commandSize, "kdialog %s \"%s\" --title \"%s\" >/dev/null 2>/dev/null",
+ 		options, message, title );
+-
+-	return system( command );
+ }
+ 
+ /*
+@@ -631,10 +627,10 @@ static int Sys_KdialogCommand( dialogType_t type, const char *message, const cha
+ Sys_XmessageCommand
+ ==============
+ */
+-static int Sys_XmessageCommand( dialogType_t type, const char *message, const char *title )
++static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title,
++		char *command, size_t commandSize )
+ {
+ 	const char *options = "";
+-	char       command[ 1024 ];
+ 
+ 	switch( type )
+ 	{
+@@ -643,10 +639,8 @@ static int Sys_XmessageCommand( dialogType_t type, const char *message, const ch
+ 		case DT_OK_CANCEL: options = "-buttons OK:0,Cancel:1"; break;
+ 	}
+ 
+-	Com_sprintf( command, sizeof( command ), "xmessage -center %s \"%s\"",
++	Com_sprintf( command, commandSize, "xmessage -center %s \"%s\" >/dev/null 2>/dev/null",
+ 		options, message );
+-
+-	return system( command );
+ }
+ 
+ /*
+@@ -666,7 +660,7 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
+ 		XMESSAGE,
+ 		NUM_DIALOG_PROGRAMS
+ 	} dialogCommandType_t;
+-	typedef int (*dialogCommandBuilder_t)( dialogType_t, const char *, const char * );
++	typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char *, char *, size_t );
+ 
+ 	const char              *session = getenv( "DESKTOP_SESSION" );
+ 	qboolean                tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
+@@ -686,7 +680,6 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
+ 	while( 1 )
+ 	{
+ 		int i;
+-		int exitCode;
+ 
+ 		for( i = NONE + 1; i < NUM_DIALOG_PROGRAMS; i++ )
+ 		{
+@@ -695,14 +688,22 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
+ 
+ 			if( !tried[ i ] )
+ 			{
+-				exitCode = commands[ i ]( type, message, title );
++				int exitCode;
++				int childSignal;
++				int childCode;
++				char command[ 1024 ];
++
++				commands[ i ]( type, message, title, command, sizeof( command ) );
++				exitCode = system( command );
++				childSignal = exitCode & 127;
++				childCode = exitCode >> 8;
+ 
+-				if( exitCode >= 0 )
++				if( exitCode != -1 && childSignal == 0 && childCode != 126 && childCode != 127 )
+ 				{
+ 					switch( type )
+ 					{
+-						case DT_YES_NO:    return exitCode ? DR_NO : DR_YES;
+-						case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
++						case DT_YES_NO:    return childCode ? DR_NO : DR_YES;
++						case DT_OK_CANCEL: return childCode ? DR_CANCEL : DR_OK;
+ 						default:           return DR_OK;
+ 					}
+ 				}
diff --git a/debian/patches/0001-Replace-usage-of-system-with-fork-exec.patch b/debian/patches/0001-Replace-usage-of-system-with-fork-exec.patch
new file mode 100644
index 0000000..a8cfea6
--- /dev/null
+++ b/debian/patches/0001-Replace-usage-of-system-with-fork-exec.patch
@@ -0,0 +1,243 @@
+From: Tim Angus <tma>
+Date: Sun, 24 Jul 2011 22:01:50 +0000
+Subject: Replace usage of system with fork/exec
+
+[This prevents arbitrary shell code execution by a malicious server operator.
+Bug present from r1773 onwards, 1.36 is not vulnerable. -smcv]
+
+Origin: upstream, commit:2097
+Applied-upstream: 1.37
+Bug-CVE: CVE-2011-1412
+---
+ code/sys/sys_unix.c |  153 ++++++++++++++++++++++++++++++++++++++-------------
+ 1 files changed, 114 insertions(+), 39 deletions(-)
+
+diff --git a/code/sys/sys_unix.c b/code/sys/sys_unix.c
+index b5ba5df..52a3118 100644
+--- a/code/sys/sys_unix.c
++++ b/code/sys/sys_unix.c
+@@ -36,6 +36,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
+ #include <pwd.h>
+ #include <libgen.h>
+ #include <fcntl.h>
++#include <sys/wait.h>
+ 
+ qboolean stdinIsATTY;
+ 
+@@ -574,28 +575,106 @@ void Sys_ErrorDialog( const char *error )
+ }
+ 
+ #ifndef MACOS_X
++static char execBuffer[ 1024 ];
++static char *execBufferPointer;
++static char *execArgv[ 16 ];
++static int execArgc;
++
++/*
++==============
++Sys_ClearExecBuffer
++==============
++*/
++static void Sys_ClearExecBuffer( void )
++{
++	execBufferPointer = execBuffer;
++	Com_Memset( execArgv, 0, sizeof( execArgv ) );
++	execArgc = 0;
++}
++
++/*
++==============
++Sys_AppendToExecBuffer
++==============
++*/
++static void Sys_AppendToExecBuffer( const char *text )
++{
++	size_t size = sizeof( execBuffer ) - ( execBufferPointer - execBuffer );
++	int length = strlen( text ) + 1;
++
++	if( length > size || execArgc >= ARRAY_LEN( execArgv ) )
++		return;
++
++	Q_strncpyz( execBufferPointer, text, size );
++	execArgv[ execArgc++ ] = execBufferPointer;
++
++	execBufferPointer += length;
++}
++
++/*
++==============
++Sys_Exec
++==============
++*/
++static int Sys_Exec( void )
++{
++	pid_t pid = fork( );
++
++	if( pid < 0 )
++		return -1;
++
++	if( pid )
++	{
++		// Parent
++		int exitCode;
++
++		wait( &exitCode );
++
++		return WEXITSTATUS( exitCode );
++	}
++	else
++	{
++		// Child
++		execvp( execArgv[ 0 ], execArgv );
++
++		// Failed to execute
++		exit( -1 );
++
++		return -1;
++	}
++}
++
+ /*
+ ==============
+ Sys_ZenityCommand
+ ==============
+ */
+-static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title,
+-		char *command, size_t commandSize )
++static void Sys_ZenityCommand( dialogType_t type, const char *message, const char *title )
+ {
+-	const char *options = "";
++	Sys_ClearExecBuffer( );
++	Sys_AppendToExecBuffer( "zenity" );
+ 
+ 	switch( type )
+ 	{
+ 		default:
+-		case DT_INFO:      options = "--info"; break;
+-		case DT_WARNING:   options = "--warning"; break;
+-		case DT_ERROR:     options = "--error"; break;
+-		case DT_YES_NO:    options = "--question --ok-label=\"Yes\" --cancel-label=\"No\""; break;
+-		case DT_OK_CANCEL: options = "--question --ok-label=\"OK\" --cancel-label=\"Cancel\""; break;
++		case DT_INFO:      Sys_AppendToExecBuffer( "--info" ); break;
++		case DT_WARNING:   Sys_AppendToExecBuffer( "--warning" ); break;
++		case DT_ERROR:     Sys_AppendToExecBuffer( "--error" ); break;
++		case DT_YES_NO:
++			Sys_AppendToExecBuffer( "--question" );
++			Sys_AppendToExecBuffer( "--ok-label=Yes" );
++			Sys_AppendToExecBuffer( "--cancel-label=No" );
++			break;
++
++		case DT_OK_CANCEL:
++			Sys_AppendToExecBuffer( "--question" );
++			Sys_AppendToExecBuffer( "--ok-label=OK" );
++			Sys_AppendToExecBuffer( "--cancel-label=Cancel" );
++			break;
+ 	}
+ 
+-	Com_sprintf( command, commandSize, "zenity %s --text=\"%s\" --title=\"%s\" >/dev/null 2>/dev/null",
+-		options, message, title );
++	Sys_AppendToExecBuffer( va( "--text=%s", message ) );
++	Sys_AppendToExecBuffer( va( "--title=%s", title ) );
+ }
+ 
+ /*
+@@ -603,23 +682,23 @@ static void Sys_ZenityCommand( dialogType_t type, const char *message, const cha
+ Sys_KdialogCommand
+ ==============
+ */
+-static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title,
+-		char *command, size_t commandSize )
++static void Sys_KdialogCommand( dialogType_t type, const char *message, const char *title )
+ {
+-	const char *options = "";
++	Sys_ClearExecBuffer( );
++	Sys_AppendToExecBuffer( "kdialog" );
+ 
+ 	switch( type )
+ 	{
+ 		default:
+-		case DT_INFO:      options = "--msgbox"; break;
+-		case DT_WARNING:   options = "--sorry"; break;
+-		case DT_ERROR:     options = "--error"; break;
+-		case DT_YES_NO:    options = "--warningyesno"; break;
+-		case DT_OK_CANCEL: options = "--warningcontinuecancel"; break;
++		case DT_INFO:      Sys_AppendToExecBuffer( "--msgbox" ); break;
++		case DT_WARNING:   Sys_AppendToExecBuffer( "--sorry" ); break;
++		case DT_ERROR:     Sys_AppendToExecBuffer( "--error" ); break;
++		case DT_YES_NO:    Sys_AppendToExecBuffer( "--warningyesno" ); break;
++		case DT_OK_CANCEL: Sys_AppendToExecBuffer( "--warningcontinuecancel" ); break;
+ 	}
+ 
+-	Com_sprintf( command, commandSize, "kdialog %s \"%s\" --title \"%s\" >/dev/null 2>/dev/null",
+-		options, message, title );
++	Sys_AppendToExecBuffer( message );
++	Sys_AppendToExecBuffer( va( "--title=%s", title ) );
+ }
+ 
+ /*
+@@ -627,20 +706,21 @@ static void Sys_KdialogCommand( dialogType_t type, const char *message, const ch
+ Sys_XmessageCommand
+ ==============
+ */
+-static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title,
+-		char *command, size_t commandSize )
++static void Sys_XmessageCommand( dialogType_t type, const char *message, const char *title )
+ {
+-	const char *options = "";
++	Sys_ClearExecBuffer( );
++	Sys_AppendToExecBuffer( "xmessage" );
++	Sys_AppendToExecBuffer( "-buttons" );
+ 
+ 	switch( type )
+ 	{
+-		default:           options = "-buttons OK"; break;
+-		case DT_YES_NO:    options = "-buttons Yes:0,No:1"; break;
+-		case DT_OK_CANCEL: options = "-buttons OK:0,Cancel:1"; break;
++		default:           Sys_AppendToExecBuffer( "OK:0" ); break;
++		case DT_YES_NO:    Sys_AppendToExecBuffer( "Yes:0,No:1" ); break;
++		case DT_OK_CANCEL: Sys_AppendToExecBuffer( "OK:0,Cancel:1" ); break;
+ 	}
+ 
+-	Com_sprintf( command, commandSize, "xmessage -center %s \"%s\" >/dev/null 2>/dev/null",
+-		options, message );
++	Sys_AppendToExecBuffer( "-center" );
++	Sys_AppendToExecBuffer( message );
+ }
+ 
+ /*
+@@ -660,7 +740,7 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
+ 		XMESSAGE,
+ 		NUM_DIALOG_PROGRAMS
+ 	} dialogCommandType_t;
+-	typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char *, char *, size_t );
++	typedef void (*dialogCommandBuilder_t)( dialogType_t, const char *, const char * );
+ 
+ 	const char              *session = getenv( "DESKTOP_SESSION" );
+ 	qboolean                tried[ NUM_DIALOG_PROGRAMS ] = { qfalse };
+@@ -689,21 +769,16 @@ dialogResult_t Sys_Dialog( dialogType_t type, const char *message, const char *t
+ 			if( !tried[ i ] )
+ 			{
+ 				int exitCode;
+-				int childSignal;
+-				int childCode;
+-				char command[ 1024 ];
+ 
+-				commands[ i ]( type, message, title, command, sizeof( command ) );
+-				exitCode = system( command );
+-				childSignal = exitCode & 127;
+-				childCode = exitCode >> 8;
++				commands[ i ]( type, message, title );
++				exitCode = Sys_Exec( );
+ 
+-				if( exitCode != -1 && childSignal == 0 && childCode != 126 && childCode != 127 )
++				if( exitCode >= 0 )
+ 				{
+ 					switch( type )
+ 					{
+-						case DT_YES_NO:    return childCode ? DR_NO : DR_YES;
+-						case DT_OK_CANCEL: return childCode ? DR_CANCEL : DR_OK;
++						case DT_YES_NO:    return exitCode ? DR_NO : DR_YES;
++						case DT_OK_CANCEL: return exitCode ? DR_CANCEL : DR_OK;
+ 						default:           return DR_OK;
+ 					}
+ 				}
diff --git a/debian/patches/series b/debian/patches/series
index f16a3a2..0032886 100644
--- a/debian/patches/series
+++ b/debian/patches/series
@@ -1,3 +1,6 @@
+0001-Fix-extension-name-comparison-for-DLL-files.patch
+0001-Fix-various-issues-with-unix-Sys_Dialog.patch
+0001-Replace-usage-of-system-with-fork-exec.patch
 0002-Add-a-special-vmMagic-that-causes-equivalent-native-.patch
 0003-Double-the-maximum-number-of-cvars.patch
 0004-Increase-the-command-buffer-from-16K-to-128K-followi.patch

-- 
Quake 3 engine



More information about the Pkg-games-commits mailing list