@@ -246,15 +246,42 @@ EvalState::EvalState(
246246 , repair(NoRepair)
247247 , emptyBindings(0 )
248248 , rootFS(
249- settings.restrictEval || settings.pureEval
250- ? ref<SourceAccessor>(AllowListSourceAccessor::create(getFSSourceAccessor(), {},
251- [&settings](const CanonPath & path) -> RestrictedPathError {
252- auto modeInformation = settings.pureEval
253- ? " in pure evaluation mode (use '--impure' to override)"
254- : " in restricted mode" ;
255- throw RestrictedPathError (" access to absolute path '%1%' is forbidden %2%" , path, modeInformation);
256- }))
257- : getFSSourceAccessor())
249+ ({
250+ /* In pure eval mode, we provide a filesystem that only
251+ contains the Nix store.
252+
253+ If we have a chroot store and pure eval is not enabled,
254+ use a union accessor to make the chroot store available
255+ at its logical location while still having the
256+ underlying directory available. This is necessary for
257+ instance if we're evaluating a file from the physical
258+ /nix/store while using a chroot store. */
259+ auto accessor = getFSSourceAccessor ();
260+
261+ auto realStoreDir = dirOf (store->toRealPath (StorePath::dummy));
262+ if (settings.pureEval || store->storeDir != realStoreDir) {
263+ auto storeFS = makeMountedSourceAccessor (
264+ {
265+ {CanonPath::root, makeEmptySourceAccessor ()},
266+ {CanonPath (store->storeDir ), makeFSSourceAccessor (realStoreDir)}
267+ });
268+ accessor = settings.pureEval
269+ ? storeFS
270+ : makeUnionSourceAccessor ({accessor, storeFS});
271+ }
272+
273+ /* Apply access control if needed. */
274+ if (settings.restrictEval || settings.pureEval )
275+ accessor = AllowListSourceAccessor::create (accessor, {},
276+ [&settings](const CanonPath & path) -> RestrictedPathError {
277+ auto modeInformation = settings.pureEval
278+ ? " in pure evaluation mode (use '--impure' to override)"
279+ : " in restricted mode" ;
280+ throw RestrictedPathError (" access to absolute path '%1%' is forbidden %2%" , path, modeInformation);
281+ });
282+
283+ accessor;
284+ }))
258285 , corepkgsFS(make_ref<MemorySourceAccessor>())
259286 , internalFS(make_ref<MemorySourceAccessor>())
260287 , derivationInternal{corepkgsFS->addFile (
@@ -344,7 +371,7 @@ void EvalState::allowPath(const Path & path)
344371void EvalState::allowPath (const StorePath & storePath)
345372{
346373 if (auto rootFS2 = rootFS.dynamic_pointer_cast <AllowListSourceAccessor>())
347- rootFS2->allowPrefix (CanonPath (store->toRealPath (storePath)));
374+ rootFS2->allowPrefix (CanonPath (store->printStorePath (storePath)));
348375}
349376
350377void EvalState::allowClosure (const StorePath & storePath)
@@ -422,16 +449,6 @@ void EvalState::checkURI(const std::string & uri)
422449}
423450
424451
425- Path EvalState::toRealPath (const Path & path, const NixStringContext & context)
426- {
427- // FIXME: check whether 'path' is in 'context'.
428- return
429- !context.empty () && store->isInStore (path)
430- ? store->toRealPath (path)
431- : path;
432- }
433-
434-
435452Value * EvalState::addConstant (const std::string & name, Value & v, Constant info)
436453{
437454 Value * v2 = allocValue ();
@@ -2051,7 +2068,7 @@ void ExprConcatStrings::eval(EvalState & state, Env & env, Value & v)
20512068 else if (firstType == nPath) {
20522069 if (!context.empty ())
20532070 state.error <EvalError>(" a string that refers to a store path cannot be appended to a path" ).atPos (pos).withFrame (env, *this ).debugThrow ();
2054- v.mkPath (state.rootPath (CanonPath (canonPath ( str () ))));
2071+ v.mkPath (state.rootPath (CanonPath (str ())));
20552072 } else
20562073 v.mkStringMove (c_str (), context);
20572074}
@@ -2432,7 +2449,7 @@ SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext
24322449 auto path = coerceToString (pos, v, context, errorCtx, false , false , true ).toOwned ();
24332450 if (path == " " || path[0 ] != ' /' )
24342451 error<EvalError>(" string '%1%' doesn't represent an absolute path" , path).withTrace (pos, errorCtx).debugThrow ();
2435- return rootPath (CanonPath ( path) );
2452+ return rootPath (path);
24362453}
24372454
24382455
@@ -3086,7 +3103,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
30863103 fetchSettings,
30873104 EvalSettings::resolvePseudoUrl (value));
30883105 auto storePath = fetchToStore (*store, SourcePath (accessor), FetchMode::Copy);
3089- return finish (rootPath (store->toRealPath (storePath)));
3106+ return finish (rootPath (store->printStorePath (storePath)));
30903107 } catch (Error & e) {
30913108 logWarning ({
30923109 .msg = HintFmt (" Nix search path entry '%1%' cannot be downloaded, ignoring" , value)
0 commit comments