Commit 8891d6de authored by Alexandre Julliard's avatar Alexandre Julliard

ntdll: Block async signals during process init and thread creation.

parent c388c58b
...@@ -2139,24 +2139,7 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3, ...@@ -2139,24 +2139,7 @@ void WINAPI LdrInitializeThunk( ULONG unknown1, ULONG unknown2, ULONG unknown3,
RemoveEntryList( &wm->ldr.InLoadOrderModuleList ); RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList ); InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList );
/* Install signal handlers; this cannot be done before, since we cannot status = server_init_process_done();
* send exceptions to the debugger before the create process event that
* is sent by REQ_INIT_PROCESS_DONE.
* We do need the handlers in place by the time the request is over, so
* we set them up here. If we segfault between here and the server call
* something is very wrong... */
if (!SIGNAL_Init()) exit(1);
/* Signal the parent process to continue */
SERVER_START_REQ( init_process_done )
{
req->module = peb->ImageBaseAddress;
req->entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
req->gui = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
status = wine_server_call( req );
}
SERVER_END_REQ;
if (status != STATUS_SUCCESS) goto error; if (status != STATUS_SUCCESS) goto error;
RtlEnterCriticalSection( &loader_section ); RtlEnterCriticalSection( &loader_section );
......
...@@ -58,6 +58,7 @@ extern void virtual_init_threading(void); ...@@ -58,6 +58,7 @@ extern void virtual_init_threading(void);
/* server support */ /* server support */
extern abs_time_t server_start_time; extern abs_time_t server_start_time;
extern void server_init_process(void); extern void server_init_process(void);
extern NTSTATUS server_init_process_done(void);
extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point ); extern size_t server_init_thread( int unix_pid, int unix_tid, void *entry_point );
extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... ); extern void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
extern void DECLSPEC_NORETURN server_protocol_perror( const char *err ); extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
......
...@@ -1018,6 +1018,7 @@ void server_init_process(void) ...@@ -1018,6 +1018,7 @@ void server_init_process(void)
sigaddset( &server_block_set, SIGUSR1 ); sigaddset( &server_block_set, SIGUSR1 );
sigaddset( &server_block_set, SIGUSR2 ); sigaddset( &server_block_set, SIGUSR2 );
sigaddset( &server_block_set, SIGCHLD ); sigaddset( &server_block_set, SIGCHLD );
pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
/* receive the first thread request fd on the main socket */ /* receive the first thread request fd on the main socket */
ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle ); ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle );
...@@ -1029,6 +1030,38 @@ void server_init_process(void) ...@@ -1029,6 +1030,38 @@ void server_init_process(void)
/*********************************************************************** /***********************************************************************
* server_init_process_done
*/
NTSTATUS server_init_process_done(void)
{
PEB *peb = NtCurrentTeb()->Peb;
IMAGE_NT_HEADERS *nt = RtlImageNtHeader( peb->ImageBaseAddress );
NTSTATUS status;
/* Install signal handlers; this cannot be done earlier, since we cannot
* send exceptions to the debugger before the create process event that
* is sent by REQ_INIT_PROCESS_DONE.
* We do need the handlers in place by the time the request is over, so
* we set them up here. If we segfault between here and the server call
* something is very wrong... */
if (!SIGNAL_Init()) exit(1);
/* Signal the parent process to continue */
SERVER_START_REQ( init_process_done )
{
req->module = peb->ImageBaseAddress;
req->entry = (char *)peb->ImageBaseAddress + nt->OptionalHeader.AddressOfEntryPoint;
req->gui = (nt->OptionalHeader.Subsystem != IMAGE_SUBSYSTEM_WINDOWS_CUI);
status = wine_server_call( req );
}
SERVER_END_REQ;
pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
return status;
}
/***********************************************************************
* server_init_thread * server_init_thread
* *
* Send an init thread request. Return 0 if OK. * Send an init thread request. Return 0 if OK.
......
...@@ -346,6 +346,8 @@ static void start_thread( struct wine_pthread_thread_info *info ) ...@@ -346,6 +346,8 @@ static void start_thread( struct wine_pthread_thread_info *info )
size = page_size; size = page_size;
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL ); NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL );
pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
RtlAcquirePebLock(); RtlAcquirePebLock();
InsertHeadList( &tls_links, &teb->TlsLinks ); InsertHeadList( &tls_links, &teb->TlsLinks );
RtlReleasePebLock(); RtlReleasePebLock();
...@@ -380,6 +382,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * ...@@ -380,6 +382,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
PRTL_THREAD_START_ROUTINE start, void *param, PRTL_THREAD_START_ROUTINE start, void *param,
HANDLE *handle_ptr, CLIENT_ID *id ) HANDLE *handle_ptr, CLIENT_ID *id )
{ {
sigset_t sigset;
struct ntdll_thread_data *thread_data; struct ntdll_thread_data *thread_data;
struct ntdll_thread_regs *thread_regs = NULL; struct ntdll_thread_regs *thread_regs = NULL;
struct startup_info *info = NULL; struct startup_info *info = NULL;
...@@ -416,7 +419,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * ...@@ -416,7 +419,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
} }
SERVER_END_REQ; SERVER_END_REQ;
if (status) goto error; if (status)
{
close( request_pipe[1] );
return status;
}
pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, &sigset );
addr = NULL; addr = NULL;
size = sigstack_total_size; size = sigstack_total_size;
...@@ -469,6 +478,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR * ...@@ -469,6 +478,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
status = STATUS_NO_MEMORY; status = STATUS_NO_MEMORY;
goto error; goto error;
} }
pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
if (id) id->UniqueThread = (HANDLE)tid; if (id) id->UniqueThread = (HANDLE)tid;
if (handle_ptr) *handle_ptr = handle; if (handle_ptr) *handle_ptr = handle;
...@@ -484,6 +494,7 @@ error: ...@@ -484,6 +494,7 @@ error:
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE ); NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
} }
if (handle) NtClose( handle ); if (handle) NtClose( handle );
pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
close( request_pipe[1] ); close( request_pipe[1] );
return status; return status;
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment