From 39afcaac4a7a713188c5c23f5fe5114fc360c8d4 Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Thu, 20 Sep 2018 13:26:35 +0200 Subject: [PATCH] server: Create the initial thread as a separate request. Signed-off-by: Alexandre Julliard --- dlls/advapi32/tests/security.c | 1 - dlls/kernel32/process.c | 98 ++++++++++++++++++++++++++++++++++++++---- include/wine/server_protocol.h | 16 +++---- server/process.c | 9 +--- server/protocol.def | 10 ++--- server/request.h | 18 +++----- server/trace.c | 10 ++--- 7 files changed, 110 insertions(+), 52 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 6424d4bb4ec..5046442c6d8 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3096,7 +3096,6 @@ static void test_process_security_child(void) CloseHandle( handle ); handle = OpenThread( THREAD_SET_THREAD_TOKEN, FALSE, GetCurrentThreadId() ); - todo_wine ok(handle == NULL, "OpenThread(THREAD_SET_THREAD_TOKEN) should have failed\n"); } diff --git a/dlls/kernel32/process.c b/dlls/kernel32/process.c index 87c9ed70152..0967f72775f 100644 --- a/dlls/kernel32/process.c +++ b/dlls/kernel32/process.c @@ -1949,6 +1949,68 @@ static pid_t exec_loader( LPCWSTR cmd_line, unsigned int flags, int socketfd, return pid; } +/* creates a struct security_descriptor and contained information in one contiguous piece of memory */ +static NTSTATUS alloc_object_attributes( const SECURITY_ATTRIBUTES *attr, struct object_attributes **ret, + data_size_t *ret_len ) +{ + unsigned int len = sizeof(**ret); + PSID owner = NULL, group = NULL; + ACL *dacl, *sacl; + BOOLEAN dacl_present, sacl_present, defaulted; + PSECURITY_DESCRIPTOR sd = NULL; + NTSTATUS status; + + *ret = NULL; + *ret_len = 0; + + if (attr) sd = attr->lpSecurityDescriptor; + + if (sd) + { + len += sizeof(struct security_descriptor); + + if ((status = RtlGetOwnerSecurityDescriptor( sd, &owner, &defaulted ))) return status; + if ((status = RtlGetGroupSecurityDescriptor( sd, &group, &defaulted ))) return status; + if ((status = RtlGetSaclSecurityDescriptor( sd, &sacl_present, &sacl, &defaulted ))) return status; + if ((status = RtlGetDaclSecurityDescriptor( sd, &dacl_present, &dacl, &defaulted ))) return status; + if (owner) len += RtlLengthSid( owner ); + if (group) len += RtlLengthSid( group ); + if (sacl_present && sacl) len += sacl->AclSize; + if (dacl_present && dacl) len += dacl->AclSize; + } + + len = (len + 3) & ~3; /* DWORD-align the entire structure */ + + *ret = HeapAlloc( GetProcessHeap(), HEAP_ZERO_MEMORY, len ); + if (!*ret) return STATUS_NO_MEMORY; + + (*ret)->attributes = (attr && attr->bInheritHandle) ? OBJ_INHERIT : 0; + + if (sd) + { + struct security_descriptor *descr = (struct security_descriptor *)(*ret + 1); + unsigned char *ptr = (unsigned char *)(descr + 1); + + descr->control = ((SECURITY_DESCRIPTOR *)sd)->Control & ~SE_SELF_RELATIVE; + if (owner) descr->owner_len = RtlLengthSid( owner ); + if (group) descr->group_len = RtlLengthSid( group ); + if (sacl_present && sacl) descr->sacl_len = sacl->AclSize; + if (dacl_present && dacl) descr->dacl_len = dacl->AclSize; + + memcpy( ptr, owner, descr->owner_len ); + ptr += descr->owner_len; + memcpy( ptr, group, descr->group_len ); + ptr += descr->group_len; + memcpy( ptr, sacl, descr->sacl_len ); + ptr += descr->sacl_len; + memcpy( ptr, dacl, descr->dacl_len ); + (*ret)->sd_len = (sizeof(*descr) + descr->owner_len + descr->group_len + descr->sacl_len + + descr->dacl_len + sizeof(WCHAR) - 1) & ~(sizeof(WCHAR) - 1); + } + *ret_len = len; + return STATUS_SUCCESS; +} + /*********************************************************************** * create_process * @@ -1964,7 +2026,9 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW static const char *cpu_names[] = { "x86", "x86_64", "PowerPC", "ARM", "ARM64" }; NTSTATUS status; BOOL success = FALSE; - HANDLE process_info; + HANDLE process_info, process_handle = 0; + struct object_attributes *objattr; + data_size_t attr_len; WCHAR *env_end; char *winedebug = NULL; startup_info_t *startup_info; @@ -2062,10 +2126,8 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW req->create_flags = flags; req->socket_fd = socketfd[1]; req->exe_file = wine_server_obj_handle( hFile ); - req->process_access = PROCESS_ALL_ACCESS; - req->process_attr = (psa && (psa->nLength >= sizeof(*psa)) && psa->bInheritHandle) ? OBJ_INHERIT : 0; - req->thread_access = THREAD_ALL_ACCESS; - req->thread_attr = (tsa && (tsa->nLength >= sizeof(*tsa)) && tsa->bInheritHandle) ? OBJ_INHERIT : 0; + 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; @@ -2074,14 +2136,33 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW if (!(status = wine_server_call( req ))) { info->dwProcessId = (DWORD)reply->pid; - info->dwThreadId = (DWORD)reply->tid; - info->hProcess = wine_server_ptr_handle( reply->phandle ); - info->hThread = wine_server_ptr_handle( reply->thandle ); + process_handle = wine_server_ptr_handle( reply->handle ); } process_info = wine_server_ptr_handle( reply->info ); } SERVER_END_REQ; + if (!status) + { + alloc_object_attributes( tsa, &objattr, &attr_len ); + SERVER_START_REQ( new_thread ) + { + req->process = wine_server_obj_handle( process_handle ); + req->access = THREAD_ALL_ACCESS; + req->suspend = !!(flags & CREATE_SUSPENDED); + req->request_fd = -1; + wine_server_add_data( req, objattr, attr_len ); + if (!(status = wine_server_call( req ))) + { + info->hProcess = process_handle; + info->hThread = wine_server_ptr_handle( reply->handle ); + info->dwThreadId = reply->tid; + } + } + SERVER_END_REQ; + HeapFree( GetProcessHeap(), 0, objattr ); + } + RtlReleasePebLock(); if (status) { @@ -2096,6 +2177,7 @@ static BOOL create_process( HANDLE hFile, LPCWSTR filename, LPWSTR cmd_line, LPW break; } close( socketfd[0] ); + CloseHandle( process_handle ); HeapFree( GetProcessHeap(), 0, startup_info ); HeapFree( GetProcessHeap(), 0, winedebug ); SetLastError( RtlNtStatusToDosError( status )); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 02734bcd8cc..da3c79b1d30 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -726,25 +726,21 @@ struct new_process_request unsigned int create_flags; int socket_fd; obj_handle_t exe_file; - unsigned int process_access; - unsigned int process_attr; - unsigned int thread_access; - unsigned int thread_attr; + unsigned int access; + unsigned int attributes; cpu_type_t cpu; data_size_t info_size; /* VARARG(info,startup_info,info_size); */ /* VARARG(env,unicode_str); */ - char __pad_52[4]; + char __pad_44[4]; }; struct new_process_reply { struct reply_header __header; obj_handle_t info; process_id_t pid; - obj_handle_t phandle; - thread_id_t tid; - obj_handle_t thandle; - char __pad_28[4]; + obj_handle_t handle; + char __pad_20[4]; }; @@ -6536,6 +6532,6 @@ union generic_reply struct terminate_job_reply terminate_job_reply; }; -#define SERVER_PROTOCOL_VERSION 562 +#define SERVER_PROTOCOL_VERSION 563 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/process.c b/server/process.c index 0698887b6ae..a00fdd7c2a2 100644 --- a/server/process.c +++ b/server/process.c @@ -1061,7 +1061,6 @@ struct process_snapshot *process_snap( int *count ) DECL_HANDLER(new_process) { struct startup_info *info; - struct thread *thread; struct process *process = NULL; struct process *parent = current->process; int socket_fd = thread_get_inflight_fd( current, req->socket_fd ); @@ -1166,7 +1165,6 @@ DECL_HANDLER(new_process) } if (!(process = create_process( socket_fd, current, req->inherit_all ))) goto done; - if (!(thread = create_thread( -1, process, NULL ))) goto done; process->startup_info = (struct startup_info *)grab_object( info ); @@ -1180,9 +1178,6 @@ DECL_HANDLER(new_process) /* connect to the window station */ connect_process_winstation( process, current ); - /* thread will be actually suspended in init_done */ - if (req->create_flags & CREATE_SUSPENDED) thread->suspend++; - /* set the process console */ if (!(req->create_flags & (DETACHED_PROCESS | CREATE_NEW_CONSOLE))) { @@ -1224,9 +1219,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->tid = get_thread_id( thread ); - reply->phandle = alloc_handle( parent, process, req->process_access, req->process_attr ); - reply->thandle = alloc_handle( parent, thread, req->thread_access, req->thread_attr ); + reply->handle = alloc_handle( parent, process, req->access, req->attributes ); done: if (process) release_object( process ); diff --git a/server/protocol.def b/server/protocol.def index 1c2e1308c4b..f7506bd10a5 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -740,10 +740,8 @@ struct rawinput_device unsigned int create_flags; /* creation flags */ int socket_fd; /* file descriptor for process socket */ obj_handle_t exe_file; /* file handle for main exe */ - unsigned int process_access; /* access rights for process object */ - unsigned int process_attr; /* attributes for process object */ - unsigned int thread_access; /* access rights for thread object */ - unsigned int thread_attr; /* attributes for thread object */ + 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(info,startup_info,info_size); /* startup information */ @@ -751,9 +749,7 @@ struct rawinput_device @REPLY obj_handle_t info; /* new process info handle */ process_id_t pid; /* process id */ - obj_handle_t phandle; /* process handle (in the current process) */ - thread_id_t tid; /* thread id */ - obj_handle_t thandle; /* thread handle (in the current process) */ + obj_handle_t handle; /* process handle (in the current process) */ @END diff --git a/server/request.h b/server/request.h index d7a4c8d7c13..624da01a905 100644 --- a/server/request.h +++ b/server/request.h @@ -734,19 +734,15 @@ C_ASSERT( FIELD_OFFSET(struct new_process_request, inherit_all) == 12 ); 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, process_access) == 28 ); -C_ASSERT( FIELD_OFFSET(struct new_process_request, process_attr) == 32 ); -C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_access) == 36 ); -C_ASSERT( FIELD_OFFSET(struct new_process_request, thread_attr) == 40 ); -C_ASSERT( FIELD_OFFSET(struct new_process_request, cpu) == 44 ); -C_ASSERT( FIELD_OFFSET(struct new_process_request, info_size) == 48 ); -C_ASSERT( sizeof(struct new_process_request) == 56 ); +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_reply, info) == 8 ); C_ASSERT( FIELD_OFFSET(struct new_process_reply, pid) == 12 ); -C_ASSERT( FIELD_OFFSET(struct new_process_reply, phandle) == 16 ); -C_ASSERT( FIELD_OFFSET(struct new_process_reply, tid) == 20 ); -C_ASSERT( FIELD_OFFSET(struct new_process_reply, thandle) == 24 ); -C_ASSERT( sizeof(struct new_process_reply) == 32 ); +C_ASSERT( FIELD_OFFSET(struct new_process_reply, handle) == 16 ); +C_ASSERT( sizeof(struct new_process_reply) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_request, info) == 12 ); C_ASSERT( sizeof(struct get_new_process_info_request) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_new_process_info_reply, success) == 8 ); diff --git a/server/trace.c b/server/trace.c index a419ddf2573..5e648a9551b 100644 --- a/server/trace.c +++ b/server/trace.c @@ -1229,10 +1229,8 @@ static void dump_new_process_request( const struct new_process_request *req ) fprintf( stderr, ", create_flags=%08x", req->create_flags ); fprintf( stderr, ", socket_fd=%d", req->socket_fd ); fprintf( stderr, ", exe_file=%04x", req->exe_file ); - fprintf( stderr, ", process_access=%08x", req->process_access ); - fprintf( stderr, ", process_attr=%08x", req->process_attr ); - fprintf( stderr, ", thread_access=%08x", req->thread_access ); - fprintf( stderr, ", thread_attr=%08x", req->thread_attr ); + 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_startup_info( ", info=", min(cur_size,req->info_size) ); @@ -1243,9 +1241,7 @@ static void dump_new_process_reply( const struct new_process_reply *req ) { fprintf( stderr, " info=%04x", req->info ); fprintf( stderr, ", pid=%04x", req->pid ); - fprintf( stderr, ", phandle=%04x", req->phandle ); - fprintf( stderr, ", tid=%04x", req->tid ); - fprintf( stderr, ", thandle=%04x", req->thandle ); + fprintf( stderr, ", handle=%04x", req->handle ); } static void dump_get_new_process_info_request( const struct get_new_process_info_request *req ) -- 2.11.4.GIT