Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent Lua infinite loop

Tags:

c#

lua

I use lua interfaces to get lua support in my C# program, the worker thread will freeze if the user submits code like this

while true do end

I have a way to detect if a infinite loop is running, but I need a nice way of exiting the DoString method from the Worker thread. Any ideas?

edit: @kikito, Yes Im deteting it something like that. The problem I have is that I cant find a clean way of killing the DoString method, it looks like the Lua interfaces main class (Lua) has some static dependencies, because if I do lua.Close(); on my instance it will abort the DoString method, but the next time I instance an lua class new Lua(); it will crash saying something about protective memory

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

like image 213
Anders Avatar asked Apr 27 '12 14:04

Anders


2 Answers

Sandboxing Lua

Setting hooks is not sufficient at all to prevent unintended waste of resources, let alone abuse- here's a simple example (the time is spent during string pattern matching- no debug hooks get called):

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

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

The nice thing with Lua is that you won't need any complicated, OS-dependent permission setup for sandboxing: you just limit time and memory (reasonable; on windows there are Job Objects, Unix has ulimits- relevant: Linux resource limitation) and then keep things like os.execute, half the io-library and modules like luasocket away from the scripter (pretty easy).

Recovering from errors in sandboxed code

You can handle almost everything (except violation of time/memory limits) without trashing your Lua interpreter: Just wrap the execution of user-supplied code inside a pcall; if you call any Lua-API functions that might fail yourself, you need to wrap them inside a function that you can pcall, too (or set a Lua panic function and handle it from there).


[I didn't want people glancing at this thread to assume that debug.sethook is adequate for sandboxing, and stackoverflow would not let me comment (yet)]

like image 153
radioflash Avatar answered Sep 21 '22 07:09

radioflash


Put the Lua loop inside a coroutine and at the end of every loop, just use Yield return null to wait for a frame (Allowing the worker thread to be executed).

like image 44
HyperBrid Avatar answered Sep 18 '22 07:09

HyperBrid