Lua Infinite Loop Prevention

I use lua interfaces to get lua support in my C # program, the workflow freezes if the user sends code like this

while true do end 

I have a way to determine if an infinite loop is working, but I need a good way to exit the DoString method from the Worker thread. Any ideas?

edit: @kikito; Yes, I am sharing with this something like this. The problem is that I cannot find a clean way to kill the DoString method, it looks like the main Lua (Lua) interface class has some static dependencies, because if I do lua.Close(); in my instance, it will abort the DoString method, but the next time I bring the class lua new Lua(); it will work by saying something about secure memory

edit: function branch displaying my .Close code https://github.com/AndersMalmgren/FreePIE/tree/detect-and-recover-infite-lua-loop

+7
source share
3 answers

Sandbox Lua

Setting the hooks is not sufficient to prevent inadvertent waste of resources, not to mention abuse - here is a simple example (time spent while matching string patterns: the debug call was not called):

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

The only reliable way to force time and memory limits on a piece of Lua code is to run the Lua interpreter in its own process and make your OS monitor such a process.

The good thing with Lua is that you don’t need a complicated, OS-dependent permission setting for the sandbox: you just limit the time and memory (reasonable, there are Job Objects on windows, Unix has corresponding restrictions: Linux resource limit ), and then save things like os.execute, half of the io libraries and modules like luasocket from (pretty easy).

Recovering from errors in isolated code

You can handle almost everything (except for violation of time / memory limitations) without confusing your Lua interpreter: just wrap the user-provided code in pcall ; if you call any Lua-API functions that may fail yourself, you need to wrap them inside a function that you can pcall also (or install the Lua panic function and process it from there).


[I did not want people to look at this thread to suggest that debug.sethook is suitable for the sandbox, and stackoverflow will not let me comment (for now)]

+5
source

I suggest handling it the same as any other Lua error. In other words, threaten the code above as if the user had just written

 error("Script execution has been cancelled after stalling for too long") 

(I assume that you detect infinite loops, assuming that no script can take more than a certain fixed amount of time to execute. Change the message accordingly if it is not)

How you have to handle this will depend on how you deal with Lua errors, but you still have to do this, so it is likely that most of the code already exists.

EDIT: Martin James's suggestion seems to be your best option. You can use debug.setHook () to run some lua code every 100 Lua instructions or so, and if too much time has passed with the same client code, throw an error. Details on this can be found on this mailing list and sample code on the lua-project repo .

0
source

I used two methods to solve this problem. The first is to call the DoFile or DoString method inside a separate task. This way you can interrupt the thread. I do not know any technique (say, off the hook) to exit the interpreter.

Another way would be to install a separate Appdomain . Using this, you can also set individual restrictions (evidence and permission set) to find out the details. CreateDomain .

0
source

All Articles