diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index 834650fdc..fab1f09e3 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -378,6 +378,105 @@ void ScriptApiSecurity::initializeSecurityClient() setLuaEnv(L, thread); } +void ScriptApiSecurity::initializeSecuritySSCSM() +{ + static const char *whitelist[] = { + "assert", + "core", + "collectgarbage", + "DIR_DELIM", //TODO: useless? + "error", + "getfenv", + "ipairs", + "next", + "pairs", + "pcall", + "print", //TODO + "rawequal", + "rawget", + "rawset", + "select", + "setfenv", + "getmetatable", + "setmetatable", + "tonumber", + "tostring", + "type", + "unpack", //TODO: replace, because of UB in some lua versions + "_VERSION", + "xpcall", + // Completely safe libraries + "coroutine", + "string", + "table", + "math", + "bit", + }; + static const char *os_whitelist[] = { + "clock", //TODO: limit resolution, to mitigate side channel attacks + "date", + "difftime", + "time" + }; + +#if USE_LUAJIT + static const char *jit_whitelist[] = { + "arch", + "flush", + "off", + "on", + "opt", + "os", + "status", + "version", + "version_num", + }; +#endif + + m_secure = true; + + lua_State *L = getStack(); + int thread = getThread(L); + + // create an empty environment + createEmptyEnv(L); + + // Copy safe base functions + lua_getglobal(L, "_G"); + lua_getfield(L, -2, "_G"); + copy_safe(L, whitelist, sizeof(whitelist)); + + // And replace unsafe ones + SECURE_API(g, dofile); + SECURE_API(g, load); + SECURE_API(g, loadfile); + SECURE_API(g, loadstring); + SECURE_API(g, require); + lua_pop(L, 2); + + + + // Copy safe OS functions + lua_getglobal(L, "os"); + lua_newtable(L); + copy_safe(L, os_whitelist, sizeof(os_whitelist)); + lua_setfield(L, -3, "os"); + lua_pop(L, 1); // Pop old OS + + +#if USE_LUAJIT + // Copy safe jit functions, if they exist + lua_getglobal(L, "jit"); + lua_newtable(L); + copy_safe(L, jit_whitelist, sizeof(jit_whitelist)); + lua_setfield(L, -3, "jit"); + lua_pop(L, 1); // Pop old jit +#endif + + // Set the environment to the one we created earlier + setLuaEnv(L, thread); +} + #endif int ScriptApiSecurity::getThread(lua_State *L) @@ -775,10 +874,11 @@ int ScriptApiSecurity::sl_g_loadfile(lua_State *L) #if CHECK_CLIENT_BUILD() ScriptApiBase *script = ModApiBase::getScriptApiBase(L); - // Client implementation - if (script->getType() == ScriptingType::Client) { + // SSCSM & CPCSM implementation + if (script->getType() == ScriptingType::Client + || script->getType() == ScriptingType::SSCSM) { std::string path = readParam(L, 1); - const std::string *contents = script->getClient()->getModFile(path); + const std::string *contents = script->getClient()->getModFile(path); //TODO if (!contents) { std::string error_msg = "Couldn't find script called: " + path; lua_pushnil(L); diff --git a/src/script/cpp_api/s_security.h b/src/script/cpp_api/s_security.h index 1241b0b06..9d760ba53 100644 --- a/src/script/cpp_api/s_security.h +++ b/src/script/cpp_api/s_security.h @@ -31,8 +31,10 @@ public: void initializeSecurity(); #if CHECK_CLIENT_BUILD() void initializeSecurityClient(); + void initializeSecuritySSCSM(); #else - inline void initializeSecurityClient() { assert(0); } + void initializeSecurityClient() { assert(0); } + void initializeSecuritySSCSM() { assert(0); } #endif // Checks if the Lua state has been secured diff --git a/src/script/scripting_sscsm.cpp b/src/script/scripting_sscsm.cpp index 185047d68..287f79d6d 100644 --- a/src/script/scripting_sscsm.cpp +++ b/src/script/scripting_sscsm.cpp @@ -3,16 +3,36 @@ // SPDX-License-Identifier: LGPL-2.1-or-later #include "scripting_sscsm.h" +#include "cpp_api/s_internal.h" +#include "lua_api/l_sscsm.h" +// #include "lua_api/l_util.h" SSCSMScripting::SSCSMScripting(SSCSMEnvironment *env) : ScriptApiBase(ScriptingType::SSCSM) { setSSCSMEnv(env); - //TODO + SCRIPTAPI_PRECHECKHEADER + + initializeSecuritySSCSM(); + + lua_getglobal(L, "core"); + int top = lua_gettop(L); + + // Initialize our lua_api modules + initializeModApi(L, top); + lua_pop(L, 1); + + // Push builtin initialization type + lua_pushstring(L, "sscsm"); + lua_setglobal(L, "INIT"); + + // infostream << "SCRIPTAPI: Initialized SSCSM modules" << std::endl; } void SSCSMScripting::initializeModApi(lua_State *L, int top) { - //TODO + // Initialize mod API modules + // ModApiUtil::Initialize(L, top); + ModApiSSCSM::Initialize(L, top); }