mirror of
https://github.com/ioquake/jedi-academy.git
synced 2025-02-13 07:31:46 +00:00
CVE-2006-3324 arbitary file overwrite
CVE-2006-3324 The Automatic Downloading option in the id3 Quake 3 Engine and the Icculus Quake 3 Engine (ioquake3) before revision 804 allows remote attackers to overwrite arbitrary files in the quake3 directory (fs_homepath cvar) via a long string of filenames, as contained in the neededpaks buffer. Luigi Auriemma q3cfilevar from Thilo Schulz in ioquake3 svn 804 git 813a6ecdc3b8572796a8a85b260b03e1c3d87ef4 - Fix bug that allows a malicious server to write and overwrite any files in the quake3 directory. Reported by Luigi Auriemma. - Moved directory traversal check to a more proper location. - Added a few sanity checks for checksum/pakname storage to fix a crash that can occur under certain circumstances.
This commit is contained in:
parent
8550620849
commit
ac9e5f1f79
1 changed files with 39 additions and 12 deletions
|
@ -2356,15 +2356,16 @@ we are not interested in a download string format, we want something human-reada
|
|||
qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
||||
searchpath_t *sp;
|
||||
qboolean havepak, badchecksum;
|
||||
char *origpos = neededpaks;
|
||||
int i;
|
||||
|
||||
if ( !fs_numServerReferencedPaks ) {
|
||||
if (!fs_numServerReferencedPaks)
|
||||
return qfalse; // Server didn't send any pack information along
|
||||
}
|
||||
|
||||
*neededpaks = 0;
|
||||
|
||||
for ( i = 0 ; i < fs_numServerReferencedPaks ; i++ ) {
|
||||
for ( i = 0 ; i < fs_numServerReferencedPaks ; i++ )
|
||||
{
|
||||
// Ok, see if we have this pak file
|
||||
badchecksum = qfalse;
|
||||
havepak = qfalse;
|
||||
|
@ -2374,6 +2375,13 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
|||
continue;
|
||||
}
|
||||
|
||||
// Make sure the server cannot make us write to non-quake3 directories.
|
||||
if(FS_CheckDirTraversal(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] ) {
|
||||
havepak = qtrue; // This is it!
|
||||
|
@ -2386,6 +2394,12 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
|||
|
||||
if (dlstring)
|
||||
{
|
||||
// We need this to make sure we won't hit the end of the buffer or the server could
|
||||
// overwrite non-pk3 files on clients by writing so much crap into neededpaks that
|
||||
// Q_strcat cuts off the .pk3 extension.
|
||||
|
||||
origpos += strlen(origpos);
|
||||
|
||||
// Remote name
|
||||
Q_strcat( neededpaks, len, "@");
|
||||
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
|
||||
|
@ -2404,6 +2418,14 @@ qboolean FS_ComparePaks( char *neededpaks, int len, qboolean dlstring ) {
|
|||
Q_strcat( neededpaks, len, fs_serverReferencedPakNames[i] );
|
||||
Q_strcat( neededpaks, len, ".pk3" );
|
||||
}
|
||||
|
||||
// Find out whether it might have overflowed the buffer and don't add this file to the
|
||||
// list if that is the case.
|
||||
if(strlen(origpos) + (origpos - neededpaks) >= len - 1)
|
||||
{
|
||||
*origpos = '\0';
|
||||
break;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -2962,7 +2984,7 @@ checksums to see if any pk3 files need to be auto-downloaded.
|
|||
=====================
|
||||
*/
|
||||
void FS_PureServerSetReferencedPaks( const char *pakSums, const char *pakNames ) {
|
||||
int i, c, d;
|
||||
int i, c, d = 0;
|
||||
|
||||
Cmd_TokenizeString( pakSums );
|
||||
|
||||
|
@ -2971,30 +2993,35 @@ void FS_PureServerSetReferencedPaks( const char *pakSums, const char *pakNames )
|
|||
c = MAX_SEARCH_PATHS;
|
||||
}
|
||||
|
||||
fs_numServerReferencedPaks = c;
|
||||
|
||||
for ( i = 0 ; i < c ; i++ ) {
|
||||
fs_serverReferencedPaks[i] = atoi( Cmd_Argv( i ) );
|
||||
}
|
||||
|
||||
for ( i = 0 ; i < c ; i++ ) {
|
||||
if (fs_serverReferencedPakNames[i]) {
|
||||
for (i = 0 ; i < ARRAY_LEN(fs_serverReferencedPakNames); i++)
|
||||
{
|
||||
if (fs_serverReferencedPakNames[i])
|
||||
Z_Free(fs_serverReferencedPakNames[i]);
|
||||
}
|
||||
fs_serverReferencedPakNames[i] = NULL;
|
||||
}
|
||||
|
||||
if ( pakNames && *pakNames ) {
|
||||
Cmd_TokenizeString( pakNames );
|
||||
|
||||
d = Cmd_Argc();
|
||||
if ( d > MAX_SEARCH_PATHS ) {
|
||||
d = MAX_SEARCH_PATHS;
|
||||
}
|
||||
|
||||
if(d > c)
|
||||
d = c;
|
||||
|
||||
for ( i = 0 ; i < d ; i++ ) {
|
||||
fs_serverReferencedPakNames[i] = CopyString( Cmd_Argv( i ) );
|
||||
}
|
||||
}
|
||||
|
||||
// ensure that there are as many checksums as there are pak names.
|
||||
if(d < c)
|
||||
c = d;
|
||||
|
||||
fs_numServerReferencedPaks = c;
|
||||
}
|
||||
|
||||
/*
|
||||
|
|
Loading…
Reference in a new issue