luaL_loadfile(mState, path.c_str());
lua_pcall(mState, 0, 0, 0);
Is there a way to put an execution time limit (say 10-20 seconds) for those two C++ statements, that load and then execute a lua file?
Since the Lua file is untrusted I don't want a malicious user to hang the program indefinitely with an infinite loop in the Lua code.
Tagging C because the Lua API is C, tagging C++ because I'm using C++
The C API is the set of functions that allow C code to interact with Lua. It comprises functions to read and write Lua global variables, to call Lua functions, to run pieces of Lua code, to register C functions so that they can later be called by Lua code, and so on.
Lua has a simple and well documented API that allows strong integration with code written in other languages. It is easy to extend Lua with libraries written in other languages. It is also easy to extend programs written in other languages with Lua.
To run a Lua scriptOpen the Lua Script Library through Prepare > Run Lua Script. Use the appearing dialog to load, save, and execute Lua scripts as well as to create new ones. Select the script to be run. Click Execute Script.
There's lua_sethook which can be used to tell the interpreter to call a hook after every 'count' instructions executed. This way you can monitor the user script and terminate it if it eats up its quota:
int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);
This can also be used from Lua:
debug.sethook(function() print("That's enough for today"); os.exit(0); end, "", 10000)
for i=1,10000 do end
If you use the techniques from http://lua-users.org/wiki/SandBoxes then you can set up a safe execution environment with sethook()
and friends entirely from Lua and then switch to sandbox mode while executing the user script. I've tried that here, just for you to get started:
-- set an execution quota
local function set_quota(secs)
local st=os.clock()
function check()
if os.clock()-st > secs then
debug.sethook() -- disable hooks
error("quota exceeded")
end
end
debug.sethook(check,"",100000);
end
-- these are the global objects, the user can use:
local env = {print=print}
-- The user code is allowed to run for 5 seconds.
set_quota(5)
-- run code under environment:
local function run(untrusted_code)
local untrusted_function, message = loadstring(untrusted_code)
if not untrusted_function then return nil, message end
setfenv(untrusted_function, env)
return pcall(untrusted_function)
end
-- here is the user code:
local userscript=[[
function fib(n)
if n<2 then return n
else return fib(n-2)+fib(n-1)
end
end
for n=1,42 do print(n,fib(n)) end
]]
-- call it:
local r,m=run(userscript)
print(r,m)
This should print values of fib() for 5 seconds and then show an error.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With