1
0
Fork 0
mirror of https://github.com/luanti-org/luanti.git synced 2025-09-30 19:22:14 +00:00

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)
This commit is contained in:
Desour 2025-02-22 15:23:37 +01:00
parent 1e0d96af26
commit 6a360e507a
5 changed files with 34 additions and 2 deletions

View file

@ -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

View file

@ -12,6 +12,7 @@
#include "client/mod_vfs.h"
#endif
#include "settings.h"
#include "constants.h"
#include <cerrno>
#include <string>
@ -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<lua_Number>(t) / static_cast<lua_Number>(CLOCKS_PER_SEC));
return 1;
}

View file

@ -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);
};

View file

@ -30,6 +30,7 @@
#include "util/png.h"
#include "player.h"
#include "daynightratio.h"
#include "constants.h"
#include <cstdio>
// 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);

View file

@ -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);