aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors
diff options
context:
space:
mode:
authorGerald Combs <gerald@wireshark.org>2012-05-15 19:13:10 +0000
committerGerald Combs <gerald@wireshark.org>2012-05-15 19:13:10 +0000
commit3e4b3756fd7262b47c1f303c99c0ddf6324a8ea5 (patch)
tree03481565234f4244d802d3945c0bd15815b5ae56 /epan/dissectors
parent691ea690c80e2333f61390247b7f86cb84c7abe1 (diff)
From Evan Huus via bug 6805:
Look before we loop Check the value of various key count parameters against the size of their parent tag *before* we start looping on them. Stick an expert error on the field and bound the loop at a sane point if the count is bogus. svn path=/trunk/; revision=42631
Diffstat (limited to 'epan/dissectors')
-rw-r--r--epan/dissectors/packet-ieee80211.c37
1 files changed, 32 insertions, 5 deletions
diff --git a/epan/dissectors/packet-ieee80211.c b/epan/dissectors/packet-ieee80211.c
index a0fdb52a9a..36ec57b1ec 100644
--- a/epan/dissectors/packet-ieee80211.c
+++ b/epan/dissectors/packet-ieee80211.c
@@ -6438,10 +6438,12 @@ static int dissect_qos_capability(proto_tree * tree, tvbuff_t * tvb, int offset,
/* 7.3.2.25 RSN information element */
static int
-dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset, guint32 tag_len)
+dissect_rsn_ie(packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb,
+ int offset, guint32 tag_len)
{
proto_item *rsn_gcs_item, *rsn_pcs_item, *rsn_akms_item, *rsn_cap_item, *rsn_pmkid_item, *rsn_gmcs_item;
proto_item *rsn_sub_pcs_item, *rsn_sub_akms_item;
+ proto_item *rsn_pcs_count, *rsn_akms_count, *rsn_pmkid_count;
proto_tree *rsn_gcs_tree, *rsn_pcs_tree, *rsn_akms_tree, *rsn_cap_tree, *rsn_pmkid_tree, *rsn_gmcs_tree;
proto_tree *rsn_sub_pcs_tree, *rsn_sub_akms_tree;
guint16 pcs_count, akms_count, pmkid_count;
@@ -6466,10 +6468,16 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset, guint32 tag_len)
offset += 4;
/* 7.3.2.25.2 Pairwise Cipher suites */
- proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ rsn_pcs_count = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
pcs_count = tvb_get_letohs(tvb, offset);
offset += 2;
+ if (offset + (pcs_count * 4) > tag_end)
+ {
+ expert_add_info_format(pinfo, rsn_pcs_count, PI_MALFORMED, PI_ERROR,
+ "Pairwise Cipher Suite Count too large, 4*%u > %d", pcs_count, tag_end - offset);
+ pcs_count = (tag_end - offset) / 4;
+ }
rsn_pcs_item = proto_tree_add_item(tree, hf_ieee80211_rsn_pcs_list, tvb, offset, pcs_count * 4, ENC_NA);
rsn_pcs_tree = proto_item_add_subtree(rsn_pcs_item, ett_rsn_pcs_tree);
@@ -6490,11 +6498,23 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset, guint32 tag_len)
offset += 4;
}
+ if(offset >= tag_end)
+ {
+ return offset;
+ }
+
/* 7.3.2.25.2 AKM suites */
- proto_tree_add_item(tree, hf_ieee80211_rsn_akms_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ rsn_akms_count = proto_tree_add_item(tree, hf_ieee80211_rsn_akms_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
akms_count = tvb_get_letohs(tvb, offset);
offset += 2;
+ if (offset + (akms_count * 4) > tag_end)
+ {
+ expert_add_info_format(pinfo, rsn_akms_count, PI_MALFORMED, PI_ERROR,
+ "Auth Key Management (AKM) Suite Count too large, 4*%u > %d", akms_count, tag_end - offset);
+ akms_count = (tag_end - offset) / 4;
+ }
+
rsn_akms_item = proto_tree_add_item(tree, hf_ieee80211_rsn_akms_list, tvb, offset, akms_count * 4, ENC_NA);
rsn_akms_tree = proto_item_add_subtree(rsn_akms_item, ett_rsn_akms_tree);
for(i = 1; i <= akms_count; i++)
@@ -6531,10 +6551,17 @@ dissect_rsn_ie(proto_tree * tree, tvbuff_t * tvb, int offset, guint32 tag_len)
return offset;
}
/* 7.3.2.25.4 PMKID */
- proto_tree_add_item(tree, hf_ieee80211_rsn_pmkid_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
+ rsn_pmkid_count = proto_tree_add_item(tree, hf_ieee80211_rsn_pmkid_count, tvb, offset, 2, ENC_LITTLE_ENDIAN);
pmkid_count = tvb_get_letohs(tvb, offset);
offset += 2;
+ if (offset + (pmkid_count * 16) > tag_end)
+ {
+ expert_add_info_format(pinfo, rsn_pmkid_count, PI_MALFORMED, PI_ERROR,
+ "PMKID Count too large, 16*%u > %d", pmkid_count, tag_end - offset);
+ pmkid_count = (tag_end - offset) / 16;
+ }
+
rsn_pmkid_item = proto_tree_add_item(tree, hf_ieee80211_rsn_pmkid_list, tvb, offset, pmkid_count * 16, ENC_NA);
rsn_pmkid_tree = proto_item_add_subtree(rsn_pmkid_item, ett_rsn_pmkid_tree);
for(i = 1; i <= pmkid_count; i++)
@@ -9008,7 +9035,7 @@ add_tagged_field(packet_info * pinfo, proto_tree * tree, tvbuff_t * tvb, int off
}
offset += 2;
- offset = dissect_rsn_ie(tree, tvb, offset, tag_len);
+ offset = dissect_rsn_ie(pinfo, tree, tvb, offset, tag_len);
break;
case TAG_EXT_SUPP_RATES: /* 7.3.2.14 Extended Supported Rates element (50) */