[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: Restricted parsing for static config files / more granular `load()` options for 5.4
- From: nobody <nobody+lua-list@...>
- Date: Mon, 13 Mar 2017 12:19:19 +0100
On 2017-03-12 20:16, Rain Gloom wrote:
> TLDR: just like we can disable bytecode loading, we should be able to
> disable certain language constructs, creating fully sandboxed configs
>
> The biggest problem that simple _ENV sandboxing can't avoid is
> infinitely long running code, one would need either the debug library to
> block a script after N instructions or use their own parser.
>
> In more detail, what can pose the biggest problems are loops and
> recursions. The latter can be hacked around with `debug.sethook` but
> loops require either bytecode inspection, a custom parser or a simple
> token based checking algorithm.
Both can be limited with debug.sethook. A while ago I wrote something
that (I think) catches everything that's relevant. Code is below,
longer explanation is at <http://stackoverflow.com/a/41945465/805875>.
(If there's a bug and this fails to fully sandbox & CPU limit the code,
please tell. I'd like my expectation & reality to match here...)
local function condfail( cond, ... )
if not cond then return nil, (...) end
return ...
end
function deserialize( str, vars )
-- create dummy environment
local env = vars and setmetatable( {}, {__index=vars} ) or {}
-- create function that returns deserialized value(s)
local f, _err = load( "return "..str, "=deserialize", "t", env )
if not f then return nil, _err end -- syntax error?
-- set up safe runner
local co = coroutine.create( f )
local hook = function( ) debug.sethook( co, error, "c", 1000000 ) end
debug.sethook( co, hook, "c" )
-- now run the deserialization
return condfail( coroutine.resume( co ) )
end
(As usual, code is public domain / CC0.)
-- nobody