engine: fix possible unprivileged config execute with fake extension

This commit is contained in:
Alibek Omarov 2024-06-12 10:44:28 +03:00
parent 4163d3655a
commit 240b6fb6f2

View file

@ -414,7 +414,6 @@ static void Host_Exec_f( void )
byte *f; byte *f;
char *txt; char *txt;
fs_offset_t len; fs_offset_t len;
const char *arg;
if( Cmd_Argc() != 2 ) if( Cmd_Argc() != 2 )
{ {
@ -422,7 +421,8 @@ static void Host_Exec_f( void )
return; return;
} }
arg = Cmd_Argv( 1 ); Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath ));
COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default
#ifndef XASH_DEDICATED #ifndef XASH_DEDICATED
if( !Cmd_CurrentCommandIsPrivileged() ) if( !Cmd_CurrentCommandIsPrivileged() )
@ -442,7 +442,7 @@ static void Host_Exec_f( void )
for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ ) for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ )
{ {
if( !Q_strcmp( arg, unprivilegedWhitelist[i] )) if( !Q_strcmp( cfgpath, unprivilegedWhitelist[i] ))
{ {
allow = true; allow = true;
break; break;
@ -451,21 +451,15 @@ static void Host_Exec_f( void )
if( !allow ) if( !allow )
{ {
Con_Printf( "exec %s: not privileged or in whitelist\n", arg ); Con_Printf( "exec %s: not privileged or in whitelist\n", cfgpath );
return; return;
} }
} }
#endif // XASH_DEDICATED #endif // XASH_DEDICATED
if( !Q_stricmp( "game.cfg", arg ))
{
// don't execute game.cfg in singleplayer // don't execute game.cfg in singleplayer
if( SV_GetMaxClients() == 1 ) if( SV_GetMaxClients() == 1 && !Q_stricmp( "game.cfg", cfgpath ))
return; return;
}
Q_strncpy( cfgpath, arg, sizeof( cfgpath ));
COM_DefaultExtension( cfgpath, ".cfg", sizeof( cfgpath )); // append as default
f = FS_LoadFile( cfgpath, &len, false ); f = FS_LoadFile( cfgpath, &len, false );
if( !f ) if( !f )
@ -474,17 +468,18 @@ static void Host_Exec_f( void )
return; return;
} }
if( !Q_stricmp( "config.cfg", arg )) if( !Q_stricmp( "config.cfg", cfgpath ))
host.config_executed = true; host.config_executed = true;
// adds \n\0 at end of the file // adds \n\0 at end of the file
txt = Z_Calloc( len + 2 ); txt = Z_Calloc( len + 2 );
memcpy( txt, f, len ); memcpy( txt, f, len );
Q_strncat( txt, "\n", len + 2 ); txt[len] = '\n';
txt[len + 1] = '\0';
Mem_Free( f ); Mem_Free( f );
if( !host.apply_game_config ) if( !host.apply_game_config )
Con_Printf( "execing %s\n", arg ); Con_Printf( "execing %s\n", Cmd_Argv( 1 ));
Cbuf_InsertText( txt ); Cbuf_InsertText( txt );
Mem_Free( txt ); Mem_Free( txt );
} }