server: Allow specifying the security descriptor for a new thread.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
be40b01c37
commit
4a328e08ac
|
@ -97,7 +97,7 @@ HANDLE WINAPI CreateRemoteThreadEx( HANDLE hProcess, SECURITY_ATTRIBUTES *sa, SI
|
||||||
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
|
if (flags & STACK_SIZE_PARAM_IS_A_RESERVATION) stack_reserve = stack;
|
||||||
else stack_commit = stack;
|
else stack_commit = stack;
|
||||||
|
|
||||||
status = RtlCreateUserThread( hProcess, NULL, TRUE,
|
status = RtlCreateUserThread( hProcess, sa ? sa->lpSecurityDescriptor : NULL, TRUE,
|
||||||
NULL, stack_reserve, stack_commit,
|
NULL, stack_reserve, stack_commit,
|
||||||
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
|
(PRTL_THREAD_START_ROUTINE)start, param, &handle, &client_id );
|
||||||
if (status == STATUS_SUCCESS)
|
if (status == STATUS_SUCCESS)
|
||||||
|
|
|
@ -544,7 +544,7 @@ NTSTATUS WINAPI NtCreateThreadEx( HANDLE *handle_ptr, ACCESS_MASK access, OBJECT
|
||||||
/***********************************************************************
|
/***********************************************************************
|
||||||
* RtlCreateUserThread (NTDLL.@)
|
* RtlCreateUserThread (NTDLL.@)
|
||||||
*/
|
*/
|
||||||
NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *descr,
|
NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, SECURITY_DESCRIPTOR *descr,
|
||||||
BOOLEAN suspended, PVOID stack_addr,
|
BOOLEAN suspended, PVOID stack_addr,
|
||||||
SIZE_T stack_reserve, SIZE_T stack_commit,
|
SIZE_T stack_reserve, SIZE_T stack_commit,
|
||||||
PRTL_THREAD_START_ROUTINE start, void *param,
|
PRTL_THREAD_START_ROUTINE start, void *param,
|
||||||
|
@ -561,6 +561,8 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
int request_pipe[2];
|
int request_pipe[2];
|
||||||
NTSTATUS status;
|
NTSTATUS status;
|
||||||
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
SIZE_T extra_stack = PTHREAD_STACK_MIN;
|
||||||
|
data_size_t len = 0;
|
||||||
|
struct object_attributes *objattr = NULL;
|
||||||
|
|
||||||
if (process != NtCurrentProcess())
|
if (process != NtCurrentProcess())
|
||||||
{
|
{
|
||||||
|
@ -587,15 +589,26 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
return result.create_thread.status;
|
return result.create_thread.status;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (server_pipe( request_pipe ) == -1) return STATUS_TOO_MANY_OPENED_FILES;
|
if (descr)
|
||||||
|
{
|
||||||
|
OBJECT_ATTRIBUTES thread_attr;
|
||||||
|
InitializeObjectAttributes( &thread_attr, NULL, 0, NULL, descr );
|
||||||
|
if ((status = alloc_object_attributes( &thread_attr, &objattr, &len ))) return status;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (server_pipe( request_pipe ) == -1)
|
||||||
|
{
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
|
return STATUS_TOO_MANY_OPENED_FILES;
|
||||||
|
}
|
||||||
wine_server_send_fd( request_pipe[0] );
|
wine_server_send_fd( request_pipe[0] );
|
||||||
|
|
||||||
SERVER_START_REQ( new_thread )
|
SERVER_START_REQ( new_thread )
|
||||||
{
|
{
|
||||||
req->access = THREAD_ALL_ACCESS;
|
req->access = THREAD_ALL_ACCESS;
|
||||||
req->attributes = 0; /* FIXME */
|
|
||||||
req->suspend = suspended;
|
req->suspend = suspended;
|
||||||
req->request_fd = request_pipe[0];
|
req->request_fd = request_pipe[0];
|
||||||
|
wine_server_add_data( req, objattr, len );
|
||||||
if (!(status = wine_server_call( req )))
|
if (!(status = wine_server_call( req )))
|
||||||
{
|
{
|
||||||
handle = wine_server_ptr_handle( reply->handle );
|
handle = wine_server_ptr_handle( reply->handle );
|
||||||
|
@ -605,6 +618,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
|
||||||
}
|
}
|
||||||
SERVER_END_REQ;
|
SERVER_END_REQ;
|
||||||
|
|
||||||
|
RtlFreeHeap( GetProcessHeap(), 0, objattr );
|
||||||
if (status)
|
if (status)
|
||||||
{
|
{
|
||||||
close( request_pipe[1] );
|
close( request_pipe[1] );
|
||||||
|
|
|
@ -767,10 +767,9 @@ struct new_thread_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
unsigned int access;
|
unsigned int access;
|
||||||
unsigned int attributes;
|
|
||||||
int suspend;
|
int suspend;
|
||||||
int request_fd;
|
int request_fd;
|
||||||
char __pad_28[4];
|
/* VARARG(objattr,object_attributes); */
|
||||||
};
|
};
|
||||||
struct new_thread_reply
|
struct new_thread_reply
|
||||||
{
|
{
|
||||||
|
@ -6535,6 +6534,6 @@ union generic_reply
|
||||||
struct terminate_job_reply terminate_job_reply;
|
struct terminate_job_reply terminate_job_reply;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 560
|
#define SERVER_PROTOCOL_VERSION 561
|
||||||
|
|
||||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -2608,7 +2608,7 @@ NTSYSAPI NTSTATUS WINAPI RtlCreateTimer(PHANDLE, HANDLE, RTL_WAITORTIMERCALLBAC
|
||||||
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
|
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeString(PUNICODE_STRING,LPCWSTR);
|
||||||
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
|
NTSYSAPI BOOLEAN WINAPI RtlCreateUnicodeStringFromAsciiz(PUNICODE_STRING,LPCSTR);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING*,ULONG,RTL_USER_PROCESS_PARAMETERS*,SECURITY_DESCRIPTOR*,SECURITY_DESCRIPTOR*,HANDLE,BOOLEAN,HANDLE,HANDLE,RTL_USER_PROCESS_INFORMATION*);
|
NTSYSAPI NTSTATUS WINAPI RtlCreateUserProcess(UNICODE_STRING*,ULONG,RTL_USER_PROCESS_PARAMETERS*,SECURITY_DESCRIPTOR*,SECURITY_DESCRIPTOR*,HANDLE,BOOLEAN,HANDLE,HANDLE,RTL_USER_PROCESS_INFORMATION*);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,const SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
|
NTSYSAPI NTSTATUS WINAPI RtlCreateUserThread(HANDLE,SECURITY_DESCRIPTOR*,BOOLEAN,PVOID,SIZE_T,SIZE_T,PRTL_THREAD_START_ROUTINE,void*,HANDLE*,CLIENT_ID*);
|
||||||
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR);
|
NTSYSAPI void WINAPI RtlDeactivateActivationContext(DWORD,ULONG_PTR);
|
||||||
NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID);
|
NTSYSAPI PVOID WINAPI RtlDecodePointer(PVOID);
|
||||||
NTSYSAPI NTSTATUS WINAPI RtlDecompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,PULONG);
|
NTSYSAPI NTSTATUS WINAPI RtlDecompressBuffer(USHORT,PUCHAR,ULONG,PUCHAR,ULONG,PULONG);
|
||||||
|
|
|
@ -590,7 +590,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
close( request_pipe[1] );
|
close( request_pipe[1] );
|
||||||
if (!(thread = create_thread( request_pipe[0], process ))) goto error;
|
if (!(thread = create_thread( request_pipe[0], process, NULL ))) goto error;
|
||||||
|
|
||||||
set_fd_events( process->msg_fd, POLLIN ); /* start listening to events */
|
set_fd_events( process->msg_fd, POLLIN ); /* start listening to events */
|
||||||
release_object( process );
|
release_object( process );
|
||||||
|
|
|
@ -769,9 +769,9 @@ struct rawinput_device
|
||||||
/* Create a new thread from the context of the parent */
|
/* Create a new thread from the context of the parent */
|
||||||
@REQ(new_thread)
|
@REQ(new_thread)
|
||||||
unsigned int access; /* wanted access rights */
|
unsigned int access; /* wanted access rights */
|
||||||
unsigned int attributes; /* object attributes */
|
|
||||||
int suspend; /* new thread should be suspended on creation */
|
int suspend; /* new thread should be suspended on creation */
|
||||||
int request_fd; /* fd for request pipe */
|
int request_fd; /* fd for request pipe */
|
||||||
|
VARARG(objattr,object_attributes); /* object attributes */
|
||||||
@REPLY
|
@REPLY
|
||||||
thread_id_t tid; /* thread id */
|
thread_id_t tid; /* thread id */
|
||||||
obj_handle_t handle; /* thread handle (in the current process) */
|
obj_handle_t handle; /* thread handle (in the current process) */
|
||||||
|
|
|
@ -753,10 +753,9 @@ C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, exit_code) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, exit_code) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_new_process_info_reply) == 16 );
|
C_ASSERT( sizeof(struct get_new_process_info_reply) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_request, access) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct new_thread_request, access) == 12 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_request, attributes) == 16 );
|
C_ASSERT( FIELD_OFFSET(struct new_thread_request, suspend) == 16 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_request, suspend) == 20 );
|
C_ASSERT( FIELD_OFFSET(struct new_thread_request, request_fd) == 20 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_request, request_fd) == 24 );
|
C_ASSERT( sizeof(struct new_thread_request) == 24 );
|
||||||
C_ASSERT( sizeof(struct new_thread_request) == 32 );
|
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 );
|
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, tid) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct new_thread_reply, handle) == 12 );
|
||||||
C_ASSERT( sizeof(struct new_thread_reply) == 16 );
|
C_ASSERT( sizeof(struct new_thread_reply) == 16 );
|
||||||
|
|
|
@ -218,7 +218,7 @@ static inline int is_valid_address( client_ptr_t addr )
|
||||||
}
|
}
|
||||||
|
|
||||||
/* create a new thread */
|
/* create a new thread */
|
||||||
struct thread *create_thread( int fd, struct process *process )
|
struct thread *create_thread( int fd, struct process *process, const struct security_descriptor *sd )
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
|
||||||
|
@ -244,6 +244,15 @@ struct thread *create_thread( int fd, struct process *process )
|
||||||
|
|
||||||
list_add_head( &thread_list, &thread->entry );
|
list_add_head( &thread_list, &thread->entry );
|
||||||
|
|
||||||
|
if (sd && !set_sd_defaults_from_token( &thread->obj, sd,
|
||||||
|
OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
|
||||||
|
DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION,
|
||||||
|
process->token ))
|
||||||
|
{
|
||||||
|
close( fd );
|
||||||
|
release_object( thread );
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
if (!(thread->id = alloc_ptid( thread )))
|
if (!(thread->id = alloc_ptid( thread )))
|
||||||
{
|
{
|
||||||
close( fd );
|
close( fd );
|
||||||
|
@ -1244,6 +1253,9 @@ unsigned int get_supported_cpu_mask(void)
|
||||||
DECL_HANDLER(new_thread)
|
DECL_HANDLER(new_thread)
|
||||||
{
|
{
|
||||||
struct thread *thread;
|
struct thread *thread;
|
||||||
|
struct unicode_str name;
|
||||||
|
const struct security_descriptor *sd;
|
||||||
|
const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
|
||||||
int request_fd = thread_get_inflight_fd( current, req->request_fd );
|
int request_fd = thread_get_inflight_fd( current, req->request_fd );
|
||||||
|
|
||||||
if (request_fd == -1 || fcntl( request_fd, F_SETFL, O_NONBLOCK ) == -1)
|
if (request_fd == -1 || fcntl( request_fd, F_SETFL, O_NONBLOCK ) == -1)
|
||||||
|
@ -1253,12 +1265,13 @@ DECL_HANDLER(new_thread)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if ((thread = create_thread( request_fd, current->process )))
|
if ((thread = create_thread( request_fd, current->process, sd )))
|
||||||
{
|
{
|
||||||
thread->system_regs = current->system_regs;
|
thread->system_regs = current->system_regs;
|
||||||
if (req->suspend) thread->suspend++;
|
if (req->suspend) thread->suspend++;
|
||||||
reply->tid = get_thread_id( thread );
|
reply->tid = get_thread_id( thread );
|
||||||
if ((reply->handle = alloc_handle( current->process, thread, req->access, req->attributes )))
|
if ((reply->handle = alloc_handle_no_access_check( current->process, thread,
|
||||||
|
req->access, objattr->attributes )))
|
||||||
{
|
{
|
||||||
/* thread object will be released when the thread gets killed */
|
/* thread object will be released when the thread gets killed */
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -102,7 +102,8 @@ extern struct thread *current;
|
||||||
|
|
||||||
/* thread functions */
|
/* thread functions */
|
||||||
|
|
||||||
extern struct thread *create_thread( int fd, struct process *process );
|
extern struct thread *create_thread( int fd, struct process *process,
|
||||||
|
const struct security_descriptor *sd );
|
||||||
extern struct thread *get_thread_from_id( thread_id_t id );
|
extern struct thread *get_thread_from_id( thread_id_t id );
|
||||||
extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int access );
|
extern struct thread *get_thread_from_handle( obj_handle_t handle, unsigned int access );
|
||||||
extern struct thread *get_thread_from_tid( int tid );
|
extern struct thread *get_thread_from_tid( int tid );
|
||||||
|
|
|
@ -1262,9 +1262,9 @@ static void dump_get_new_process_info_reply( const struct get_new_process_info_r
|
||||||
static void dump_new_thread_request( const struct new_thread_request *req )
|
static void dump_new_thread_request( const struct new_thread_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " access=%08x", req->access );
|
fprintf( stderr, " access=%08x", req->access );
|
||||||
fprintf( stderr, ", attributes=%08x", req->attributes );
|
|
||||||
fprintf( stderr, ", suspend=%d", req->suspend );
|
fprintf( stderr, ", suspend=%d", req->suspend );
|
||||||
fprintf( stderr, ", request_fd=%d", req->request_fd );
|
fprintf( stderr, ", request_fd=%d", req->request_fd );
|
||||||
|
dump_varargs_object_attributes( ", objattr=", cur_size );
|
||||||
}
|
}
|
||||||
|
|
||||||
static void dump_new_thread_reply( const struct new_thread_reply *req )
|
static void dump_new_thread_reply( const struct new_thread_reply *req )
|
||||||
|
|
Loading…
Reference in New Issue