Added a fix for the quota workaround

This commit is contained in:
PeAd 2022-04-25 16:52:05 +02:00
parent e04ddbe3ae
commit 161ad488da

View File

@ -153,19 +153,33 @@ function sandbox.protect(code, options)
return function(...) return function(...)
local queryInvoker = function(...) local tmp = table.pack(pcall(f, ...)); cleanup(); return tmp end;
if quota and quota_supported then if quota and quota_supported then
local timeout = function() local timeout = function()
cleanup() if(type(debug) == 'table' and type(debug.sethook) == 'function') then
-- If the function were to be using pcall, it may capture the error accidentally or intentionally.
-- This allows us to repeatedly invoke the hook on every instruction and only stop if the function
-- which is currently getting executed is our invoker.
-- This will NOT work properly if for whatever reason the sandbox got access to the sandbox.protect
-- as the function sets a new hook and never sets it back to the last one.
sethook( function()
local fn = debug.getinfo(2 , 'f').func;
if( fn ~= queryInvoker and fn ~= cleanup and not (fn == table.pack and debug.getinfo(3 , 'f').func == queryInvoker) ) then
error('Quota exceeded: ' .. tostring(quota)) error('Quota exceeded: ' .. tostring(quota))
else
cleanup();
end
end, "", 1)
end
error('Quota exceeded: ' .. tostring(quota));
end end
sethook(timeout, "", quota) sethook(timeout, "", quota)
end end
string.rep = nil -- luacheck: no global string.rep = nil -- luacheck: no global
local t = table.pack(pcall(f, ...)) local t = queryInvoker(...);
cleanup()
if not t[1] then error(t[2]) end if not t[1] then error(t[2]) end