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.
This commit is contained in:
1 parent
f9c12e0c41
commit
6151c78dc5
1 file changed
+36
-64
+36
-64
@@ -16,8 +16,8 @@
|
|||||||
# • PHP 8.3 has been security-only since 2025-12-31; PHP 8.4 leaves active
|
# • 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.
|
# 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
|
# To fall back to PHP 8.4, change only the `phpBase` line below (and drop the
|
||||||
# the `phpBase` line below.
|
# security floor to the matching 8.4.x release).
|
||||||
#
|
#
|
||||||
# Security floor (October 2026):
|
# Security floor (October 2026):
|
||||||
# CVE-2026-109618 (RCE via OOM corruption) and CVE-2026-109619 (RCE via
|
# 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
|
# 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
|
# 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.
|
# 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
|
# nixpkgs bumped php85 to 8.5.12 in 81513f364091c759812f716cef3c175109d07342
|
||||||
# enforced here. Once flake.lock is at or past that commit the `else`
|
# and fixed the `filter` extension tests in
|
||||||
# branch below stops being taken and can be deleted.
|
# 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
|
let
|
||||||
# The first 8.5.x release that carries the fixes above. Bump only upward.
|
# The first 8.5.x release that carries the fixes above. Bump only upward.
|
||||||
phpSecurityFloor = "8.5.12";
|
phpSecurityFloor = "8.5.12";
|
||||||
|
|
||||||
# php-8.5.12.tar.bz2, the same artifact and URL shape nixpkgs' own
|
# Stock nixpkgs package: correct version, correct extension recipes and
|
||||||
# generic.nix fetches. Verified against php.net on 2026-10-23.
|
# upstream's own test fixes. `.override { version = ...; phpSrc = ...; }`
|
||||||
phpSourceHash = "sha256-/7YO3EN87WO1E35JhNs3moERxQBJxxFRDYuVgnfvwag=";
|
# is deliberately *not* used here — rewriting the version while keeping the
|
||||||
|
# extension recipes of another release is how you end up with test (or
|
||||||
# `.override` (not `overrideAttrs`) on purpose: php85 is a `makeOverridable`
|
# ABI) failures that look like packaging bugs.
|
||||||
# buildEnv, so this threads `version`/`phpSrc` into generic.nix while
|
phpBase = pkgs.php85;
|
||||||
# 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;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
|
|
||||||
custom-php = phpBase.buildEnv {
|
custom-php = phpBase.buildEnv {
|
||||||
# `enabled` is nixpkgs' default extension set. It already contains every
|
# `enabled` is nixpkgs' default extension set. It already contains every
|
||||||
# module Nextcloud lists as required or recommended (ctype, curl, dom,
|
# module Nextcloud lists as required or recommended (ctype, curl, dom,
|
||||||
# fileinfo, gd, intl, mbstring, openssl, posix, session, simplexml,
|
# fileinfo, gd, intl, mbstring, openssl, posix, session, simplexml,
|
||||||
# xmlreader, xmlwriter, zip, zlib, pdo_pgsql, pdo_mysql, bcmath, gmp,
|
# xmlreader, xmlwriter, zip, zlib, pdo_pgsql, pdo_mysql, bcmath, gmp,
|
||||||
# exif, sodium, sysvsem, pcntl, ...). OPcache is compiled into PHP >= 8.5
|
# exif, sodium, sysvsem, pcntl, filter, ...). OPcache is compiled into
|
||||||
# and no longer appears as a separate extension.
|
# PHP >= 8.5 and no longer appears as a separate extension.
|
||||||
extensions = { enabled, all }:
|
extensions = { enabled, all }: enabled ++ (with 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; [
|
|
||||||
bz2 # Nextcloud: bz2 archive support
|
bz2 # Nextcloud: bz2 archive support
|
||||||
apcu # Nextcloud: memcache.local (apc.enable_cli=1 below is mandatory for occ + cron)
|
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
|
redis # Nextcloud: memcache.distributed / file locking once a Redis server is configured
|
||||||
@@ -136,6 +103,12 @@ let
|
|||||||
};
|
};
|
||||||
in
|
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 {
|
options.sovran_systemsOS.phpPackage = lib.mkOption {
|
||||||
type = lib.types.package;
|
type = lib.types.package;
|
||||||
@@ -163,4 +136,3 @@ in
|
|||||||
];
|
];
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
Reference in new issue
Block a user