LuaL_openlibs()和沙盒脚本

sky*_*gle 9 c c++ lua

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

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

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

Mud*_*Mud 15

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);
  }
}
Run Code Online (Sandbox Code Playgroud)


Tun*_*yen 9

我不知道如何禁用模块,但你仍然可以选择加载哪些模块而不是加载它们luaL_openlibs.Lua 5.1手册的7.3节说:

luaopen_*函数(以打开库)不能被直接调用,像一个普通的C函数.它们必须通过Lua调用,就像Lua函数一样.

也就是说,而不是像在Lua 5.0中那样直接调用函数:

luaopen_table(L);
Run Code Online (Sandbox Code Playgroud)

...你将它作为一个C函数推送,其名称和用途lua_call或类似于Lua 5.1:

lua_pushcfunction(L, luaopen_table);
lua_pushliteral(L, LUA_TABLIBNAME);
lua_call(L, 1, 0);
Run Code Online (Sandbox Code Playgroud)

您可以执行此操作的功能列在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
Run Code Online (Sandbox Code Playgroud)

  • 我应该指出,这是针对 lua 5.1 的,虽然它可能适用于 lua 5.2,但它不再是推荐的方式。最好的办法是查看 lua 发行版的 linit.c 文件,看看他们是如何做到的 (2认同)

jpj*_*obs 9

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

  • 这还不够,用户可以要求它们返回``io=require('io')``` (2认同)