Protect mg_name and mg_flags from being set by Lua (#11010)

This commit is contained in:
sfan5 2021-03-04 20:38:28 +01:00 committed by GitHub
parent 5b42b5a8c2
commit ac8ac19169
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

@ -27,12 +27,36 @@ with this program; if not, write to the Free Software Foundation, Inc.,
#include "log.h" #include "log.h"
#define SET_SECURITY_CHECK(L, name) \ /* This protects:
if (o->m_settings == g_settings && ScriptApiSecurity::isSecure(L) && \ * 'secure.*' settings from being set
name.compare(0, 7, "secure.") == 0) { \ * some mapgen settings from being set
throw LuaError("Attempt to set secure setting."); \ * (not security-criticial, just to avoid messing up user configs)
*/
#define CHECK_SETTING_SECURITY(L, name) \
if (o->m_settings == g_settings) { \
if (checkSettingSecurity(L, name) == -1) \
return 0; \
} }
static inline int checkSettingSecurity(lua_State* L, const std::string &name)
{
if (ScriptApiSecurity::isSecure(L) && name.compare(0, 7, "secure.") == 0)
throw LuaError("Attempt to set secure setting.");
bool is_mainmenu = false;
#ifndef SERVER
is_mainmenu = ModApiBase::getGuiEngine(L) != nullptr;
#endif
if (!is_mainmenu && (name == "mg_name" || name == "mg_flags")) {
errorstream << "Tried to set global setting " << name << ", ignoring. "
"minetest.set_mapgen_setting() should be used instead." << std::endl;
infostream << script_get_backtrace(L) << std::endl;
return -1;
}
return 0;
}
LuaSettings::LuaSettings(Settings *settings, const std::string &filename) : LuaSettings::LuaSettings(Settings *settings, const std::string &filename) :
m_settings(settings), m_settings(settings),
m_filename(filename) m_filename(filename)
@ -130,6 +154,7 @@ int LuaSettings::l_get_np_group(lua_State *L)
return 1; return 1;
} }
// get_flags(self, key) -> table or nil
int LuaSettings::l_get_flags(lua_State *L) int LuaSettings::l_get_flags(lua_State *L)
{ {
NO_MAP_LOCK_REQUIRED; NO_MAP_LOCK_REQUIRED;
@ -162,7 +187,7 @@ int LuaSettings::l_set(lua_State* L)
std::string key = std::string(luaL_checkstring(L, 2)); std::string key = std::string(luaL_checkstring(L, 2));
const char* value = luaL_checkstring(L, 3); const char* value = luaL_checkstring(L, 3);
SET_SECURITY_CHECK(L, key); CHECK_SETTING_SECURITY(L, key);
if (!o->m_settings->set(key, value)) if (!o->m_settings->set(key, value))
throw LuaError("Invalid sequence found in setting parameters"); throw LuaError("Invalid sequence found in setting parameters");
@ -179,14 +204,14 @@ int LuaSettings::l_set_bool(lua_State* L)
std::string key = std::string(luaL_checkstring(L, 2)); std::string key = std::string(luaL_checkstring(L, 2));
bool value = readParam<bool>(L, 3); bool value = readParam<bool>(L, 3);
SET_SECURITY_CHECK(L, key); CHECK_SETTING_SECURITY(L, key);
o->m_settings->setBool(key, value); o->m_settings->setBool(key, value);
return 1; return 0;
} }
// set(self, key, value) // set_np_group(self, key, value)
int LuaSettings::l_set_np_group(lua_State *L) int LuaSettings::l_set_np_group(lua_State *L)
{ {
NO_MAP_LOCK_REQUIRED; NO_MAP_LOCK_REQUIRED;
@ -196,7 +221,7 @@ int LuaSettings::l_set_np_group(lua_State *L)
NoiseParams value; NoiseParams value;
read_noiseparams(L, 3, &value); read_noiseparams(L, 3, &value);
SET_SECURITY_CHECK(L, key); CHECK_SETTING_SECURITY(L, key);
o->m_settings->setNoiseParams(key, value); o->m_settings->setNoiseParams(key, value);
@ -211,7 +236,7 @@ int LuaSettings::l_remove(lua_State* L)
std::string key = std::string(luaL_checkstring(L, 2)); std::string key = std::string(luaL_checkstring(L, 2));
SET_SECURITY_CHECK(L, key); CHECK_SETTING_SECURITY(L, key);
bool success = o->m_settings->remove(key); bool success = o->m_settings->remove(key);
lua_pushboolean(L, success); lua_pushboolean(L, success);