6 ms·
> Scripts should not be able to crash the system, run indefinitely, or corrupt other parts of the system. To ensure that, Lunatik uses the Lua VM facilities for
by pansa2 6y ago
> Scripts should not be able to crash the system, run indefinitely, or corrupt other parts of the system. To ensure that, Lunatik uses the Lua VM facilities for sandboxing the scripts so that they run in a safe execution environment [...] the number of instructions can be limited, so that infinite loops are not possible.
Lua's sandbox should be able to prevent scripts from crashing or corrupting the system, but I'd be surprised if it could prevent a script from running indefinitely. In particular, limiting the number of Lua bytecode instructions is insufficient - even a single call to `string.find` can lock up the CPU [0].
> They are using the standard Lua, rather than the LuaJIT fork, Neto said, in answer to another question.
Using LuaJIT would make sandboxing significantly more difficult, because it's much more complex than regular Lua and hence more likely to have exploitable bugs. This is the reason that game consoles disallow JIT-compilation - and hence games tend to use regular Lua rather than LuaJIT.
[0] http://lua-users.org/lists/lua-l/2011-02/msg01595.html http://lua-users.org/lists/lua-l/2011-02/msg01595.html
- brmgb 6y ago> In particular, limiting the number of Lua bytecode instructions is insufficient - even a single call to `string.find` can lock up the CPU [0]. At first glance, the second part of this sentence doesn't seem to support the initial premise. I am not too familiar with Lua bytecode but wouldn't "string.find" actually be compiled to multiple bytecode instructions ? Unless a single bytecode instruction can lock up the cpu, doing so would most likely require either looping or recursive calls. Thus, by puting a hard limit on the number of instructions the sandbox can execute, it would end up aborting.
- lmm 6y ago> I am not too familiar with Lua bytecode but wouldn't "string.find" actually be compiled to multiple bytecode instructions ? It's probably a single opcode of "invoke native-code standard-library function/intrinsic".
- pansa2 6y agoYes. `string.find` is implemented in C. Invoking it (no matter how complex its arguments) requires just a few bytecode instructions.
- brmgb 6y agoWell, then that's library dependent and not an intrinsic part of the language. So shipping Lua safely would mean having to swap or drop parts of the standard library for something a bit more robust. Apparently, that's what Lunatik does so the work seems to already have been done.
- anonymoushn 6y agoAppending strings together is a single bytecode instruction and this cannot really be fixed.
- 0x76 6y agoYou can't prevent infinite loops unless you've solved the halting problem right? They could of course just limit the run time if they really wanted to make sure scripts don't run indefinitely.
- deleted 6y ago[deleted]
- pansa2 6y ago> They could of course just limit the run time It seems as though this would be more robust than limiting the number of bytecode instructions. I wonder if that’s true and if so, why it’s not more commonly recommended.
- coldtea 6y ago>You can't prevent infinite loops unless you've solved the halting problem right? Only in general arbitrary turing complete runtimes. For restricted subsets of instructions and specific implementations of runtimes you can. E.g. one could trivially disallow "jump" control flow, and limit loops to N iterations.
- DarkWiiPlayer 6y agoIt's more simple than that: pull the plug on the entire turing machine. Lua runs in a VM, so you can stop it from the outside, which wouldn't be possible if the code was running directly in the CPU (Without an OS underneath it, that is).
- mikevin 6y agoYou could argue this doesn't really count as preventing though. It's preventing a symptom instead of the underlying problem.
- d33 6y agoePBF prevents infinite loops by restricting the language: https://lwn.net/Articles/794934/ https://lwn.net/Articles/794934/
- WalterGR 6y agoI'd be surprised if it could prevent a script from running indefinitely. In particular, limiting the number of Lua bytecode instructions is insufficient FTA: “Lua has a facility to interrupt a script after it has run a certain number of instructions.”
- OskarS 6y agostring.find is implemented in C, not Lua. As far as Lua is concerned, that call is a single instruction.
- DarkWiiPlayer 6y agoA single instruction that can run for a long time. That's the point.
- pctammela 6y agoditto for eBPF when acessing the C helpers
- dathinab 6y agoYou could have a string.find C implementation which gets an additional budget parameter and depending on it might limit search or similar (and reports back how much "budged" was used) Through always under the assumption that the C function is implemented correctly and adding need to do some explicit budged keeping makes it more complex and in turn more prone to errors.
- raverbashing 6y agoJust add a time limit to the sandbox as well
- lioeters 6y agoApparently, the sandbox cannot enforce such a time limit. From a similar thread to the one linked from the root comment: > ..Attempts to control untrusted scripts may be in vain. E.g. string.find, string.rep and other C functions can be abused and will either run forever or allocate unlimited amounts of memory. This is true for both Lua and LuaJIT. > The only reasonably safe way to handle untrusted Lua scripts is to isolate them in a process context and to make use of per-process quotas/limits provided by the operating system. Improved functions sandboxing in Lua and LuaJIT - http://lua-users.org/lists/lua-l/2011-02/msg01106.html http://lua-users.org/lists/lua-l/2011-02/msg01106.html
- DarkWiiPlayer 6y ago> This is the reason that game consoles disallow JIT-compilation - and hence games tend to use regular Lua rather than LuaJIT. You can disable the JIT in LuaJIT and still get better performance because it's a different implementation of the VM. > but I'd be surprised if it could prevent a script from running indefinitely. You'd have to patch the standard library a bit to avid things like `string.find` causing trouble, but as far as core Lua features go, yes, you can do that and all you need is to install a debug hook (Preferably from C, because performance, but you can even do this 100% from within Lua) ----- EDIT: Here's some benchmarks I did for this a while ago https://gist.github.com/DarkWiiPlayer/f639a38df53e39df63497cc18e8d0498 https://gist.github.com/DarkWiiPlayer/f639a38df53e39df63497c...