https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=a5f96c196e71c7df4cac2575db7be97e95a39df4
commit a5f96c196e71c7df4cac2575db7be97e95a39df4 Author: Takashi Yano <takashi.y...@nifty.ne.jp> Date: Sat Aug 16 05:57:06 2025 +0900 Cygwin: spawn: Make ch_spwan_local be initialized properly The class child_info_spawn has two constructors: one without arguments and one with two arguments. The former does not initialize any members. Commit 1f836c5f7394 used the latter to ensure that the local ch_spawn (i.e., ch_spawn_local) would be properly initialized. However, this was insufficient - it initialized only the base child_info members, not the fields specific to child_info_spawn. This led to the issue reported in https://cygwin.com/pipermail/cygwin/2025-August/258660.html. This patch introduces a new constructor to properly initialize member variable 'ev', etc., which were referred without initialization, and switches ch_spawn_local to use it. 'subproc_ready', which may not be initialized, is also initialized in the constructor of the base class child_info. Addresses: https://cygwin.com/pipermail/cygwin/2025-August/258660.html Fixes: 1f836c5f7394 ("Cygwin: spawn: Make system() thread-safe") Reported-by: Denis Excoffier <cyg...@denis-excoffier.org> Reviewed-by: Jeremy Drake <cyg...@jdrake.com> Signed-off-by: Takashi Yano <takashi.y...@nifty.ne.jp> (cherry picked from commit 880c96576b2423d1e77e25a3a2da7fc761377728) Diff: --- winsup/cygwin/local_includes/child_info.h | 3 ++- winsup/cygwin/sigproc.cc | 9 ++++++++- winsup/cygwin/spawn.cc | 2 +- winsup/cygwin/syscalls.cc | 2 +- 4 files changed, 12 insertions(+), 4 deletions(-) diff --git a/winsup/cygwin/local_includes/child_info.h b/winsup/cygwin/local_includes/child_info.h index 2da62ffaa..25d99fa7d 100644 --- a/winsup/cygwin/local_includes/child_info.h +++ b/winsup/cygwin/local_includes/child_info.h @@ -33,7 +33,7 @@ enum child_status #define EXEC_MAGIC_SIZE sizeof(child_info) /* Change this value if you get a message indicating that it is out-of-sync. */ -#define CURR_CHILD_INFO_MAGIC 0xacbf4682U +#define CURR_CHILD_INFO_MAGIC 0x77f25a01U #include "pinfo.h" struct cchildren @@ -149,6 +149,7 @@ public: void cleanup (); child_info_spawn () {}; + child_info_spawn (child_info_types); child_info_spawn (child_info_types, bool); void record_children (); void reattach_children (); diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc index 361887981..30779cf8e 100644 --- a/winsup/cygwin/sigproc.cc +++ b/winsup/cygwin/sigproc.cc @@ -895,7 +895,8 @@ child_info::child_info (unsigned in_cb, child_info_types chtype, msv_count (0), cb (in_cb), intro (PROC_MAGIC_GENERIC), magic (CHILD_INFO_MAGIC), type (chtype), cygheap (::cygheap), cygheap_max (::cygheap_max), flag (0), retry (child_info::retry_count), - rd_proc_pipe (NULL), wr_proc_pipe (NULL), sigmask (_my_tls.sigmask) + rd_proc_pipe (NULL), wr_proc_pipe (NULL), subproc_ready (NULL), + sigmask (_my_tls.sigmask) { fhandler_union_cb = sizeof (fhandler_union); user_h = cygwin_user_h; @@ -946,6 +947,12 @@ child_info_fork::child_info_fork () : { } +child_info_spawn::child_info_spawn (child_info_types chtype) : + child_info (sizeof *this, chtype, false), hExeced (NULL), ev (NULL), + sem (NULL), moreinfo (NULL) +{ +} + child_info_spawn::child_info_spawn (child_info_types chtype, bool need_subproc_ready) : child_info (sizeof *this, chtype, need_subproc_ready) { diff --git a/winsup/cygwin/spawn.cc b/winsup/cygwin/spawn.cc index 680f0fefd..71add8755 100644 --- a/winsup/cygwin/spawn.cc +++ b/winsup/cygwin/spawn.cc @@ -950,7 +950,7 @@ spawnve (int mode, const char *path, const char *const *argv, if (!envp) envp = empty_env; - child_info_spawn ch_spawn_local (_CH_NADA, false); + child_info_spawn ch_spawn_local (_CH_NADA); switch (_P_MODE (mode)) { case _P_OVERLAY: diff --git a/winsup/cygwin/syscalls.cc b/winsup/cygwin/syscalls.cc index 863f8f23c..1b1ff17b0 100644 --- a/winsup/cygwin/syscalls.cc +++ b/winsup/cygwin/syscalls.cc @@ -4535,7 +4535,7 @@ popen (const char *command, const char *in_type) fcntl (stdchild, F_SETFD, stdchild_state | FD_CLOEXEC); /* Start a shell process to run the given command without forking. */ - child_info_spawn ch_spawn_local (_CH_NADA, false); + child_info_spawn ch_spawn_local (_CH_NADA); pid_t pid = ch_spawn_local.worker ("/bin/sh", argv, environ, _P_NOWAIT, __std[0], __std[1]);