Commit 8d0d6307aac for php.net
commit 8d0d6307aaca39223d5dd9461dc8dea90286a3bb
Author: Ilia Alshanetsky <ilia@ilia.ws>
Date: Fri Aug 21 13:13:21 2026 -0400
Fix three Win32-only defects in proc_open descriptor handling
init_process_info() memset the pointer parameter instead of the
PROCESS_INFORMATION structure it points at, leaving the struct
uninitialized before CreateProcessW(). Zero it through the pointer.
find_comspec_nt() dereferences *comspec in its cleanup while the
caller only assigns it on success, so a failed SearchPathW() read an
indeterminate value. Initialize the caller's variable to NULL.
set_proc_descriptor_to_blackhole() tested CreateFileA() against NULL,
but CreateFileA() signals failure with INVALID_HANDLE_VALUE, so a
failed open went undetected and an invalid handle was inherited by
the child. Test against INVALID_HANDLE_VALUE.
Closes GH-23412
diff --git a/NEWS b/NEWS
index d81d3170a6f..51580b6c778 100644
--- a/NEWS
+++ b/NEWS
@@ -50,6 +50,11 @@ PHP NEWS
. Fixed a crash when SQLite3::close() is called from a userland callback.
(Ilia Alshanetsky)
+- Standard:
+ . Fixed three Windows-only proc_open() defects: an uninitialized
+ PROCESS_INFORMATION, an indeterminate comspec pointer after a failed
+ lookup, and an unchecked CreateFileA() failure. (Ilia Alshanetsky)
+
- XSL:
. Fixed bug GH-23730 (use-after-free when XSLTProcessor::importStylesheet()
is called during a transformation). (David Carlier)
diff --git a/ext/standard/proc_open.c b/ext/standard/proc_open.c
index d2d51de5a85..bd4cf7a0a0e 100644
--- a/ext/standard/proc_open.c
+++ b/ext/standard/proc_open.c
@@ -695,7 +695,7 @@ static void init_startup_info(STARTUPINFOW *si, descriptorspec_item *descriptors
static void init_process_info(PROCESS_INFORMATION *pi)
{
- memset(&pi, 0, sizeof(pi));
+ memset(pi, 0, sizeof(*pi));
}
/* on success, returns length of *comspec, which then needs to be efree'd by caller */
@@ -746,7 +746,7 @@ static size_t find_comspec_nt(wchar_t **comspec)
static zend_result convert_command_to_use_shell(wchar_t **cmdw, size_t cmdw_len)
{
- wchar_t *comspec;
+ wchar_t *comspec = NULL;
size_t len = find_comspec_nt(&comspec);
if (len == 0) {
php_error_docref(NULL, E_WARNING, "Command conversion failed");
@@ -829,7 +829,7 @@ static zend_result set_proc_descriptor_to_blackhole(descriptorspec_item *desc)
#ifdef PHP_WIN32
desc->childend = CreateFileA("nul", GENERIC_READ | GENERIC_WRITE,
FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL);
- if (desc->childend == NULL) {
+ if (desc->childend == INVALID_HANDLE_VALUE) {
php_error_docref(NULL, E_WARNING, "Failed to open nul");
return FAILURE;
}