mirror of
https://github.com/ZDoom/gzdoom.git
synced 2024-11-26 05:51:20 +00:00
Uniform way to guard ACS stack and variables
ACS VM stack and map/world/global variables arrays are now checked for out of bounds access
This commit is contained in:
parent
0f62cd67a5
commit
d5bc0a1fa9
2 changed files with 46 additions and 41 deletions
|
@ -835,12 +835,12 @@ inline int uallong(const int &foo)
|
||||||
//============================================================================
|
//============================================================================
|
||||||
|
|
||||||
// ACS variables with world scope
|
// ACS variables with world scope
|
||||||
int32_t ACS_WorldVars[NUM_WORLDVARS];
|
static BoundsCheckingArray<int32_t, NUM_WORLDVARS> ACS_WorldVars;
|
||||||
FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
|
static BoundsCheckingArray<FWorldGlobalArray, NUM_WORLDVARS> ACS_WorldArrays;
|
||||||
|
|
||||||
// ACS variables with global scope
|
// ACS variables with global scope
|
||||||
int32_t ACS_GlobalVars[NUM_GLOBALVARS];
|
BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
|
||||||
FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
|
BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
|
||||||
|
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
//
|
//
|
||||||
|
@ -851,21 +851,7 @@ FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
|
||||||
//
|
//
|
||||||
//----------------------------------------------------------------------------
|
//----------------------------------------------------------------------------
|
||||||
|
|
||||||
struct FACSStackMemory
|
using FACSStackMemory = BoundsCheckingArray<int32_t, STACK_SIZE>;
|
||||||
{
|
|
||||||
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
|
struct FACSStack
|
||||||
{
|
{
|
||||||
|
@ -1470,10 +1456,10 @@ void ACSStringPool::UnlockForLevel(int lnum)
|
||||||
|
|
||||||
void P_MarkWorldVarStrings()
|
void P_MarkWorldVarStrings()
|
||||||
{
|
{
|
||||||
GlobalACSStrings.MarkStringArray(ACS_WorldVars, countof(ACS_WorldVars));
|
GlobalACSStrings.MarkStringArray(ACS_WorldVars.Pointer(), ACS_WorldVars.Size());
|
||||||
for (size_t i = 0; i < countof(ACS_WorldArrays); ++i)
|
for (size_t i = 0; i < ACS_WorldArrays.Size(); ++i)
|
||||||
{
|
{
|
||||||
GlobalACSStrings.MarkStringMap(ACS_WorldArrays[i]);
|
GlobalACSStrings.MarkStringMap(ACS_WorldArrays.Pointer()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1485,10 +1471,10 @@ void P_MarkWorldVarStrings()
|
||||||
|
|
||||||
void P_MarkGlobalVarStrings()
|
void P_MarkGlobalVarStrings()
|
||||||
{
|
{
|
||||||
GlobalACSStrings.MarkStringArray(ACS_GlobalVars, countof(ACS_GlobalVars));
|
GlobalACSStrings.MarkStringArray(ACS_GlobalVars.Pointer(), ACS_GlobalVars.Size());
|
||||||
for (size_t i = 0; i < countof(ACS_GlobalArrays); ++i)
|
for (size_t i = 0; i < ACS_GlobalArrays.Size(); ++i)
|
||||||
{
|
{
|
||||||
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays[i]);
|
GlobalACSStrings.MarkStringMap(ACS_GlobalArrays.Pointer()[i]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1571,14 +1557,14 @@ void P_ClearACSVars(bool alsoglobal)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
memset (ACS_WorldVars, 0, sizeof(ACS_WorldVars));
|
ACS_WorldVars.Fill(0);
|
||||||
for (i = 0; i < NUM_WORLDVARS; ++i)
|
for (i = 0; i < NUM_WORLDVARS; ++i)
|
||||||
{
|
{
|
||||||
ACS_WorldArrays[i].Clear ();
|
ACS_WorldArrays[i].Clear ();
|
||||||
}
|
}
|
||||||
if (alsoglobal)
|
if (alsoglobal)
|
||||||
{
|
{
|
||||||
memset (ACS_GlobalVars, 0, sizeof(ACS_GlobalVars));
|
ACS_GlobalVars.Fill(0);
|
||||||
for (i = 0; i < NUM_GLOBALVARS; ++i)
|
for (i = 0; i < NUM_GLOBALVARS; ++i)
|
||||||
{
|
{
|
||||||
ACS_GlobalArrays[i].Clear ();
|
ACS_GlobalArrays[i].Clear ();
|
||||||
|
@ -1726,10 +1712,10 @@ static void ReadArrayVars (FSerializer &file, FWorldGlobalArray *vars, size_t co
|
||||||
|
|
||||||
void P_ReadACSVars(FSerializer &arc)
|
void P_ReadACSVars(FSerializer &arc)
|
||||||
{
|
{
|
||||||
ReadVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
|
ReadVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
|
||||||
ReadVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
|
ReadVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
|
||||||
ReadArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
|
ReadArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
|
||||||
ReadArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
|
ReadArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
|
||||||
GlobalACSStrings.ReadStrings(arc, "acsglobalstrings");
|
GlobalACSStrings.ReadStrings(arc, "acsglobalstrings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1741,10 +1727,10 @@ void P_ReadACSVars(FSerializer &arc)
|
||||||
|
|
||||||
void P_WriteACSVars(FSerializer &arc)
|
void P_WriteACSVars(FSerializer &arc)
|
||||||
{
|
{
|
||||||
WriteVars (arc, ACS_WorldVars, NUM_WORLDVARS, "acsworldvars");
|
WriteVars (arc, ACS_WorldVars.Pointer(), NUM_WORLDVARS, "acsworldvars");
|
||||||
WriteVars (arc, ACS_GlobalVars, NUM_GLOBALVARS, "acsglobalvars");
|
WriteVars (arc, ACS_GlobalVars.Pointer(), NUM_GLOBALVARS, "acsglobalvars");
|
||||||
WriteArrayVars (arc, ACS_WorldArrays, NUM_WORLDVARS, "acsworldarrays");
|
WriteArrayVars (arc, ACS_WorldArrays.Pointer(), NUM_WORLDVARS, "acsworldarrays");
|
||||||
WriteArrayVars (arc, ACS_GlobalArrays, NUM_GLOBALVARS, "acsglobalarrays");
|
WriteArrayVars (arc, ACS_GlobalArrays.Pointer(), NUM_GLOBALVARS, "acsglobalarrays");
|
||||||
GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
|
GlobalACSStrings.WriteStrings(arc, "acsglobalstrings");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
31
src/p_acs.h
31
src/p_acs.h
|
@ -60,13 +60,32 @@ struct InitIntToZero
|
||||||
};
|
};
|
||||||
typedef TMap<int32_t, int32_t, THashTraits<int32_t>, InitIntToZero> FWorldGlobalArray;
|
typedef TMap<int32_t, int32_t, THashTraits<int32_t>, InitIntToZero> FWorldGlobalArray;
|
||||||
|
|
||||||
// ACS variables with world scope
|
// Type of elements count is unsigned int instead of size_t to match ACSStringPool interface
|
||||||
extern int32_t ACS_WorldVars[NUM_WORLDVARS];
|
template <typename T, unsigned int N>
|
||||||
extern FWorldGlobalArray ACS_WorldArrays[NUM_WORLDVARS];
|
struct BoundsCheckingArray
|
||||||
|
{
|
||||||
|
T &operator[](const unsigned int index)
|
||||||
|
{
|
||||||
|
if (index >= N)
|
||||||
|
{
|
||||||
|
I_Error("Out of bounds memory access in ACS VM");
|
||||||
|
}
|
||||||
|
|
||||||
|
return buffer[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
T *Pointer() { return buffer; }
|
||||||
|
unsigned int Size() const { return N; }
|
||||||
|
|
||||||
|
void Fill(const T &value) { std::fill(std::begin(buffer), std::end(buffer), value); }
|
||||||
|
|
||||||
|
private:
|
||||||
|
T buffer[N];
|
||||||
|
};
|
||||||
|
|
||||||
// ACS variables with global scope
|
// ACS variables with global scope
|
||||||
extern int32_t ACS_GlobalVars[NUM_GLOBALVARS];
|
extern BoundsCheckingArray<int32_t, NUM_GLOBALVARS> ACS_GlobalVars;
|
||||||
extern FWorldGlobalArray ACS_GlobalArrays[NUM_GLOBALVARS];
|
extern BoundsCheckingArray<FWorldGlobalArray, NUM_GLOBALVARS> ACS_GlobalArrays;
|
||||||
|
|
||||||
#define LIBRARYID_MASK 0xFFF00000
|
#define LIBRARYID_MASK 0xFFF00000
|
||||||
#define LIBRARYID_SHIFT 20
|
#define LIBRARYID_SHIFT 20
|
||||||
|
@ -359,7 +378,7 @@ public:
|
||||||
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
|
ACSProfileInfo *GetFunctionProfileData(ScriptFunction *func) { return GetFunctionProfileData((int)(func - (ScriptFunction *)Functions)); }
|
||||||
const char *LookupString (uint32_t index) const;
|
const char *LookupString (uint32_t index) const;
|
||||||
|
|
||||||
int32_t *MapVars[NUM_MAPVARS];
|
BoundsCheckingArray<int32_t *, NUM_MAPVARS> MapVars;
|
||||||
|
|
||||||
static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0);
|
static FBehavior *StaticLoadModule (int lumpnum, FileReader * fr=NULL, int len=0);
|
||||||
static void StaticLoadDefaultModules ();
|
static void StaticLoadDefaultModules ();
|
||||||
|
|
Loading…
Reference in a new issue