* cygserver.cc (main): Call listen right after creating the

transport.
	* transport_pipes.cc (transport_layer_pipes::listen): Create
	first instance of the named pipe here.  Connect the client side
	to block it for further use by the system.
	(transport_layer_pipes::accept): Don't handle first pipe instance
	here.  Change debug output accordingly.
This commit is contained in:
Corinna Vinschen 2012-11-23 15:19:41 +00:00
parent 916015a6af
commit 5ed0628cf0
3 changed files with 44 additions and 30 deletions

View File

@ -1,3 +1,13 @@
2012-11-23 Corinna Vinschen <corinna@vinschen.de>
* cygserver.cc (main): Call listen right after creating the
transport.
* transport_pipes.cc (transport_layer_pipes::listen): Create
first instance of the named pipe here. Connect the client side
to block it for further use by the system.
(transport_layer_pipes::accept): Don't handle first pipe instance
here. Change debug output accordingly.
2012-11-23 Christopher Faylor <me.cygwin2012@cgf.cx> 2012-11-23 Christopher Faylor <me.cygwin2012@cgf.cx>
* Makefile.in: Use /bin/mkdir to make install directories. * Makefile.in: Use /bin/mkdir to make install directories.

View File

@ -715,15 +715,15 @@ main (const int argc, char *argv[])
transport_layer_base *const transport = create_server_transport (); transport_layer_base *const transport = create_server_transport ();
assert (transport); assert (transport);
if (transport->listen () == -1)
return 1;
process_cache cache (process_cache_size, cleanup_threads); process_cache cache (process_cache_size, cleanup_threads);
server_submission_loop submission_loop (&request_queue, transport, &cache); server_submission_loop submission_loop (&request_queue, transport, &cache);
request_queue.add_submission_loop (&submission_loop); request_queue.add_submission_loop (&submission_loop);
if (transport->listen () == -1)
return 1;
cache.start (); cache.start ();
request_queue.start (); request_queue.start ();

View File

@ -107,7 +107,32 @@ transport_layer_pipes::listen ()
_is_listening_endpoint = true; _is_listening_endpoint = true;
/* no-op */ debug ("Try to create named pipe: %ls", _pipe_name);
HANDLE listen_pipe =
CreateNamedPipeW (_pipe_name,
PIPE_ACCESS_DUPLEX | FILE_FLAG_FIRST_PIPE_INSTANCE,
PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
0, 0, 1000, &sec_all_nih);
if (listen_pipe != INVALID_HANDLE_VALUE)
{
HANDLE connect_pipe =
CreateFileW (_pipe_name, GENERIC_READ | GENERIC_WRITE, 0, &sec_all_nih,
OPEN_EXISTING, 0, NULL);
if (connect_pipe == INVALID_HANDLE_VALUE)
{
CloseHandle (listen_pipe);
listen_pipe = INVALID_HANDLE_VALUE;
}
}
if (listen_pipe == INVALID_HANDLE_VALUE)
{
system_printf ("failed to create named pipe: "
"is the daemon already running?");
return -1;
}
return 0; return 0;
} }
@ -125,38 +150,19 @@ transport_layer_pipes::accept (bool *const recoverable)
// Read: http://www.securityinternals.com/research/papers/namedpipe.php // Read: http://www.securityinternals.com/research/papers/namedpipe.php
// See also the Microsoft security bulletins MS00-053 and MS01-031. // See also the Microsoft security bulletins MS00-053 and MS01-031.
// FIXME: Remove FILE_CREATE_PIPE_INSTANCE. debug ("Try to create named pipe instance %ld: %ls",
pipe_instance + 1, _pipe_name);
const bool first_instance = (pipe_instance == 0);
debug ("Try to create named pipe: %ls", _pipe_name);
const HANDLE accept_pipe = const HANDLE accept_pipe =
CreateNamedPipeW (_pipe_name, CreateNamedPipeW (_pipe_name, PIPE_ACCESS_DUPLEX,
(PIPE_ACCESS_DUPLEX PIPE_TYPE_BYTE | PIPE_WAIT, PIPE_UNLIMITED_INSTANCES,
| (first_instance ? FILE_FLAG_FIRST_PIPE_INSTANCE : 0)), 0, 0, 1000, &sec_all_nih);
(PIPE_TYPE_BYTE | PIPE_WAIT),
PIPE_UNLIMITED_INSTANCES,
0, 0, 1000,
&sec_all_nih);
const bool duplicate = (accept_pipe == INVALID_HANDLE_VALUE
&& pipe_instance == 0
&& GetLastError () == ERROR_ACCESS_DENIED);
if (accept_pipe != INVALID_HANDLE_VALUE) if (accept_pipe != INVALID_HANDLE_VALUE)
InterlockedIncrement (&pipe_instance); InterlockedIncrement (&pipe_instance);
LeaveCriticalSection (&pipe_instance_lock); LeaveCriticalSection (&pipe_instance_lock);
if (duplicate)
{
*recoverable = false;
system_printf ("failed to create named pipe: "
"is the daemon already running?");
return NULL;
}
if (accept_pipe == INVALID_HANDLE_VALUE) if (accept_pipe == INVALID_HANDLE_VALUE)
{ {
debug_printf ("error creating pipe (%lu).", GetLastError ()); debug_printf ("error creating pipe (%lu).", GetLastError ());
@ -164,8 +170,6 @@ transport_layer_pipes::accept (bool *const recoverable)
return NULL; return NULL;
} }
assert (accept_pipe);
if (!ConnectNamedPipe (accept_pipe, NULL) if (!ConnectNamedPipe (accept_pipe, NULL)
&& GetLastError () != ERROR_PIPE_CONNECTED) && GetLastError () != ERROR_PIPE_CONNECTED)
{ {