CVE-2015-9253
Description
PHP php-fpm master process enters infinite restart loop when child uses non-blocking STDIN with exec functions, causing CPU exhaustion and disk fill.
AI Insight
LLM-synthesized narrative grounded in this CVE's description and references.
PHP php-fpm master process enters infinite restart loop when child uses non-blocking STDIN with exec functions, causing CPU exhaustion and disk fill.
Vulnerability
In PHP versions 7.1.x before 7.1.20, 7.2.x before 7.2.8, and 7.3.x before 7.3.0alpha3, the php-fpm master process enters an endless restart loop when a child process uses program execution functions (e.g., exec, passthru, shell_exec, system) with a non-blocking STDIN stream [2]. The bug was originally reported in 2015 in the context of SSH multiplexing [1] and later generalized to any non-blocking STDIN scenario [2].
Exploitation
An attacker who can execute arbitrary PHP code on a server running php-fpm (e.g., a customer of a shared-hosting facility) can trigger the vulnerability by calling stream_set_blocking(fopen('php://stdin', 'r'), false) before invoking any program execution function [2]. No special network position or authentication beyond the ability to run PHP scripts is required. The child process crashes, causing the master to restart it repeatedly in an infinite loop [1][2].
Impact
Successful exploitation causes the php-fpm master process to consume 100% CPU and generate a large volume of error logs, rapidly filling disk space [2]. This results in a denial of service (DoS) for the hosting server, affecting all hosted sites. The master process may become unresponsive to stop/restart signals, requiring a SIGKILL to terminate [2].
Mitigation
The fix was included in PHP 7.1.20, 7.2.8, and 7.3.0alpha3 [2]. Ubuntu released updates in USN-3766-1 (2018) for 18.04 LTS and USN-4279-1 (2020) for other releases [3][4]. Users should upgrade to the patched versions or apply the vendor-provided updates. No workaround is documented; disabling php-fpm or restricting execution functions may reduce risk but is not a complete mitigation.
AI Insight generated on May 24, 2026. Synthesized from this CVE's description and the cited reference URLs; citations are validated against the source bundle.
Affected products
14- osv-coords13 versionspkg:rpm/opensuse/php7&distro=openSUSE%20Leap%2015.4pkg:rpm/suse/php72&distro=SUSE%20Linux%20Enterprise%20Module%20for%20Web%20and%20Scripting%2012pkg:rpm/suse/php72&distro=SUSE%20Linux%20Enterprise%20Software%20Development%20Kit%2012%20SP5pkg:rpm/suse/php7&distro=SUSE%20Enterprise%20Storage%206pkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-ESPOSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015%20SP1-LTSSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-ESPOSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20High%20Performance%20Computing%2015-LTSSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-BCLpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20Server%2015%20SP1-LTSSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20Server%2015-LTSSpkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015pkg:rpm/suse/php7&distro=SUSE%20Linux%20Enterprise%20Server%20for%20SAP%20Applications%2015%20SP1
< 7.2.34-150000.4.103.1+ 12 more
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.5-1.75.1
- (no CPE)range: < 7.2.5-1.75.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
- (no CPE)range: < 7.2.34-150000.4.103.1
Patches
24 files changed · +51 −6
NEWS+4 −0 modified@@ -5,6 +5,10 @@ PHP NEWS - Date: . Fixed bug #76462 (Undefined property: DateInterval::$f). (Anatol) +- FPM: + . Fixed bug #73342 (Vulnerability in php-fpm by changing stdin to + non-blocking). (Nikita) + 22 Jun 2019, PHP 7.1.19 - CLI Server:
sapi/fpm/fpm/fpm_children.c+1 −0 modified@@ -146,6 +146,7 @@ static struct fpm_child_s *fpm_child_find(pid_t pid) /* {{{ */ static void fpm_child_init(struct fpm_worker_pool_s *wp) /* {{{ */ { fpm_globals.max_requests = wp->config->pm_max_requests; + fpm_globals.listening_socket = dup(wp->listening_socket); if (0 > fpm_stdio_init_child(wp) || 0 > fpm_log_init_child(wp) ||
sapi/fpm/fpm/fpm_stdio.c+0 −6 modified@@ -103,12 +103,6 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ fpm_globals.error_log_fd = -1; zlog_set_fd(-1); - if (wp->listening_socket != STDIN_FILENO) { - if (0 > dup2(wp->listening_socket, STDIN_FILENO)) { - zlog(ZLOG_SYSERROR, "failed to init child stdio: dup2()"); - return -1; - } - } return 0; } /* }}} */
sapi/fpm/tests/bug73342-nonblocking-stdio.phpt+46 −0 added@@ -0,0 +1,46 @@ +--TEST-- +FPM: bug73342 - Non-blocking stdin +--SKIPIF-- +<?php include "skipif.inc"; ?> +--FILE-- +<?php + +require_once "tester.inc"; + +$cfg = <<<EOT +[global] +error_log = {{FILE:LOG}} +[unconfined] +listen = {{ADDR}} +pm = dynamic +pm.max_children = 5 +pm.start_servers = 1 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +EOT; + +$code = <<<EOT +<?php +echo "Before\n"; +stream_set_blocking(fopen('php://stdin', 'r'), false); +echo "After\n"; +EOT; + +$tester = new FPM\Tester($cfg, $code); +$tester->start(); +$tester->expectLogStartNotices(); +$tester->request()->expectBody("Before\nAfter"); +$tester->request()->expectBody("Before\nAfter"); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- +<?php +require_once "tester.inc"; +FPM\Tester::clean(); +?>
acd652bf1eb0Merge 36f979369026ef9a5c6a616a39ed1cd55d7a9fa0 into 5dd1ef90caec3021e6ce55c8554e695edf641eaf
3 files changed · +47 −6
sapi/fpm/fpm/fpm_children.c+1 −0 modified@@ -146,6 +146,7 @@ static struct fpm_child_s *fpm_child_find(pid_t pid) /* {{{ */ static void fpm_child_init(struct fpm_worker_pool_s *wp) /* {{{ */ { fpm_globals.max_requests = wp->config->pm_max_requests; + fpm_globals.listening_socket = dup(wp->listening_socket); if (0 > fpm_stdio_init_child(wp) || 0 > fpm_log_init_child(wp) ||
sapi/fpm/fpm/fpm_stdio.c+0 −6 modified@@ -103,12 +103,6 @@ int fpm_stdio_init_child(struct fpm_worker_pool_s *wp) /* {{{ */ fpm_globals.error_log_fd = -1; zlog_set_fd(-1); - if (wp->listening_socket != STDIN_FILENO) { - if (0 > dup2(wp->listening_socket, STDIN_FILENO)) { - zlog(ZLOG_SYSERROR, "failed to init child stdio: dup2()"); - return -1; - } - } return 0; } /* }}} */
sapi/fpm/tests/bug73342-nonblocking-stdio.phpt+46 −0 added@@ -0,0 +1,46 @@ +--TEST-- +Bug #73342: Vulnerability in php-fpm by changing stdin to non-blocking +--SKIPIF-- +<?php include "skipif.inc"; ?> +--FILE-- +<?php + +require_once "tester.inc"; + +$cfg = <<<EOT +[global] +error_log = {{FILE:LOG}} +[unconfined] +listen = {{ADDR}} +pm = dynamic +pm.max_children = 5 +pm.start_servers = 1 +pm.min_spare_servers = 1 +pm.max_spare_servers = 3 +EOT; + +$code = <<<EOT +<?php +echo "Before\n"; +stream_set_blocking(fopen('php://stdin', 'r'), false); +echo "After\n"; +EOT; + +$tester = new FPM\Tester($cfg, $code); +$tester->start(); +$tester->expectLogStartNotices(); +$tester->request()->expectBody("Before\nAfter"); +$tester->request()->expectBody("Before\nAfter"); +$tester->terminate(); +$tester->expectLogTerminatingNotices(); +$tester->close(); + +?> +Done +--EXPECT-- +Done +--CLEAN-- +<?php +require_once "tester.inc"; +FPM\Tester::clean(); +?>
Vulnerability mechanics
Root cause
"php-fpm duplicated the listening socket onto STDIN of child processes, so when a child set STDIN to non-blocking mode the master process entered an infinite restart loop."
Attack vector
An attacker who can execute PHP code on a shared-hosting server (e.g. via a web application) can call any program execution function such as `exec()`, `shell_exec()`, `passthru()`, or `system()` with a child process that sets STDIN to non-blocking mode. Because php-fpm had previously `dup2()`'d the listening socket onto STDIN, the child's non-blocking STDIN causes the master process to misinterpret the socket state, triggering an endless loop of child restarts. This consumes 100% CPU and rapidly fills the error log with "child exited" notices, potentially exhausting disk space [ref_id=1].
Affected code
The vulnerability resides in `sapi/fpm/fpm/fpm_stdio.c` in the `fpm_stdio_init_child()` function, which used `dup2()` to duplicate the listening socket onto `STDIN_FILENO`. The patch also modifies `sapi/fpm/fpm/fpm_children.c` to store a duplicated listening socket via `dup()` in `fpm_child_init()`.
What the fix does
The patch removes the `dup2(wp->listening_socket, STDIN_FILENO)` call from `fpm_stdio_init_child()` so the listening socket is no longer duplicated onto STDIN. Instead, `fpm_child_init()` now stores a separate duplicated file descriptor via `dup(wp->listening_socket)` into `fpm_globals.listening_socket`. This prevents child processes from inheriting the listening socket as STDIN, so when a child sets STDIN to non-blocking mode it no longer interferes with the master process's socket handling, breaking the infinite restart loop [patch_id=2247143][patch_id=2247142].
Preconditions
- authAttacker must be able to execute arbitrary PHP code on a server running php-fpm (e.g., a shared-hosting customer with a web application).
- inputThe executed PHP code must call a program execution function (exec, shell_exec, passthru, system) that launches a child process which sets STDIN to non-blocking.
Generated on May 24, 2026. Inputs: CWE entries + fix-commit diffs from this CVE's patches. Citations validated against bundle.
References
8- usn.ubuntu.com/3766-1/mitrevendor-advisoryx_refsource_UBUNTU
- usn.ubuntu.com/4279-1/mitrevendor-advisoryx_refsource_UBUNTU
- bugs.php.net/bug.phpmitrex_refsource_MISC
- bugs.php.net/bug.phpmitrex_refsource_CONFIRM
- bugs.php.net/bug.phpmitrex_refsource_MISC
- github.com/php/php-src/blob/PHP-7.1.20/NEWSmitrex_refsource_CONFIRM
- github.com/php/php-src/commit/69dee5c732fe982c82edb17d0dbc3e79a47748d8mitrex_refsource_CONFIRM
- www.futureweb.at/security/CVE-2015-9253/mitrex_refsource_MISC
News mentions
0No linked articles in our index yet.