Add basic rate limitation for Lua file access

This commit is contained in:
LJ Sonic 2023-03-19 14:52:12 +01:00
parent 62aef145f5
commit 0f9c5582a3

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);
}