From 4b044e30d7ae9a8343eb5d42706272ba13d5ad6f Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Wed, 3 Jan 2018 23:28:48 -0500 Subject: [PATCH] - ACS stack checking (proxy commit by Rachael) --- src/p_acs.cpp | 39 ++++++++++++++++++++++++++++++++++----- 1 file changed, 34 insertions(+), 5 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 22afac1b6..e499f9d01 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -851,9 +851,25 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS]; // //---------------------------------------------------------------------------- +struct FACSStackMemory +{ + int32_t& operator[](const size_t index) + { + if (index >= STACK_SIZE) + { + I_Error("Corrupted stack pointer in ACS VM"); + } + + return buffer[index]; + } + +private: + int32_t buffer[STACK_SIZE]; +}; + struct FACSStack { - int32_t buffer[STACK_SIZE]; + FACSStackMemory buffer; int sp; FACSStack *next; FACSStack *prev; @@ -1488,7 +1504,20 @@ void P_CollectACSGlobalStrings() { for (FACSStack *stack = FACSStack::head; stack != NULL; stack = stack->next) { - GlobalACSStrings.MarkStringArray(stack->buffer, stack->sp); + const int32_t sp = stack->sp; + + if (0 == sp) + { + continue; + } + else if (sp < 0 && sp >= STACK_SIZE) + { + I_Error("Corrupted stack pointer in ACS VM"); + } + else + { + GlobalACSStrings.MarkStringArray(&stack->buffer[0], sp); + } } FBehavior::StaticMarkLevelVarStrings(); P_MarkWorldVarStrings(); @@ -6889,7 +6918,7 @@ inline int getshort (int *&pc) return res; } -static bool CharArrayParms(int &capacity, int &offset, int &a, int *Stack, int &sp, bool ranged) +static bool CharArrayParms(int &capacity, int &offset, int &a, FACSStackMemory& Stack, int &sp, bool ranged) { if (ranged) { @@ -7012,7 +7041,7 @@ int DLevelScript::RunScript () } FACSStack stackobj; - int32_t *Stack = stackobj.buffer; + FACSStackMemory& Stack = stackobj.buffer; int &sp = stackobj.sp; int *pc = this->pc; @@ -7376,7 +7405,7 @@ int DLevelScript::RunScript () sp -= sizeof(CallReturn)/sizeof(int); retsp = &Stack[sp]; activeBehavior->GetFunctionProfileData(activeFunction)->AddRun(runaway - ret->EntryInstrCount); - sp = int(locals - Stack); + sp = int(locals - &Stack[0]); pc = ret->ReturnModule->Ofs2PC(ret->ReturnAddress); activeFunction = ret->ReturnFunction; activeBehavior = ret->ReturnModule;