Lua沙箱技术求助:如何让沙箱代码调用自身自定义函数
沙箱无法调用自定义函数的修复方案
问题背景
练习25.8 图25.6《使用钩子阻止调用未授权函数》中的沙箱存在两个核心问题:
- 沙箱内代码无法调用自身定义的函数
- 提供的测试代码无法正常运行,无法将沙箱运行时的函数加入
validfunc授权表
当前代码的核心问题
- 授权时机错误:原代码在沙箱代码运行完成后才将
chunkEnv中的函数加入授权表,但运行时钩子已在执行检查,导致自定义函数调用直接报错 - 授权匹配逻辑错误:原代码用函数名作为
validfunc的key,但钩子检查的是函数对象本身,两者不匹配 - 变量作用域问题:钩子函数中局部
info变量未向外暴露,导致后续print操作出现nil错误 - 沙箱内代码冲突:测试文件中自行定义
hook函数并调用,会被主程序钩子拦截
修正后的主代码
local debug = require "debug" -- CPU步数限制 local steplimit = 1000 local count = 0 -- 授权函数表:存储函数对象而非名称 local validfunc = {} -- 提前授权必要的全局安全函数 validfunc[print] = true -- 钩子函数:检查调用权限 local function hook(event) local info if event == "call" then info = debug.getinfo(2, "fn") local func = info.func -- 检查是否已授权,或属于沙箱环境函数 if not validfunc[func] then local funcEnv = debug.getinfo(2, "f").env if funcEnv ~= chunkEnv then error("调用未授权函数: " .. (info.name or "匿名函数")) end -- 自动授权沙箱内定义的函数 validfunc[func] = true end end count = count + 1 if count > steplimit then error("脚本CPU占用超限") end -- 避免info为nil时的打印错误 if info then print(string.format('函数名:%s, 当前步数:%d', info.name or '匿名函数', count)) end end -- 加载沙箱脚本 local chunkEnv = setmetatable({}, { __index = _G }) local f, errorMsg = loadfile("test_lua_exercise_25_8.lua", "t", chunkEnv) if not f then error("加载脚本失败: " .. errorMsg) end -- 设置钩子 debug.sethook(hook, "c", 100) -- 运行沙箱(用pcall捕获错误便于调试) local success, err = pcall(f) if not success then print("沙箱运行错误:", err) end -- 关闭钩子 debug.sethook() -- 打印已授权函数 print("\n已授权函数列表:") for func, _ in pairs(validfunc) do local info = debug.getinfo(func, "fn") print(info.name or "匿名函数", func) end
修正后的沙箱测试代码(test_lua_exercise_25_8.lua)
-- 定义沙箱内的自定义函数 local function testFunc() print("沙箱内testFunc被调用") end -- 调用自定义函数 testFunc() -- 递归调用测试 local count = 0 local function loopFunc() count = count + 1 print("循环次数:", count) if count < 5 then loopFunc() end end loopFunc()
关键修复说明
- 匹配授权逻辑:
validfunc改为存储函数对象,与钩子中debug.getinfo返回的func直接匹配 - 动态授权沙箱函数:钩子中检查函数的环境,若属于沙箱的
chunkEnv则自动加入授权表,无需提前收集 - 修复变量作用域:统一
info变量的作用域,避免打印时出现nil错误 - 提前授权全局函数:将
print等必要全局函数加入授权表,防止沙箱内调用被拦截 - 错误捕获:用
pcall包裹沙箱运行,便于调试错误
内容的提问来源于stack exchange,提问作者kos
相关产品推荐
相关产品推荐

