Skip to content

Commit 52f00a3

Browse files
committed
libexpr: add temp roots for external paths during evaluation
Protect store paths from previous sessions against concurrent GC by adding addTempRoot at consumption sites in import and the PackageInfo constructor. Current-session paths already have temp roots from writeDerivation.
1 parent 53ab737 commit 52f00a3

2 files changed

Lines changed: 12 additions & 1 deletion

File tree

src/libexpr/get-drvs.cc

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ PackageInfo::PackageInfo(EvalState & state, ref<Store> store, const std::string
2424

2525
this->drvPath = drvPath;
2626

27+
/* Prevent GC from deleting the .drv before we read it. This
28+
constructor is only called from CLI entry points (nix-build)
29+
where the path originates from a previous session, so it
30+
has no temp root from the current process. */
31+
store->addTempRoot(drvPath);
2732
auto drv = store->derivationFromPath(drvPath);
2833

2934
name = drvPath.name();

src/libexpr/primops.cc

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -306,8 +306,14 @@ static void import(EvalState & state, const PosIdx pos, Value & vPath, Value * v
306306
auto isValidDerivationInStore = [&]() -> std::optional<StorePath> {
307307
if (!state.store->isStorePath(path2))
308308
return std::nullopt;
309+
if (!isDerivation(path2))
310+
return std::nullopt;
309311
auto storePath = state.store->parseStorePath(path2);
310-
if (!(state.store->isValidPath(storePath) && isDerivation(path2)))
312+
/* Add a temp root before checking validity to prevent GC
313+
from deleting the path between our check and the
314+
subsequent readDerivation(). */
315+
state.store->addTempRoot(storePath);
316+
if (!state.store->isValidPath(storePath))
311317
return std::nullopt;
312318
return storePath;
313319
};

0 commit comments

Comments
 (0)