mirror of
https://github.com/NixOS/nix.git
synced 2025-11-23 02:39:37 +01:00
Mount allowed paths on storeFS with pure eval
No `AllowListSourceAccessor` for pure eval --- not needed anymore!
This commit is contained in:
parent
3bf1268ac6
commit
80edaab12f
2 changed files with 63 additions and 37 deletions
|
|
@ -213,8 +213,9 @@ EvalState::EvalState(
|
||||||
, settings{settings}
|
, settings{settings}
|
||||||
, symbols(StaticEvalSymbols::staticSymbolTable())
|
, symbols(StaticEvalSymbols::staticSymbolTable())
|
||||||
, repair(NoRepair)
|
, repair(NoRepair)
|
||||||
, storeFS(makeMountedSourceAccessor({
|
, storeFS([&] {
|
||||||
{CanonPath::root, makeEmptySourceAccessor()},
|
auto accessor = makeMountedSourceAccessor({{CanonPath::root, makeEmptySourceAccessor()}});
|
||||||
|
|
||||||
/* In the pure eval case, we can simply require
|
/* In the pure eval case, we can simply require
|
||||||
valid paths. However, in the *impure* eval
|
valid paths. However, in the *impure* eval
|
||||||
case this gets in the way of the union
|
case this gets in the way of the union
|
||||||
|
|
@ -233,15 +234,36 @@ EvalState::EvalState(
|
||||||
exception, and make union source accessor
|
exception, and make union source accessor
|
||||||
catch it, so we don't need to do this hack.
|
catch it, so we don't need to do this hack.
|
||||||
*/
|
*/
|
||||||
{CanonPath(store->storeDir), store->getFSAccessor(settings.pureEval)},
|
if (settings.pureEval) {
|
||||||
}))
|
/* This is just an overkill way to make sure other store
|
||||||
, rootFS([&] {
|
paths get this error, and not the "doesn't exist" error
|
||||||
auto accessor = [&]() -> decltype(rootFS) {
|
that the mounted source accessor would do on its own. */
|
||||||
|
accessor->mount(
|
||||||
|
CanonPath::root,
|
||||||
|
AllowListSourceAccessor::create(
|
||||||
|
getFSSourceAccessor(),
|
||||||
|
{},
|
||||||
|
{CanonPath::root, CanonPath(store->storeDir)},
|
||||||
|
[&](const CanonPath & path) -> RestrictedPathError {
|
||||||
|
throw RestrictedPathError(
|
||||||
|
"access to absolute path '%1%' is forbidden in pure evaluation mode (use '--impure' to override)",
|
||||||
|
CanonPath(store->storeDir) / path);
|
||||||
|
}));
|
||||||
|
/* We don't want to list store paths */
|
||||||
|
accessor->mount(CanonPath(store->storeDir), makeEmptySourceAccessor());
|
||||||
|
} else {
|
||||||
|
accessor->mount(CanonPath(store->storeDir), store->getFSAccessor(false));
|
||||||
|
}
|
||||||
|
|
||||||
|
return accessor;
|
||||||
|
}())
|
||||||
|
, rootFS([&] -> decltype(rootFS) {
|
||||||
/* In pure eval mode, we provide a filesystem that only
|
/* In pure eval mode, we provide a filesystem that only
|
||||||
contains the Nix store. */
|
contains the Nix store. */
|
||||||
if (settings.pureEval)
|
if (settings.pureEval)
|
||||||
return storeFS;
|
return storeFS;
|
||||||
|
|
||||||
|
auto makeImpureAccessor = [&]() -> decltype(rootFS) {
|
||||||
/* If we have a chroot store and pure eval is not enabled,
|
/* If we have a chroot store and pure eval is not enabled,
|
||||||
use a union accessor to make the chroot store available
|
use a union accessor to make the chroot store available
|
||||||
at its logical location while still having the underlying
|
at its logical location while still having the underlying
|
||||||
|
|
@ -253,18 +275,16 @@ EvalState::EvalState(
|
||||||
return makeUnionSourceAccessor({getFSSourceAccessor(), storeFS});
|
return makeUnionSourceAccessor({getFSSourceAccessor(), storeFS});
|
||||||
|
|
||||||
return getFSSourceAccessor();
|
return getFSSourceAccessor();
|
||||||
}();
|
};
|
||||||
|
|
||||||
/* Apply access control if needed. */
|
/* Apply access control if needed. */
|
||||||
if (settings.restrictEval || settings.pureEval)
|
if (settings.restrictEval)
|
||||||
accessor = AllowListSourceAccessor::create(
|
return AllowListSourceAccessor::create(
|
||||||
accessor, {}, {}, [&settings](const CanonPath & path) -> RestrictedPathError {
|
makeImpureAccessor(), {}, {}, [](const CanonPath & path) -> RestrictedPathError {
|
||||||
auto modeInformation = settings.pureEval ? "in pure evaluation mode (use '--impure' to override)"
|
throw RestrictedPathError("access to absolute path '%1%' is forbidden in restricted mode", path);
|
||||||
: "in restricted mode";
|
|
||||||
throw RestrictedPathError("access to absolute path '%1%' is forbidden %2%", path, modeInformation);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
return accessor;
|
return makeImpureAccessor();
|
||||||
}())
|
}())
|
||||||
, corepkgsFS(make_ref<MemorySourceAccessor>())
|
, corepkgsFS(make_ref<MemorySourceAccessor>())
|
||||||
, internalFS(make_ref<MemorySourceAccessor>())
|
, internalFS(make_ref<MemorySourceAccessor>())
|
||||||
|
|
@ -351,13 +371,19 @@ void EvalState::allowPathLegacy(const Path & path)
|
||||||
|
|
||||||
void EvalState::allowPath(const StorePath & storePath)
|
void EvalState::allowPath(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
if (auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
if (settings.pureEval) {
|
||||||
|
storeFS->mount(CanonPath(store->printStorePath(storePath)), ref{store->getFSAccessor(storePath)});
|
||||||
|
}
|
||||||
|
if (settings.restrictEval) {
|
||||||
|
auto rootFS2 = rootFS.dynamic_pointer_cast<AllowListSourceAccessor>();
|
||||||
|
assert(rootFS2);
|
||||||
rootFS2->allowPrefix(CanonPath(store->printStorePath(storePath)));
|
rootFS2->allowPrefix(CanonPath(store->printStorePath(storePath)));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void EvalState::allowClosure(const StorePath & storePath)
|
void EvalState::allowClosure(const StorePath & storePath)
|
||||||
{
|
{
|
||||||
if (!rootFS.dynamic_pointer_cast<AllowListSourceAccessor>())
|
if (!settings.pureEval && !settings.restrictEval)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
StorePathSet closure;
|
StorePathSet closure;
|
||||||
|
|
|
||||||
|
|
@ -65,7 +65,7 @@ traverseDir="${_NIX_TEST_SOURCE_DIR}/restricted-traverse-me"
|
||||||
ln -sfn "${_NIX_TEST_SOURCE_DIR}/restricted-secret" "${_NIX_TEST_SOURCE_DIR}/restricted-innocent"
|
ln -sfn "${_NIX_TEST_SOURCE_DIR}/restricted-secret" "${_NIX_TEST_SOURCE_DIR}/restricted-innocent"
|
||||||
mkdir -p "$traverseDir"
|
mkdir -p "$traverseDir"
|
||||||
goUp="..$(echo "$traverseDir" | sed -e 's,[^/]\+,..,g')"
|
goUp="..$(echo "$traverseDir" | sed -e 's,[^/]\+,..,g')"
|
||||||
output="$(nix eval --raw --restrict-eval -I "$traverseDir" \
|
output="$(nix eval --raw --impure --restrict-eval -I "$traverseDir" \
|
||||||
--expr "builtins.readFile \"$traverseDir/$goUp${_NIX_TEST_SOURCE_DIR}/restricted-innocent\"" \
|
--expr "builtins.readFile \"$traverseDir/$goUp${_NIX_TEST_SOURCE_DIR}/restricted-innocent\"" \
|
||||||
2>&1 || :)"
|
2>&1 || :)"
|
||||||
echo "$output" | grep "is forbidden"
|
echo "$output" | grep "is forbidden"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue