From a5dc9f23b94eddb634e915f600bc928b3e6ed316 Mon Sep 17 00:00:00 2001 From: midipix Date: Fri, 6 Jan 2017 19:20:23 -0500 Subject: daemon initialization: simplified logic, fixed params-related race hazard. --- src/daemon/ntapi_dsr_init.c | 38 ++++++++++-------- src/daemon/ntapi_dsr_internal_connection.c | 62 +++++++++++++++--------------- 2 files changed, 53 insertions(+), 47 deletions(-) (limited to 'src/daemon') diff --git a/src/daemon/ntapi_dsr_init.c b/src/daemon/ntapi_dsr_init.c index f028efd..317a421 100644 --- a/src/daemon/ntapi_dsr_init.c +++ b/src/daemon/ntapi_dsr_init.c @@ -54,19 +54,23 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) return status; if (params->pevent_daemon_ready) - *(params->pevent_daemon_ready) = params->hevent_daemon_ready; + at_store( + (intptr_t *)params->pevent_daemon_ready, + (intptr_t)params->hevent_daemon_ready); } /* 'internal-client-is-ready' event */ if (!params->hevent_internal_client_ready) { - if ((status = __ntapi->tt_create_inheritable_event( + if ((status = __ntapi->tt_create_private_event( ¶ms->hevent_internal_client_ready, NT_NOTIFICATION_EVENT, NT_EVENT_NOT_SIGNALED))) return status; if (params->pevent_internal_client_ready) - *(params->pevent_internal_client_ready) = params->hevent_internal_client_ready; + at_store( + (intptr_t *)params->pevent_internal_client_ready, + (intptr_t)params->hevent_internal_client_ready); } /* daemon dedicated thread: general parameters */ @@ -82,17 +86,17 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) tparams.stack_info = params->stack_info; /* daemon dedicated thread: create */ - status = __ntapi->tt_create_local_thread(&tparams); - params->hthread_daemon_loop = tparams.hthread; - if (status) return status; + if ((status = __ntapi->tt_create_local_thread(&tparams))) + return status; + params->hthread_daemon_loop = tparams.hthread; /* wait for the server to be ready */ timeout.quad = NT_DSR_INIT_MAX_WAIT; if ((status = __ntapi->zw_wait_for_single_object( params->hevent_daemon_ready, - 0,&timeout))) { + NT_SYNC_NON_ALERTABLE,&timeout))) { __ntapi->zw_terminate_thread( tparams.hthread, status); @@ -112,24 +116,25 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) tparams.start = (nt_thread_start_routine *)__ntapi_dsr_internal_client_connect; tparams.arg = params; - status = __ntapi->tt_create_local_thread(&tparams); + if ((status = __ntapi->tt_create_local_thread(&tparams))) + return status; + params->hthread_internal_client = tparams.hthread; - if (status) return status; /* wait until the internal connection had been established */ timeout.quad = NT_DSR_INIT_MAX_WAIT; - status = __ntapi->zw_wait_for_single_object( - params->hevent_internal_client_ready, - 0, - &timeout); + if ((status = __ntapi->zw_wait_for_single_object( + params->hevent_internal_client_ready, + NT_SYNC_NON_ALERTABLE,&timeout))) + return status; if (params->flags & NT_DSR_INIT_CLOSE_EVENTS) { __ntapi->zw_close(params->hevent_daemon_ready); __ntapi->zw_close(params->hevent_internal_client_ready); } - return status; + return NT_STATUS_SUCCESS;; } @@ -137,6 +142,9 @@ int32_t __stdcall __ntapi_dsr_init(nt_daemon_params * params) int32_t __stdcall __ntapi_dsr_start_impl(nt_daemon_params * params) { int32_t status; + void * ctx; + + ctx = params->daemon_loop_context; if ((status = __ntapi_dsr_once(params))) return status; @@ -147,7 +155,7 @@ int32_t __stdcall __ntapi_dsr_start_impl(nt_daemon_params * params) if ((status = __ntapi_dsr_connect_internal_client(params))) return status; - if ((status = params->daemon_loop_routine(params->daemon_loop_context))) + if ((status = params->daemon_loop_routine(ctx))) return status; return NT_STATUS_SUCCESS; diff --git a/src/daemon/ntapi_dsr_internal_connection.c b/src/daemon/ntapi_dsr_internal_connection.c index 7246eff..2d6e39f 100644 --- a/src/daemon/ntapi_dsr_internal_connection.c +++ b/src/daemon/ntapi_dsr_internal_connection.c @@ -12,23 +12,7 @@ #include #include "ntapi_impl.h" -static int32_t __stdcall __ntapi_dsr_connect_internal_client_exit( - nt_daemon_params * params, - int32_t status) -{ - at_store_32( - ¶ms->exit_code_daemon_start, - status); - - if (status == NT_STATUS_SUCCESS) - at_store_32( - ¶ms->exit_code_daemon_loop, - NT_STATUS_SERVICE_NOTIFICATION); - - return status; -} - -static int32_t __stdcall __ntapi_dsr_internal_client_connect_exit( +static int32_t __stdcall __ntapi_dsr_internal_client_connect_fail( nt_daemon_params * params, int32_t status) { @@ -48,7 +32,11 @@ int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params) intptr_t port_id; nt_port_message port_msg; nt_large_integer timeout; - void * _hport_client; + void * hport; + void * hready; + + /* avoid out-of-scope use */ + hready = params->hthread_internal_client; /* report state */ at_store_32( @@ -64,8 +52,7 @@ int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params) (nt_port_message *)0, (nt_port_message *)&port_msg, &timeout))) - return __ntapi_dsr_connect_internal_client_exit( - params,status); + return status; /* the internal client must be first */ if (port_msg.client_id.process_id != pe_get_current_process_id()) @@ -73,21 +60,24 @@ int32_t __stdcall __ntapi_dsr_connect_internal_client(nt_daemon_params * params) /* accept connection request */ if ((status = __ntapi->zw_accept_connect_port( - &_hport_client, + &hport, port_msg.client_id.process_id, (nt_port_message *)&port_msg, NT_LPC_ACCEPT_CONNECTION, (nt_port_section_write *)0, (nt_port_section_read *)0))) - return __ntapi_dsr_connect_internal_client_exit( - params,status); + return status; /* finalize connection */ - status = __ntapi->zw_complete_connect_port( - _hport_client); + if ((status = __ntapi->zw_complete_connect_port(hport))) + return status; + + /* await client thread task completion */ + __ntapi->zw_wait_for_single_object( + hready,NT_SYNC_NON_ALERTABLE,0); - return __ntapi_dsr_connect_internal_client_exit( - params,status); + /* all done */ + return NT_STATUS_SUCCESS; } @@ -129,12 +119,19 @@ int32_t __stdcall __ntapi_dsr_internal_client_connect(nt_daemon_params * params) &server_name, &sqos, 0,0,0,0,0))) - return __ntapi_dsr_internal_client_connect_exit( + return __ntapi_dsr_internal_client_connect_fail( params,status); - /* return port info */ + /* update port info */ if (params->pport_internal_client) - *(params->pport_internal_client) = params->hport_internal_client; + at_store( + (intptr_t *)params->pport_internal_client, + (intptr_t)params->hport_internal_client); + + /* report status */ + at_store_32( + ¶ms->exit_code_internal_client, + status); /* signal the 'internal-client-is-ready' event */ status = __ntapi->zw_set_event( @@ -142,6 +139,7 @@ int32_t __stdcall __ntapi_dsr_internal_client_connect(nt_daemon_params * params) 0); /* exit the task-specific thread */ - return __ntapi_dsr_internal_client_connect_exit( - params,status); + return __ntapi->zw_terminate_thread( + NT_CURRENT_THREAD_HANDLE, + status); } -- cgit v1.2.3