[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: "Soni L." <fakedme@...>
- Date: Sun, 12 Mar 2017 16:33:21 -0300
On 12/03/17 04:16 PM, 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.
Bytecodes are not portable and a full parser is unnecessarily big if
the author just wants to block a few language constructs.
I am not sure how well a token parser would work, it is still too
complicated imo, even if it does not mean two parsers running at once
doing the same thing, it is still a pointless duplication of effort.
My solution would to add more option to the `load()` functions that
could manipulate what the parser should accept. The recursion problem
is a bit more difficult, based on my understanding of Lua, it would
either have to hook in at the compiler level, but that is only
feasible when recurring on locally defined functions, as expecting the
compiler to figure out if passing the local function to another would
mean that the other function would somehow call that first function
and end up in some weird recursion would be too much work (complex
graph analysis would have to be involved to make it correct).
So recursion is really best solved with `debug.sethook` and inspecting
each call event to determine if the function is already on the stack.
So, what are everyone's thoughts? Is this actually a problem in the wild?
I once used a deserializer to deserialize something like this:
local t = {}
local function _(wait, ...)
for i=1,wait do
t[#t+1]={}
end
t[#t+1]={...}
end
_(2,0,0)
_(2,0,0)
_(1,0,0,1,0,2,0)
-- etc
return t
Since I was serializing events(?) and I needed to do some minor
(de)compression for a few events here and there because of limited disk
space.
(It was so long ago that I actually forgot what it was for (or what the
code was). Oops.)
--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.