diff options
author | Pascal Quantin <pascal.quantin@gmail.com> | 2018-02-13 23:25:40 +0100 |
---|---|---|
committer | Anders Broman <a.broman58@gmail.com> | 2018-02-14 05:29:45 +0000 |
commit | 944e661514feca102e49e2d776f0a484e24fc597 (patch) | |
tree | b543f01c8454f6c8d0d0c05a1d7792aced1b04db /epan/dissectors/packet-openflow_v6.c | |
parent | 4904dd5517dd1b9f7096a3b61d91f32c8ea14331 (diff) |
OpenFlow 1.5: add extra property length checks
Bug: 14420
Change-Id: I1813bc6285f950d86dc569f4286bf34c120b5e3c
Reviewed-on: https://code.wireshark.org/review/25780
Reviewed-by: Pascal Quantin <pascal.quantin@gmail.com>
Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com>
Tested-by: Petri Dish Buildbot
Reviewed-by: Anders Broman <a.broman58@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-openflow_v6.c')
-rw-r--r-- | epan/dissectors/packet-openflow_v6.c | 95 |
1 files changed, 85 insertions, 10 deletions
diff --git a/epan/dissectors/packet-openflow_v6.c b/epan/dissectors/packet-openflow_v6.c index 0be7d72558..a7be077033 100644 --- a/epan/dissectors/packet-openflow_v6.c +++ b/epan/dissectors/packet-openflow_v6.c @@ -2638,6 +2638,7 @@ static int dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { proto_tree *prop_tree; + proto_item *prop_item; guint16 prop_type; guint16 prop_length; @@ -2651,7 +2652,7 @@ dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_ offset+=2; /* uint16_t len; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_port_desc_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_port_desc_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; switch (prop_type) { @@ -2664,6 +2665,11 @@ dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_ break; case OFPPDPT_EXPERIMENTER: + if (prop_length <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_port_desc_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -2678,6 +2684,11 @@ dissect_openflow_port_desc_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_ break; default: + if (prop_length <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_port_desc_prop_undecoded, tvb, offset, prop_length - 4, "Unknown port desc. property."); offset += prop_length - 4; @@ -3257,6 +3268,7 @@ static int dissect_openflow_portmod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { proto_tree *prop_tree; + proto_item *prop_item; guint16 prop_type; guint16 prop_length; @@ -3270,7 +3282,7 @@ dissect_openflow_portmod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr offset+=2; /* uint16_t len; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_portmod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_portmod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; switch (prop_type) { @@ -3283,6 +3295,11 @@ dissect_openflow_portmod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr break; case OFPPMPT_EXPERIMENTER: + if (prop_length <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_portmod_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -3297,6 +3314,11 @@ dissect_openflow_portmod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tr break; default: + if (prop_length <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_portmod_prop_undecoded, tvb, offset, prop_length - 4, "Unknown port desc. property."); offset += prop_length - 4; @@ -3373,7 +3395,7 @@ static const value_string openflow_v6_tablemod_prop_type_values[] = { static int dissect_openflow_tablemod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { - proto_item *ti; + proto_item *ti, *prop_item; proto_tree *prop_tree, *flags_tree; guint16 prop_type; @@ -3389,7 +3411,7 @@ dissect_openflow_tablemod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t offset+=2; /* uint16_t len; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_tablemod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_tablemod_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; switch (prop_type) { @@ -3423,6 +3445,11 @@ dissect_openflow_tablemod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t break; case OFPTMPT_EXPERIMENTER: + if (prop_length <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_tablemod_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -3437,6 +3464,11 @@ dissect_openflow_tablemod_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_t break; default: + if (prop_length <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_tablemod_prop_undecoded, tvb, offset, prop_length - 4, "Unknown table mod. property."); offset += prop_length - 4; @@ -4341,6 +4373,7 @@ static int dissect_openflow_port_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { proto_tree *prop_tree; + proto_item *prop_item; guint16 prop_type; guint16 prop_length; @@ -4354,7 +4387,7 @@ dissect_openflow_port_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto offset+=2; /* uint16_t len; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_port_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_port_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; switch (prop_type) { @@ -4367,6 +4400,11 @@ dissect_openflow_port_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto break; case OFPPSPT_EXPERIMENTER: + if (prop_length <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_port_stats_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -4381,6 +4419,11 @@ dissect_openflow_port_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto break; default: + if (prop_length <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_port_stats_prop_undecoded, tvb, offset, prop_length - 4, "Unknown port stats. property."); offset += prop_length - 4; @@ -4515,6 +4558,7 @@ static int dissect_openflow_queue_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { proto_tree *prop_tree; + proto_item *prop_item; guint16 prop_type; guint16 prop_length; @@ -4528,11 +4572,16 @@ dissect_openflow_queue_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, prot offset+=2; /* uint16_t len; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_queue_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_queue_stats_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset+=2; switch (prop_type) { case OFPMP_EXPERIMENTER: + if (prop_length <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_queue_stats_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -4548,6 +4597,11 @@ dissect_openflow_queue_stats_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, prot break; default: + if (prop_length <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_queue_stats_prop_undecoded, tvb, offset, length - 4, "Unknown queue stats prop body."); offset += prop_length - 4; @@ -5510,7 +5564,7 @@ static const value_string openflow_v6_async_config_prop_type_values[] = { static int dissect_openflow_async_config_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) { - proto_item *ti; + proto_item *ti, *prop_item; proto_tree *prop_tree, *pi_tree, *ps_tree, *fr_tree, *rs_tree, *ts_tree, *rf_tree; guint16 prop_type; guint16 prop_len; @@ -5525,7 +5579,7 @@ dissect_openflow_async_config_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro offset += 2; /* uint16_t length; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_async_config_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_async_config_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); offset += 2; switch (prop_type) { @@ -5607,6 +5661,11 @@ dissect_openflow_async_config_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro case OFPACPT_EXPERIMENTER_SLAVE: case OFPACPT_EXPERIMENTER_MASTER: + if (prop_len <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(prop_tree, hf_openflow_v6_async_config_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -5622,6 +5681,11 @@ dissect_openflow_async_config_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, pro break; default: + if (prop_len <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(prop_tree, pinfo, &ei_openflow_v6_async_config_prop_undecoded, tvb, offset, prop_len - 4, "Unknown async config prop body."); offset += prop_len - 4; @@ -5759,9 +5823,10 @@ static const value_string openflow_v6_bundle_prop_type_values[] = { }; static int -dissect_openflow_bundle_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tree *tree, int offset, guint16 length _U_) +dissect_openflow_bundle_prop_v6(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, int offset, guint16 length) { proto_tree *prop_tree; + proto_item *prop_item; guint16 prop_type; guint16 prop_len; @@ -5774,10 +5839,15 @@ dissect_openflow_bundle_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_prop_type, tvb, offset, 2, ENC_BIG_ENDIAN); /* uint16_t length; */ - proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); + prop_item = proto_tree_add_item(prop_tree, hf_openflow_v6_bundle_prop_length, tvb, offset, 2, ENC_BIG_ENDIAN); switch (prop_type) { case OFPBPT_EXPERIMENTER: + if (prop_len <= 12) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } /* uint32_t experimenter; */ proto_tree_add_item(tree, hf_openflow_v6_bundle_prop_experimenter_experimenter, tvb, offset, 4, ENC_BIG_ENDIAN); offset+=4; @@ -5793,6 +5863,11 @@ dissect_openflow_bundle_prop_v6(tvbuff_t *tvb, packet_info *pinfo _U_, proto_tre break; default: + if (prop_len <= 4) { + expert_add_info(pinfo, prop_item, &ei_openflow_v6_length_too_short); + offset = length; + break; + } proto_tree_add_expert_format(tree, pinfo, &ei_openflow_v6_bundle_prop_undecoded, tvb, offset, prop_len - 4, "Unknown bundle prop body."); offset += prop_len - 4; |