LuaL_openlibs() 和脚本沙箱化。
我正在将 Lua (5.1) 嵌入到一个 C/C++ 应用程序中。
我使用 LuaL_openlibs()
函数来加载基本库。但是,这个函数加载了一些其他的库,我想要禁用它们,让它们对我的 Lua 脚本不可用。
具体来说,我想要禁用 IO 和 OS 模块。是否有一个函数可以调用,以编程方式禁用 (或卸载) 这些模块,以便我可以创建一个安全的沙盒环境来运行 Lua 脚本?
原文链接 https://stackoverflow.com/questions/4551101
我不知道如何禁用模块,但是你仍然可以选择加载哪些模块,而不是全部加载。Lua 5.1 手册中的第 7.3 节 说:
luaopen_*
函数(打开库函数)不能像普通的 C 函数一样直接调用,必须通过 Lua 调用,就像调用 Lua 函数一样。
也就是说,在 Lua 5.0 中,你可以直接调用函数,如下:
luaopen_table(L);
... 但在 Lua 5.1 中,你需要将它作为 C 函数压入堆栈并使用 lua_call
或类似函数调用:
lua_pushcfunction(L, luaopen_table);
lua_pushliteral(L, LUA_TABLIBNAME);
lua_call(L, 1, 0);
可以这样做的函数在 lualib.h
中列出:
Function | Name
----------------+-----------------
luaopen_base | ""
luaopen_table | LUA_TABLIBNAME
luaopen_io | LUA_IOLIBNAME
luaopen_os | LUA_OSLIBNAME
luaopen_string | LUA_STRLIBNAME
luaopen_math | LUA_MATHLIBNAME
luaopen_debug | LUA_DBLIBNAME
luaopen_package | LUA_LOADLIBNAME
luaL_openlibs
只是遍历在同一文件中声明的库加载器列表。只需删除/注释掉 luaopen_io
和 luaopen_os
行即可。完成。
如果不想编辑 Lua 源代码,那么可以定义自己的函数,将这两个库排除在外:
#define LUA_LIB
#include "lua.h"
#include "lualib.h"
#include "lauxlib.h"
static const luaL_Reg lualibs[] = {
{"", luaopen_base},
{LUA_LOADLIBNAME, luaopen_package},
{LUA_TABLIBNAME, luaopen_table},
{LUA_STRLIBNAME, luaopen_string},
{LUA_MATHLIBNAME, luaopen_math},
{LUA_DBLIBNAME, luaopen_debug},
{NULL, NULL}
};
LUALIB_API void my_openlibs (lua_State *L) {
const luaL_Reg *lib = lualibs;
for (; lib->func; lib++) {
lua_pushcfunction(L, lib->func);
lua_pushstring(L, lib->name);
lua_call(L, 1, 0);
}
}
所有解决方案中最简单的一个:只需在加载库后执行 io=nil;os=nil
。
重申我的回答另一个问题。
自Lua 5.3起,您需要luaL_requiref
这些内容,根据luaL_openlibs的源代码。我在任何手册中都没有找到有关此的参考资料。因此,这里是一个示例,仅打开了允许Lua向标准输出print
的基本库。
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
int main( int argc, char *argv[] ) {
lua_State *lua = luaL_newstate();
luaL_requiref( lua, "_G", luaopen_base, 1 );
lua_pop( lua, 1 );
luaL_dostring( lua, "print \"Hello, lua\"" );
lua_close( lua );
return 0;
}
例如,您可以像这样只加载除了base
之外的I/O库。
luaL_requiref( lua, LUA_IOLIBNAME, luaopen_io, 1 );
lua_pop( lua, 1 );
另请参见手册。
- 如何在roblox studio中1:1导入真实世界的地形?
- 求解,lua_resume的第二次调用继续执行协程问题。
- 【上海普陀区】内向猫网络招募【Skynet游戏框架Lua后端程序员】
- SF爱好求教:如何用lua实现游戏内调用数据库函数实现账号密码注册?
- Lua实现网站后台开发
- LUA错误显式返回,社区常见的规约是怎么样的
- lua5.3下载库失败
- 请问如何实现文本框内容和某个网页搜索框内容连接,并把网页输出来的结果反馈到另外一个文本框上
- lua lanes多线程使用
- 一个kv数据库
- openresty 有没有比较轻量的 docker 镜像
- 想问一下,有大佬用过luacurl吗
- 在Lua执行过程中使用Load函数出现问题
- 为什么 neovim 里没有显示一些特殊字符?
- Lua比较两个表的值(不考虑键的顺序)
- 有个lua简单的项目,外包,有意者加微信 liuheng600456详谈,最好在成都
- 如何在 Visual Studio 2022 中运行 Lua 代码?
- addEventListener 返回 nil Lua
- Lua中获取用户配置主目录的跨平台方法
- 如何编写 Lua 模式将字符串(嵌套数组)转换为真正的数组?
在早期版本的Lua中,你可以指定要加载哪些库。具体而言,在我的lualib.h副本中,我看到声明了以下函数:
LUALIB_API int (luaopen_base) (lua_State *L); LUALIB_API int (luaopen_table) (lua_State *L); LUALIB_API int (luaopen_io) (lua_State *L); LUALIB_API int (luaopen_os) (lua_State *L); LUALIB_API int (luaopen_string) (lua_State *L); LUALIB_API int (luaopen_math) (lua_State *L); LUALIB_API int (luaopen_debug) (lua_State *L); LUALIB_API int (luaopen_package) (lua_State *L); LUALIB_API void (luaL_openlibs) (lua_State *L);
我不知道不加载所有库的后果,因为我的代码中调用了luaL_openlibs()。《Lua编程第一版》可以在线获得,并提到luaL_openlibs()应该替换luaopen_*()函数调用。但是,为了向后兼容,旧的函数仍然可能包含在内。http://www.lua.org/pil/24.1.html
希望有所帮助。