summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2017-02-16 15:31:56 -0800
committerGerald Combs <gerald@wireshark.org>2017-02-17 17:19:06 +0000
commit560a6c3823cf560b883e29db0a403517def86639 (patch)
tree9bdc7d4bc914cb4698af10b329bbe31d4a2e0a82
parent48eff6a36bac1526756bbb42a8c9841641792938 (diff)
downloadwireshark-560a6c3823cf560b883e29db0a403517def86639.tar.gz
Rawshark: Try to avoid a VC runtime crash.
The MSDN documentation for _read says "If fd is invalid, the file is not open for reading, or the file is locked, the invalid parameter handler is invoked, as described in Parameter Validation." This means that on Windows, if our parent has closed stdin when we call _read we'll crash. Add a check to bail out early if that's happened. Fix a sign cast while we're here. Change-Id: I8afb75f6e56c6a6c2b62103ba7e2fb635dc85702 Reviewed-on: https://code.wireshark.org/review/20153 Reviewed-by: Gerald Combs <gerald@wireshark.org>
-rw-r--r--doc/rawshark.pod4
-rw-r--r--rawshark.c27
2 files changed, 26 insertions, 5 deletions
diff --git a/doc/rawshark.pod b/doc/rawshark.pod
index c2c722a2bb..9119839591 100644
--- a/doc/rawshark.pod
+++ b/doc/rawshark.pod
@@ -199,6 +199,10 @@ Read packet data from I<input source>. It can be either the name of a FIFO
(named pipe) or ``-'' to read data from the standard input, and must have
the record format specified above.
+If you are sending data to rawshark from a parent process on Windows you
+should not close rawshark's standard input handle prematurely, otherwise
+the C runtime might trigger an exception.
+
=item -R E<lt>read (display) filterE<gt>
Cause the specified filter (which uses the syntax of read/display filters,
diff --git a/rawshark.c b/rawshark.c
index bc6e783630..e319acd01c 100644
--- a/rawshark.c
+++ b/rawshark.c
@@ -875,10 +875,10 @@ main(int argc, char *argv[])
/* Do we need to PCAP header and magic? */
if (skip_pcap_header) {
- size_t bytes_left = sizeof(struct pcap_hdr) + sizeof(guint32);
+ unsigned int bytes_left = (unsigned int) sizeof(struct pcap_hdr) + sizeof(guint32);
gchar buf[sizeof(struct pcap_hdr) + sizeof(guint32)];
while (bytes_left != 0) {
- ssize_t bytes = ws_read(fd, buf, (int)bytes_left);
+ ssize_t bytes = ws_read(fd, buf, bytes_left);
if (bytes <= 0) {
cmdarg_err("Not enough bytes for pcap header.");
ret = FORMAT_ERROR;
@@ -926,7 +926,7 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, gchar **err_info,
struct pcap_pkthdr mem_hdr;
struct pcaprec_hdr disk_hdr;
ssize_t bytes_read = 0;
- size_t bytes_needed = sizeof(disk_hdr);
+ unsigned int bytes_needed = (unsigned int) sizeof(disk_hdr);
guchar *ptr = (guchar*) &disk_hdr;
*err = 0;
@@ -936,9 +936,26 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, gchar **err_info,
ptr = (guchar*) &mem_hdr;
}
+ /*
+ * Newer versions of the VC runtime do parameter validation. If stdin
+ * has been closed, calls to _read, _get_osfhandle, et al will trigger
+ * the invalid parameter handler and crash.
+ * We could alternatively use ReadFile or set an invalid parameter
+ * handler.
+ * We could also tell callers not to close stdin prematurely.
+ */
+#ifdef _WIN32
+ DWORD ghi_flags;
+ if (fd == 0 && GetHandleInformation(GetStdHandle(STD_INPUT_HANDLE), &ghi_flags) == 0) {
+ *err = 0;
+ *err_info = NULL;
+ return FALSE;
+ }
+#endif
+
/* Copied from capture_loop.c */
while (bytes_needed > 0) {
- bytes_read = ws_read(fd, ptr, (int)bytes_needed);
+ bytes_read = ws_read(fd, ptr, bytes_needed);
if (bytes_read == 0) {
*err = 0;
*err_info = NULL;
@@ -984,7 +1001,7 @@ raw_pipe_read(struct wtap_pkthdr *phdr, guchar * pd, int *err, gchar **err_info,
ptr = pd;
while (bytes_needed > 0) {
- bytes_read = ws_read(fd, ptr, (int)bytes_needed);
+ bytes_read = ws_read(fd, ptr, bytes_needed);
if (bytes_read == 0) {
*err = WTAP_ERR_SHORT_READ;
*err_info = NULL;