mirror of
https://github.com/aphrody-labs/cygwin.git
synced 2026-10-14 06:09:10 +00:00
Cygwin: pty: do not leak nat handles when adopting the pcon's in open_setup()
When a Cygwin process opens a pty slave whose pseudo console is already
active, open() has just installed duplicates of the cyg master-side
pipe ends into io_handle_nat and output_handle_nat. The pcon adoption
added in "Cygwin: pty: Fixup pty state after a cygwin app exits"
overwrites those two slots via &get_handle_nat() / &get_output_handle_nat()
without closing them first, so two handles leak on every pcon-backed
grandchild open. It also hands the result of OpenProcess() straight to
DuplicateHandle() without a NULL check, so if the nat-pipe owner has
already exited both duplications fail and leave the nat slots NULL,
which then breaks the slave's input routing.
Close the old slots before replacing them, skip the replacement
entirely when OpenProcess() returns NULL so we degrade to the handles
open() installed, and make the pair transactional so a partial success
cannot leave one original slot and one pcon slot.
Fixes: b34394d456 ("Cygwin: pty: Fixup pty state after a cygwin app exits")
Assisted-by: Opus 4.8
Signed-off-by: Johannes Schindelin <johannes.schindelin@gmx.de>
Reviewed-by: Takashi Yano <takashi.yano@nifty.ne.jp>
This commit is contained in:
1 parent
10140bec21
commit
60a88896dc
1 file changed
+27
-7
@@ -1212,13 +1212,33 @@ fhandler_pty_slave::open_setup (int flags)
|
||||
{
|
||||
HANDLE pcon_owner = OpenProcess (PROCESS_DUP_HANDLE, FALSE,
|
||||
get_ttyp ()->nat_pipe_owner_pid);
|
||||
DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
|
||||
GetCurrentProcess (), &get_handle_nat (),
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_out,
|
||||
GetCurrentProcess (), &get_output_handle_nat (),
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
CloseHandle (pcon_owner);
|
||||
if (pcon_owner)
|
||||
{
|
||||
HANDLE new_in = NULL, new_out = NULL;
|
||||
bool ok_in = DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_in,
|
||||
GetCurrentProcess (), &new_in,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
bool ok_out = DuplicateHandle (pcon_owner, get_ttyp ()->h_pcon_out,
|
||||
GetCurrentProcess (), &new_out,
|
||||
0, TRUE, DUPLICATE_SAME_ACCESS);
|
||||
if (ok_in && ok_out)
|
||||
{
|
||||
/* Close the cyg master-side handles open() installed before
|
||||
replacing them, so they do not leak. */
|
||||
CloseHandle (get_handle_nat ());
|
||||
CloseHandle (get_output_handle_nat ());
|
||||
set_handle_nat (new_in);
|
||||
set_output_handle_nat (new_out);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (new_in)
|
||||
CloseHandle (new_in);
|
||||
if (new_out)
|
||||
CloseHandle (new_out);
|
||||
}
|
||||
CloseHandle (pcon_owner);
|
||||
}
|
||||
}
|
||||
|
||||
set_flags ((flags & ~O_TEXT) | O_BINARY);
|
||||
|
||||
Reference in new issue
Block a user