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
|
// 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)
|
static inline void push_original(lua_State *L, const char *lib, const char *func)
|
||||||
{
|
{
|
||||||
@ -83,7 +98,10 @@ void ScriptApiSecurity::initializeSecurity()
|
|||||||
"unpack",
|
"unpack",
|
||||||
"_VERSION",
|
"_VERSION",
|
||||||
"xpcall",
|
"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",
|
"coroutine",
|
||||||
"string",
|
"string",
|
||||||
"table",
|
"table",
|
||||||
@ -167,6 +185,17 @@ void ScriptApiSecurity::initializeSecurity()
|
|||||||
lua_pop(L, 1);
|
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
|
// Copy safe IO functions
|
||||||
lua_getfield(L, old_globals, "io");
|
lua_getfield(L, old_globals, "io");
|
||||||
lua_newtable(L);
|
lua_newtable(L);
|
||||||
@ -222,6 +251,19 @@ void ScriptApiSecurity::initializeSecurity()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
lua_pop(L, 1); // Pop globals_backup
|
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()
|
void ScriptApiSecurity::initializeSecurityClient()
|
||||||
|
Loading…
Reference in New Issue
Block a user