The following commit has been merged in the master branch:
commit 098df1ac41512b418ccee2492fa660370e41fd2e
Author: Simon McVittie <[email protected]>
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 <[email protected]>  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

_______________________________________________
Pkg-games-commits mailing list
[email protected]
http://lists.alioth.debian.org/cgi-bin/mailman/listinfo/pkg-games-commits

Reply via email to