server: Allow specifying the security descriptor for a new process.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
39afcaac4a
commit
ac7ae92af1
|
@ -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 */
|
||||
|
|
|
@ -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)
|
||||
{
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 );
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue