diff --git a/doc/manual/rl-next/checkSourcePath-purity-regression.md b/doc/manual/rl-next/checkSourcePath-purity-regression.md new file mode 100644 index 000000000..0d4ac48b7 --- /dev/null +++ b/doc/manual/rl-next/checkSourcePath-purity-regression.md @@ -0,0 +1,15 @@ +--- +synopsis: Forbid impure path accesses in pure evaluation mode again +category: Fixes +cls: [2708] +credits: [alois31] +--- +Lix 2.92.0 mistakenly started allowing the access to ancestors of allowed paths in pure evaluation mode. +This made it possible to bypass the purity restrictions, for example by copying arbitrary files to the store: +```nix +builtins.path { + path = "/"; + filter = …; +} +``` +Restore the previous behaviour of prohibiting such impure accesses. diff --git a/lix/libexpr/eval.cc b/lix/libexpr/eval.cc index ea493294b..211c1cb7e 100644 --- a/lix/libexpr/eval.cc +++ b/lix/libexpr/eval.cc @@ -464,6 +464,10 @@ retry: } current = std::move(next); } + // Downstream users (e.g. `builtins.readDir` or `builtins.path`) will want to descend. + if (level && !level->allowAllChildren) { + goto failed; + } resolvedPaths.insert_or_assign(path_.canonical().abs(), current); return current; diff --git a/tests/functional/pure-eval.sh b/tests/functional/pure-eval.sh index ace1db001..7940c43b7 100644 --- a/tests/functional/pure-eval.sh +++ b/tests/functional/pure-eval.sh @@ -18,6 +18,7 @@ echo "$missingImpureErrorMsg" | grepQuiet -- --impure || \ (! nix eval --expr builtins.currentSystem) (! nix-instantiate --pure-eval ./simple.nix) +(! nix eval --expr 'builtins.readDir "/"') [[ $(nix eval --impure --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x") == 123 ]] (! nix eval --expr "(import (builtins.fetchurl { url = \"file://$(pwd)/pure-eval.nix\"; })).x")