Use a securely seeded global PRNG for the VM.

It's not 2005 anymore.
This commit is contained in:
Mike Pall
2020-06-15 12:21:05 +02:00
parent 34e53736c6
commit a44f53acf5
22 changed files with 411 additions and 174 deletions

View File

@@ -25,6 +25,7 @@
#include "lj_trace.h"
#include "lj_dispatch.h"
#include "lj_vm.h"
#include "lj_prng.h"
#include "lj_lex.h"
#include "lj_alloc.h"
#include "luajit.h"
@@ -185,16 +186,33 @@ static void close_state(lua_State *L)
}
#if LJ_64 && !LJ_GC64 && !(defined(LUAJIT_USE_VALGRIND) && defined(LUAJIT_USE_SYSMALLOC))
lua_State *lj_state_newstate(lua_Alloc f, void *ud)
lua_State *lj_state_newstate(lua_Alloc allocf, void *allocd)
#else
LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
LUA_API lua_State *lua_newstate(lua_Alloc allocf, void *allocd)
#endif
{
GG_State *GG = (GG_State *)f(ud, NULL, 0, sizeof(GG_State));
lua_State *L = &GG->L;
global_State *g = &GG->g;
PRNGState prng;
GG_State *GG;
lua_State *L;
global_State *g;
/* We need the PRNG for the memory allocator, so initialize this first. */
if (!lj_prng_seed_secure(&prng)) {
lj_assertX(0, "secure PRNG seeding failed");
/* Can only return NULL here, so this errors with "not enough memory". */
return NULL;
}
#ifndef LUAJIT_USE_SYSMALLOC
if (allocf == LJ_ALLOCF_INTERNAL) {
allocd = lj_alloc_create(&prng);
if (!allocd) return NULL;
allocf = lj_alloc_f;
}
#endif
GG = (GG_State *)allocf(allocd, NULL, 0, sizeof(GG_State));
if (GG == NULL || !checkptrGC(GG)) return NULL;
memset(GG, 0, sizeof(GG_State));
L = &GG->L;
g = &GG->g;
L->gct = ~LJ_TTHREAD;
L->marked = LJ_GC_WHITE0 | LJ_GC_FIXED | LJ_GC_SFIXED; /* Prevent free. */
L->dummy_ffid = FF_C;
@@ -202,8 +220,14 @@ LUA_API lua_State *lua_newstate(lua_Alloc f, void *ud)
g->gc.currentwhite = LJ_GC_WHITE0 | LJ_GC_FIXED;
g->strempty.marked = LJ_GC_WHITE0;
g->strempty.gct = ~LJ_TSTR;
g->allocf = f;
g->allocd = ud;
g->allocf = allocf;
g->allocd = allocd;
g->prng = prng;
#ifndef LUAJIT_USE_SYSMALLOC
if (allocf == lj_alloc_f) {
lj_alloc_setprng(allocd, &g->prng);
}
#endif
setgcref(g->mainthref, obj2gco(L));
setgcref(g->uvhead.prev, obj2gco(&g->uvhead));
setgcref(g->uvhead.next, obj2gco(&g->uvhead));