[php-src] master: Merge branch 'PHP-8.5' into PHP-8.6

From: Date: Sun, 04 Oct 2026 15:54:08 +0000
Subject: [php-src] master: Merge branch 'PHP-8.5' into PHP-8.6
Groups: php.cvs 
Request: Send a blank email to php-cvs+get-141924@lists.php.net to get a copy of this message
Author: Ilia Alshanetsky (iliaal) Date: 2026-10-04T11:43:10-04:00 Commit: https://github.com/php/php-src/commit/a422c5500f78b8ce337b50df4570b52023512847 Raw diff: https://github.com/php/php-src/commit/a422c5500f78b8ce337b50df4570b52023512847.diff Merge branch 'PHP-8.5' into PHP-8.6 * PHP-8.5: ext/standard: Close owned proc_open descriptors on setup failure Changed paths: A ext/standard/tests/general_functions/proc_open_descriptor_0_setup_failure.phpt A ext/standard/tests/general_functions/proc_open_socket_descriptor_0_setup_failure.phpt M NEWS M ext/standard/proc_open.c Diff: diff --git a/NEWS b/NEWS index 9c885b9e9a44..d9d65d5527a1 100644 --- a/NEWS +++ b/NEWS @@ -128,6 +128,8 @@ PHP NEWS read failure. (Ilia Alshanetsky) . Fixed iptcembed() corrupting JPEG headers when called recursively from an output handler. (Ilia Alshanetsky) + . Fixed proc_open() leaking descriptor zero when descriptor setup fails. + (Ilia Alshanetsky) - Tidy: . Fixed a use-after-free when a tidyNode is used after its document is diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c index 8bd3361f59cb..4fd24058f7cb 100644 --- a/ext/standard/proc_open.c +++ b/ext/standard/proc_open.c @@ -1185,8 +1185,9 @@ static void close_all_descriptors(descriptorspec_item *descriptors, int ndesc) { for (int i = 0; i < ndesc; i++) { close_descriptor(descriptors[i].childend); - if (descriptors[i].parentend) + if (descriptors[i].type != DESCRIPTOR_TYPE_STD) { close_descriptor(descriptors[i].parentend); + } } } diff --git a/ext/standard/tests/general_functions/proc_open_descriptor_0_setup_failure.phpt b/ext/standard/tests/general_functions/proc_open_descriptor_0_setup_failure.phpt new file mode 100644 index 000000000000..ea654b0f497a --- /dev/null +++ b/ext/standard/tests/general_functions/proc_open_descriptor_0_setup_failure.phpt @@ -0,0 +1,29 @@ +--TEST-- +proc_open() closes descriptor 0 when setup fails after pipe allocation +--SKIPIF-- +<?php +if (!function_exists("proc_open")) { + die("skip proc_open() unavailable"); +} +if (!@is_dir("/proc/self/fd")) { + die("skip requires /proc/self/fd"); +} +?> +--FILE-- +<?php +$code = <<<'PHP' +fclose(STDIN); +var_dump(@proc_open("true", [0 => ["pipe", "w"], 1 => ["bogus_type"]], $pipes)); +$fd = fopen("/dev/null", "r"); +var_dump(readlink("/proc/self/fd/0")); +fclose($fd); +PHP; +$process = proc_open([PHP_BINARY, "-n", "-r", $code], [1 => ["pipe", "w"]], $pipes); +echo stream_get_contents($pipes[1]); +fclose($pipes[1]); +var_dump(proc_close($process)); +?> +--EXPECT-- +bool(false) +string(9) "/dev/null" +int(0) diff --git a/ext/standard/tests/general_functions/proc_open_socket_descriptor_0_setup_failure.phpt b/ext/standard/tests/general_functions/proc_open_socket_descriptor_0_setup_failure.phpt new file mode 100644 index 000000000000..88e4eee1b20b --- /dev/null +++ b/ext/standard/tests/general_functions/proc_open_socket_descriptor_0_setup_failure.phpt @@ -0,0 +1,29 @@ +--TEST-- +proc_open() closes descriptor 0 when setup fails after socket allocation +--SKIPIF-- +<?php +if (!function_exists("proc_open")) { + die("skip proc_open() unavailable"); +} +if (!@is_dir("/proc/self/fd")) { + die("skip requires /proc/self/fd"); +} +?> +--FILE-- +<?php +$code = <<<'PHP' +fclose(STDIN); +var_dump(@proc_open("true", [0 => ["socket"], 1 => ["bogus_type"]], $pipes)); +$fd = fopen("/dev/null", "r"); +var_dump(readlink("/proc/self/fd/0")); +fclose($fd); +PHP; +$process = proc_open([PHP_BINARY, "-n", "-r", $code], [1 => ["pipe", "w"]], $pipes); +echo stream_get_contents($pipes[1]); +fclose($pipes[1]); +var_dump(proc_close($process)); +?> +--EXPECT-- +bool(false) +string(9) "/dev/null" +int(0)

« previous php.cvs (#141924) next »