[newlib-cygwin] Cygwin: execve: reduce parent handle to non-inheritable SYNCHRONIZE

Corinna Vinschen corinna@sourceware.org
Tue Jan 29 19:38:00 GMT 2019


https://sourceware.org/git/gitweb.cgi?p=newlib-cygwin.git;h=4d738e0f62403c3f1b082abf927aab00056230c5

commit 4d738e0f62403c3f1b082abf927aab00056230c5
Author: Corinna Vinschen <corinna@vinschen.de>
Date:   Tue Jan 29 20:37:00 2019 +0100

    Cygwin: execve: reduce parent handle to non-inheritable SYNCHRONIZE
    
    Keeping an inheritable handle open results in that handle being
    spilled over into grandchild processes, which is not desired.
    Duplicate original parent handle into a non-inheritable one with
    minimal SYNCHRONIZE permissions and close the original handle.
    
    Signed-off-by: Corinna Vinschen <corinna@vinschen.de>

Diff:
---
 winsup/cygwin/dcrt0.cc   | 30 +++++++++++++++++++++++-------
 winsup/cygwin/sigproc.cc |  3 ++-
 2 files changed, 25 insertions(+), 8 deletions(-)

diff --git a/winsup/cygwin/dcrt0.cc b/winsup/cygwin/dcrt0.cc
index 6b564dc..463df31 100644
--- a/winsup/cygwin/dcrt0.cc
+++ b/winsup/cygwin/dcrt0.cc
@@ -685,14 +685,30 @@ child_info_spawn::handle_spawn ()
 
   ready (true);
 
-  /* Keep pointer to parent open if we've execed so that pid will not be reused.
-     Otherwise, we no longer need this handle so close it.
-     Need to do this after debug_fixup_after_fork_exec or DEBUGGING handling of
-     handles might get confused. */
-  if (type != _CH_EXEC && child_proc_info->parent)
+  if (child_proc_info->parent)
     {
-      CloseHandle (child_proc_info->parent);
-      child_proc_info->parent = NULL;
+      if (type == _CH_EXEC)
+	{
+	  /* Keep pointer to parent open if we've execed so that pid will not be
+	     reused.  Try to Urther reduce permissions. */
+	  HANDLE new_parent;
+
+	  if (DuplicateHandle (GetCurrentProcess (), child_proc_info->parent,
+			       GetCurrentProcess (), &new_parent,
+			       SYNCHRONIZE, FALSE, 0))
+	    {
+	      CloseHandle (child_proc_info->parent);
+	      child_proc_info->parent = new_parent;
+	    }
+	}
+      else
+	{
+	  /* Otherwise, we no longer need this handle so close it.  Need to do
+	     this after debug_fixup_after_fork_exec or DEBUGGING handling of
+	     handles might get confused. */
+	  CloseHandle (child_proc_info->parent);
+	  child_proc_info->parent = NULL;
+	}
     }
 
   signal_fixup_after_exec ();
diff --git a/winsup/cygwin/sigproc.cc b/winsup/cygwin/sigproc.cc
index 42eeb30..080fe58 100644
--- a/winsup/cygwin/sigproc.cc
+++ b/winsup/cygwin/sigproc.cc
@@ -814,7 +814,8 @@ child_info::child_info (unsigned in_cb, child_info_types chtype,
      allow the child to copy cygheap etc. from the parent to itself.  If
      we're forking, we also need handle duplicate access. */
   parent = NULL;
-  DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ;
+  DWORD perms = PROCESS_QUERY_LIMITED_INFORMATION | PROCESS_VM_READ
+		| SYNCHRONIZE;
   if (type == _CH_FORK)
     {
       perms |= PROCESS_DUP_HANDLE;



More information about the Cygwin-cvs mailing list