从C API调用Lua脚本的执行时间限制

12
luaL_loadfile(mState, path.c_str());
lua_pcall(mState, 0, 0, 0);

有没有一种方法可以为这两个C++语句设置执行时间限制(比如10-20秒),这些语句加载然后执行一个Lua文件?

由于Lua文件是不可信的,我不想一个恶意用户通过Lua代码中的无限循环来无限期地挂起程序。

标签中加入C是因为Lua API是C,加入C++是因为我在使用C++。

1个回答

28

可以使用lua_sethook告诉解释器在执行每个“count”指令后调用钩子。这样,您就可以监视用户脚本并在其耗尽配额时终止它:

 int lua_sethook (lua_State *L, lua_Hook f, int mask, int count);

这个也可以在Lua中使用:

debug.sethook(function() print("That's enough for today"); os.exit(0); end, "", 10000)
for i=1,10000 do end

如果使用http://lua-users.org/wiki/SandBoxes中的技术,那么您可以使用sethook()和相关函数从Lua完全设置安全执行环境,然后在执行用户脚本时切换到沙盒模式。我已经在这里尝试过了,只是为了让您开始:

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

这应该打印出fib()的值5秒钟,然后显示一个错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接