diff options
author | Pascal Quantin <pascal@wireshark.org> | 2019-06-19 09:45:25 +0200 |
---|---|---|
committer | Pascal Quantin <pascal@wireshark.org> | 2019-06-19 08:47:01 +0000 |
commit | dd15b203c7ec8a8ec5c930cf018c838991ee3182 (patch) | |
tree | dbba36306fa6c7ac759b56ac21fc7a5834de3aa1 /epan/dissectors/packet-babel.c | |
parent | 484deec1f18eb9c4d73bcb558066263c422c34ef (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/dissectors/packet-babel.c')
-rw-r--r-- | epan/dissectors/packet-babel.c | 27 |
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 |