server: Allow specifying the security descriptor for a new process.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2018-09-20 13:39:28 +02:00
parent 39afcaac4a
commit ac7ae92af1
9 changed files with 38 additions and 24 deletions

View File

@ -3053,7 +3053,6 @@ static void test_process_security_child(void)
ret = DuplicateHandle( GetCurrentProcess(), handle, GetCurrentProcess(),
&handle1, PROCESS_ALL_ACCESS, TRUE, 0 );
err = GetLastError();
todo_wine
ok(!ret && err == ERROR_ACCESS_DENIED, "duplicating handle should have failed "
"with STATUS_ACCESS_DENIED, instead of err:%d\n", err);
@ -3061,10 +3060,8 @@ static void test_process_security_child(void)
/* These two should fail - they are denied by ACL */
handle = OpenProcess( PROCESS_VM_READ, FALSE, GetCurrentProcessId() );
todo_wine
ok(handle == NULL, "OpenProcess(PROCESS_VM_READ) should have failed\n");
handle = OpenProcess( PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId() );
todo_wine
ok(handle == NULL, "OpenProcess(PROCESS_ALL_ACCESS) should have failed\n");
/* Documented privilege elevation */

View File

@ -2120,6 +2120,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
/* create the process on the server side */
alloc_object_attributes( psa, &objattr, &attr_len );
SERVER_START_REQ( new_process )
{
req->inherit_all = inherit;
@ -2127,10 +2128,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
req->socket_fd = socketfd[1];
req->exe_file = wine_server_obj_handle( hFile );
req->access = PROCESS_ALL_ACCESS;
req->attributes = (psa && psa->nLength >= sizeof(*psa) && psa->bInheritHandle) ? OBJ_INHERIT : 0;
req->cpu = cpu;
req->info_size = startup_info_size;
wine_server_add_data( req, objattr, attr_len );
wine_server_add_data( req, startup_info, startup_info_size );
wine_server_add_data( req, env, (env_end - env) * sizeof(WCHAR) );
if (!(status = wine_server_call( req )))
@ -2141,6 +2141,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW
process_info = wine_server_ptr_handle( reply->info );
}
SERVER_END_REQ;
HeapFree( GetProcessHeap(), 0, objattr );
if (!status)
{

View File

@ -727,12 +727,11 @@ struct new_process_request
int socket_fd;
obj_handle_t exe_file;
unsigned int access;
unsigned int attributes;
cpu_type_t cpu;
data_size_t info_size;
/* VARARG(objattr,object_attributes); */
/* VARARG(info,startup_info,info_size); */
/* VARARG(env,unicode_str); */
char __pad_44[4];
};
struct new_process_reply
{
@ -6532,6 +6531,6 @@ union generic_reply
struct terminate_job_reply terminate_job_reply;
};
#define SERVER_PROTOCOL_VERSION 563
#define SERVER_PROTOCOL_VERSION 564
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */

View File

@ -485,7 +485,8 @@ 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 thread *parent_thread, int inherit_all )
struct process *create_process( int fd, struct thread *parent_thread, int inherit_all,
const struct security_descriptor *sd )
{
struct process *process;
@ -532,6 +533,12 @@ struct process *create_process( int fd, struct thread *parent_thread, int inheri
process->end_time = 0;
list_add_tail( &process_list, &process->entry );
if (sd && !default_set_sd( &process->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION ))
{
close( fd );
goto error;
}
if (!(process->id = process->group_id = alloc_ptid( process )))
{
close( fd );
@ -1061,6 +1068,10 @@ struct process_snapshot *process_snap( int *count )
DECL_HANDLER(new_process)
{
struct startup_info *info;
const void *info_ptr;
struct unicode_str name;
const struct security_descriptor *sd;
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
struct process *process = NULL;
struct process *parent = current->process;
int socket_fd = thread_get_inflight_fd( current, req->socket_fd );
@ -1070,6 +1081,12 @@ DECL_HANDLER(new_process)
set_error( STATUS_INVALID_PARAMETER );
return;
}
if (!objattr)
{
set_error( STATUS_INVALID_PARAMETER );
close( socket_fd );
return;
}
if (fcntl( socket_fd, F_SETFL, O_NONBLOCK ) == -1)
{
set_error( STATUS_INVALID_HANDLE );
@ -1098,7 +1115,7 @@ DECL_HANDLER(new_process)
if (!req->info_size) /* create an orphaned process */
{
if ((process = create_process( socket_fd, NULL, 0 )))
if ((process = create_process( socket_fd, NULL, 0, sd )))
{
create_thread( -1, process, NULL );
release_object( process );
@ -1123,7 +1140,7 @@ DECL_HANDLER(new_process)
goto done;
}
info->data_size = get_req_data_size();
info_ptr = get_req_data_after_objattr( objattr, &info->data_size );
info->info_size = min( req->info_size, info->data_size );
if (req->info_size < sizeof(*info->data))
@ -1137,9 +1154,9 @@ DECL_HANDLER(new_process)
close( socket_fd );
goto done;
}
memcpy( info->data, get_req_data(), info_size );
memcpy( info->data, info_ptr, info_size );
memset( (char *)info->data + info_size, 0, sizeof(*info->data) - info_size );
memcpy( info->data + 1, (const char *)get_req_data() + req->info_size, env_size );
memcpy( info->data + 1, (const char *)info_ptr + req->info_size, env_size );
info->info_size = sizeof(startup_info_t);
info->data_size = info->info_size + env_size;
}
@ -1147,7 +1164,7 @@ DECL_HANDLER(new_process)
{
data_size_t pos = sizeof(*info->data);
if (!(info->data = memdup( get_req_data(), info->data_size )))
if (!(info->data = memdup( info_ptr, info->data_size )))
{
close( socket_fd );
goto done;
@ -1164,7 +1181,7 @@ DECL_HANDLER(new_process)
#undef FIXUP_LEN
}
if (!(process = create_process( socket_fd, current, req->inherit_all ))) goto done;
if (!(process = create_process( socket_fd, current, req->inherit_all, sd ))) goto done;
process->startup_info = (struct startup_info *)grab_object( info );
@ -1219,7 +1236,7 @@ DECL_HANDLER(new_process)
info->process = (struct process *)grab_object( process );
reply->info = alloc_handle( current->process, info, SYNCHRONIZE, 0 );
reply->pid = get_process_id( process );
reply->handle = alloc_handle( parent, process, req->access, req->attributes );
reply->handle = alloc_handle_no_access_check( parent, process, req->access, objattr->attributes );
done:
if (process) release_object( process );

View File

@ -114,7 +114,8 @@ struct process_snapshot
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 thread *parent_thread, int inherit_all );
extern struct process *create_process( int fd, struct thread *parent_thread, int inherit_all,
const struct security_descriptor *sd );
extern data_size_t init_process( struct thread *thread );
extern struct thread *get_process_first_thread( struct process *process );
extern struct process *get_process_from_id( process_id_t id );

View File

@ -741,9 +741,9 @@ struct rawinput_device
int socket_fd; /* file descriptor for process socket */
obj_handle_t exe_file; /* file handle for main exe */
unsigned int access; /* access rights for process object */
unsigned int attributes; /* attributes for process object */
cpu_type_t cpu; /* CPU that the new process will use */
data_size_t info_size; /* size of startup info */
VARARG(objattr,object_attributes); /* object attributes */
VARARG(info,startup_info,info_size); /* startup information */
VARARG(env,unicode_str); /* environment for new process */
@REPLY

View File

@ -577,7 +577,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 )))
if ((process = create_process( client, NULL, 0, NULL )))
{
create_thread( -1, process, NULL );
release_object( process );

View File

@ -735,10 +735,9 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, create_flags) == 16 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, socket_fd) == 20 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, exe_file) == 24 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, access) == 28 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, attributes) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 36 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 40 );
C_ASSERT( sizeof(struct new_process_request) == 48 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 32 );
C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 36 );
C_ASSERT( sizeof(struct new_process_request) == 40 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, info) == 8 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 );
C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 );

View File

@ -1230,9 +1230,9 @@ static void dump_new_process_request( const struct new_process_request *req )
fprintf( stderr, ", socket_fd=%d", req->socket_fd );
fprintf( stderr, ", exe_file=%04x", req->exe_file );
fprintf( stderr, ", access=%08x", req->access );
fprintf( stderr, ", attributes=%08x", req->attributes );
dump_cpu_type( ", cpu=", &req->cpu );
fprintf( stderr, ", info_size=%u", req->info_size );
dump_varargs_object_attributes( ", objattr=", cur_size );
dump_varargs_startup_info( ", info=", min(cur_size,req->info_size) );
dump_varargs_unicode_str( ", env=", cur_size );
}