diff options
author | sfan5 <sfan5@live.de> | 2021-12-17 19:04:46 +0100 |
---|---|---|
committer | sfan5 <sfan5@live.de> | 2021-12-18 20:37:13 +0100 |
commit | b2409b14d0682655363c1b3b3b6bafbaa7e7c1bf (patch) | |
tree | 03cb1bac4e9bbad1490c44b8ec2e361cb8d7ec27 /src/script/cpp_api | |
parent | f4054595482bf4573075f45d3ca56076a0d6113e (diff) | |
download | minetest-b2409b14d0682655363c1b3b3b6bafbaa7e7c1bf.tar.gz minetest-b2409b14d0682655363c1b3b3b6bafbaa7e7c1bf.tar.bz2 minetest-b2409b14d0682655363c1b3b3b6bafbaa7e7c1bf.zip |
Refactor trusted mod checking code
Diffstat (limited to 'src/script/cpp_api')
-rw-r--r-- | src/script/cpp_api/s_security.cpp | 33 | ||||
-rw-r--r-- | src/script/cpp_api/s_security.h | 14 |
2 files changed, 42 insertions, 5 deletions
diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 11c277839..ccd1214e3 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> @@ -604,6 +605,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) { diff --git a/src/script/cpp_api/s_security.h b/src/script/cpp_api/s_security.h index 73e763548..619bf824f 100644 --- a/src/script/cpp_api/s_security.h +++ b/src/script/cpp_api/s_security.h @@ -40,11 +40,6 @@ with this program; if not, write to the Free Software Foundation, Inc., class ScriptApiSecurity : virtual public ScriptApiBase { public: - int getThread(lua_State *L); - // creates an empty Lua environment - void createEmptyEnv(lua_State *L); - // sets the enviroment to the table thats on top of the stack - void setLuaEnv(lua_State *L, int thread); // Sets up security on the ScriptApi's Lua state void initializeSecurity(); void initializeSecurityClient(); @@ -57,8 +52,17 @@ public: // Checks if mods are allowed to read (and optionally write) to the path static bool checkPath(lua_State *L, const char *path, bool write_required, bool *write_allowed=NULL); + // Check if mod is whitelisted in the given setting + // This additionally checks that the mod's main file scope is executing. + static bool checkWhitelisted(lua_State *L, const std::string &setting); private: + int getThread(lua_State *L); + // sets the enviroment to the table thats on top of the stack + void setLuaEnv(lua_State *L, int thread); + // creates an empty Lua environment + void createEmptyEnv(lua_State *L); + // Syntax: "sl_" <Library name or 'g' (global)> '_' <Function name> // (sl stands for Secure Lua) |