server: Inherit standard handles together with explicit handle list.
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@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
97636bc9b6
commit
fde5967f72
|
@ -354,10 +354,26 @@ static void shrink_handle_table( struct handle_table *table )
|
||||||
table->entries = new_entries;
|
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 */
|
/* copy the handle table of the parent process */
|
||||||
/* return 1 if OK, 0 on error */
|
/* return 1 if OK, 0 on error */
|
||||||
struct handle_table *copy_handle_table( struct process *process, struct process *parent,
|
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 *parent_table = parent->handles;
|
||||||
struct handle_table *table;
|
struct handle_table *table;
|
||||||
|
@ -371,20 +387,16 @@ struct handle_table *copy_handle_table( struct process *process, struct process
|
||||||
|
|
||||||
if (handles)
|
if (handles)
|
||||||
{
|
{
|
||||||
struct handle_entry *dst, *src;
|
memset( table->entries, 0, parent_table->count * sizeof(*table->entries) );
|
||||||
int index;
|
|
||||||
|
|
||||||
dst = table->entries;
|
|
||||||
memset( dst, 0, parent_table->count * sizeof(*dst) );
|
|
||||||
|
|
||||||
for (i = 0; i < handle_count; i++)
|
for (i = 0; i < handle_count; i++)
|
||||||
{
|
{
|
||||||
src = get_handle( parent, handles[i] );
|
inherit_handle( parent, handles[i], table );
|
||||||
if (!src || !(src->access & RESERVED_INHERIT)) continue;
|
}
|
||||||
grab_object_for_handle( src->ptr );
|
|
||||||
index = handle_to_index( handles[i] );
|
for (i = 0; i < 3; i++)
|
||||||
dst[index] = *src;
|
{
|
||||||
table->last = max( table->last, index );
|
inherit_handle( parent, std_handles[i], table );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
@ -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 void close_process_handles( struct process *process );
|
||||||
extern struct handle_table *alloc_handle_table( struct process *process, int count );
|
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,
|
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);
|
extern unsigned int get_handle_table_count( struct process *process);
|
||||||
|
|
||||||
#endif /* __WINE_SERVER_HANDLE_H */
|
#endif /* __WINE_SERVER_HANDLE_H */
|
||||||
|
|
|
@ -502,7 +502,7 @@ static void start_sigkill_timer( struct process *process )
|
||||||
|
|
||||||
/* create a new process */
|
/* create a new process */
|
||||||
/* if the function fails the fd is closed */
|
/* 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,
|
const struct security_descriptor *sd, const obj_handle_t *handles,
|
||||||
unsigned int handle_count, struct token *token )
|
unsigned int handle_count, struct token *token )
|
||||||
{
|
{
|
||||||
|
@ -576,8 +576,14 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
|
||||||
}
|
}
|
||||||
else
|
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->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 );
|
: alloc_handle_table( process, 0 );
|
||||||
/* Note: for security reasons, starting a new process does not attempt
|
/* Note: for security reasons, starting a new process does not attempt
|
||||||
* to use the current impersonation token for the new process */
|
* to use the current impersonation token for the new process */
|
||||||
|
@ -1227,7 +1233,7 @@ DECL_HANDLER(new_process)
|
||||||
goto done;
|
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 )))
|
handles, req->handles_size / sizeof(*handles), token )))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
@ -1325,7 +1331,7 @@ DECL_HANDLER(exec_process)
|
||||||
close( socket_fd );
|
close( socket_fd );
|
||||||
return;
|
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 );
|
create_thread( -1, process, NULL );
|
||||||
release_object( process );
|
release_object( process );
|
||||||
}
|
}
|
||||||
|
|
|
@ -108,7 +108,7 @@ struct process
|
||||||
extern unsigned int alloc_ptid( void *ptr );
|
extern unsigned int alloc_ptid( void *ptr );
|
||||||
extern void free_ptid( unsigned int id );
|
extern void free_ptid( unsigned int id );
|
||||||
extern void *get_ptid_entry( 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,
|
const struct security_descriptor *sd, const obj_handle_t *handles,
|
||||||
unsigned int handle_count, struct token *token );
|
unsigned int handle_count, struct token *token );
|
||||||
extern data_size_t init_process( struct thread *thread );
|
extern data_size_t init_process( struct thread *thread );
|
||||||
|
|
|
@ -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 );
|
int client = accept( get_unix_fd( master_socket->fd ), (struct sockaddr *) &dummy, &len );
|
||||||
if (client == -1) return;
|
if (client == -1) return;
|
||||||
fcntl( client, F_SETFL, O_NONBLOCK );
|
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 );
|
create_thread( -1, process, NULL );
|
||||||
release_object( process );
|
release_object( process );
|
||||||
|
|
Loading…
Reference in New Issue