From be9afb2f5325e610ec0662b38a5fcf0f8ba6b3e3 Mon Sep 17 00:00:00 2001 From: Sovran Systems Date: Fri, 23 Oct 2026 01:34:23 +0000 Subject: [PATCH] php: pin the shared interpreter to 8.5.12 for CVE-2026-109618/-109619 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35 were released on 2026-10-21 to fix two critical vulnerabilities in PHP itself: CVE-2026-109618 RCE via OOM corruption (GHSA-w8hw-w9fx-j79w) CVE-2026-109619 RCE via stale global state (GHSA-6wmf-4rv5-p3rp) Both are unauthenticated RCE, CVSS v4.0 9.2, and PHP states that updating is the only complete mitigation. The advisories name PHP-FPM as susceptible, so the phpfpm-nextcloud and phpfpm-wordpress pools are in scope, not just the Apache/mod_php configuration the public write-ups focus on. nixpkgs bumped php85 in 81513f364091c759812f716cef3c175109d07342 on the same day, but the revision this flake pins (7694c4f6b853, 2026-10-16) predates it and still reports php85 8.5.11 — as does the pinned nixos-26.05 rev, so `pkgs.stable` is not a way out of this either. Rather than pin the whole nixpkgs input forward and freeze every other package, pin the interpreter: • phpSecurityFloor records the first patched 8.5.x release. • phpBase falls through to pkgs.php85 untouched when nixpkgs has caught up, so the workaround retires itself; bump the floor only upward. • `.override` rather than `overrideAttrs`: php85 is a makeOverridable buildEnv, so version/phpSrc reach generic.nix while the default extension set survives. overrideAttrs would keep the new source but drop `enabled`, silently removing gd, intl, pdo_pgsql and the rest from both pools. Nothing else changes: one interpreter, one extension set, one php.ini, and every consumer (both FPM pools, the Nextcloud cron job, occ and wp-cli) still resolves through config.sovran_systemsOS.phpPackage, so CLI and FPM stay in lockstep at 8.5.12. The source is php-8.5.12.tar.bz2 from php.net, hashed here. Hydra cannot have this exact derivation, so the first rebuild compiles PHP plus bz2, apcu, redis, imagick and memcached locally — a one-off cost, after which it is a store path like any other and the configuration stays reproducible. `nixos-rebuild switch` is enough: the phpfpm units change closure and restart, no reboot and no staged generation required. --- modules/php.nix | 35 ++++++++++++++++++++++++++++++++++- 1 file changed, 34 insertions(+), 1 deletion(-) diff --git a/modules/php.nix b/modules/php.nix index 9ec05dd..89ed70a 100755 --- a/modules/php.nix +++ b/modules/php.nix @@ -18,9 +18,42 @@ # # To fall back to PHP 8.4 (nixpkgs' current default `pkgs.php`) change only # the `phpBase` line below. +# +# Security floor (October 2026): +# CVE-2026-109618 (RCE via OOM corruption) and CVE-2026-109619 (RCE via +# stale global state) are critical, unauthenticated flaws in PHP itself, +# 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. let - phpBase = pkgs.php85; + # 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; + }; + }; custom-php = phpBase.buildEnv { # `enabled` is nixpkgs' default extension set. It already contains every