summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--mesecons_luacontroller/init.lua56
1 files changed, 21 insertions, 35 deletions
diff --git a/mesecons_luacontroller/init.lua b/mesecons_luacontroller/init.lua
index 7df2bdc..e669f93 100644
--- a/mesecons_luacontroller/init.lua
+++ b/mesecons_luacontroller/init.lua
@@ -216,6 +216,17 @@ local function safe_string_rep(str, n)
return string.rep(str, n)
end
+-- string.find with a pattern can be used to DoS the server.
+-- Therefore, limit string.find to patternless matching.
+local function safe_string_find(...)
+ if (select(4, ...)) ~= true then
+ debug.sethook() -- Clear hook
+ error("string.find: 'plain' (fourth parameter) must always be true in a LuaController")
+ end
+
+ return string.find(...)
+end
+
local function remove_functions(x)
local tp = type(x)
if tp == "table" then
@@ -292,6 +303,7 @@ local function create_environment(pos, mem, event)
rep = safe_string_rep,
reverse = string.reverse,
sub = string.sub,
+ find = safe_string_find,
},
math = {
abs = math.abs,
@@ -354,22 +366,6 @@ local function timeout()
end
-local function code_prohibited(code)
- -- LuaJIT doesn't increment the instruction counter when running
- -- loops, so we have to sanitize inputs if we're using LuaJIT.
- if not rawget(_G, "jit") then
- return false
- end
- local prohibited = {"while", "for", "repeat", "until", "goto"}
- code = " "..code.." "
- for _, p in ipairs(prohibited) do
- if string.find(code, "[^%w_]"..p.."[^%w_]") then
- return "Prohibited command: "..p
- end
- end
-end
-
-
local function create_sandbox(code, env)
if code:byte(1) == 27 then
return nil, "Binary code prohibited."
@@ -378,24 +374,17 @@ local function create_sandbox(code, env)
if not f then return nil, msg end
setfenv(f, env)
+ -- Turn off JIT optimization for user code so that count
+ -- events are generated when adding debug hooks
+ if rawget(_G, "jit") then
+ jit.off(f, true)
+ end
+
return function(...)
- -- Normal Lua: Use instruction counter to stop execution
- -- after luacontroller_maxevents.
- -- LuaJIT: Count function calls instead of instructions, allows usage
- -- of function keyword. However, LuaJIT still doesn't trigger
- -- lines events when using infinite loops.
+ -- Use instruction counter to stop execution
+ -- after luacontroller_maxevents
local maxevents = mesecon.setting("luacontroller_maxevents", 10000)
- if not rawget(_G, "jit") then
- debug.sethook(timeout, "", maxevents)
- else
- local events = 0
- debug.sethook(function ()
- events = events + 1
- if events > maxevents then
- timeout()
- end
- end, "c")
- end
+ debug.sethook(timeout, "", maxevents)
local ok, ret = pcall(f, ...)
debug.sethook() -- Clear hook
if not ok then error(ret, 0) end
@@ -432,9 +421,6 @@ local function run(pos, event)
local mem = load_memory(meta)
local code = meta:get_string("code")
- local err = code_prohibited(code)
- if err then return err end
-
-- Create environment
local env = create_environment(pos, mem, event)