Fix bug that allows a malicious server to write and overwrite any files in the main folder
diff --git a/src/engine/cm/cm_load_tech3.cpp b/src/engine/cm/cm_load_tech3.cpp
index d1fde1f..51e26b0 100644
--- a/src/engine/cm/cm_load_tech3.cpp
+++ b/src/engine/cm/cm_load_tech3.cpp
@@ -1217,7 +1217,7 @@ void idCollisionModelManagerLocal::LoadMap( pointer name, bool clientload, sint*
{
Com_Error( ERR_DROP, "idCollisionModelManagerLocal::LoadMap: %s has wrong version number (%i should be %i)", name, header.version, BSP_VERSION );
}
-
+
cmod_base = ( uchar8* ) buf;
// load into heap
diff --git a/src/engine/framework/FileSystem.cpp b/src/engine/framework/FileSystem.cpp
index 023a255..a046553 100644
--- a/src/engine/framework/FileSystem.cpp
+++ b/src/engine/framework/FileSystem.cpp
@@ -3786,6 +3786,7 @@ bool idFileSystemLocal::ComparePaks( valueType* neededpaks, sint len, bool dlstr
{
searchpath_t* sp;
bool havepak, badchecksum;
+ valueType* origpos = neededpaks;
sint i;
if( !fs_numServerReferencedPaks )
@@ -3807,6 +3808,13 @@ bool idFileSystemLocal::ComparePaks( valueType* neededpaks, sint len, bool dlstr
continue;
}
+ // Make sure the server cannot make us write to non-quake3 directories.
+ if( strstr( fs_serverReferencedPakNames[i], "../" ) || strstr( fs_serverReferencedPakNames[i], "..\\" ) )
+ {
+ Com_Printf( "WARNING: Invalid download name %s\n", fs_serverReferencedPakNames[i] );
+ continue;
+ }
+
for( sp = fs_searchpaths ; sp ; sp = sp->next )
{
if( sp->pack && sp->pack->checksum == fs_serverReferencedPaks[i] )
@@ -3822,6 +3830,8 @@ bool idFileSystemLocal::ComparePaks( valueType* neededpaks, sint len, bool dlstr
if( dlstring )
{
+ origpos += ::strlen( origpos );
+
// Remote name
Q_strcat( neededpaks, len, "@" );
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
@@ -3843,6 +3853,12 @@ bool idFileSystemLocal::ComparePaks( valueType* neededpaks, sint len, bool dlstr
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
Q_strcat( neededpaks, len, ".pk3" );
}
+
+ if( ::strlen( origpos ) + ( origpos - neededpaks ) >= len - 1 )
+ {
+ *origpos = '\0';
+ break;
+ }
}
else
{
@@ -4461,7 +4477,7 @@ checksums to see if any pk3 files need to be auto-downloaded.
*/
void idFileSystemLocal::PureServerSetReferencedPaks( pointer pakSums, pointer pakNames )
{
- sint i, c, d;
+ sint i, c, d = 0;
cmdSystem->TokenizeString( pakSums );
@@ -4471,14 +4487,7 @@ void idFileSystemLocal::PureServerSetReferencedPaks( pointer pakSums, pointer pa
c = MAX_SEARCH_PATHS;
}
- fs_numServerReferencedPaks = c;
-
- for( i = 0 ; i < c ; i++ )
- {
- fs_serverReferencedPaks[i] = atoi( cmdSystem->Argv( i ) );
- }
-
- for( i = 0 ; i < c ; i++ )
+ for( i = 0 ; i < sizeof( fs_serverReferencedPakNames ) / sizeof( *fs_serverReferencedPakNames ); i++ )
{
if( fs_serverReferencedPakNames[i] )
{
@@ -4498,12 +4507,23 @@ void idFileSystemLocal::PureServerSetReferencedPaks( pointer pakSums, pointer pa
{
d = MAX_SEARCH_PATHS;
}
+ else if( d > c )
+ {
+ d = c;
+ }
for( i = 0 ; i < d ; i++ )
{
fs_serverReferencedPakNames[i] = CopyString( cmdSystem->Argv( i ) );
}
}
+
+ if( d < c )
+ {
+ c = d;
+ }
+
+ fs_numServerReferencedPaks = c;
}
/*
GitHub
sha: ee5f4ff5