Move vCallFlake into EvalState

This fixes a use-after-free bug:

1. s = new EvalState();
2. callFlake()
3. static vCallFlake now references s
4. delete s;
5. s2 = new EvalState();
6. callFlake()
7. static vCallFlake still references s
8. crash

Nix 2.3 did not have a problem with recreating EvalState.
This commit is contained in:
Robert Hensing 2021-08-29 18:55:38 +02:00
parent af94b54db3
commit 8bc76acc7c
2 changed files with 5 additions and 6 deletions

View file

@ -100,6 +100,7 @@ public:
/* Store used to build stuff. */
const ref<Store> buildStore;
RootValue vCallFlake = nullptr;
private:
SrcToStore srcToStore;

View file

@ -663,16 +663,14 @@ void callFlake(EvalState & state,
mkString(*vRootSubdir, lockedFlake.flake.lockedRef.subdir);
static RootValue vCallFlake = nullptr;
if (!vCallFlake) {
vCallFlake = allocRootValue(state.allocValue());
if (!state.vCallFlake) {
state.vCallFlake = allocRootValue(state.allocValue());
state.eval(state.parseExprFromString(
#include "call-flake.nix.gen.hh"
, "/"), **vCallFlake);
, "/"), **state.vCallFlake);
}
state.callFunction(**vCallFlake, *vLocks, *vTmp1, noPos);
state.callFunction(**state.vCallFlake, *vLocks, *vTmp1, noPos);
state.callFunction(*vTmp1, *vRootSrc, *vTmp2, noPos);
state.callFunction(*vTmp2, *vRootSubdir, vRes, noPos);
}