Blame SOURCES/wireshark-0011-cve-2022-3190.patch

5516f7
From 0f27a83c5692b2afebe6e6934c1051f76aa2ecf9 Mon Sep 17 00:00:00 2001
5516f7
From: Jason Cohen <kryojenik2@gmail.com>
5516f7
Date: Wed, 31 Aug 2022 11:10:17 -0500
5516f7
Subject: [PATCH] f5ethtrailer: Improve "old-style" heuristic
5516f7
5516f7
Remove a chance for an infinate loop in the disection heuristic.
5516f7
---
5516f7
 epan/dissectors/packet-f5ethtrailer.c | 108 +++++++++++++-------------
5516f7
 1 file changed, 56 insertions(+), 52 deletions(-)
5516f7
5516f7
diff --git a/epan/dissectors/packet-f5ethtrailer.c b/epan/dissectors/packet-f5ethtrailer.c
5516f7
index b2ba8f899d..915348ea83 100644
5516f7
--- a/epan/dissectors/packet-f5ethtrailer.c
5516f7
+++ b/epan/dissectors/packet-f5ethtrailer.c
5516f7
@@ -2751,69 +2751,73 @@ dissect_dpt_trailer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *d
5516f7
 static gint
5516f7
 dissect_old_trailer(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void *data)
5516f7
 {
5516f7
-    proto_tree *type_tree   = NULL;
5516f7
-    proto_item *ti          = NULL;
5516f7
     guint offset            = 0;
5516f7
-    guint processed         = 0;
5516f7
-    f5eth_tap_data_t *tdata = (f5eth_tap_data_t *)data;
5516f7
-    guint8 type;
5516f7
-    guint8 len;
5516f7
-    guint8 ver;
5516f7
 
5516f7
     /* While we still have data in the trailer.  For old format trailers, this needs
5516f7
      * type, length, version (3 bytes) and for new format trailers, the magic header (4 bytes).
5516f7
      * All old format trailers are at least 4 bytes long, so just check for length of magic.
5516f7
      */
5516f7
-    while (tvb_reported_length_remaining(tvb, offset)) {
5516f7
-        type = tvb_get_guint8(tvb, offset);
5516f7
-        len = tvb_get_guint8(tvb, offset + F5_OFF_LENGTH) + F5_OFF_VERSION;
5516f7
-        ver = tvb_get_guint8(tvb, offset + F5_OFF_VERSION);
5516f7
-
5516f7
-        if (len <= tvb_reported_length_remaining(tvb, offset) && type >= F5TYPE_LOW
5516f7
-            && type <= F5TYPE_HIGH && len >= F5_MIN_SANE && len <= F5_MAX_SANE
5516f7
-            && ver <= F5TRAILER_VER_MAX) {
5516f7
-            /* Parse out the specified trailer. */
5516f7
-            switch (type) {
5516f7
-            case F5TYPE_LOW:
5516f7
-                ti        = proto_tree_add_item(tree, hf_low_id, tvb, offset, len, ENC_NA);
5516f7
-                type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_low);
5516f7
-
5516f7
-                processed = dissect_low_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
-                if (processed > 0) {
5516f7
-                    tdata->trailer_len += processed;
5516f7
-                    tdata->noise_low = 1;
5516f7
-                }
5516f7
-                break;
5516f7
-            case F5TYPE_MED:
5516f7
-                ti        = proto_tree_add_item(tree, hf_med_id, tvb, offset, len, ENC_NA);
5516f7
-                type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_med);
5516f7
-
5516f7
-                processed = dissect_med_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
-                if (processed > 0) {
5516f7
-                    tdata->trailer_len += processed;
5516f7
-                    tdata->noise_med = 1;
5516f7
-                }
5516f7
-                break;
5516f7
-            case F5TYPE_HIGH:
5516f7
-                ti        = proto_tree_add_item(tree, hf_high_id, tvb, offset, len, ENC_NA);
5516f7
-                type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_high);
5516f7
-
5516f7
-                processed =
5516f7
-                    dissect_high_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
-                if (processed > 0) {
5516f7
-                    tdata->trailer_len += processed;
5516f7
-                    tdata->noise_high = 1;
5516f7
-                }
5516f7
-                break;
5516f7
+    while (tvb_reported_length_remaining(tvb, offset) >= F5_MIN_SANE) {
5516f7
+        /* length field does not include the type and length bytes.  Add them back in */
5516f7
+        guint8 len = tvb_get_guint8(tvb, offset + F5_OFF_LENGTH) + F5_OFF_VERSION;
5516f7
+        if (len > tvb_reported_length_remaining(tvb, offset)
5516f7
+            || len < F5_MIN_SANE || len > F5_MAX_SANE) {
5516f7
+            /* Invalid length - either a malformed trailer, corrupt packet, or not f5ethtrailer */
5516f7
+            return offset;
5516f7
+        }
5516f7
+        guint8 type = tvb_get_guint8(tvb, offset);
5516f7
+        guint8 ver = tvb_get_guint8(tvb, offset + F5_OFF_VERSION);
5516f7
+
5516f7
+        /* Parse out the specified trailer. */
5516f7
+        proto_tree *type_tree   = NULL;
5516f7
+        proto_item *ti          = NULL;
5516f7
+        f5eth_tap_data_t *tdata = (f5eth_tap_data_t *)data;
5516f7
+        guint processed = 0;
5516f7
+
5516f7
+        switch (type) {
5516f7
+        case F5TYPE_LOW:
5516f7
+            ti        = proto_tree_add_item(tree, hf_low_id, tvb, offset, len, ENC_NA);
5516f7
+            type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_low);
5516f7
+
5516f7
+            processed = dissect_low_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
+            if (processed > 0) {
5516f7
+                tdata->trailer_len += processed;
5516f7
+                tdata->noise_low = 1;
5516f7
             }
5516f7
-            if (processed == 0) {
5516f7
-                proto_item_set_len(ti, 1);
5516f7
-                return offset;
5516f7
+            break;
5516f7
+        case F5TYPE_MED:
5516f7
+            ti        = proto_tree_add_item(tree, hf_med_id, tvb, offset, len, ENC_NA);
5516f7
+            type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_med);
5516f7
+
5516f7
+            processed = dissect_med_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
+            if (processed > 0) {
5516f7
+                tdata->trailer_len += processed;
5516f7
+                tdata->noise_med = 1;
5516f7
+            }
5516f7
+            break;
5516f7
+        case F5TYPE_HIGH:
5516f7
+            ti        = proto_tree_add_item(tree, hf_high_id, tvb, offset, len, ENC_NA);
5516f7
+            type_tree = proto_item_add_subtree(ti, ett_f5ethtrailer_high);
5516f7
+
5516f7
+            processed =
5516f7
+                dissect_high_trailer(tvb, pinfo, type_tree, offset, len, ver, tdata);
5516f7
+            if (processed > 0) {
5516f7
+                tdata->trailer_len += processed;
5516f7
+                tdata->noise_high = 1;
5516f7
             }
5516f7
+            break;
5516f7
+        default:
5516f7
+            /* Unknown type - malformed trailer, corrupt packet, or not f5ethtrailer - bali out*/
5516f7
+            return offset;
5516f7
+        }
5516f7
+        if (processed == 0) {
5516f7
+            /* couldn't process trailer - bali out */
5516f7
+            proto_item_set_len(ti, 1);
5516f7
+            return offset;
5516f7
         }
5516f7
         offset += processed;
5516f7
     }
5516f7
-return offset;
5516f7
+    return offset;
5516f7
 } /* dissect_old_trailer() */
5516f7
 
5516f7
 /*---------------------------------------------------------------------------*/
5516f7
-- 
5516f7
GitLab