aboutsummaryrefslogtreecommitdiffstats
path: root/epan
diff options
context:
space:
mode:
authorPascal Quantin <pascal@wireshark.org>2019-06-19 09:45:25 +0200
committerPascal Quantin <pascal@wireshark.org>2019-06-19 08:47:01 +0000
commitdd15b203c7ec8a8ec5c930cf018c838991ee3182 (patch)
treedbba36306fa6c7ac759b56ac21fc7a5834de3aa1 /epan
parent484deec1f18eb9c4d73bcb558066263c422c34ef (diff)
Babel: prevent an infinite loop while parsing sub-TLV
While at it, ensure that we have no overflow when parsing the sub-TLV. Bug: 15856 Change-Id: I2ceb30fd8a6abc2577c9df7baf6ceb45ee5f5b38 Reviewed-on: https://code.wireshark.org/review/33656 Petri-Dish: Pascal Quantin <pascal@wireshark.org> Tested-by: Petri Dish Buildbot Reviewed-by: Pascal Quantin <pascal@wireshark.org>
Diffstat (limited to 'epan')
-rw-r--r--epan/dissectors/packet-babel.c27
1 files changed, 21 insertions, 6 deletions
diff --git a/epan/dissectors/packet-babel.c b/epan/dissectors/packet-babel.c
index 6259a50a65..83303635b7 100644
--- a/epan/dissectors/packet-babel.c
+++ b/epan/dissectors/packet-babel.c
@@ -13,6 +13,7 @@
#include <epan/packet.h>
#include <epan/to_str.h>
+#include <epan/expert.h>
void proto_register_babel(void);
void proto_reg_handoff_babel(void);
@@ -51,6 +52,8 @@ static gint ett_subtlv = -1;
static gint ett_timestamp = -1;
static gint ett_mandatory = -1;
+static expert_field ei_babel_subtlv_invalid_length = EI_INIT;
+
#define UDP_PORT_RANGE_BABEL "6696"
#define MESSAGE_PAD1 0
@@ -246,8 +249,8 @@ format_timestamp(const guint32 i)
}
static int
-dissect_babel_subtlvs(tvbuff_t * tvb, guint8 type, guint8 beg, guint8 end,
- proto_tree *message_tree)
+dissect_babel_subtlvs(tvbuff_t * tvb, packet_info *pinfo, guint8 type,
+ guint16 beg, guint16 end, proto_tree *message_tree)
{
proto_tree *channel_tree = NULL;
proto_item *sub_item;
@@ -265,6 +268,10 @@ dissect_babel_subtlvs(tvbuff_t * tvb, guint8 type, guint8 beg, guint8 end,
"Sub TLV %s (%u)",
val_to_str_const(subtype, subtlvs, "unknown"),
subtype);
+ if (sublen == 0) {
+ expert_add_info(pinfo, sub_item, &ei_babel_subtlv_invalid_length);
+ break;
+ }
if (message_tree) {
subtlv_tree = proto_item_add_subtree(sub_item, ett_subtlv);
@@ -340,7 +347,8 @@ dissect_babel_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
i = offset;
while (i-offset < bodylen) {
- guint8 type, len = 0, total_length;
+ guint8 type, len = 0;
+ guint16 total_length;
proto_tree *message_tree = NULL;
int message = 4 + i;
@@ -396,7 +404,7 @@ dissect_babel_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(message_tree, hf_babel_message_interval,
tvb, message + 6, 2, ENC_BIG_ENDIAN);
if(len > 6)
- dissect_babel_subtlvs(tvb, type, message + 8,
+ dissect_babel_subtlvs(tvb, pinfo, type, message + 8,
message + 2 + len, message_tree);
} else if (type == MESSAGE_IHU) {
proto_tree *subtree;
@@ -418,7 +426,7 @@ dissect_babel_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 4, len - 2, ENC_NA);
if (rc < len - 6)
- dissect_babel_subtlvs(tvb, type, message + 8 + rc,
+ dissect_babel_subtlvs(tvb, pinfo, type, message + 8 + rc,
message + 2 + len, message_tree);
} else if (type == MESSAGE_ROUTER_ID) {
proto_tree_add_item(message_tree, hf_babel_message_routerid,
@@ -480,7 +488,7 @@ dissect_babel_body(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree,
proto_tree_add_item(subtree, hf_babel_message_prefix,
tvb, message + 12, len - 10, ENC_NA);
if (((guint8)rc) < len - 10)
- dissect_babel_subtlvs(tvb, type, message + 12 + rc,
+ dissect_babel_subtlvs(tvb, pinfo, type, message + 12 + rc,
message + 2 + len, message_tree);
} else if (type == MESSAGE_REQUEST) {
proto_tree *subtree;
@@ -688,11 +696,18 @@ proto_register_babel(void)
&ett_mandatory
};
+ static ei_register_info ei[] = {
+ { &ei_babel_subtlv_invalid_length, { "babel.subtlv.invalid_length", PI_PROTOCOL, PI_ERROR, "Invalid Sub-TLV length", EXPFILL }},
+ };
+ expert_module_t *expert_babel;
+
proto_babel =
proto_register_protocol("Babel Routing Protocol", "Babel", "babel");
proto_register_field_array(proto_babel, hf, array_length(hf));
proto_register_subtree_array(ett, array_length(ett));
+ expert_babel = expert_register_protocol(proto_babel);
+ expert_register_field_array(expert_babel, ei, array_length(ei));
}
void