From 8bc76acc7c3665897a1b7e14574b379664f058d2 Mon Sep 17 00:00:00 2001 From: Robert Hensing Date: Sun, 29 Aug 2021 18:55:38 +0200 Subject: [PATCH] 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. --- src/libexpr/eval.hh | 1 + src/libexpr/flake/flake.cc | 10 ++++------ 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/libexpr/eval.hh b/src/libexpr/eval.hh index 6f3474854..22b0a584b 100644 --- a/src/libexpr/eval.hh +++ b/src/libexpr/eval.hh @@ -100,6 +100,7 @@ public: /* Store used to build stuff. */ const ref buildStore; + RootValue vCallFlake = nullptr; private: SrcToStore srcToStore; diff --git a/src/libexpr/flake/flake.cc b/src/libexpr/flake/flake.cc index 9e00ff188..ee345bdbc 100644 --- a/src/libexpr/flake/flake.cc +++ b/src/libexpr/flake/flake.cc @@ -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); }