From 14c35c31d8e77f95abaa601c42566636197641e1 Mon Sep 17 00:00:00 2001 From: Guy Harris Date: Mon, 16 Nov 2015 14:33:32 -0800 Subject: Create C handles for pipes before running dumpcap. If the C handles can't be created, there's no point in running dumpcap. Catch some more possible _open_osfhandle() failures while we're at it. Change-Id: I2b955378705fc932f8d383804e908e95a957be44 Ping-Bug: 11702 Reviewed-on: https://code.wireshark.org/review/11890 Petri-Dish: Guy Harris Tested-by: Petri Dish Buildbot Reviewed-by: Guy Harris --- capchild/capture_sync.c | 129 +++++++++++++++++++++++++++++++++--------------- 1 file changed, 90 insertions(+), 39 deletions(-) (limited to 'capchild') diff --git a/capchild/capture_sync.c b/capchild/capture_sync.c index 97777c6399..8273ee6dac 100644 --- a/capchild/capture_sync.c +++ b/capchild/capture_sync.c @@ -363,6 +363,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi #ifdef _WIN32 HANDLE sync_pipe_read; /* pipe used to send messages from child to parent */ HANDLE sync_pipe_write; /* pipe used to send messages from child to parent */ + int signal_pipe_write_fd; HANDLE signal_pipe; /* named pipe used to send messages from parent to child (currently only stop) */ GString *args = g_string_sized_new(200); gchar *quoted_arg; @@ -583,6 +584,26 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi return FALSE; } + /* + * Associate a C run-time file handle with the Windows HANDLE for the + * read side of the message pipe. + * + * (See http://www.flounder.com/handles.htm for information on various + * types of file handle in C/C++ on Windows.) + */ + sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY); + if (sync_pipe_read_fd == -1) { + /* Couldn't create the pipe between parent and child. */ + report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno)); + CloseHandle(sync_pipe_read); + CloseHandle(sync_pipe_write); + for (i = 0; i < argc; i++) { + g_free( (gpointer) argv[i]); + } + g_free(argv); + return FALSE; + } + /* Create the signal pipe */ signal_pipe_name = g_strdup_printf(SIGNAL_PIPE_FORMAT, control_id); signal_pipe = CreateNamedPipe(utf_8to16(signal_pipe_name), @@ -593,6 +614,8 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi /* Couldn't create the signal pipe between parent and child. */ report_failure("Couldn't create signal pipe: %s", win32strerror(GetLastError())); + ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */ + CloseHandle(sync_pipe_write); for (i = 0; i < argc; i++) { g_free( (gpointer) argv[i]); } @@ -600,6 +623,27 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi return FALSE; } + /* + * Associate a C run-time file handle with the Windows HANDLE for the + * read side of the message pipe. + * + * (See http://www.flounder.com/handles.htm for information on various + * types of file handle in C/C++ on Windows.) + */ + signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY); + if (sync_pipe_read_fd == -1) { + /* Couldn't create the pipe between parent and child. */ + report_failure("Couldn't get C file handle for sync pipe: %s", g_strerror(errno)); + ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */ + CloseHandle(sync_pipe_write); + CloseHandle(signal_pipe); + for (i = 0; i < argc; i++) { + g_free( (gpointer) argv[i]); + } + g_free(argv); + return FALSE; + } + /* init STARTUPINFO */ memset(&si, 0, sizeof(si)); si.cb = sizeof(si); @@ -643,8 +687,9 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { report_failure("Couldn't run %s in child process: %s", args->str, win32strerror(GetLastError())); - CloseHandle(sync_pipe_read); + ws_close(sync_pipe_read_fd); /* Should close sync_pipe_read */ CloseHandle(sync_pipe_write); + CloseHandle(signal_pipe); for (i = 0; i < argc; i++) { g_free( (gpointer) argv[i]); } @@ -654,12 +699,7 @@ sync_pipe_start(capture_options *capture_opts, capture_session *cap_session, voi cap_session->fork_child = pi.hProcess; g_string_free(args, TRUE); - /* associate the operating system filehandle to a C run-time file handle */ - /* (good file handle infos at: http://www.flounder.com/handles.htm) */ - sync_pipe_read_fd = _open_osfhandle( (intptr_t) sync_pipe_read, _O_BINARY); - - /* associate the operating system filehandle to a C run-time file handle */ - cap_session->signal_pipe_write_fd = _open_osfhandle( (intptr_t) signal_pipe, _O_BINARY); + cap_session->signal_pipe_write_fd = signal_pipe_write_fd; #else /* _WIN32 */ if (pipe(sync_pipe) < 0) { @@ -812,13 +852,53 @@ sync_pipe_open_command(char** argv, int *data_read_fd, return -1; } + /* + * Associate a C run-time file handle with the Windows HANDLE for the + * read side of the message pipe. + * + * (See http://www.flounder.com/handles.htm for information on various + * types of file handle in C/C++ on Windows.) + */ + *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY); + if (*message_read_fd == -1) { + *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno)); + CloseHandle(sync_pipe[PIPE_READ]); + CloseHandle(sync_pipe[PIPE_WRITE]); + for (i = 0; argv[i] != NULL; i++) { + g_free( (gpointer) argv[i]); + } + g_free( (gpointer) argv); + return -1; + } + /* Create a pipe for the child process to send us data */ /* (increase this value if you have trouble while fast capture file switches) */ if (! CreatePipe(&data_pipe[PIPE_READ], &data_pipe[PIPE_WRITE], &sa, 5120)) { /* Couldn't create the message pipe between parent and child. */ *msg = g_strdup_printf("Couldn't create data pipe: %s", win32strerror(GetLastError())); - CloseHandle(sync_pipe[PIPE_READ]); + ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */ + CloseHandle(sync_pipe[PIPE_WRITE]); + for (i = 0; argv[i] != NULL; i++) { + g_free( (gpointer) argv[i]); + } + g_free( (gpointer) argv); + return -1; + } + + /* + * Associate a C run-time file handle with the Windows HANDLE for the + * read side of the data pipe. + * + * (See http://www.flounder.com/handles.htm for information on various + * types of file handle in C/C++ on Windows.) + */ + *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY); + if (*data_read_fd == -1) { + *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno)); + CloseHandle(data_pipe[PIPE_READ]); + CloseHandle(data_pipe[PIPE_WRITE]); + ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */ CloseHandle(sync_pipe[PIPE_WRITE]); for (i = 0; argv[i] != NULL; i++) { g_free( (gpointer) argv[i]); @@ -857,9 +937,9 @@ sync_pipe_open_command(char** argv, int *data_read_fd, CREATE_NEW_CONSOLE, NULL, NULL, &si, &pi)) { *msg = g_strdup_printf("Couldn't run %s in child process: %s", args->str, win32strerror(GetLastError())); - CloseHandle(data_pipe[PIPE_READ]); + ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */ CloseHandle(data_pipe[PIPE_WRITE]); - CloseHandle(sync_pipe[PIPE_READ]); + ws_close(*message_read_fd); /* Should close sync_pipe[PIPE_READ] */ CloseHandle(sync_pipe[PIPE_WRITE]); for (i = 0; argv[i] != NULL; i++) { g_free( (gpointer) argv[i]); @@ -869,35 +949,6 @@ sync_pipe_open_command(char** argv, int *data_read_fd, } *fork_child = pi.hProcess; g_string_free(args, TRUE); - - /* associate the operating system filehandles to C run-time file handles */ - /* (good file handle infos at: http://www.flounder.com/handles.htm) */ - *data_read_fd = _open_osfhandle( (intptr_t) data_pipe[PIPE_READ], _O_BINARY); - if (*data_read_fd == -1) { - *msg = g_strdup_printf("Couldn't get C file handle for data read pipe: %s", g_strerror(errno)); - CloseHandle(data_pipe[PIPE_READ]); - CloseHandle(data_pipe[PIPE_WRITE]); - CloseHandle(sync_pipe[PIPE_READ]); - CloseHandle(sync_pipe[PIPE_WRITE]); - for (i = 0; argv[i] != NULL; i++) { - g_free( (gpointer) argv[i]); - } - g_free( (gpointer) argv); - return -1; - } - *message_read_fd = _open_osfhandle( (intptr_t) sync_pipe[PIPE_READ], _O_BINARY); - if (*message_read_fd == -1) { - *msg = g_strdup_printf("Couldn't get C file handle for message read pipe: %s", g_strerror(errno)); - ws_close(*data_read_fd); /* Should close data_pipe[PIPE_READ] */ - CloseHandle(data_pipe[PIPE_WRITE]); - CloseHandle(sync_pipe[PIPE_READ]); - CloseHandle(sync_pipe[PIPE_WRITE]); - for (i = 0; argv[i] != NULL; i++) { - g_free( (gpointer) argv[i]); - } - g_free( (gpointer) argv); - return -1; - } #else /* _WIN32 */ /* Create a pipe for the child process to send us messages */ if (pipe(sync_pipe) < 0) { -- cgit v1.2.3