[newlib-cygwin] Cygwin: pty: grow GetConsoleProcessList buffer in find_pcon_pty()
Takashi Yano via Cygwin-cvs <[email protected]> Tue, 30 Jun 2026 08:26:19 +0000 (GMT)
| Newsgroups | gmane.os.cygwin.cvs |
|---|---|
| Message-ID | <[email protected]> |
https://sourceware.org/git/gitweb.cgi?p=3Dnewlib-cygwin.git;h=3D10140bec21e= 4433ddbfb2308c8a4052f3eaaafa4 commit 10140bec21e4433ddbfb2308c8a4052f3eaaafa4 Author: Johannes Schindelin <[email protected]> Date: Fri May 29 19:07:26 2026 +0200 Cygwin: pty: grow GetConsoleProcessList buffer in find_pcon_pty() =20 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. =20 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-251544= 8548). 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. =20 Fixes: 6eed1ef74869 ("Cygwin: pty: detect pcon-backed pty for non-Cygwi= n-spawned children") Suggested-by: Takashi Yano <[email protected]> Assisted-by: Opus 4.7 Signed-off-by: Johannes Schindelin <[email protected]> Reviewed-by: Takashi Yano <[email protected]> Diff: --- 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 667aa2682..ba65aca3d 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" =20 HANDLE NO_COPY tty_list::mutex =3D NULL; =20 @@ -135,7 +136,9 @@ tty_list::init () int tty_list::find_pcon_pty () { - DWORD pids[128]; + tmp_pathbuf tp; + DWORD *pids =3D (DWORD *) tp.c_get (); + const DWORD buf_size =3D NT_MAX_PATH / sizeof (DWORD); DWORD count =3D 0; bool got_pids =3D false; =20 @@ -144,10 +147,20 @@ tty_list::find_pcon_pty () if (!ttys[i].has_active_pcon ()) continue; =20 - /* 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-25154485= 48 */ if (!got_pids) { - count =3D GetConsoleProcessList (pids, 128); + DWORD buf_size1 =3D 1; + while ((count =3D GetConsoleProcessList (pids, buf_size1)) > buf_size1) + { + if (count > buf_size) + return -1; + buf_size1 =3D count; + } if (!count) return -1; got_pids =3D true;