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,
RemoveEntryList( &wm->ldr.InLoadOrderModuleList );
InsertHeadList( &peb->LdrData->InLoadOrderModuleList, &wm->ldr.InLoadOrderModuleList );
/* Install signal handlers; this cannot be done before, 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;
status = server_init_process_done();
if (status != STATUS_SUCCESS) goto error;
RtlEnterCriticalSection( &loader_section );
......
......@@ -58,6 +58,7 @@ extern void virtual_init_threading(void);
/* server support */
extern abs_time_t server_start_time;
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 void DECLSPEC_NORETURN server_protocol_error( const char *err, ... );
extern void DECLSPEC_NORETURN server_protocol_perror( const char *err );
......
......@@ -1018,6 +1018,7 @@ void server_init_process(void)
sigaddset( &server_block_set, SIGUSR1 );
sigaddset( &server_block_set, SIGUSR2 );
sigaddset( &server_block_set, SIGCHLD );
pthread_functions.sigprocmask( SIG_BLOCK, &server_block_set, NULL );
/* receive the first thread request fd on the main socket */
ntdll_get_thread_data()->request_fd = receive_fd( &dummy_handle );
......@@ -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
*
* Send an init thread request. Return 0 if OK.
......
......@@ -346,6 +346,8 @@ static void start_thread( struct wine_pthread_thread_info *info )
size = page_size;
NtProtectVirtualMemory( NtCurrentProcess(), &teb->DeallocationStack, &size, PAGE_NOACCESS, NULL );
pthread_functions.sigprocmask( SIG_UNBLOCK, &server_block_set, NULL );
RtlAcquirePebLock();
InsertHeadList( &tls_links, &teb->TlsLinks );
RtlReleasePebLock();
......@@ -380,6 +382,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
PRTL_THREAD_START_ROUTINE start, void *param,
HANDLE *handle_ptr, CLIENT_ID *id )
{
sigset_t sigset;
struct ntdll_thread_data *thread_data;
struct ntdll_thread_regs *thread_regs = NULL;
struct startup_info *info = NULL;
......@@ -416,7 +419,13 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
}
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;
size = sigstack_total_size;
......@@ -469,6 +478,7 @@ NTSTATUS WINAPI RtlCreateUserThread( HANDLE process, const SECURITY_DESCRIPTOR *
status = STATUS_NO_MEMORY;
goto error;
}
pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
if (id) id->UniqueThread = (HANDLE)tid;
if (handle_ptr) *handle_ptr = handle;
......@@ -484,6 +494,7 @@ error:
NtFreeVirtualMemory( NtCurrentProcess(), &addr, &size, MEM_RELEASE );
}
if (handle) NtClose( handle );
pthread_functions.sigprocmask( SIG_SETMASK, &sigset, NULL );
close( request_pipe[1] );
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