@@ -246,21 +246,37 @@ 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())
258- , storeFS(
259- makeMountedSourceAccessor (
260- {
261- {CanonPath::root, makeEmptySourceAccessor ()},
262- {CanonPath (store->storeDir ), makeFSSourceAccessor (dirOf (store->toRealPath (StorePath::dummy)))}
263- }))
249+ ({
250+ auto accessor = getFSSourceAccessor ();
251+
252+ /* If we have a chroot store, make a union accessor to
253+ make the chroot store available at its logical location
254+ while still having the underlying directory
255+ available. This is necessary for instance if we're
256+ evaluating a file from the physical /nix/store while
257+ using a chroot store. */
258+ auto realStoreDir = dirOf (store->toRealPath (StorePath::dummy));
259+ if (store->storeDir != realStoreDir) {
260+ auto storeFS = makeMountedSourceAccessor (
261+ {
262+ {CanonPath::root, makeEmptySourceAccessor ()},
263+ {CanonPath (store->storeDir ), makeFSSourceAccessor (realStoreDir)}
264+ });
265+ accessor = makeUnionSourceAccessor ({accessor, storeFS});
266+ }
267+
268+ /* Apply access control if needed. */
269+ if (settings.restrictEval || settings.pureEval )
270+ accessor = AllowListSourceAccessor::create (accessor, {},
271+ [&settings](const CanonPath & path) -> RestrictedPathError {
272+ auto modeInformation = settings.pureEval
273+ ? " in pure evaluation mode (use '--impure' to override)"
274+ : " in restricted mode" ;
275+ throw RestrictedPathError (" access to absolute path '%1%' is forbidden %2%" , path, modeInformation);
276+ });
277+
278+ accessor;
279+ }))
264280 , corepkgsFS(make_ref<MemorySourceAccessor>())
265281 , internalFS(make_ref<MemorySourceAccessor>())
266282 , derivationInternal{corepkgsFS->addFile (
@@ -350,7 +366,7 @@ void EvalState::allowPath(const Path & path)
350366void EvalState::allowPath (const StorePath & storePath)
351367{
352368 if (auto rootFS2 = rootFS.dynamic_pointer_cast <AllowListSourceAccessor>())
353- rootFS2->allowPrefix (CanonPath (store->toRealPath (storePath)));
369+ rootFS2->allowPrefix (CanonPath (store->printStorePath (storePath)));
354370}
355371
356372void EvalState::allowClosure (const StorePath & storePath)
@@ -2428,7 +2444,7 @@ SourcePath EvalState::coerceToPath(const PosIdx pos, Value & v, NixStringContext
24282444 auto path = coerceToString (pos, v, context, errorCtx, false , false , true ).toOwned ();
24292445 if (path == " " || path[0 ] != ' /' )
24302446 error<EvalError>(" string '%1%' doesn't represent an absolute path" , path).withTrace (pos, errorCtx).debugThrow ();
2431- return stringWithContextToPath (path, context );
2447+ return rootPath (path);
24322448}
24332449
24342450
@@ -3082,7 +3098,7 @@ std::optional<SourcePath> EvalState::resolveLookupPathPath(const LookupPath::Pat
30823098 fetchSettings,
30833099 EvalSettings::resolvePseudoUrl (value));
30843100 auto storePath = fetchToStore (*store, SourcePath (accessor), FetchMode::Copy);
3085- return finish (rootPath (store->toRealPath (storePath)));
3101+ return finish (rootPath (store->printStorePath (storePath)));
30863102 } catch (Error & e) {
30873103 logWarning ({
30883104 .msg = HintFmt (" Nix search path entry '%1%' cannot be downloaded, ignoring" , value)
0 commit comments