[PATCH] server: Inherit standard handles together with explicit handle list.

Nikolay Sivov nsivov at codeweavers.com
Tue Sep 29 04:12:14 CDT 2020


Restores standard handles behavior pre-c58a10c16395c30e7793cde1f748febe0432a6ad,
always inheriting them when inherit mode is enabled.

Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=49895
Signed-off-by: Nikolay Sivov <nsivov at codeweavers.com>
---
 server/handle.c  | 36 ++++++++++++++++++++++++------------
 server/handle.h  |  3 ++-
 server/process.c | 14 ++++++++++----
 server/process.h |  2 +-
 server/request.c |  2 +-
 5 files changed, 38 insertions(+), 19 deletions(-)

diff --git a/server/handle.c b/server/handle.c
index d4df33f4730..15382256f10 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -354,10 +354,26 @@ static void shrink_handle_table( struct handle_table *table )
     table->entries = new_entries;
 }
 
+static void inherit_handle( struct process *parent, const obj_handle_t handle, struct handle_table *table )
+{
+    struct handle_entry *dst, *src;
+    int index;
+
+    dst = table->entries;
+
+    src = get_handle( parent, handle );
+    if (!src || !(src->access & RESERVED_INHERIT)) return;
+    grab_object_for_handle( src->ptr );
+    index = handle_to_index( handle );
+    dst[index] = *src;
+    table->last = max( table->last, index );
+}
+
 /* copy the handle table of the parent process */
 /* return 1 if OK, 0 on error */
 struct handle_table *copy_handle_table( struct process *process, struct process *parent,
-                                        const obj_handle_t *handles, unsigned int handle_count )
+                                        const obj_handle_t *handles, unsigned int handle_count,
+                                        const obj_handle_t *std_handles )
 {
     struct handle_table *parent_table = parent->handles;
     struct handle_table *table;
@@ -371,20 +387,16 @@ struct handle_table *copy_handle_table( struct process *process, struct process
 
     if (handles)
     {
-        struct handle_entry *dst, *src;
-        int index;
-
-        dst = table->entries;
-        memset( dst, 0, parent_table->count * sizeof(*dst) );
+        memset( table->entries, 0, parent_table->count * sizeof(*table->entries) );
 
         for (i = 0; i < handle_count; i++)
         {
-            src = get_handle( parent, handles[i] );
-            if (!src || !(src->access & RESERVED_INHERIT)) continue;
-            grab_object_for_handle( src->ptr );
-            index = handle_to_index( handles[i] );
-            dst[index] = *src;
-            table->last = max( table->last, index );
+            inherit_handle( parent, handles[i], table );
+        }
+
+        for (i = 0; i < 3; i++)
+        {
+            inherit_handle( parent, std_handles[i], table );
         }
     }
     else
diff --git a/server/handle.h b/server/handle.h
index bb541de13b1..ac3104dc003 100644
--- a/server/handle.h
+++ b/server/handle.h
@@ -51,7 +51,8 @@ extern obj_handle_t find_inherited_handle( struct process *process, const struct
 extern void close_process_handles( struct process *process );
 extern struct handle_table *alloc_handle_table( struct process *process, int count );
 extern struct handle_table *copy_handle_table( struct process *process, struct process *parent,
-                                               const obj_handle_t *handles, unsigned int handle_count );
+                                               const obj_handle_t *handles, unsigned int handle_count,
+                                               const obj_handle_t *std_handles );
 extern unsigned int get_handle_table_count( struct process *process);
 
 #endif  /* __WINE_SERVER_HANDLE_H */
diff --git a/server/process.c b/server/process.c
index 26958308ca7..1786493a814 100644
--- a/server/process.c
+++ b/server/process.c
@@ -502,7 +502,7 @@ static void start_sigkill_timer( struct process *process )
 
 /* create a new process */
 /* if the function fails the fd is closed */
-struct process *create_process( int fd, struct process *parent, int inherit_all,
+struct process *create_process( int fd, struct process *parent, int inherit_all, const startup_info_t *info,
                                 const struct security_descriptor *sd, const obj_handle_t *handles,
                                 unsigned int handle_count, struct token *token )
 {
@@ -576,8 +576,14 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
     }
     else
     {
+        obj_handle_t std_handles[3];
+
+        std_handles[0] = info->hstdin;
+        std_handles[1] = info->hstdout;
+        std_handles[2] = info->hstderr;
+
         process->parent_id = parent->id;
-        process->handles = inherit_all ? copy_handle_table( process, parent, handles, handle_count )
+        process->handles = inherit_all ? copy_handle_table( process, parent, handles, handle_count, std_handles )
                                        : alloc_handle_table( process, 0 );
         /* Note: for security reasons, starting a new process does not attempt
          * to use the current impersonation token for the new process */
@@ -1227,7 +1233,7 @@ DECL_HANDLER(new_process)
         goto done;
     }
 
-    if (!(process = create_process( socket_fd, parent, req->inherit_all, sd,
+    if (!(process = create_process( socket_fd, parent, req->inherit_all, info->data, sd,
                                     handles, req->handles_size / sizeof(*handles), token )))
         goto done;
 
@@ -1325,7 +1331,7 @@ DECL_HANDLER(exec_process)
         close( socket_fd );
         return;
     }
-    if (!(process = create_process( socket_fd, NULL, 0, NULL, NULL, 0, NULL ))) return;
+    if (!(process = create_process( socket_fd, NULL, 0, NULL, NULL, NULL, 0, NULL ))) return;
     create_thread( -1, process, NULL );
     release_object( process );
 }
diff --git a/server/process.h b/server/process.h
index bc81d563b47..56092e5b1ac 100644
--- a/server/process.h
+++ b/server/process.h
@@ -108,7 +108,7 @@ struct process
 extern unsigned int alloc_ptid( void *ptr );
 extern void free_ptid( unsigned int id );
 extern void *get_ptid_entry( unsigned int id );
-extern struct process *create_process( int fd, struct process *parent, int inherit_all,
+extern struct process *create_process( int fd, struct process *parent, int inherit_all, const startup_info_t *info,
                                        const struct security_descriptor *sd, const obj_handle_t *handles,
                                        unsigned int handle_count, struct token *token );
 extern data_size_t init_process( struct thread *thread );
diff --git a/server/request.c b/server/request.c
index 40e9478e09e..97bf1a746d2 100644
--- a/server/request.c
+++ b/server/request.c
@@ -583,7 +583,7 @@ static void master_socket_poll_event( struct fd *fd, int event )
         int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len );
         if (client == -1) return;
         fcntl( client, F_SETFL, O_NONBLOCK );
-        if ((process = create_process( client, NULL, 0, NULL, NULL, 0, NULL )))
+        if ((process = create_process( client, NULL, 0, NULL, NULL, NULL, 0, NULL )))
         {
             create_thread( -1, process, NULL );
             release_object( process );
-- 
2.28.0




More information about the wine-devel mailing list