Skip to content

Commit

Permalink
Move vCallFlake into EvalState
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
roberth committed Aug 29, 2021
1 parent af94b54 commit 8bc76ac
Show file tree
Hide file tree
Showing 2 changed files with 5 additions and 6 deletions.
1 change: 1 addition & 0 deletions src/libexpr/eval.hh
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ public:
/* Store used to build stuff. */
const ref<Store> buildStore;

RootValue vCallFlake = nullptr;

private:
SrcToStore srcToStore;
Expand Down
10 changes: 4 additions & 6 deletions src/libexpr/flake/flake.cc
Original file line number Diff line number Diff line change
Expand Up @@ -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);
}
Expand Down

0 comments on commit 8bc76ac

Please sign in to comment.