LuaJIT sandboxing
Posted: Sat May 02, 2015 7:19 pm
Well after a lot of effort I got LuaJIT sandboxing working. The sandbox is just a coroutine with a limited environment but a c function is attached to the sandboxed coroutine that forces the coroutine to yield after running so many statements.
In other words...
won't make it hang.
The only problem comes up if the lua sandbox is executing a c function. The yield function cannot make a c function yield (How could it possibly do that and by ANSI C compliant?). This means that if the sandboxed lua code can get any c function to hang... then lua will hang
So you do have to be careful about what you expose to the sandbox. Here is an example that will cause the sandbox to hang if the standard string library is exposed to it.
Obviously, the FFI library would be really stupid to expose to sandboxed code.
Later, I will add a lua wrapper that will partially implement c funcs such as string.find so that they too will yield.
The interesting thing is that I had to write a c library to do this. The c library is simple. It defines a c func that gets set as a debug hook. This hook is set to the coroutine directly in c. (Otherwise, lua actually uses a wrapper c func that calls a generic lua/c function. This causes lua complain about crossing c boundaries and it is for this reason that the debug hook with the yield has to be written in c and not lua.)
Also make sure that you use jit.off(sandboxedFunc,true) or you will run into problems as soon as luaJIT determines that sandboxedFunc needs to be compiled.
Here's the link: https://github.com/GoogleBot42/LuaJIT-Sandbox
In other words...
Code: Select all
while true do end
The only problem comes up if the lua sandbox is executing a c function. The yield function cannot make a c function yield (How could it possibly do that and by ANSI C compliant?). This means that if the sandboxed lua code can get any c function to hang... then lua will hang
So you do have to be careful about what you expose to the sandbox. Here is an example that will cause the sandbox to hang if the standard string library is exposed to it.
Code: Select all
string.find(string.rep("a", 50), string.rep("a?", 50)..string.rep("a", 50))"
Later, I will add a lua wrapper that will partially implement c funcs such as string.find so that they too will yield.
The interesting thing is that I had to write a c library to do this. The c library is simple. It defines a c func that gets set as a debug hook. This hook is set to the coroutine directly in c. (Otherwise, lua actually uses a wrapper c func that calls a generic lua/c function. This causes lua complain about crossing c boundaries and it is for this reason that the debug hook with the yield has to be written in c and not lua.)
Also make sure that you use jit.off(sandboxedFunc,true) or you will run into problems as soon as luaJIT determines that sandboxedFunc needs to be compiled.
Here's the link: https://github.com/GoogleBot42/LuaJIT-Sandbox