Compare commits

...
4 Commits
Author SHA1 Message Date
naturallaw777 1ee932bcb2 chore(release): prepare v1.2.3 2026-10-27 06:21:32 -05:00
naturallaw777 9a4a4ee51a 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.
2026-10-26 21:27:00 -05:00
naturallaw777 6151c78dc5 php: drop duplicate filter-test backport that breaks the php-filter build
flake.lock pins nixpkgs a8e753600fb4, which already ships php85 8.5.12
(81513f3640) and upstream's `filter` test fix (a5fc1be5b6).  Both commits
are ancestors of the pin, so the local backport in this module was dead
weight at best:

  * pkgs/development/interpreters/php/default.nix at the pin already says
    php85 = 8.5.12, so the `lib.versionAtLeast` guard was never false and
    the `.override { version / phpSrc }` branch never ran;
  * pkgs/top-level/php-packages.nix at the pin already carries the
    oom_filter_*.phpt substitution.

patchFilterTests appended that same substituteInPlace a second time:

  --replace-fail "'-n'," "'-n', '-d', 'extension=$PWD/modules/filter.so',"

The replacement text still contains the `'-n',` it searches for, so the
second pass matched and injected the extension flag twice.  php-cgi then
emitted `Module "filter" is already loaded` (E_CORE_WARNING) into the
output the OOM tests capture, all three oom_filter_*.phpt failed against
their --EXPECTF-- section, `make test` exited non-zero and the builder
died with exit code 2:

  error: Cannot build '...-php-filter-8.5.12.drv'.
  Reason: builder failed with exit code 2.

which then cascaded into php-extra-init-8.5.12.ini, php-with-extensions
and man-paths ("1 dependency failed").

Use the stock pkgs.php85 and let nixpkgs own the extension patches.  The
CVE-2026-109618 / CVE-2026-109619 floor is kept, but as an assert, so a
rolled-back pin fails loudly instead of silently rebuilding a version
under another release's extension recipes.
2026-10-26 21:19:55 -05:00
naturallaw777 f9c12e0c41 updated nixpkgs with Bisq 1.10.10 2026-10-26 20:59:00 -05:00
5 changed files with 94 additions and 88 deletions

No files matched your search

+17
View File
@@ -7,6 +7,23 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
---
## [1.2.3] - 2026-10-27
### Added
- Php: assert the security floor via config.assertions, not a module-level assert
- Php: drop duplicate filter-test backport that breaks the php-filter build
- Php: fix the filter tests that break the 8.5.12 build
- Php: pin the shared interpreter to 8.5.12 for CVE-2026-109618/-109619
### Changed
- Updated nixpkgs
- Updated to Bisq 1.10.10
### Documentation
- Update changelog and versions with nixpkgs and matrix-synapse 1.163.0
[1.2.3]: https://git.sovransystems.com/Sovran_Systems/Sovran_SystemsOS/releases/tag/v1.2.3
## [1.2.2] - 2026-10-21
### Changed
+11 -11
View File
@@ -21,9 +21,9 @@ Lightning infrastructure, private cloud, and communications platform when you
are ready.
[Visit the Website](https://sovransystems.com) ·
[Download the ISO](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.2.iso) ·
[Download the ISO](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.3.iso) ·
[Try it safely in a VM](#try-it-first-in-a-virtual-machine) ·
[Verify the Download](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.2.iso.sha256) ·
[Verify the Download](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.3.iso.sha256) ·
[Build from Source](#build-from-source)
<img src="assets/desktop-screenshot.webp" alt="Sovran_SystemsOS private Bitcoin desktop" width="800" />
@@ -401,8 +401,8 @@ with an imaging application such as [Balena Etcher](https://etcher.balena.io).
### 1. Download the ISO and checksum
- [Download Sovran_SystemsOS-1.2.2.iso](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.2.iso)
- [Download Sovran_SystemsOS-1.2.2.iso.sha256](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.2.iso.sha256)
- [Download Sovran_SystemsOS-1.2.3.iso](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.3.iso)
- [Download Sovran_SystemsOS-1.2.3.iso.sha256](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.3.iso.sha256)
The download may take some time. Do not rename or modify the ISO before
verifying it, and keep both files in the same folder.
@@ -419,13 +419,13 @@ ISO must match the published one exactly.
Open a terminal in the download folder and run:
```bash
sha256sum --check Sovran_SystemsOS-1.2.2.iso.sha256
sha256sum --check Sovran_SystemsOS-1.2.3.iso.sha256
```
A successful comparison reports:
```text
Sovran_SystemsOS-1.2.2.iso: OK
Sovran_SystemsOS-1.2.3.iso: OK
```
</details>
@@ -436,11 +436,11 @@ Sovran_SystemsOS-1.2.2.iso: OK
Open Terminal in the download folder and run:
```bash
shasum -a 256 Sovran_SystemsOS-1.2.2.iso
shasum -a 256 Sovran_SystemsOS-1.2.3.iso
```
Compare the value shown in Terminal with the value inside
`Sovran_SystemsOS-1.2.2.iso.sha256`.
`Sovran_SystemsOS-1.2.3.iso.sha256`.
</details>
@@ -450,7 +450,7 @@ Compare the value shown in Terminal with the value inside
Open PowerShell in the download folder and run:
```powershell
Get-FileHash .\Sovran_SystemsOS-1.2.2.iso -Algorithm SHA256
Get-FileHash .\Sovran_SystemsOS-1.2.3.iso -Algorithm SHA256
```
Compare the value under `Hash` with the published checksum.
@@ -465,7 +465,7 @@ match exactly.
1. Download and install [Balena Etcher](https://etcher.balena.io), then
connect the USB drive.
2. Choose **Flash from file** and select `Sovran_SystemsOS-1.2.2.iso`.
2. Choose **Flash from file** and select `Sovran_SystemsOS-1.2.3.iso`.
3. Choose **Select target**, select the USB drive, and review your selection
carefully.
4. Choose **Flash** and wait for the writing and verification process to
@@ -883,7 +883,7 @@ primary location for collaboration. Please read our
## Privacy. Sovereignty. Bitcoin.
[Visit Sovran Systems](https://sovransystems.com) ·
[Download Sovran_SystemsOS](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.2.iso) ·
[Download Sovran_SystemsOS](https://downloads.sovransystems.com/Sovran_SystemsOS-1.2.3.iso) ·
[View the License](LICENSE)
</div>
+1 -1
View File
@@ -1 +1 @@
1.2.2
1.2.3
Generated
+12 -12
View File
@@ -5,11 +5,11 @@
"nixpkgs": "nixpkgs"
},
"locked": {
"lastModified": 1792500275,
"narHash": "sha256-Y86rSoq9EWo6538kYoWZCnH9+bl0jNS1vQrnNvm8znE=",
"lastModified": 1793024720,
"narHash": "sha256-BCWUWH/JIjBI6BlKp5FPYqE2gUNLo1o8kAjQyYy6bXs=",
"owner": "emmanuelrosa",
"repo": "btc-clients-nix",
"rev": "487c7e9ce3978601d37ac10b18610db672850f3b",
"rev": "ccc52fdce1278b4a5dcfa9685b7f31c5e9fecd9f",
"type": "github"
},
"original": {
@@ -41,11 +41,11 @@
},
"nixpkgs": {
"locked": {
"lastModified": 1792155732,
"narHash": "sha256-3Dk56anLQ1V1VklQFKFD6ul3cKQk40sThurHlPHIhOo=",
"lastModified": 1793022574,
"narHash": "sha256-YPCj3u7PtWJxdt+wI01foiGdNSPXA5z7O4Be9rMQS/8=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "7694c4f6b8537d50062ff36c21ef36de3c9322d7",
"rev": "a8e753600fb48f8f0dd882cc5ad284438241f85a",
"type": "github"
},
"original": {
@@ -56,11 +56,11 @@
},
"nixpkgs-stable": {
"locked": {
"lastModified": 1792503283,
"narHash": "sha256-vhe2jyvRCgufWPqDuDq1S3t3ypE+ka46IFutV02xKso=",
"lastModified": 1792898606,
"narHash": "sha256-Mg3rRjsbMqhSMxop5PYMXos8SwAjejrxSgVThTvP9eg=",
"owner": "nixos",
"repo": "nixpkgs",
"rev": "cd4ea8d57de16f4810bc5f14207bac45fbf19f67",
"rev": "1f607aa79b6356ed45d3cd3c8079c196e79efa2c",
"type": "github"
},
"original": {
@@ -72,11 +72,11 @@
},
"nixpkgs_2": {
"locked": {
"lastModified": 1792502884,
"narHash": "sha256-IoNisKcGbUjdd45qCqywGMCYmZ5EnkxezvLII0FWwNA=",
"lastModified": 1792773339,
"narHash": "sha256-rZLrzrC6i+jnTAlvPZHogKDulY7WWDEv9hJeHieO7Zw=",
"owner": "NixOS",
"repo": "nixpkgs",
"rev": "02c087f3fe673c9e317f206a627cb6b910336dbe",
"rev": "3ec636362e1816bc2f0888fa0fa2c69f1bc9e504",
"type": "github"
},
"original": {
+53 -64
View File
@@ -16,8 +16,8 @@
# • PHP 8.3 has been security-only since 2025-12-31; PHP 8.4 leaves active
# support on 2026-12-31; PHP 8.5 is actively supported until 2027-12-31.
#
# To fall back to PHP 8.4 (nixpkgs' current default `pkgs.php`) change only
# the `phpBase` line below.
# To fall back to PHP 8.4, change only the `phpBase` line below (and drop the
# security floor to the matching 8.4.x release).
#
# Security floor (October 2026):
# CVE-2026-109618 (RCE via OOM corruption) and CVE-2026-109619 (RCE via
@@ -25,78 +25,45 @@
# CVSS v4.0 9.2 each, fixed in 8.5.12 / 8.4.27 / 8.3.36 / 8.2.35 on
# 2026-10-21. PHP-FPM is named as susceptible in both advisories, so the
# pools below are in scope; updating is the only complete mitigation.
# nixpkgs bumped php85 in 81513f364091c759812f716cef3c175109d07342 the same
# day, but the nixpkgs revision this flake pins predates it, so the floor is
# enforced here. Once flake.lock is at or past that commit the `else`
# branch below stops being taken and can be deleted.
#
# nixpkgs bumped php85 to 8.5.12 in 81513f364091c759812f716cef3c175109d07342
# and fixed the `filter` extension tests in
# a5fc1be5b6c2d0c934143b57363aef9a15cce508. flake.lock pins nixpkgs
# a8e753600fb48f8f0dd882cc5ad284438241f85a, which is *after* both of them
# (verified: pkgs/development/interpreters/php/default.nix at that rev says
# php85 = 8.5.12, and pkgs/top-level/php-packages.nix already carries the
# oom_filter_*.phpt patch). So the stock package is used as-is and the
# floor below is only an assertion that catches a rolled-back pin.
#
# Do NOT re-apply the `filter` test fix locally. It uses
# --replace-fail "'-n'," "'-n', '-d', 'extension=$PWD/modules/filter.so',"
# and the replacement text still contains the `'-n',` it searches for, so a
# second application silently injects `-d extension=.../filter.so` twice.
# PHP then emits `Module "filter" is already loaded` (Zend/zend_API.c,
# E_CORE_WARNING) into the php-cgi output the tests capture, all three
# oom_filter_*.phpt fail on the unexpected line, `make test` exits non-zero
# and the builder dies with exit code 2 — the exact failure the patch was
# meant to prevent.
let
# The first 8.5.x release that carries the fixes above. Bump only upward.
phpSecurityFloor = "8.5.12";
# php-8.5.12.tar.bz2, the same artifact and URL shape nixpkgs' own
# generic.nix fetches. Verified against php.net on 2026-10-23.
phpSourceHash = "sha256-/7YO3EN87WO1E35JhNs3moERxQBJxxFRDYuVgnfvwag=";
# `.override` (not `overrideAttrs`) on purpose: php85 is a `makeOverridable`
# buildEnv, so this threads `version`/`phpSrc` into generic.nix while
# keeping the default extension set. `overrideAttrs` would keep the new
# source but drop the extension set, which would silently strip gd, intl,
# pdo_pgsql and friends out of the pools below.
phpBase =
if lib.versionAtLeast pkgs.php85.version phpSecurityFloor then
pkgs.php85
else
pkgs.php85.override {
version = phpSecurityFloor;
phpSrc = pkgs.fetchurl {
url = "https://www.php.net/distributions/php-${phpSecurityFloor}.tar.bz2";
hash = phpSourceHash;
};
};
# Stock nixpkgs package: correct version, correct extension recipes and
# upstream's own test fixes. `.override { version = ...; phpSrc = ...; }`
# is deliberately *not* used here — rewriting the version while keeping the
# extension recipes of another release is how you end up with test (or
# ABI) failures that look like packaging bugs.
phpBase = pkgs.php85;
custom-php = phpBase.buildEnv {
# `enabled` is nixpkgs' default extension set. It already contains every
# module Nextcloud lists as required or recommended (ctype, curl, dom,
# fileinfo, gd, intl, mbstring, openssl, posix, session, simplexml,
# xmlreader, xmlwriter, zip, zlib, pdo_pgsql, pdo_mysql, bcmath, gmp,
# exif, sodium, sysvsem, pcntl, ...). OPcache is compiled into PHP >= 8.5
# and no longer appears as a separate extension.
extensions = { enabled, all }:
let
# nixpkgs builds PHP with `--disable-all` and every extension as a
# shared module. Three of the OOM regression tests shipped with
# 8.5.12 spawn `php-cgi -n` on purpose — no php.ini, so no shared
# module, so filter_input() is never defined and the request never
# reaches the code under test. php-filter's `make test` then fails
# with "doesn't reach hard limit" for oom_filter_input,
# oom_filter_input_array and oom_filter_default_encoded, and the
# whole system build stops there.
#
# Upstream nixpkgs fixes this in a5fc1be5b6 ("php: fix `filter`
# tests"), shipped alongside the 8.5.12 bump. This lock predates
# it, so apply the same substitution here; drop this once flake.lock
# is past a5fc1be5b6, since the two would otherwise both patch.
#
# Done by rewriting the filter derivation in the extension list
# rather than through buildEnv's `packageOverrides`: that argument
# only reaches the unwrapped PHP, while the extension set is folded
# from mkPhp's own packageOverrides, so it is silently ignored here.
patchFilterTests = ext:
if (ext.extensionName or "") != "filter" then
ext
else
ext.overrideAttrs (prevAttrs: {
postConfigure = (prevAttrs.postConfigure or "") + ''
substituteInPlace \
tests/oom_filter_input.phpt \
tests/oom_filter_input_array.phpt \
tests/oom_filter_default_encoded.phpt \
--replace-fail "'-n'," "'-n', '-d', 'extension=$PWD/modules/filter.so',"
'';
});
in
map patchFilterTests enabled ++ (with all; [
# exif, sodium, sysvsem, pcntl, filter, ...). OPcache is compiled into
# PHP >= 8.5 and no longer appears as a separate extension.
extensions = { enabled, all }: enabled ++ (with all; [
bz2 # Nextcloud: bz2 archive support
apcu # Nextcloud: memcache.local (apc.enable_cli=1 below is mandatory for occ + cron)
redis # Nextcloud: memcache.distributed / file locking once a Redis server is configured
@@ -144,6 +111,29 @@ in
};
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 = {
@@ -163,4 +153,3 @@ in
];
};
}