From 6d37a670273d716e5c4db35083d09e4bf647c513 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sun, 7 Jan 2018 15:02:22 +0200 Subject: [PATCH] Added unsafe execution context for console commands Some console commands are insecure because they access user's file system Such commands cannot be executed from MENUDEF and KEYCONF aliases --- src/c_dispatch.cpp | 68 ++++++++++++++++++---------------------------- src/c_dispatch.h | 27 ++++++++++++++++++ 2 files changed, 54 insertions(+), 41 deletions(-) diff --git a/src/c_dispatch.cpp b/src/c_dispatch.cpp index 75779cc939..b8e221e389 100644 --- a/src/c_dispatch.cpp +++ b/src/c_dispatch.cpp @@ -126,7 +126,8 @@ FButtonStatus Button_Mlook, Button_Klook, Button_Use, Button_AltAttack, Button_AM_PanLeft, Button_AM_PanRight, Button_AM_PanDown, Button_AM_PanUp, Button_AM_ZoomIn, Button_AM_ZoomOut; -bool ParsingKeyConf, ParsingMenuDef = false; +bool ParsingKeyConf; +static bool UnsafeExecutionContext; // To add new actions, go to the console and type "key ". // This will give you the key value to use in the first column. Then @@ -187,24 +188,6 @@ static const char *KeyConfCommands[] = "clearplayerclasses" }; -static const char *MenuDefCommands[] = -{ - "snd_reset", - "reset2defaults", - "reset2saved", - "menuconsole", - "clearnodecache", - "am_restorecolors", - "undocolorpic", - "special", - "puke", - "fpuke", - "pukename", - "event", - "netevent", - "openmenu" -}; - // CODE -------------------------------------------------------------------- IMPLEMENT_CLASS(DWaitingCommand, false, false) @@ -602,25 +585,6 @@ void C_DoCommand (const char *cmd, int keynum) } } - if (ParsingMenuDef) - { - int i; - - for (i = countof(MenuDefCommands)-1; i >= 0; --i) - { - if (strnicmp (beg, MenuDefCommands[i], len) == 0 && - MenuDefCommands[i][len] == 0) - { - break; - } - } - if (i < 0) - { - Printf ("Invalid command for MENUDEF/ZScript: %s\n", beg); - return; - } - } - // Check if this is an action if (*beg == '+' || *beg == '-') { @@ -707,9 +671,9 @@ DEFINE_ACTION_FUNCTION(DOptionMenuItemCommand, DoCommand) if (CurrentMenu == nullptr) return 0; PARAM_PROLOGUE; PARAM_STRING(cmd); - ParsingMenuDef = true; + UnsafeExecutionContext = true; C_DoCommand(cmd); - ParsingMenuDef = false; + UnsafeExecutionContext = false; return 0; } @@ -1061,6 +1025,17 @@ void FConsoleCommand::Run (FCommandLine &argv, APlayerPawn *who, int key) m_RunFunc (argv, who, key); } +void FUnsafeConsoleCommand::Run (FCommandLine &args, APlayerPawn *instigator, int key) +{ + if (UnsafeExecutionContext) + { + Printf(TEXTCOLOR_RED "Cannot execute unsafe command " TEXTCOLOR_GOLD "%s\n", m_Name); + return; + } + + FConsoleCommand::Run (args, instigator, key); +} + FConsoleAlias::FConsoleAlias (const char *name, const char *command, bool noSave) : FConsoleCommand (name, NULL), bRunning(false), bKill(false) @@ -1381,9 +1356,13 @@ CCMD (alias) alias = NULL; } } + else if (ParsingKeyConf) + { + new FUnsafeConsoleAlias (argv[1], argv[2]); + } else { - new FConsoleAlias (argv[1], argv[2], ParsingKeyConf); + new FConsoleAlias (argv[1], argv[2], false); } } } @@ -1521,6 +1500,13 @@ void FConsoleAlias::SafeDelete () } } +void FUnsafeConsoleAlias::Run (FCommandLine &args, APlayerPawn *instigator, int key) +{ + UnsafeExecutionContext = true; + FConsoleAlias::Run(args, instigator, key); + UnsafeExecutionContext = false; +} + void FExecList::AddCommand(const char *cmd, const char *file) { // Pullins are special and need to be separated from general commands. diff --git a/src/c_dispatch.h b/src/c_dispatch.h index 24a7c42ecf..dac14b818a 100644 --- a/src/c_dispatch.h +++ b/src/c_dispatch.h @@ -127,6 +127,22 @@ protected: FConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \ void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key) +class FUnsafeConsoleCommand : public FConsoleCommand +{ +public: + FUnsafeConsoleCommand (const char *name, CCmdRun RunFunc) + : FConsoleCommand (name, RunFunc) + { + } + + virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override; +}; + +#define UNSAFE_CCMD(n) \ + static void Cmd_##n (FCommandLine &, APlayerPawn *, int key); \ + static FUnsafeConsoleCommand Cmd_##n##_Ref (#n, Cmd_##n); \ + void Cmd_##n (FCommandLine &argv, APlayerPawn *who, int key) + const int KEY_DBLCLICKED = 0x8000; class FConsoleAlias : public FConsoleCommand @@ -147,6 +163,17 @@ protected: bool bKill; }; +class FUnsafeConsoleAlias : public FConsoleAlias +{ +public: + FUnsafeConsoleAlias (const char *name, const char *command) + : FConsoleAlias (name, command, true) + { + } + + virtual void Run (FCommandLine &args, APlayerPawn *instigator, int key) override; +}; + // Actions struct FButtonStatus {