防止Lua无限循环

And*_*ers 10 c# lua

我使用lua接口在我的C#程序中获得lua支持,如果用户提交这样的代码,工作线程将冻结

while true do end
Run Code Online (Sandbox Code Playgroud)

我有办法检测无限循环是否正在运行,但我需要一种从Worker线程退出DoString方法的好方法.有任何想法吗?

编辑:@kikito,是的,我正在发现它.我遇到的问题是我无法找到一种杀死DoString方法的简洁方法,看起来Lua接口主类(Lua)有一些静态依赖,因为如果我lua.Close();在我的实例上执行它会中止DoString方法,但是下次我实例一个lua类时,new Lua();它会崩溃说一些保护性记忆

编辑:显示我的.Close代码的功能分支 https://github.com/AndersMalmgren/FreePIE/tree/detect-and-recover-infite-lua-loop

rad*_*ash 8

沙盒Lua

设置挂钩是不够的,在所有的,以防止资源的浪费意外,更何况是与滥用这里有一个简单的例子(具体时间字符串模式中度过匹配-没有调试钩子被调用):

s=('a'):rep(20000):match('.-b')

对一段Lua代码强制时间/内存约束的唯一可靠方法是在自己的进程中运行Lua解释器,并使您的OS监视器进行处理.

Lua的好处是你不需要任何复杂的,依赖于操作系统的沙箱权限设置:你只需要限制时间和内存(合理;在Windows上有Job Objects,Unix有ulimits相关:Linux资源限制)和然后保持像os.execute,一半的io库和luasocket这样的模块远离脚本编写器(非常简单).

从沙盒代码中的错误中恢复

您可以处理几乎所有内容(除了违反时间/内存限制)而不会破坏您的Lua解释器:只需将用户提供的代码执行包装在pcall中 ; 如果你调用任何可能自己失败的Lua-API函数,你需要将它们包装在一个你可以实现的函数中(或者设置一个Lua恐慌函数并从那里处理它).


[我不希望人们看到这个线程假设debug.sethook足以进行沙盒,而stackoverflow不会让我发表评论(还)]


kik*_*ito 0

我建议像处理任何其他 Lua 错误一样处理它。换句话说,威胁上面的代码,就像用户刚刚编写的一样

error("Script execution has been cancelled after stalling for too long")
Run Code Online (Sandbox Code Playgroud)

(我假设您通过假设没有脚本运行时间不应超过固定时间来检测无限循环。如果情况并非如此,请适当更改消息)

你必须处理这个问题的方式取决于你如何处理 Lua 错误 - 但无论如何你都必须这样做,所以很可能大部分代码已经在那里了。

编辑:看来马丁·詹姆斯的建议是你最好的选择。您可以使用 debug.setHook() 每 100 个 Lua 指令运行一些 lua 代码,如果相同的客户端代码运行了太多时间,则抛出错误。有关详细信息可以在此邮件列表中找到,并且可以在lua-project repo上找到代码示例。