lua-users home
lua-l archive

[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