[php-src] PHP-8.6: Fix stream error operation leak in stream_select()

From: Date: Thu, 22 Oct 2026 14:06:42 +0000
Subject: [php-src] PHP-8.6: Fix stream error operation leak in stream_select()
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-142577@lists.php.net to get a copy of this message
Author: Seifeddine Gmati (azjezz) Committer: ndossche (ndossche) Date: 2026-10-22T15:57:26+02:00 Commit: https://github.com/php/php-src/commit/2762817831d4aa86f242e38b9a9efc17d1b7877b Raw diff: https://github.com/php/php-src/commit/2762817831d4aa86f242e38b9a9efc17d1b7877b.diff Fix stream error operation leak in stream_select() Ensure the stream error operation is ended before returning false when PHP_SAFE_MAX_FD() fails. Closes GH-24507. Signed-off-by: azjezz <azjezz@protonmail.com> Changed paths: A ext/standard/tests/streams/gh24506.phpt M NEWS M ext/standard/streamsfuncs.c Diff: diff --git a/NEWS b/NEWS index 20c05edb71e0..9f6000dfb911 100644 --- a/NEWS +++ b/NEWS @@ -6,6 +6,10 @@ PHP NEWS . Fixed bug GH-24461 (DISCARD ALL on persistent connection cleanup drops PgBouncer's prepared statements). (David Carlier, Artem Ukrainskiy) +- Streams: + . Fixed bug GH-24506 (stream_select() leaks a stream-error operation level + on its FD_SETSIZE failure path). (azjezz) + 21 Oct 2026, PHP 8.6.0RC4 - Core: diff --git a/ext/standard/streamsfuncs.c b/ext/standard/streamsfuncs.c index a03aed1ccdd4..98de1e44af7f 100644 --- a/ext/standard/streamsfuncs.c +++ b/ext/standard/streamsfuncs.c @@ -835,6 +835,7 @@ PHP_FUNCTION(stream_select) } if (!PHP_SAFE_MAX_FD(max_fd, max_set_count)) { + php_stream_error_operation_end(context); RETURN_FALSE; } diff --git a/ext/standard/tests/streams/gh24506.phpt b/ext/standard/tests/streams/gh24506.phpt new file mode 100644 index 000000000000..dc11c2c7cee6 --- /dev/null +++ b/ext/standard/tests/streams/gh24506.phpt @@ -0,0 +1,52 @@ +--TEST-- +GH-24506 (stream_select() leaks stream error operations on FD_SETSIZE failure) +--EXTENSIONS-- +posix +--SKIPIF-- +<?php +if (PHP_FD_SETSIZE > 4096) { + die('skip FD_SETSIZE is too large'); +} +if (!function_exists('posix_setrlimit') + || !posix_setrlimit(POSIX_RLIMIT_NOFILE, PHP_FD_SETSIZE + 32, PHP_FD_SETSIZE + 32)) { + die('skip Failed to set POSIX_RLIMIT_NOFILE'); +} +?> +--FILE-- +<?php +posix_setrlimit(POSIX_RLIMIT_NOFILE, PHP_FD_SETSIZE + 32, PHP_FD_SETSIZE + 32); + +$streams = []; +for ($i = 0; $i < PHP_FD_SETSIZE; $i++) { + $streams[] = fopen(__FILE__, 'r'); +} +[$reader, $writer] = stream_socket_pair(STREAM_PF_UNIX, STREAM_SOCK_STREAM, STREAM_IPPROTO_IP); + +$warnings = 0; +set_error_handler(static function (int $errno, string $message) use (&$warnings): bool { + if (str_contains($message, 'larger value of FD_SETSIZE')) { + $warnings++; + return true; + } + return false; +}); + +$failures = 0; +for ($i = 0; $i < 1001; $i++) { + $read = [$reader]; + $write = $except = null; + if (stream_select($read, $write, $except, 0) === false) { + $failures++; + } +} +restore_error_handler(); + +var_dump($warnings, $failures); +var_dump(fwrite($writer, 'x')); +var_dump(fread($reader, 1)); +?> +--EXPECT-- +int(1001) +int(1001) +int(1) +string(1) "x"

« previous php.cvs (#142577) next »