Research collected from outside sources and what this site derives from them; every fact links to a saved copy of its source Research or story?

The fix, mapped to the code

The editor asked for the kind of source-code mapping we did at secrets.sgit.ai/review: the project as layered graphs, the intent on one side and the code derived from the syntax tree on the other, with the join between them. Here the intent is the two flaws and the design of the patch; the code is what the patch changed in php-src, read from the diff by a parser rather than a model. Three layers, 54 nodes and 68 edges; walk them in the navigator, or read the map below.

Commit 3584a98bd · 389 files changed, 37 of them in the engine and bundled extensions traced here · 36 areas

The flaws

CVE-2026-109618: RCE via OOM corruption An out-of-memory condition during request handling could leave request memory in an uninitialised state that later cleanup reads. CVSS v4.0 9.2. GHSA-w8hw-w9fx-j79w. CVE record

CVE-2026-109619: RCE via stale global state Global state that referenced request memory was not always reset, so a later request on the same worker could read freed memory. CVSS v4.0 9.2. GHSA-6wmf-4rv5-p3rp. CVE record

What the fix does, and where

Each card is one thing the patch does, with the functions it uses and the files it changed. The text describes the remediation; how the flaw is reached is on the two flaws and the code, which this layer sits beside.

A hard limit that ends the process cleanly

A new memory_hard_limit_percent sets a ceiling above memory_limit; reaching it ends the worker with _exit(), leaving no cleanup to corrupt. zend_mm_panic also uses _exit now.

Functions. zend_mm_hard_limit_error · new setting memory_hard_limit_percent

Addresses: CVE-2026-109618

The change, by area

The patch is 389 files because the new allocation contract touched every place in the engine and the bundled extensions that used to abort on a failed allocation. The twenty largest areas:

AreaFilesAddedRemoved
Zend/962932268
tests/3411091
ext/standard52106185
ext/mbstring3057076
ext/gd1949817
ext/session541663
ext/soap143758
main/734550
ext/zlib1134410
ext/filter83359
ext/date17326122
ext/exif831823
ext/zend_test827842
ext/xmlreader82365
ext/pcre818610
ext/fileinfo316851
ext/iconv714611
ext/json813723
ext/simplexml413426
ext/opcache711311

The full per-file data, with the functions each hunk changed, is data/review.json and review/code/files.json, derived from git show of the commit.

How this was built