On Mon, Mar 17, 2014 at 3:33 PM, Roberto Ierusalimschy
<roberto@inf.puc-rio.br> wrote:
> Nice idea with __gc !!!
> But unfortunately, "memory usage limiter" fails to stop this simple
> malicious one-liner until all available memory has been exhausted:
>
> -- track memory use
> do
> -- maximum memory (in KB) that can be used
> local memlimit = 1000
> local mt = {__gc = function (u)
> if collectgarbage("count") > memlimit then
> error("script uses too much memory")
> else
> setmetatable({}, getmetatable(u))
> end
> end}
> setmetatable({}, mt)
> end
>
> -- memory eater
> local t={}; while t do t[#t+1] = t end
>
>
> Nevertheless, it will be stopped by "CPU usage limiter".
So, we are still in the game :-)
Anyway, one way to improve this sandbox is to check memory in function
'step', too.
-- Roberto
Aha, this thread has come back to life. I was a bit confused. :-)
There are a lot of simple ways to consume a huge amount of CPU time and memory with very few Lua statements. One of my favourites is:
s = ('xxxxxxxxxxxxxxxx'):rep(99999999):rep(99999999):rep(99999999)
This not only consumes a lot of memory, but because nearly all of the time is spent in string.rep, debug hooks won't be called either (the entire function call is a single Lua operation). And even if you don't provide string.rep, there may be many other C functions that can be exploited similarly. How about io.lines('/dev/urandom')? It forces you to be very careful about any C function you provide. (Or use the OS provided mechanisms to limit CPU time for the entire thread/process.)
In comparison the "s = s .. s .. s .. s .. s .. s" attack uses no functions at all, but the work involves a lot of Lua operations, so it can be stopped by a debug hook.
--
Sent from my Game Boy.