Merge branch 'io-limit' into 'next'

Add basic rate limitation for Lua file access

See merge request STJr/SRB2!1947
This commit is contained in:
sphere 2023-03-31 16:13:42 +00:00
commit 3c81938496
2 changed files with 33 additions and 11 deletions

View file

@ -24,12 +24,14 @@
#include "../byteptr.h"
#include "../lua_script.h"
#include "../m_misc.h"
#include "../i_time.h"
#define IO_INPUT 1
#define IO_OUTPUT 2
#define FILELIMIT (1024 * 1024) // Size limit for reading/writing files
#define MAXBYTESPERMINUTE (10 * 1024 * 1024) // Rate limit for writing files
#define MAXOPENSPERMINUTE 50 // Rate limit for opening new files
#define FMT_FILECALLBACKID "file_callback_%d"
@ -46,6 +48,10 @@ static const char *whitelist[] = {
};
static INT64 numwrittenbytes = 0;
static INT64 numopenedfiles = 0;
static int pushresult (lua_State *L, int i, const char *filename) {
int en = errno; /* calls to Lua API may change this value */
if (i) {
@ -252,6 +258,17 @@ static int io_openlocal (lua_State *L) {
"Files can't be opened while being downloaded\n",
filename);
// Reading not restricted
if (client && (strchr(mode, 'w') || strchr(mode, 'a') || strchr(mode, '+')))
{
if (numopenedfiles >= (I_GetTime() / (60*TICRATE) + 1) * MAXOPENSPERMINUTE)
I_Error("Access denied to %s\n"
"File opening rate exceeded\n",
filename);
numopenedfiles++;
}
MakePathDirs(realfilename);
// Open and return the file
@ -527,9 +544,12 @@ static int g_write (lua_State *L, FILE *f, int arg) {
else {
size_t l;
const char *s = luaL_checklstring(L, arg, &l);
if (ftell(f) + l > FILELIMIT) {
luaL_error(L,"write limit bypassed in file. Changes have been discarded.");
break;
if (client) {
if (numwrittenbytes + l > (I_GetTime() / (60*TICRATE) + 1) * MAXBYTESPERMINUTE) {
luaL_error(L,"file write rate limit exceeded; changes have been discarded");
break;
}
numwrittenbytes += l;
}
status = status && (fwrite(s, sizeof(char), l, f) == l);
}

View file

@ -43,18 +43,20 @@ tic_t I_GetTime(void)
void I_InitializeTime(void)
{
g_time.time = 0;
g_time.timefrac = 0;
enterprecise = 0;
oldenterprecise = 0;
tictimer = 0.0;
CV_RegisterVar(&cv_timescale);
// I_StartupTimer is preserved for potential subsystems that need to setup
// timing information for I_GetPreciseTime and sleeping
I_StartupTimer();
g_time.time = 0;
g_time.timefrac = 0;
enterprecise = I_GetPreciseTime();
oldenterprecise = enterprecise;
entertic = 0;
oldentertics = 0;
tictimer = 0.0;
}
void I_UpdateTime(fixed_t timescale)