diff options
author | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
---|---|---|
committer | Elias Fleckenstein <eliasfleckenstein@web.de> | 2022-05-17 22:12:00 +0200 |
commit | 21df26984da91143c15587f5a03c98d68c3adc4e (patch) | |
tree | aaa707a628ad331f67890023dffe1b4f60dd01d3 /src/script/cpp_api/s_security.cpp | |
parent | b09fc5de5cdb021f43ad32b7e3f50dc75c0bc622 (diff) | |
parent | eabf05758e3ba5f6f4bb1b8d1d1f02179b84e410 (diff) | |
download | dragonfireclient-21df26984da91143c15587f5a03c98d68c3adc4e.tar.xz |
Merge branch 'master' of https://github.com/minetest/minetest
Diffstat (limited to 'src/script/cpp_api/s_security.cpp')
-rw-r--r-- | src/script/cpp_api/s_security.cpp | 72 |
1 files changed, 66 insertions, 6 deletions
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index bd9c80e15..76509038f 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -27,6 +27,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #include <cerrno> #include <string> +#include <algorithm> #include <iostream> @@ -97,6 +98,7 @@ void ScriptApiSecurity::initializeSecurity() "type", "unpack", "_VERSION", + "vector", "xpcall", }; static const char *whitelist_tables[] = { @@ -106,6 +108,7 @@ void ScriptApiSecurity::initializeSecurity() "string", "table", "math", + "bit" }; static const char *io_whitelist[] = { "open", @@ -120,21 +123,17 @@ void ScriptApiSecurity::initializeSecurity() "date", "difftime", "getenv", - "setlocale", "time", - "tmpname", }; static const char *debug_whitelist[] = { "gethook", "traceback", "getinfo", "getmetatable", - "setupvalue", "setmetatable", "upvalueid", "sethook", "debug", - "setlocal", }; static const char *package_whitelist[] = { "config", @@ -220,6 +219,7 @@ void ScriptApiSecurity::initializeSecurity() // And replace unsafe ones SECURE_API(os, remove); SECURE_API(os, rename); + SECURE_API(os, setlocale); lua_setglobal(L, "os"); lua_pop(L, 1); // Pop old OS @@ -251,6 +251,15 @@ void ScriptApiSecurity::initializeSecurity() lua_pop(L, 1); // Pop old jit #endif + // Get rid of 'core' in the old globals, we don't want anyone thinking it's + // safe or even usable. + lua_pushnil(L); + lua_setfield(L, old_globals, "core"); + + // 'vector' as well. + lua_pushnil(L); + lua_setfield(L, old_globals, "vector"); + lua_pop(L, 1); // Pop globals_backup @@ -286,19 +295,21 @@ void ScriptApiSecurity::initializeSecurityClient() "rawset", "select", "setfenv", - // getmetatable can be used to escape the sandbox + // getmetatable can be used to escape the sandbox <- ??? "setmetatable", "tonumber", "tostring", "type", "unpack", "_VERSION", + "vector", "xpcall", // Completely safe libraries "coroutine", "string", "table", "math", + "bit", }; static const char *os_whitelist[] = { "clock", @@ -307,7 +318,7 @@ void ScriptApiSecurity::initializeSecurityClient() "time" }; static const char *debug_whitelist[] = { - "getinfo", + "getinfo", // used by builtin and unset before mods load "traceback" }; #if USE_LUAJIT @@ -607,6 +618,38 @@ bool ScriptApiSecurity::checkPath(lua_State *L, const char *path, return false; } +bool ScriptApiSecurity::checkWhitelisted(lua_State *L, const std::string &setting) +{ + assert(str_starts_with(setting, "secure.")); + + // We have to make sure that this function is being called directly by + // a mod, otherwise a malicious mod could override this function and + // steal its return value. + lua_Debug info; + + // Make sure there's only one item below this function on the stack... + if (lua_getstack(L, 2, &info)) + return false; + FATAL_ERROR_IF(!lua_getstack(L, 1, &info), "lua_getstack() failed"); + FATAL_ERROR_IF(!lua_getinfo(L, "S", &info), "lua_getinfo() failed"); + + // ...and that that item is the main file scope. + if (strcmp(info.what, "main") != 0) + return false; + + // Mod must be listed in secure.http_mods or secure.trusted_mods + lua_rawgeti(L, LUA_REGISTRYINDEX, CUSTOM_RIDX_CURRENT_MOD_NAME); + if (!lua_isstring(L, -1)) + return false; + std::string mod_name = readParam<std::string>(L, -1); + + std::string value = g_settings->get(setting); + value.erase(std::remove(value.begin(), value.end(), ' '), value.end()); + auto mod_list = str_split(value, ','); + + return CONTAINS(mod_list, mod_name); +} + int ScriptApiSecurity::sl_g_dofile(lua_State *L) { @@ -838,3 +881,20 @@ int ScriptApiSecurity::sl_os_remove(lua_State *L) return 2; } + +int ScriptApiSecurity::sl_os_setlocale(lua_State *L) +{ + const bool cat = lua_gettop(L) > 1; + // Don't allow changes + if (!lua_isnoneornil(L, 1)) { + lua_pushnil(L); + return 1; + } + + push_original(L, "os", "setlocale"); + lua_pushnil(L); + if (cat) + lua_pushvalue(L, 2); + lua_call(L, cat ? 2 : 1, 1); + return 1; +} |