LuaL_openlibs()和沙盒脚本

时间:2010-12-29 02:41:24

标签: c++ c lua

我在一个C / C ++应用程序中嵌入了Lua(5.1)。

我正在使用LuaL_openlibs()函数来加载基础库。但是,此函数会加载一些我想要禁用的其他库,以便它们不能用于我的Lua脚本。

具体来说,我想禁用IO和OS模块。是否有一个函数可以调用程序来禁用(或卸载)这些模块,以便我可以创建一个安全的沙箱环境来运行Lua脚本?

5 个答案:

答案 0 :(得分:13)

luaL_openlibs只是遍历在同一文件中声明的库加载器列表。只需删除/注释掉luaopen_ioluaopen_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);
  }
}

答案 1 :(得分:9)

最简单的解决方案:加载库后只需io=nil;os=nil

答案 2 :(得分:8)

我不知道如何禁用模块,但您仍然可以选择加载哪些模块而不是使用luaL_openlibs加载它们。 Section 7.3 of the Lua 5.1 manual说:

  

luaopen_*函数(打开库)不能像常规C函数那样直接调用。必须通过Lua调用它们,就像Lua函数一样。

也就是说,而不是直接调用Lua 5.0中的函数:

luaopen_table(L);

...你把它作为一个带有名字的C函数推送,并在Lua 5.1中使用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

答案 3 :(得分:0)

在旧版本的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

HTH

答案 4 :(得分:0)

也在这里重复我的answer to another question

从Lua 5.3开始,您需要根据luaL_openlibs中的源代码来luaL_requiref。我发现在任何手册中都没有提到它。因此,这是一个仅打开基本库的示例,该库允许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 );

另请参阅the manual