r811 - in trunk: . code/client code/qcommon
DONOTREPLY at icculus.org
DONOTREPLY at icculus.org
Mon Jul 3 17:37:51 EDT 2006
Author: thilo
Date: 2006-07-03 17:37:50 -0400 (Mon, 03 Jul 2006)
New Revision: 811
Modified:
trunk/README
trunk/code/client/cl_parse.c
trunk/code/qcommon/cvar.c
trunk/code/qcommon/files.c
trunk/code/qcommon/q_shared.h
trunk/code/qcommon/qcommon.h
Log:
- Fix arbitrary cvar overwrite flaw: http://aluigi.altervista.org/adv.htm
- Add myself to maintainer list :)
Modified: trunk/README
===================================================================
--- trunk/README 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/README 2006-07-03 21:37:50 UTC (rev 811)
@@ -244,6 +244,7 @@
Aaron Gyes <floam at sh dot nu>
Ludwig Nussel <ludwig.nussel at suse.de>
Ryan C. Gordon <icculus at icculus.org>
+ Thilo Schulz <arny at ats.s.bawue.de>
Tim Angus <tim at ngus.net>
Zachary J. Slater <zakk at timedoctor.org>
Modified: trunk/code/client/cl_parse.c
===================================================================
--- trunk/code/client/cl_parse.c 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/code/client/cl_parse.c 2006-07-03 21:37:50 UTC (rev 811)
@@ -368,16 +368,35 @@
// scan through all the variables in the systeminfo and locally set cvars to match
s = systemInfo;
while ( s ) {
+ int cvar_flags;
+
Info_NextPair( &s, key, value );
if ( !key[0] ) {
break;
}
+
// ehw!
- if ( !Q_stricmp( key, "fs_game" ) ) {
+ if (!Q_stricmp(key, "fs_game"))
+ {
+ if(FS_CheckDirTraversal(value))
+ {
+ Com_Printf("WARNING: Server sent invalid fs_game value %s\n", value);
+ continue;
+ }
+
gameSet = qtrue;
}
- Cvar_Set( key, value );
+ if((cvar_flags = Cvar_Flags(key)) == CVAR_NONEXISTENT)
+ Cvar_Get(key, value, CVAR_SERVER_CREATED | CVAR_ROM);
+ else
+ {
+ // If this cvar may not be modified by a server discard the value.
+ if(!(cvar_flags & (CVAR_SYSTEMINFO | CVAR_SERVER_CREATED)))
+ continue;
+
+ Cvar_Set(key, value);
+ }
}
// if game folder should not be set and it is set at the client side
if ( !gameSet && *Cvar_VariableString("fs_game") ) {
Modified: trunk/code/qcommon/cvar.c
===================================================================
--- trunk/code/qcommon/cvar.c 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/code/qcommon/cvar.c 2006-07-03 21:37:50 UTC (rev 811)
@@ -161,6 +161,20 @@
}
}
+/*
+============
+Cvar_Flags
+============
+*/
+int Cvar_Flags(const char *var_name)
+{
+ cvar_t *var;
+
+ if(! (var = Cvar_FindVar(var_name)) )
+ return CVAR_NONEXISTENT;
+ else
+ return var->flags;
+}
/*
============
Modified: trunk/code/qcommon/files.c
===================================================================
--- trunk/code/qcommon/files.c 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/code/qcommon/files.c 2006-07-03 21:37:50 UTC (rev 811)
@@ -2570,6 +2570,23 @@
/*
================
+FS_idPak
+
+Check whether the string contains stuff like "../" to prevent directory traversal bugs
+and return qtrue if it does.
+================
+*/
+
+qboolean FS_CheckDirTraversal(const char *checkdir)
+{
+ if(strstr(checkdir, "../") || strstr(checkdir, "..\\"))
+ return qtrue;
+
+ return qfalse;
+}
+
+/*
+================
FS_ComparePaks
----------------
@@ -2617,7 +2634,7 @@
}
// Make sure the server cannot make us write to non-quake3 directories.
- if(strstr(fs_serverReferencedPakNames[i], "../") || strstr(fs_serverReferencedPakNames[i], "..\\"))
+ if(FS_CheckDirTraversal(fs_serverReferencedPakNames[i]))
{
Com_Printf("WARNING: Invalid download name %s\n", fs_serverReferencedPakNames[i]);
continue;
Modified: trunk/code/qcommon/q_shared.h
===================================================================
--- trunk/code/qcommon/q_shared.h 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/code/qcommon/q_shared.h 2006-07-03 21:37:50 UTC (rev 811)
@@ -756,6 +756,9 @@
#define CVAR_CHEAT 512 // can not be changed if cheats are disabled
#define CVAR_NORESTART 1024 // do not clear when a cvar_restart is issued
+#define CVAR_SERVER_CREATED 2048 // cvar was created by a server the client connected to.
+#define CVAR_NONEXISTENT 0xFFFFFFFF // Cvar doesn't exist.
+
// nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s {
char *name;
Modified: trunk/code/qcommon/qcommon.h
===================================================================
--- trunk/code/qcommon/qcommon.h 2006-06-17 21:01:57 UTC (rev 810)
+++ trunk/code/qcommon/qcommon.h 2006-07-03 21:37:50 UTC (rev 811)
@@ -480,6 +480,9 @@
void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
// returns an empty string if not defined
+int Cvar_Flags(const char *var_name);
+// returns CVAR_NONEXISTENT if cvar doesn't exist or the flags of that particular CVAR.
+
void Cvar_CommandCompletion( void(*callback)(const char *s) );
// callback with each valid string
@@ -648,6 +651,7 @@
// separated checksums will be checked for files, with the
// sole exception of .cfg files.
+qboolean FS_CheckDirTraversal(const char *checkdir);
qboolean FS_idPak( char *pak, char *base );
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );
More information about the quake3-commits
mailing list