From 6a360e507af492a32577d253d3e82053d06f97ce Mon Sep 17 00:00:00 2001 From: Desour Date: Sat, 22 Feb 2025 15:23:37 +0100 Subject: [PATCH] limit clock precision to 20 us 20 us was the value, firefox used as first response to the spectre attacks. now it's 100 us or 5 us, depending on whether it's "cross-origin isolated". we only have one origin, so choosing 20 us is probably fine, I guess see also: https://www.mozilla.org/en-US/security/advisories/mfsa2018-01/ https://developer.mozilla.org/en-US/docs/Web/API/Performance/now#security_requirements other clocks: * os.time() and os.date() only have seconds precision, AFAIK. * dtime is only given once per step, so it's not useful * there might be other ways to build clocks (if we get async envs for sscsm, with a busy loop, for example) --- src/constants.h | 4 ++++ src/script/cpp_api/s_security.cpp | 15 ++++++++++++++- src/script/cpp_api/s_security.h | 1 + src/script/lua_api/l_util.cpp | 13 ++++++++++++- src/script/lua_api/l_util.h | 3 +++ 5 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/constants.h b/src/constants.h index e97bd0507b..9f66b69f83 100644 --- a/src/constants.h +++ b/src/constants.h @@ -105,3 +105,7 @@ // The intent is to ensure that the rendering doesn't turn terribly blurry // when filtering is enabled. #define TEXTURE_FILTER_MIN_SIZE 192U + +// Resolution of clocks that SSCSM has access to, in us. +// Used as countermeasure against side-channel attacks. +#define SSCSM_CLOCK_RESOLUTION_US 20 diff --git a/src/script/cpp_api/s_security.cpp b/src/script/cpp_api/s_security.cpp index a1d4cc9bb7..f78c93de79 100644 --- a/src/script/cpp_api/s_security.cpp +++ b/src/script/cpp_api/s_security.cpp @@ -12,6 +12,7 @@ #include "client/mod_vfs.h" #endif #include "settings.h" +#include "constants.h" #include #include @@ -413,7 +414,6 @@ void ScriptApiSecurity::initializeSecuritySSCSM() "bit", }; static const char *os_whitelist[] = { - "clock", //TODO: limit resolution, to mitigate side channel attacks "date", "difftime", "time" @@ -463,6 +463,10 @@ void ScriptApiSecurity::initializeSecuritySSCSM() lua_getglobal(L, "os"); lua_newtable(L); copy_safe(L, os_whitelist, sizeof(os_whitelist)); + + // And replace unsafe ones + SECURE_API(os, clock); + lua_setfield(L, -3, "os"); lua_pop(L, 1); // Pop old OS @@ -1074,3 +1078,12 @@ int ScriptApiSecurity::sl_os_setlocale(lua_State *L) lua_call(L, cat ? 2 : 1, 1); return 1; } + + +int ScriptApiSecurity::sl_os_clock(lua_State *L) +{ + auto t = clock(); + t = t - t % (SSCSM_CLOCK_RESOLUTION_US * CLOCKS_PER_SEC / 1'000'000); + lua_pushnumber(L, static_cast(t) / static_cast(CLOCKS_PER_SEC)); + return 1; +} diff --git a/src/script/cpp_api/s_security.h b/src/script/cpp_api/s_security.h index 9d760ba530..d72612ffe1 100644 --- a/src/script/cpp_api/s_security.h +++ b/src/script/cpp_api/s_security.h @@ -117,4 +117,5 @@ private: static int sl_os_rename(lua_State *L); static int sl_os_remove(lua_State *L); static int sl_os_setlocale(lua_State *L); + static int sl_os_clock(lua_State *L); }; diff --git a/src/script/lua_api/l_util.cpp b/src/script/lua_api/l_util.cpp index cb16be4876..06f1a65ff8 100644 --- a/src/script/lua_api/l_util.cpp +++ b/src/script/lua_api/l_util.cpp @@ -30,6 +30,7 @@ #include "util/png.h" #include "player.h" #include "daynightratio.h" +#include "constants.h" #include // only available in zstd 1.3.5+ @@ -82,6 +83,16 @@ int ModApiUtil::l_get_us_time(lua_State *L) return 1; } +// get_us_time() for SSCSM +int ModApiUtil::l_get_us_time_sscsm(lua_State *L) +{ + NO_MAP_LOCK_REQUIRED; + auto t = porting::getTimeUs(); + t = t - t % SSCSM_CLOCK_RESOLUTION_US; + lua_pushnumber(L, t); + return 1; +} + // Maximum depth of a JSON object: // Reading and writing should not overflow the Lua, C, or jsoncpp stacks. constexpr static u16 MAX_JSON_DEPTH = 1024; @@ -802,7 +813,7 @@ void ModApiUtil::InitializeSSCSM(lua_State *L, int top) { API_FCT(log); - API_FCT(get_us_time); //TODO: is us to precise? + registerFunction(L, "get_us_time", l_get_us_time_sscsm, top); API_FCT(parse_json); API_FCT(write_json); diff --git a/src/script/lua_api/l_util.h b/src/script/lua_api/l_util.h index 3e1f6e0e32..90944b0de3 100644 --- a/src/script/lua_api/l_util.h +++ b/src/script/lua_api/l_util.h @@ -28,6 +28,9 @@ private: // get us precision time static int l_get_us_time(lua_State *L); + // get_us_time() for SSCSM. less precise + static int l_get_us_time_sscsm(lua_State *L); + // parse_json(str[, nullvalue]) static int l_parse_json(lua_State *L);