forked from Mirrorlandia_minetest/minetest
Isolate library tables between sandbox and insecure env
This commit is contained in:
parent
52c0384bd1
commit
623f0a8613
@ -45,6 +45,21 @@ static inline void copy_safe(lua_State *L, const char *list[], unsigned len, int
|
||||
}
|
||||
}
|
||||
|
||||
static void shallow_copy_table(lua_State *L, int from=-2, int to=-1)
|
||||
{
|
||||
if (from < 0) from = lua_gettop(L) + from + 1;
|
||||
if (to < 0) to = lua_gettop(L) + to + 1;
|
||||
lua_pushnil(L);
|
||||
while (lua_next(L, from) != 0) {
|
||||
assert(lua_type(L, -1) != LUA_TTABLE);
|
||||
// duplicate key and value for lua_rawset
|
||||
lua_pushvalue(L, -2);
|
||||
lua_pushvalue(L, -2);
|
||||
lua_rawset(L, to);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
}
|
||||
|
||||
// Pushes the original version of a library function on the stack, from the old version
|
||||
static inline void push_original(lua_State *L, const char *lib, const char *func)
|
||||
{
|
||||
@ -83,7 +98,10 @@ void ScriptApiSecurity::initializeSecurity()
|
||||
"unpack",
|
||||
"_VERSION",
|
||||
"xpcall",
|
||||
// Completely safe libraries
|
||||
};
|
||||
static const char *whitelist_tables[] = {
|
||||
// These libraries are completely safe BUT we need to duplicate their table
|
||||
// to ensure the sandbox can't affect the insecure env
|
||||
"coroutine",
|
||||
"string",
|
||||
"table",
|
||||
@ -167,6 +185,17 @@ void ScriptApiSecurity::initializeSecurity()
|
||||
lua_pop(L, 1);
|
||||
|
||||
|
||||
// Copy safe libraries
|
||||
for (const char *libname : whitelist_tables) {
|
||||
lua_getfield(L, old_globals, libname);
|
||||
lua_newtable(L);
|
||||
shallow_copy_table(L);
|
||||
|
||||
lua_setglobal(L, libname);
|
||||
lua_pop(L, 1);
|
||||
}
|
||||
|
||||
|
||||
// Copy safe IO functions
|
||||
lua_getfield(L, old_globals, "io");
|
||||
lua_newtable(L);
|
||||
@ -222,6 +251,19 @@ void ScriptApiSecurity::initializeSecurity()
|
||||
#endif
|
||||
|
||||
lua_pop(L, 1); // Pop globals_backup
|
||||
|
||||
|
||||
/*
|
||||
* In addition to copying the tables in whitelist_tables, we also need to
|
||||
* replace the string metatable. Otherwise old_globals.string would
|
||||
* be accessible via getmetatable("").__index from inside the sandbox.
|
||||
*/
|
||||
lua_pushliteral(L, "");
|
||||
lua_newtable(L);
|
||||
lua_getglobal(L, "string");
|
||||
lua_setfield(L, -2, "__index");
|
||||
lua_setmetatable(L, -2);
|
||||
lua_pop(L, 1); // Pop empty string
|
||||
}
|
||||
|
||||
void ScriptApiSecurity::initializeSecurityClient()
|
||||
|
Loading…
Reference in New Issue
Block a user