libexpr: fix accessing uninitialized values and fix pure-eval docs
We got UBSan working on Lix, so we of course immediately found a bug and some definitely nonsense behaviour. Accessing `pureEval` or `restrictEval` from a default setting value is nonsense, since they would never be actually set by the time that value is set so they are not going to do anything. The configuration is not applied in an initializer (and even if it were, it's not going to be in the right order). After looking into *that*, we hunted down what actually was applying these, since clearly this code did not do anything. The EvalState constructor should have a "search path added and removed here :)" sign on it, because that's where it is done. We added an explicit initialization of the optional in there because it was otherwise unclear why pureEval also has the search path to allowed paths setup code run. We then realized that the `pureEval` documentation was *also* bogus, and we rewrote it. In so doing, we realized that we forgot to file a bug to make `builtins.storePath` work in pure eval mode, so we filed one of those: https://git.lix.systems/lix-project/lix/issues/402 Yaks have been thoroughly shorn. UBSan report: ../src/libexpr/eval-settings.cc:66:10: runtime error: member call on address 0x752fa9a13060 which does not point to an object of type 'nix::BaseSetting<b ool>' 0x752fa9a13060: note: object has invalid vptr 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ^~~~~~~~~~~~~~~~~~~~~~~ invalid vptr 0 0x752fa95106a6 in nix::EvalSettings::getDefaultNixPath[abi:cxx11]() /home/jade/lix/lix2/build/src/libexpr/eval-settings.cc:66:10 1 0x752fa950e420 in nix::EvalSettings::EvalSettings() /home/jade/lix/lix2/build/src/libexpr/eval-settings.hh:36:15 2 0x752fa9469f1f in __cxx_global_var_init.50 /home/jade/lix/lix2/build/src/libexpr/eval-settings.cc:98:14 3 0x752fa9469f1f in _GLOBAL__sub_I_eval_settings.cc /home/jade/lix/lix2/build/src/libexpr/eval-settings.cc 4 0x752fabbd308d in call_init (/nix/store/k7zgvzp2r31zkg9xqgjim7mbknryv6bs-glibc-2.39-52/lib/ld-linux-x86-64.so.2+0x508d) (BuildId: a5b8228edc9f16078ac3c894af964eeb990ecb4c) 5 0x752fabbd317b in _dl_init (/nix/store/k7zgvzp2r31zkg9xqgjim7mbknryv6bs-glibc-2.39-52/lib/ld-linux-x86-64.so.2+0x517b) (BuildId: a5b8228edc9f16078ac3c894af964eeb990ecb4c) 6 0x752fabbe9c2f in _dl_start_user (/nix/store/k7zgvzp2r31zkg9xqgjim7mbknryv6bs-glibc-2.39-52/lib/ld-linux-x86-64.so.2+0x1bc2f) (BuildId: a5b8228edc9f16078ac3c894af964eeb990ecb4c) Change-Id: I5d8ffb7bfbe24b6584020ac74eed93d9f2e6d111
This commit is contained in:
parent
a960576f58
commit
1eef1927b6
4 changed files with 23 additions and 13 deletions
|
@ -63,11 +63,9 @@ Strings EvalSettings::getDefaultNixPath()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!evalSettings.restrictEval && !evalSettings.pureEval) {
|
add(getNixDefExpr() + "/channels");
|
||||||
add(getNixDefExpr() + "/channels");
|
add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
|
||||||
add(rootChannelsDir() + "/nixpkgs", "nixpkgs");
|
add(rootChannelsDir());
|
||||||
add(rootChannelsDir());
|
|
||||||
}
|
|
||||||
|
|
||||||
return res;
|
return res;
|
||||||
}
|
}
|
||||||
|
|
|
@ -75,8 +75,17 @@ struct EvalSettings : Config
|
||||||
R"(
|
R"(
|
||||||
Pure evaluation mode ensures that the result of Nix expressions is fully determined by explicitly declared inputs, and not influenced by external state:
|
Pure evaluation mode ensures that the result of Nix expressions is fully determined by explicitly declared inputs, and not influenced by external state:
|
||||||
|
|
||||||
- Restrict file system and network access to files specified by cryptographic hash
|
- File system and network access is restricted to accesses to immutable data only:
|
||||||
- Disable [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem) and [`builtins.currentTime`](@docroot@/language/builtin-constants.md#builtins-currentTime)
|
- Path literals relative to the home directory like `~/lix` are rejected at parse time.
|
||||||
|
- Access to absolute paths that did not result from Nix language evaluation is rejected when such paths are given as parameters to builtins like, for example, [`builtins.readFile`](@docroot@/language/builtins.md#builtins-readFile).
|
||||||
|
|
||||||
|
Access is nonetheless allowed to (absolute) paths in the Nix store that are returned by builtins like [`builtins.filterSource`](@docroot@/language/builtins.md#builtins-filterSource), [`builtins.fetchTarball`](@docroot@/language/builtins.md#builtins-fetchTarball) and similar.
|
||||||
|
- Impure fetches such as not specifying a commit ID for `builtins.fetchGit` or not specifying a hash for `builtins.fetchTarball` are rejected.
|
||||||
|
- In flakes, access to relative paths outside of the root of the flake's source tree (often, a git repository) is rejected.
|
||||||
|
- The evaluator ignores `NIX_PATH`, `-I` and the `nix-path` setting. Thus, [`builtins.nixPath`](@docroot@/language/builtin-constants.md#builtins-nixPath) is an empty list.
|
||||||
|
- The builtins [`builtins.currentSystem`](@docroot@/language/builtin-constants.md#builtins-currentSystem) and [`builtins.currentTime`](@docroot@/language/builtin-constants.md#builtins-currentTime) are absent from `builtins`.
|
||||||
|
- [`builtins.getEnv`](@docroot@/language/builtin-constants.md#builtins-currentSystem) always returns empty string for any variable.
|
||||||
|
- [`builtins.storePath`](@docroot@/language/builtins.md#builtins-storePath) throws an error (Lix may change this, tracking issue: <https://git.lix.systems/lix-project/lix/issues/402>)
|
||||||
)"
|
)"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -98,6 +107,7 @@ struct EvalSettings : Config
|
||||||
allowed to access `https://github.com/NixOS/patchelf.git`.
|
allowed to access `https://github.com/NixOS/patchelf.git`.
|
||||||
)"};
|
)"};
|
||||||
|
|
||||||
|
|
||||||
Setting<bool> traceFunctionCalls{this, false, "trace-function-calls",
|
Setting<bool> traceFunctionCalls{this, false, "trace-function-calls",
|
||||||
R"(
|
R"(
|
||||||
If set to `true`, the Nix evaluator will trace every function call.
|
If set to `true`, the Nix evaluator will trace every function call.
|
||||||
|
|
|
@ -418,7 +418,7 @@ EvalState::EvalState(
|
||||||
}
|
}
|
||||||
|
|
||||||
if (evalSettings.restrictEval || evalSettings.pureEval) {
|
if (evalSettings.restrictEval || evalSettings.pureEval) {
|
||||||
allowedPaths = PathSet();
|
allowedPaths = std::optional(PathSet());
|
||||||
|
|
||||||
for (auto & i : searchPath.elements) {
|
for (auto & i : searchPath.elements) {
|
||||||
auto r = resolveSearchPathPath(i.path);
|
auto r = resolveSearchPathPath(i.path);
|
||||||
|
|
|
@ -923,14 +923,15 @@ static RegisterPrimOp primop_getEnv({
|
||||||
.args = {"s"},
|
.args = {"s"},
|
||||||
.doc = R"(
|
.doc = R"(
|
||||||
`getEnv` returns the value of the environment variable *s*, or an
|
`getEnv` returns the value of the environment variable *s*, or an
|
||||||
empty string if the variable doesn’t exist. This function should be
|
empty string if the variable doesn't exist. This function should be
|
||||||
used with care, as it can introduce all sorts of nasty environment
|
used with care, as it can introduce all sorts of nasty environment
|
||||||
dependencies in your Nix expression.
|
dependencies in your Nix expression.
|
||||||
|
|
||||||
`getEnv` is used in Nix Packages to locate the file
|
`getEnv` is used in nixpkgs for evil impurities such as locating the file
|
||||||
`~/.nixpkgs/config.nix`, which contains user-local settings for Nix
|
`~/.config/nixpkgs/config.nix` which contains user-local settings for nixpkgs.
|
||||||
Packages. (That is, it does a `getEnv "HOME"` to locate the user’s
|
(That is, it does a `getEnv "HOME"` to locate the user's home directory.)
|
||||||
home directory.)
|
|
||||||
|
When in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval), this function always returns an empty string.
|
||||||
)",
|
)",
|
||||||
.fun = prim_getEnv,
|
.fun = prim_getEnv,
|
||||||
});
|
});
|
||||||
|
@ -1506,6 +1507,7 @@ static RegisterPrimOp primop_storePath({
|
||||||
in a new path (e.g. `/nix/store/ld01dnzc…-source-source`).
|
in a new path (e.g. `/nix/store/ld01dnzc…-source-source`).
|
||||||
|
|
||||||
Not available in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
Not available in [pure evaluation mode](@docroot@/command-ref/conf-file.md#conf-pure-eval).
|
||||||
|
Lix may change this, tracking issue: <https://git.lix.systems/lix-project/lix/issues/402>
|
||||||
|
|
||||||
See also [`builtins.fetchClosure`](#builtins-fetchClosure).
|
See also [`builtins.fetchClosure`](#builtins-fetchClosure).
|
||||||
)",
|
)",
|
||||||
|
|
Loading…
Reference in a new issue