lua-users home
lua-l archive

Re: Restricted parsing for static config files / more granular `load()` options for 5.4

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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

AltStyle によって変換されたページ (->オリジナル) /