php: assert the security floor via config.assertions, not a module-level assert
The previous commit moved the CVE-2026-109618/109619 floor into a bare
`assert ... ; { ... }` above the module body. That breaks evaluation:
error: infinite recursion encountered
... while evaluating the module argument `pkgs` in
/nix/store/...-source/modules/php.nix
... noting that argument `pkgs` is not externally provided, so querying
`_module.args` instead, requiring `config`
A module-level assert is checked as soon as the module's attrset is forced
to WHNF, which the module system does while merging definitions (it is the
`checkUnmatched` branch in lib/modules.nix that was on the stack). At that
point `pkgs` is not an externally supplied argument — there are no
specialArgs here — so it resolves through `config._module.args.pkgs`
(lib/modules.nix:745), and that option lives in the same fixpoint that is
still being computed. Hence the loop. The old code never hit this because
`phpBase` was only forced from inside `options`/`config`, i.e. after the
fixpoint existed.
Move the check to `config.assertions`, which is evaluated inside the
fixpoint once `pkgs` is available. Behaviour is unchanged: a rolled-back
nixpkgs pin still fails the build with the floor message instead of
silently building a vulnerable PHP.
This commit is contained in:
1 parent
6151c78dc5
commit
9a4a4ee51a
1 file changed
+23
-6
+23
-6
@@ -103,12 +103,6 @@ let
|
||||
};
|
||||
in
|
||||
|
||||
assert lib.assertMsg (lib.versionAtLeast phpBase.version phpSecurityFloor) ''
|
||||
sovran_systemsOS: the pinned nixpkgs ships PHP ${phpBase.version}, below the
|
||||
security floor ${phpSecurityFloor} (CVE-2026-109618 / CVE-2026-109619).
|
||||
Update the nixpkgs input in flake.lock instead of pinning a version here.
|
||||
'';
|
||||
|
||||
{
|
||||
options.sovran_systemsOS.phpPackage = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
@@ -117,6 +111,29 @@ assert lib.assertMsg (lib.versionAtLeast phpBase.version phpSecurityFloor) ''
|
||||
};
|
||||
|
||||
config = {
|
||||
# Security floor. This has to live in `config.assertions`, NOT in a
|
||||
# module-level `assert` above the module body: a bare
|
||||
# `assert <cond>; { ... }` forces `phpBase` (and therefore `pkgs`) as
|
||||
# soon as the module's attrset is forced to WHNF, which happens while
|
||||
# the module system is still merging `_module.args`. `pkgs` is not an
|
||||
# externally supplied argument here, so it resolves through
|
||||
# `config._module.args.pkgs` (lib/modules.nix:745) — which requires
|
||||
# `config`, the very fixpoint being computed — giving
|
||||
# "error: infinite recursion encountered" pointing at modules/php.nix.
|
||||
# `config.assertions` is evaluated inside the fixpoint, once `pkgs`
|
||||
# exists, which is the supported way to assert on package versions.
|
||||
assertions = [
|
||||
{
|
||||
assertion = lib.versionAtLeast phpBase.version phpSecurityFloor;
|
||||
message = ''
|
||||
sovran_systemsOS: the pinned nixpkgs ships PHP ${phpBase.version},
|
||||
below the security floor ${phpSecurityFloor} (CVE-2026-109618 /
|
||||
CVE-2026-109619). Update the nixpkgs input in flake.lock instead
|
||||
of pinning a version in modules/php.nix.
|
||||
'';
|
||||
}
|
||||
];
|
||||
|
||||
users.users = {
|
||||
|
||||
php = {
|
||||
|
||||
Reference in new issue
Block a user