mirror of
https://github.com/minetest-mods/mesecons.git
synced 2024-09-27 23:00:29 +02:00
Protect server against Luacontroller memory usage
This commit is contained in:
parent
4c5b13a347
commit
622b82cfd6
|
@ -590,8 +590,12 @@ local function load_memory(meta)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
||||||
local function save_memory(pos, meta, mem)
|
local function serialize_memory(mem)
|
||||||
local memstring = minetest.serialize(remove_functions(mem))
|
return minetest.serialize(remove_functions(mem))
|
||||||
|
end
|
||||||
|
|
||||||
|
|
||||||
|
local function save_serialized_memory(pos, meta, memstring)
|
||||||
local memsize_max = mesecon.setting("luacontroller_memsize", 100000)
|
local memsize_max = mesecon.setting("luacontroller_memsize", 100000)
|
||||||
|
|
||||||
if (#memstring <= memsize_max) then
|
if (#memstring <= memsize_max) then
|
||||||
|
@ -629,6 +633,8 @@ local function run_inner(pos, code, event)
|
||||||
-- Create the sandbox and execute code
|
-- Create the sandbox and execute code
|
||||||
local f, msg = create_sandbox(code, env)
|
local f, msg = create_sandbox(code, env)
|
||||||
if not f then return false, msg end
|
if not f then return false, msg end
|
||||||
|
local mem_use_limit = collectgarbage("count") + mesecon.setting("luacontroller_volatile_mem_limit", 2000)
|
||||||
|
local oom_msg = "not enough memory" -- Used to detect OOM errors, kind of a hack.
|
||||||
-- Start string true sandboxing
|
-- Start string true sandboxing
|
||||||
local onetruestring = getmetatable("")
|
local onetruestring = getmetatable("")
|
||||||
-- If a string sandbox is already up yet inconsistent, something is very wrong
|
-- If a string sandbox is already up yet inconsistent, something is very wrong
|
||||||
|
@ -637,16 +643,43 @@ local function run_inner(pos, code, event)
|
||||||
local success, msg = pcall(f)
|
local success, msg = pcall(f)
|
||||||
onetruestring.__index = string
|
onetruestring.__index = string
|
||||||
-- End string true sandboxing
|
-- End string true sandboxing
|
||||||
if not success then return false, msg end
|
if collectgarbage("count") > mem_use_limit then
|
||||||
|
-- Volatile memory limit exceeded.
|
||||||
|
success = false
|
||||||
|
msg = oom_msg
|
||||||
|
end
|
||||||
|
-- Serialize the persistent memory.
|
||||||
|
local memstring
|
||||||
|
if success then
|
||||||
|
success, memstring = pcall(serialize_memory, env.mem)
|
||||||
|
if not success then
|
||||||
|
msg = memstring
|
||||||
|
-- Rethrow non-OOM errors.
|
||||||
|
if msg ~= oom_msg then error(msg, 0) end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not success then
|
||||||
|
-- Handle OOM errors by collecting garbage.
|
||||||
|
if msg == oom_msg then
|
||||||
|
env, itbl, mem = nil -- Let the memory be collected.
|
||||||
|
collectgarbage()
|
||||||
|
print("Error: Luacontroller at " .. minetest.pos_to_string(pos)
|
||||||
|
.. " exhausted its available volatile memory. Controller overheats.")
|
||||||
|
burn_controller(pos)
|
||||||
|
end
|
||||||
|
return false, msg
|
||||||
|
end
|
||||||
if type(env.port) ~= "table" then
|
if type(env.port) ~= "table" then
|
||||||
return false, "Ports set are invalid."
|
return false, "Ports set are invalid."
|
||||||
end
|
end
|
||||||
|
local success, memstring = pcall(serialize_memory, env.mem)
|
||||||
|
if not success then return false, memstring end -- memstring is the error message here.
|
||||||
|
|
||||||
-- Actually set the ports
|
-- Actually set the ports
|
||||||
set_port_states(pos, env.port)
|
set_port_states(pos, env.port)
|
||||||
|
|
||||||
-- Save memory. This may burn the luacontroller if a memory overflow occurs.
|
-- Save memory. This may burn the luacontroller if a memory overflow occurs.
|
||||||
save_memory(pos, meta, env.mem)
|
save_serialized_memory(pos, meta, memstring)
|
||||||
|
|
||||||
-- Execute deferred tasks
|
-- Execute deferred tasks
|
||||||
for _, v in ipairs(itbl) do
|
for _, v in ipairs(itbl) do
|
||||||
|
|
|
@ -24,6 +24,11 @@ mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000 10
|
||||||
mesecon.luacontroller_maxevents (Controller execution time limit) int 10000 1000 100000
|
mesecon.luacontroller_maxevents (Controller execution time limit) int 10000 1000 100000
|
||||||
mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000
|
mesecon.luacontroller_memsize (Controller memory limit) int 100000 10000 1000000
|
||||||
|
|
||||||
|
# The amount of server memory a controller is allowed, measured in kilobytes.
|
||||||
|
# This actually measures the memory usage after the script is done, not during its runtime.
|
||||||
|
# Thus, controllers can lag the server even with a low limit.
|
||||||
|
mesecon.luacontroller_volatile_mem_limit (Controller volatile memory limit) int 2000 10 10000000
|
||||||
|
|
||||||
# Use node timer for interrupts (runs in active blocks only).
|
# Use node timer for interrupts (runs in active blocks only).
|
||||||
# IID is ignored and at most one interrupt may be queued if this setting is enabled.
|
# IID is ignored and at most one interrupt may be queued if this setting is enabled.
|
||||||
mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false
|
mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false
|
||||||
|
|
Loading…
Reference in New Issue
Block a user