From b93938956e872495d73cb049de87fd3192c1e0a4 Mon Sep 17 00:00:00 2001 From: Alibek Omarov Date: Wed, 3 Nov 2021 20:28:42 +0600 Subject: [PATCH] engine: allow exec command with config filenames whitelist --- engine/common/common.h | 1 + engine/common/host.c | 46 ++++++++++++++++++++++++++++++++++++------ 2 files changed, 41 insertions(+), 6 deletions(-) diff --git a/engine/common/common.h b/engine/common/common.h index e653e570..6f5def15 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -480,6 +480,7 @@ void Cbuf_AddFilteredText( const char *text ); void Cbuf_InsertText( const char *text ); void Cbuf_ExecStuffCmds( void ); void Cbuf_Execute (void); +qboolean Cmd_CurrentCommandIsPrivileged( void ); int Cmd_Argc( void ); const char *Cmd_Args( void ); const char *Cmd_Argv( int arg ); diff --git a/engine/common/host.c b/engine/common/host.c index 6b285f5c..c0a63d68 100644 --- a/engine/common/host.c +++ b/engine/common/host.c @@ -354,10 +354,11 @@ Host_Exec_f */ void Host_Exec_f( void ) { - string cfgpath; + string cfgpath; byte *f; char *txt; fs_offset_t len; + char *arg; if( Cmd_Argc() != 2 ) { @@ -365,14 +366,47 @@ void Host_Exec_f( void ) return; } - if( !Q_stricmp( "game.cfg", Cmd_Argv( 1 ))) + arg = Cmd_Argv( 1 ); + +#ifndef XASH_DEDICATED + if( !Cmd_CurrentCommandIsPrivileged() ) + { + const char *unprivilegedWhitelist[] = + { + NULL, "mapdefault.cfg", "scout.cfg", "sniper.cfg", + "soldier.cfg", "demoman.cfg", "medic.cfg", "hwguy.cfg", + "pyro.cfg", "spy.cfg", "engineer.cfg", "civilian.cfg" + }; + int i; + qboolean allow = false; + + unprivilegedWhitelist[0] = va( "%s.cfg", clgame.mapname ); + + for( i = 0; i < ARRAYSIZE( unprivilegedWhitelist ); i++ ) + { + if( !Q_strcmp( arg, unprivilegedWhitelist[i] )) + { + allow = true; + break; + } + } + + if( !allow ) + { + Con_Printf( "exec %s: not privileged or in whitelist\n", arg ); + return; + } + } +#endif // XASH_DEDICATED + + if( !Q_stricmp( "game.cfg", arg )) { // don't execute game.cfg in singleplayer if( SV_GetMaxClients() == 1 ) return; } - Q_strncpy( cfgpath, Cmd_Argv( 1 ), sizeof( cfgpath )); + Q_strncpy( cfgpath, arg, sizeof( cfgpath )); COM_DefaultExtension( cfgpath, ".cfg" ); // append as default f = FS_LoadFile( cfgpath, &len, false ); @@ -382,7 +416,7 @@ void Host_Exec_f( void ) return; } - if( !Q_stricmp( "config.cfg", Cmd_Argv( 1 ))) + if( !Q_stricmp( "config.cfg", arg )) host.config_executed = true; // adds \n\0 at end of the file @@ -392,7 +426,7 @@ void Host_Exec_f( void ) Mem_Free( f ); if( !host.apply_game_config ) - Con_Printf( "execing %s\n", Cmd_Argv( 1 )); + Con_Printf( "execing %s\n", arg ); Cbuf_InsertText( txt ); Mem_Free( txt ); } @@ -989,7 +1023,7 @@ void Host_InitCommon( int argc, char **argv, const char *progname, qboolean bCha Sys_InitLog(); - Cmd_AddRestrictedCommand( "exec", Host_Exec_f, "execute a script file" ); + Cmd_AddCommand( "exec", Host_Exec_f, "execute a script file" ); Cmd_AddCommand( "memlist", Host_MemStats_f, "prints memory pool information" ); Cmd_AddRestrictedCommand( "userconfigd", Host_Userconfigd_f, "execute all scripts from userconfig.d" );