PHP2Shell fix explained two weeks on: the new hard memory limit, exit code 137, open regressions and the php-src crash backlog Eight php-src issues filed since the October 21 PHP2Shell fix (commit 31c0ea7d, +11,556 and -1,017 lines) name the fix commit, four of them behavior regressions, and none of their fixes is merged yet, according to an analysis of the php-src tracker. The fix makes memory_limit soft and adds a hard limit at 200% of memory_limit by default (memory_limit plus 1 GB once the limit exceeds 1 GB), set via the new ini memory_hard_limit_percent, and crossing it ends the process with _exit(137) without running shutdown functions; it shipped in PHP 8.5.12, 8.4.27, 8.3.36 and 8.2.35. The analysis found a sprintf call that gave a normal fatal error (exit 255) on PHP 8.5.0 and 8.3.30 now ends with exit code 137 on 8.5.12, and that public sanitizer crash reports in php-src mostly close within days (median 1.8 days across 362), a queue the PHP2Shell root cause was never in. PHP2Shell fix explained two weeks on: the new hard memory limit, exit code 137, open regressions and the php-src crash backlog The PHP2Shell fix shipped on October 21. We went through the php-src issues filed since then, ran one regression on patched and unpatched PHP, and counted the public crash backlog. This explains reporting by IEEE Spectrum, "PHP2Shell Is a Wakeup Call for AI in Cybersecurity" November 2, 2026 https://spectrum.ieee.org/ai-in-cybersecurity-php2shell-vulnerability . Read the original first: https://spectrum.ieee.org/ai-in-cybersecurity-php2shell-vulnerability https://spectrum.ieee.org/ai-in-cybersecurity-php2shell-vulnerability In one minute - The PHP2Shell bug came from a fatal error at memory limit jumping out of C code that was halfway through setting up internal state. IEEE Spectrum describes it as memory too small to hold the data, which is a buffer overflow and a different bug. - The fix commit 31c0ea7d, +11,556 and -1,017 lines makes memory limit soft and adds a hard limit, 200% of memory limit by default. Crossing the hard limit ends the process with exit 137 . - Eight php-src issues filed since the release name the fix commit. Four are behavior regressions, and none of their fixes is merged yet. - A sprintf call that gave a normal fatal error exit 255 on PHP 8.5.0 and 8.3.30 ends the process with exit code 137 on 8.5.12. We ran it on all three. - Public sanitizer crash reports in php-src mostly close within days median 1.8 days across 362 . The PHP2Shell root cause was never in that queue. Why we looked IEEE Spectrum's piece on PHP2Shell is on the front page today under the headline "AI is forcing us to pay off 40 years of technical debt." Most of it is about finding bugs. One of the researchers it quotes makes the opposite point partway through: fixing is the hard half, because you have to close every path and keep everything that already works working. That seemed worth checking. The fix shipped on October 21, so there are two weeks of public bug reports to look at. We went through them. First, what the bug was The Spectrum article describes the root cause as an out-of-memory error, "in which the amount of memory allocated is too small to hold the data." That definition describes a buffer overflow, which is a different bug. The PHP Foundation's write-up is more specific. If a request hit memory limit at exactly the wrong moment, the fatal error jumped out of C code that was halfway through setting up internal state PHP does this with a longjmp, zend bailout . The half-built state stayed behind, and later code treated it as valid. Both CVEs, CVE-2026-109618 and CVE-2026-109619, come from that one pattern. What the fix changed, briefly Mattias Geniar wrote up the mechanics on release day, with runs on patched and unpatched builds in containers ma.ttias.be/php-memory-hard-limit . Read that for detail. The short version, which we also checked against Zend/zend alloc.c on the PHP-8.5 branch: - memory limit is now soft. An allocation that crosses it still succeeds, and the fatal error is raised at the next safe point. - A new hard limit sits above it, 200% of memory limit by default or memory limit plus 1 GB once the limit is above 1 GB . The 8.5 source sets it through a new ini, memory hard limit percent. We read that in the code and did not test the setting itself. - An allocation that is not allowed to fail, and would cross the hard limit, prints one line to stderr and calls exit 137 . Shutdown functions do not run. The commit is 31c0ea7d, "Avoid state corruption via bailout," +11,556 and -1,017 lines. It shipped in 8.5.12, 8.4.27, 8.3.36 and 8.2.35. One small thing we noticed: on the PHP-8.5 branch, the new setting is not in UPGRADING, php.ini-production or php.ini-development. What broke A GitHub search for the fix commit's hash 31c0ea7d on 8.5, 3584a98bda on 8.2 turns up eight issues filed since the release. Four of them are behavior regressions, covered below in the order they were filed. The other four: a pending out-of-memory error that gets dropped when compilation fails GH-24631 , a stack-limit test that has segfaulted on x32 every night since October 22 GH-24799 , an older FPM settings-leak report that a commenter tied to the fix GH-24689 , and a use-after-free that was closed as a duplicate of an earlier report GH-24672 . GH-24492 filed on release day . Some code paths still use the allocator that is not allowed to fail, with a size the caller picks. Those used to give the normal fatal error. Now they cross the hard limit and the process exits. The reporter's simplest case: