我正在将Lua(5.1)嵌入到一个C/C++应用程序中。我使用LuaL_openlibs()函数来加载基本库。然而,这个函数加载了一些我想禁用的其他库,这样它们就不能用于我的Lua脚本了。具体来说,我想禁用IO和OS模块。有没有一个函数可以让我通过编程禁用(或卸载)这些模块,这样我就可以创建一个安全的沙箱环境来运行Lua脚本?
LuaL_openlibs()
wtlkbnrh1#
我不知道如何禁用模块,但您仍然可以选择加载哪些模块,而不是使用luaL_openlibs加载所有模块。Lua 5.1手册的第7.3节说:luaopen_*函数(用于打开库)不能像常规C函数那样直接调用。它们必须通过Lua调用,就像Lua函数一样。也就是说,不是像Lua 5.0中那样直接调用函数:
luaL_openlibs
luaopen_*
luaopen_table(L);
...你可以将它作为一个C函数使用它的名字,并在Lua 5.1中使用lua_call或类似的东西:
lua_call
lua_pushcfunction(L, luaopen_table); lua_pushliteral(L, LUA_TABLIBNAME); lua_call(L, 1, 0);
可以使用的函数在lualib.h中列出:
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
nx7onnlm2#
最简单的解决方案:在加载库后执行io=nil;os=nil。
io=nil;os=nil
6ioyuze23#
在旧版本的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.htmlHTH
ffscu2ro4#
我的answer to another question也在这里。从Lua 5.3开始,你需要luaL_requiref这些,基于luaL_openlibs中的源代码。我在任何手册中都没有找到这方面的参考资料。所以这里有一个例子,它只打开了允许lua到print到标准输出的基本库。
luaL_requiref
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库。
base
luaL_requiref( lua, LUA_IOLIBNAME, luaopen_io, 1 ); lua_pop( lua, 1 );
另请参阅手册。
tzcvj98z5#
我想指出的是,包库也应该被禁用。
package.loadlib("/usr/lib/liblua.so.5.1", "lua_call")()
将加载一个C函数,然后用不正确的参数调用它,从而导致segfault。这可能会导致比segfaults更大的问题
xzlaal3s6#
luaL_openlibs只是遍历在同一个文件中声明的库加载器列表。只需删除/注解掉luaopen_io和luaopen_os行。好了如果你不想编辑Lua源代码,那么你可以定义自己的函数,省去这两个库:
luaopen_io
luaopen_os
#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); } }
6条答案
按热度按时间wtlkbnrh1#
我不知道如何禁用模块,但您仍然可以选择加载哪些模块,而不是使用
luaL_openlibs
加载所有模块。Lua 5.1手册的第7.3节说:luaopen_*
函数(用于打开库)不能像常规C函数那样直接调用。它们必须通过Lua调用,就像Lua函数一样。也就是说,不是像Lua 5.0中那样直接调用函数:
...你可以将它作为一个C函数使用它的名字,并在Lua 5.1中使用
lua_call
或类似的东西:可以使用的函数在
lualib.h
中列出:nx7onnlm2#
最简单的解决方案:在加载库后执行
io=nil;os=nil
。6ioyuze23#
在旧版本的Lua中,您可以指定要加载哪些库。具体来说,在我的lualib. h副本中,我看到声明了以下函数:
我无法告诉您不加载所有库的后果,因为我在代码中调用了luaL_openlibs()。第一版的Lua编程可以在线获得,并提到luaL_openlibs()应该取代luaopen_*()函数调用。然而,为了向后兼容性,仍然可以包括较旧的函数。http://www.lua.org/pil/24.1.html
HTH
ffscu2ro4#
我的answer to another question也在这里。
从Lua 5.3开始,你需要
luaL_requiref
这些,基于luaL_openlibs中的源代码。我在任何手册中都没有找到这方面的参考资料。所以这里有一个例子,它只打开了允许lua到print
到标准输出的基本库。例如,除了
base
之外,您还可以像这样加载I/O库。另请参阅手册。
tzcvj98z5#
我想指出的是,包库也应该被禁用。
将加载一个C函数,然后用不正确的参数调用它,从而导致segfault。这可能会导致比segfaults更大的问题
xzlaal3s6#
luaL_openlibs
只是遍历在同一个文件中声明的库加载器列表。只需删除/注解掉luaopen_io
和luaopen_os
行。好了如果你不想编辑Lua源代码,那么你可以定义自己的函数,省去这两个库: