wireshark/CVE-2023-2857.patch

220 lines
10 KiB
Diff
Raw Normal View History

From 6c7199da0c84a966ac9b06cd7fbb6aa0ccff9acb Mon Sep 17 00:00:00 2001
From: Guy Harris <gharris@sonic.net>
Date: Tue, 16 May 2023 18:09:41 -0700
Subject: [PATCH] blf: add some sanity checks.
Have blf_pull_logcontainer_into_memory() return a libwiretap error code
and additional information string, including various values being
inconsistent.
(If any of those correspond to identifiable file problems, they should
be reported with WTAP_ERR_BAD_FILE and with a description more relevant
to somebody writing code to write those files.)
Fixes #19063.
(backported from commit c899be35a94440b6c46cf5715c5f24eda597f4c1)
---
wiretap/blf.c | 134 +++++++++++++++++++++++++++++++++++++++++++-------
1 file changed, 115 insertions(+), 19 deletions(-)
diff --git a/wiretap/blf.c b/wiretap/blf.c
index 92b7f55ed56..ed2ee5f7135 100644
--- a/wiretap/blf.c
+++ b/wiretap/blf.c
@@ -433,12 +433,18 @@ blf_find_logcontainer_for_address(blf_t *blf_data, gint64 pos, blf_log_container
}
static gboolean
-blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_container) {
+blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_container, int *err, gchar **err_info) {
blf_t *blf_data = params->blf_data;
blf_log_container_t tmp;
if (index_log_container >= blf_data->log_containers->len) {
- ws_debug("cannot pull an unknown log container into memory");
+ /*
+ * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
+ * malformed file (WTAP_ERR_BAD_FILE)?
+ */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: index_log_container (%u) >= blf_data->log_containers->len (%u)",
+ index_log_container, blf_data->log_containers->len);
return FALSE;
}
@@ -450,20 +456,56 @@ blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_containe
if (tmp.compression_method == BLF_COMPRESSION_ZLIB) {
#ifdef HAVE_ZLIB
- int err = 0;
- gchar *err_info;
-
- file_seek(params->fh, tmp.infile_data_start, SEEK_SET, &err);
- if (err < 0) {
- ws_debug("cannot seek to start of log_container");
+ if (file_seek(params->fh, tmp.infile_data_start, SEEK_SET, err) == -1) {
return FALSE;
}
/* pull compressed data into buffer */
unsigned char *compressed_data = g_try_malloc0((gsize)tmp.infile_length);
- guint64 data_length = (unsigned int)tmp.infile_length - (tmp.infile_data_start - tmp.infile_start_pos);
- if (!wtap_read_bytes_or_eof(params->fh, compressed_data, (unsigned int)data_length, &err, &err_info)) {
- ws_debug("cannot read compressed data");
+ if (tmp.infile_start_pos < 0) {
+ /*
+ * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
+ * malformed file (WTAP_ERR_BAD_FILE)?
+ */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: tmp.infile_start_pos (%" G_GINT64_FORMAT ") < 0",
+ tmp.infile_start_pos);
+ return FALSE;
+ }
+ if (tmp.infile_data_start < (guint64)tmp.infile_start_pos) {
+ /*
+ * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
+ * malformed file (WTAP_ERR_BAD_FILE)?
+ */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: tmp.infile_data_start (%" G_GUINT64_FORMAT ") < tmp.infile_start_pos (%" G_GINT64_FORMAT ")",
+ tmp.infile_data_start, tmp.infile_start_pos);
+ return FALSE;
+ }
+ if (tmp.infile_length < tmp.infile_data_start - (guint64)tmp.infile_start_pos) {
+ /*
+ * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
+ * malformed file (WTAP_ERR_BAD_FILE)?
+ */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: tmp.infile_length (%" G_GUINT64_FORMAT ") < (tmp.infile_data_start (%" G_GUINT64_FORMAT ") - tmp.infile_start_pos (%" G_GINT64_FORMAT ")) = %" G_GUINT64_FORMAT,
+ tmp.infile_length,
+ tmp.infile_data_start, tmp.infile_start_pos,
+ tmp.infile_data_start - (guint64)tmp.infile_start_pos);
+ return FALSE;
+ }
+ guint64 data_length = tmp.infile_length - (tmp.infile_data_start - (guint64)tmp.infile_start_pos);
+ if (data_length > UINT_MAX) {
+ /*
+ * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
+ * malformed file (WTAP_ERR_BAD_FILE)?
+ */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: data_length (%" G_GUINT64_FORMAT ") > UINT_MAX",
+ data_length);
+ return FALSE;
+ }
+ if (!wtap_read_bytes_or_eof(params->fh, compressed_data, (unsigned int)data_length, err, err_info)) {
return FALSE;
}
@@ -477,6 +519,18 @@ blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_containe
/* the actual DE-compression work. */
if (Z_OK != inflateInit(&infstream)) {
+ /*
+ * XXX - check the error code and handle this appropriately.
+ */
+ *err = WTAP_ERR_INTERNAL;
+ if (infstream.msg != NULL) {
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: inflateInit failed for LogContainer %d, message\"%s\"",
+ index_log_container,
+ infstream.msg);
+ } else {
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: inflateInit failed for LogContainer %d",
+ index_log_container);
+ }
ws_debug("inflateInit failed for LogContainer %d", index_log_container);
if (infstream.msg != NULL) {
ws_debug("inflateInit returned: \"%s\"", infstream.msg);
@@ -487,6 +541,50 @@ blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_containe
int ret = inflate(&infstream, Z_NO_FLUSH);
/* Z_OK should not happen here since we know how big the buffer should be */
if (Z_STREAM_END != ret) {
+ switch (ret) {
+
+ case Z_NEED_DICT:
+ *err = WTAP_ERR_DECOMPRESS;
+ *err_info = g_strdup("preset dictionary needed");
+ break;
+
+ case Z_STREAM_ERROR:
+ *err = WTAP_ERR_DECOMPRESS;
+ *err_info = (infstream.msg != NULL) ? g_strdup(infstream.msg) : NULL;
+ break;
+
+ case Z_MEM_ERROR:
+ /* This means "not enough memory". */
+ *err = ENOMEM;
+ *err_info = NULL;
+ break;
+
+ case Z_DATA_ERROR:
+ /* This means "deflate stream invalid" */
+ *err = WTAP_ERR_DECOMPRESS;
+ *err_info = (infstream.msg != NULL) ? g_strdup(infstream.msg) : NULL;
+ break;
+
+ case Z_BUF_ERROR:
+ /* XXX - this is recoverable; what should we do here? */
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: Z_BUF_ERROR from inflate(), message \"%s\"",
+ (infstream.msg != NULL) ? infstream.msg : "(none)");
+ break;
+
+ case Z_VERSION_ERROR:
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: Z_VERSION_ERROR from inflate(), message \"%s\"",
+ (infstream.msg != NULL) ? infstream.msg : "(none)");
+ break;
+
+ default:
+ *err = WTAP_ERR_INTERNAL;
+ *err_info = g_strdup_printf("blf_pull_logcontainer_into_memory: unexpected error %d from inflate(), message \"%s\"",
+ ret,
+ (infstream.msg != NULL) ? infstream.msg : "(none)");
+ break;
+ }
ws_debug("inflate failed (return code %d) for LogContainer %d", ret, index_log_container);
if (infstream.msg != NULL) {
ws_debug("inflate returned: \"%s\"", infstream.msg);
@@ -495,6 +593,9 @@ blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_containe
}
if (Z_OK != inflateEnd(&infstream)) {
+ /* Returns either Z_OK or Z_STREAM_ERROR. */
+ *err = WTAP_ERR_DECOMPRESS;
+ *err_info = (infstream.msg != NULL) ? g_strdup(infstream.msg) : NULL;
ws_debug("inflateEnd failed for LogContainer %d", index_log_container);
if (infstream.msg != NULL) {
ws_debug("inflateEnd returned: \"%s\"", infstream.msg);
@@ -506,6 +607,8 @@ blf_pull_logcontainer_into_memory(blf_params_t *params, guint index_log_containe
g_array_index(blf_data->log_containers, blf_log_container_t, index_log_container) = tmp;
return TRUE;
#else
+ *err = WTAP_ERR_DECOMPRESSION_NOT_SUPPORTED;
+ *err_info = NULL;
return FALSE;
#endif
}
@@ -593,14 +696,7 @@ blf_read_bytes_or_eof(blf_params_t *params, guint64 real_pos, void *target_buffe
case BLF_COMPRESSION_ZLIB:
while (current_container_index <= end_container_index) {
- if (!blf_pull_logcontainer_into_memory(params, current_container_index)) {
- /*
- * XXX - does this represent a bug (WTAP_ERR_INTERNAL) or a
- * malformed file (WTAP_ERR_BAD_FILE)?
- */
- *err = WTAP_ERR_INTERNAL;
- *err_info = g_strdup_printf("blf_read_bytes_or_eof: cannot pull in container");
- ws_debug("cannot pull in container");
+ if (!blf_pull_logcontainer_into_memory(params, current_container_index, err, err_info)) {
return FALSE;
}
--
GitLab