- Fix arbitrary cvar overwrite flaw: http://aluigi.altervista.org/adv.htm

- Add myself to maintainer list :)
This commit is contained in:
Thilo Schulz 2006-07-03 21:37:50 +00:00
parent d42b87ae87
commit 7d51d75b05
6 changed files with 61 additions and 3 deletions

1
README
View file

@ -244,6 +244,7 @@ Maintainers
Aaron Gyes <floam at sh dot nu> Aaron Gyes <floam at sh dot nu>
Ludwig Nussel <ludwig.nussel@suse.de> Ludwig Nussel <ludwig.nussel@suse.de>
Ryan C. Gordon <icculus@icculus.org> Ryan C. Gordon <icculus@icculus.org>
Thilo Schulz <arny@ats.s.bawue.de>
Tim Angus <tim@ngus.net> Tim Angus <tim@ngus.net>
Zachary J. Slater <zakk@timedoctor.org> Zachary J. Slater <zakk@timedoctor.org>

View file

@ -368,17 +368,36 @@ void CL_SystemInfoChanged( void ) {
// scan through all the variables in the systeminfo and locally set cvars to match // scan through all the variables in the systeminfo and locally set cvars to match
s = systemInfo; s = systemInfo;
while ( s ) { while ( s ) {
int cvar_flags;
Info_NextPair( &s, key, value ); Info_NextPair( &s, key, value );
if ( !key[0] ) { if ( !key[0] ) {
break; break;
} }
// ehw! // 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; gameSet = qtrue;
} }
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); Cvar_Set(key, value);
} }
}
// if game folder should not be set and it is set at the client side // if game folder should not be set and it is set at the client side
if ( !gameSet && *Cvar_VariableString("fs_game") ) { if ( !gameSet && *Cvar_VariableString("fs_game") ) {
Cvar_Set( "fs_game", "" ); Cvar_Set( "fs_game", "" );

View file

@ -161,6 +161,20 @@ void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize
} }
} }
/*
============
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;
}
/* /*
============ ============

View file

@ -2568,6 +2568,23 @@ qboolean FS_idPak( char *pak, char *base ) {
return qfalse; return qfalse;
} }
/*
================
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 FS_ComparePaks
@ -2617,7 +2634,7 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
} }
// Make sure the server cannot make us write to non-quake3 directories. // 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]); Com_Printf("WARNING: Invalid download name %s\n", fs_serverReferencedPakNames[i]);
continue; continue;

View file

@ -756,6 +756,9 @@ default values.
#define CVAR_CHEAT 512 // can not be changed if cheats are disabled #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_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! // nothing outside the Cvar_*() functions should modify these fields!
typedef struct cvar_s { typedef struct cvar_s {
char *name; char *name;

View file

@ -480,6 +480,9 @@ char *Cvar_VariableString( const char *var_name );
void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize ); void Cvar_VariableStringBuffer( const char *var_name, char *buffer, int bufsize );
// returns an empty string if not defined // 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) ); void Cvar_CommandCompletion( void(*callback)(const char *s) );
// callback with each valid string // callback with each valid string
@ -648,6 +651,7 @@ void FS_PureServerSetLoadedPaks( const char *pakSums, const char *pakNames );
// separated checksums will be checked for files, with the // separated checksums will be checked for files, with the
// sole exception of .cfg files. // sole exception of .cfg files.
qboolean FS_CheckDirTraversal(const char *checkdir);
qboolean FS_idPak( char *pak, char *base ); qboolean FS_idPak( char *pak, char *base );
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ); qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring );