From 83cd53c9b1c52498d62fb6d501396ff782037c70 Mon Sep 17 00:00:00 2001 From: "alexey.lysiuk" Date: Sat, 6 Jan 2018 13:26:51 +0200 Subject: [PATCH] Added partial bounds check for instruction pointer in ACS VM This change adds verification of instruction pointer for indirect usages only, i.e. via NEXT...() macros --- src/p_acs.cpp | 45 ++++++++++++++++++++++++++++++--------------- 1 file changed, 30 insertions(+), 15 deletions(-) diff --git a/src/p_acs.cpp b/src/p_acs.cpp index 7ef6f56839..19f9de486d 100644 --- a/src/p_acs.cpp +++ b/src/p_acs.cpp @@ -761,6 +761,35 @@ protected: private: DLevelScript(); + int getbyte(int *&pc) + { + CheckInstructionPointer(pc); + + int res = *(uint8_t *)pc; + pc = (int *)((uint8_t *)pc+1); + return res; + } + + int getshort(int *&pc) + { + CheckInstructionPointer(pc); + + int res = LittleShort( *(int16_t *)pc); + pc = (int *)((uint8_t *)pc+2); + return res; + } + + void CheckInstructionPointer(int *pc) const + { + const uint32_t offset = activeBehavior->PC2Ofs(pc); + const uint32_t size = activeBehavior->GetDataSize(); + + if (offset >= size) + { + I_Error("Out of bounds instruction pointer in ACS VM"); + } + } + friend class DACSThinker; }; @@ -6896,7 +6925,7 @@ enum }; -#define NEXTWORD (LittleLong(*pc++)) +#define NEXTWORD (CheckInstructionPointer(pc), LittleLong(*pc++)) #define NEXTBYTE (fmt==ACS_LittleEnhanced?getbyte(pc):NEXTWORD) #define NEXTSHORT (fmt==ACS_LittleEnhanced?getshort(pc):NEXTWORD) #define STACK(a) (Stack[sp - (a)]) @@ -6904,20 +6933,6 @@ enum // Direct instructions that take strings need to have the tag applied. #define TAGSTR(a) (a|activeBehavior->GetLibraryID()) -inline int getbyte (int *&pc) -{ - int res = *(uint8_t *)pc; - pc = (int *)((uint8_t *)pc+1); - return res; -} - -inline int getshort (int *&pc) -{ - int res = LittleShort( *(int16_t *)pc); - pc = (int *)((uint8_t *)pc+2); - return res; -} - static bool CharArrayParms(int &capacity, int &offset, int &a, FACSStackMemory& Stack, int &sp, bool ranged) { if (ranged)