Skip to content
Snippets Groups Projects
Commit 737f3667 authored by Thomas Rudin's avatar Thomas Rudin Committed by Vitaliy
Browse files

LuaC: add lightweight interrupts (#449)

parent 302a2893
No related branches found
No related tags found
No related merge requests found
...@@ -266,32 +266,45 @@ local function remove_functions(x) ...@@ -266,32 +266,45 @@ local function remove_functions(x)
return x return x
end end
-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards -- The setting affects API so is not intended to be changeable at runtime
local function get_interrupt(pos, itbl, send_warning) local get_interrupt
-- iid = interrupt id if mesecon.setting("luacontroller_lightweight_interrupts", false) then
local function interrupt(time, iid) -- use node timer
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y get_interrupt = function(pos, itbl, send_warning)
-- Hence the values get moved out. Should take less time than original, so totally compatible return (function(time, iid)
if type(time) ~= "number" then return end if type(time) ~= "number" then error("Delay must be a number") end
table.insert(itbl, function () if iid ~= nil then send_warning("Interrupt IDs are disabled on this server") end
-- Outside string metatable sandbox, can safely run this now table.insert(itbl, function() minetest.get_node_timer(pos):start(time) end)
local luac_id = minetest.get_meta(pos):get_int("luac_id")
-- Check if IID is dodgy, so you can't use interrupts to store an infinite amount of data.
-- Note that this is safe from alter-after-free because this code gets run after the sandbox has ended.
-- This runs outside of the timer and *shouldn't* harm perf. unless dodgy data is being sent in the first place
iid = remove_functions(iid)
local msg_ser = minetest.serialize(iid)
if #msg_ser <= mesecon.setting("luacontroller_interruptid_maxlen", 256) then
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
else
send_warning("An interrupt ID was too large!")
end
end) end)
end end
return interrupt else
-- use global action queue
-- itbl: Flat table of functions to run after sandbox cleanup, used to prevent various security hazards
get_interrupt = function(pos, itbl, send_warning)
-- iid = interrupt id
local function interrupt(time, iid)
-- NOTE: This runs within string metatable sandbox, so don't *rely* on anything of the form (""):y
-- Hence the values get moved out. Should take less time than original, so totally compatible
if type(time) ~= "number" then error("Delay must be a number") end
table.insert(itbl, function ()
-- Outside string metatable sandbox, can safely run this now
local luac_id = minetest.get_meta(pos):get_int("luac_id")
-- Check if IID is dodgy, so you can't use interrupts to store an infinite amount of data.
-- Note that this is safe from alter-after-free because this code gets run after the sandbox has ended.
-- This runs outside of the timer and *shouldn't* harm perf. unless dodgy data is being sent in the first place
iid = remove_functions(iid)
local msg_ser = minetest.serialize(iid)
if #msg_ser <= mesecon.setting("luacontroller_interruptid_maxlen", 256) then
mesecon.queue:add_action(pos, "lc_interrupt", {luac_id, iid}, time, iid, 1)
else
send_warning("An interrupt ID was too large!")
end
end)
end
return interrupt
end
end end
-- Given a message object passed to digiline_send, clean it up into a form -- Given a message object passed to digiline_send, clean it up into a form
-- which is safe to transmit over the network and compute its "cost" (a very -- which is safe to transmit over the network and compute its "cost" (a very
-- rough estimate of its memory usage). -- rough estimate of its memory usage).
...@@ -414,7 +427,6 @@ local function get_digiline_send(pos, itbl, send_warning) ...@@ -414,7 +427,6 @@ local function get_digiline_send(pos, itbl, send_warning)
end end
end end
local safe_globals = { local safe_globals = {
-- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly) -- Don't add pcall/xpcall unless willing to deal with the consequences (unless very careful, incredibly likely to allow killing server indirectly)
"assert", "error", "ipairs", "next", "pairs", "select", "assert", "error", "ipairs", "next", "pairs", "select",
...@@ -651,6 +663,14 @@ local function reset(pos) ...@@ -651,6 +663,14 @@ local function reset(pos)
set_port_states(pos, {a=false, b=false, c=false, d=false}) set_port_states(pos, {a=false, b=false, c=false, d=false})
end end
local function node_timer(pos)
if minetest.registered_nodes[minetest.get_node(pos).name].is_burnt then
return false
end
run(pos, {type="interrupt"})
return false
end
----------------------- -----------------------
-- A.Queue callbacks -- -- A.Queue callbacks --
----------------------- -----------------------
...@@ -823,6 +843,7 @@ for d = 0, 1 do ...@@ -823,6 +843,7 @@ for d = 0, 1 do
mesecon.receptor_off(pos, output_rules) mesecon.receptor_off(pos, output_rules)
end, end,
is_luacontroller = true, is_luacontroller = true,
on_timer = node_timer,
on_blast = mesecon.on_blastnode, on_blast = mesecon.on_blastnode,
}) })
end end
......
...@@ -24,6 +24,10 @@ mesecon.luacontroller_digiline_maxlen (Digiline message size limit) int 50000 10 ...@@ -24,6 +24,10 @@ 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
# 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.
mesecon.luacontroller_lightweight_interrupts (Lightweight interrupts) bool false
[mesecons_movestones] [mesecons_movestones]
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment