Re: [PATCH] Cygwin: pty: detect pcon-backed pty for non-Cygwin-spawned children
Takashi Yano <[email protected]> Tue, 30 Jun 2026 17:26:17 +0900
| Newsgroups | gmane.os.cygwin.patches |
|---|---|
| Message-ID | <[email protected]> |
On Sat, 27 Jun 2026 10:18:27 +0200 (CEST) Johannes Schindelin wrote: > Hi Takashi & Mark, > > On Wed, 24 Jun 2026, Takashi Yano wrote: > > > On Thu, 30 Apr 2026 15:04:04 +0000 > > "Johannes Schindelin via GitGitGadget" <[email protected]> wrote: > > > From: Johannes Schindelin <[email protected]> > > > > > > When a Cygwin process (e.g. `bash` under MinTTY) spawns a native > > > Win32 child (e.g. `git.exe`) with pseudo console support enabled, > > > the child gets a pseudo console that bridges the pty. If that native > > > child then spawns a Cygwin grandchild (e.g. `vim`, `less`), the > > > grandchild inherits the pseudo console's console handles. In > > > `init_std_file_from_handle()`, the grandchild's msys2-runtime sees > > > `GetConsoleScreenBufferInfo()` succeed on those handles and, with > > > no valid `ctty` set, falls back to `FH_CONSOLE` and gives the > > > process `cons0` instead of connecting to the pty. > > > > > [...] > > > > Pushed to master branch with my fixup patches. > > I had a buffer-grow follow-up to this patch sitting in > https://github.com/git-for-windows/msys2-runtime/pull/131/commits/77e01abd83836b4b7488328ca899aea3a8e4ffbe > that I should have sent before you picked up the original and pushed it to > master; sorry for the delay. > > -- snip -- > From 77e01abd83836b4b7488328ca899aea3a8e4ffbe Mon Sep 17 00:00:00 2001 > From: Johannes Schindelin <[email protected]> > Date: Fri, 29 May 2026 19:07:26 +0200 > Subject: [PATCH] Cygwin: pty: grow GetConsoleProcessList buffer in > find_pcon_pty() > > find_pcon_pty() was passing a fixed 128-DWORD stack array to > GetConsoleProcessList(). If the calling Cygwin process happens to be > attached to a console with more than 128 processes, the Win32 > function returns the required size and the buffer contents are > undefined; the existing if-zero check did not catch that case, so > the subsequent loop walked uninitialised data and could either miss > the candidate pty or, worse, match against junk PIDs and return the > wrong tty index. > > Adopt the buffer-too-small dance from > fhandler_termios::get_console_process_id() in > winsup/cygwin/fhandler/termios.cc, which already had to solve this > problem and which also notes that the new condrv does not accept > oversized first-call buffers > (https://github.com/microsoft/terminal/issues/18264#issuecomment-2515448548). > The buffer comes from tmp_pathbuf so the same NT_MAX_PATH cap > (currently 1024 DWORDs, i.e. 4096 processes) applies; we bail out > with -1 if even that is not enough rather than allocate unbounded > memory or guess. Bumping the start-with size from 1 would defeat the > condrv work-around mentioned above, so we keep the same one-element > initial probe as termios.cc and let the loop grow. > > Suggested-by: Takashi Yano <[email protected]> > Assisted-by: Opus 4.7 > Signed-off-by: Johannes Schindelin <[email protected]> > (cherry picked from commit b65e1544d45567f0033c57a0aa1543c5e654950a) > --- > winsup/cygwin/tty.cc | 19 ++++++++++++++++--- > 1 file changed, 16 insertions(+), 3 deletions(-) > > diff --git a/winsup/cygwin/tty.cc b/winsup/cygwin/tty.cc > index 5cce05de34..9bc2a084fb 100644 > --- a/winsup/cygwin/tty.cc > +++ b/winsup/cygwin/tty.cc > @@ -19,6 +19,7 @@ details. */ > #include "cygheap.h" > #include "pinfo.h" > #include "shared_info.h" > +#include "tls_pbuf.h" > > HANDLE NO_COPY tty_list::mutex = NULL; > > @@ -135,7 +136,9 @@ tty_list::init () > int > tty_list::find_pcon_pty () > { > - DWORD pids[128]; > + tmp_pathbuf tp; > + DWORD *pids = (DWORD *) tp.c_get (); > + const DWORD buf_size = NT_MAX_PATH / sizeof (DWORD); > DWORD count = 0; > bool got_pids = false; > > @@ -144,10 +147,20 @@ tty_list::find_pcon_pty () > if (!ttys[i].has_active_pcon ()) > continue; > > - /* Fetch the console process list lazily, only on first candidate. */ > + /* Fetch the console process list lazily, only on first candidate. > + The buffer-too-large dance mirrors the one in termios.cc's > + get_console_process_id() and works around new condrv's dislike > + of oversized first-call buffers, see > + https://github.com/microsoft/terminal/issues/18264#issuecomment-2515448548 */ > if (!got_pids) > { > - count = GetConsoleProcessList (pids, 128); > + DWORD buf_size1 = 1; > + while ((count = GetConsoleProcessList (pids, buf_size1)) > buf_size1) > + { > + if (count > buf_size) > + return -1; > + buf_size1 = count; > + } > if (!count) > return -1; > got_pids = true; > -- snap -- > > Ciao, > Johannes > LGTM. Thanks! Pushed to master. -- Takashi Yano <[email protected]>