aboutsummaryrefslogtreecommitdiffstats
path: root/epan/dissectors/packet-vlan.c
diff options
context:
space:
mode:
authorPascal Quantin <pascal.quantin@gmail.com>2018-03-05 21:51:11 +0100
committerAlexis La Goutte <alexis.lagoutte@gmail.com>2018-03-06 07:20:55 +0000
commitb434e0a03be45ed796af7271972672a0b43cffa8 (patch)
tree77a421963d41c12d9f9e4ea14bd617c4e723ee9d /epan/dissectors/packet-vlan.c
parentc39dbd68d472046cf97211c86267e0305630d934 (diff)
VLAN: define a recursion depth limit
Altough the dissection consumes 4 bytes each time it is called, it can trigger a stack overflow for big packets. Let's limmit the number of allowed VLAN tags for a given packet. Bug: 14469 Change-Id: Ieb6834ab3350dc7e8c301e6479577855a253897e Reviewed-on: https://code.wireshark.org/review/26270 Petri-Dish: Pascal Quantin <pascal.quantin@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Alexis La Goutte <alexis.lagoutte@gmail.com>
Diffstat (limited to 'epan/dissectors/packet-vlan.c')
-rw-r--r--epan/dissectors/packet-vlan.c18
1 files changed, 16 insertions, 2 deletions
diff --git a/epan/dissectors/packet-vlan.c b/epan/dissectors/packet-vlan.c
index 00d75bf2d9..8f23257465 100644
--- a/epan/dissectors/packet-vlan.c
+++ b/epan/dissectors/packet-vlan.c
@@ -23,6 +23,7 @@
#include <epan/prefs.h>
#include <epan/to_str.h>
#include <epan/addr_resolv.h>
+#include <epan/proto_data.h>
void proto_register_vlan(void);
void proto_reg_handoff_vlan(void);
@@ -54,6 +55,8 @@ static dissector_handle_t ethertype_handle;
static capture_dissector_handle_t llc_cap_handle;
static capture_dissector_handle_t ipx_cap_handle;
+static int proto_vlan;
+
static header_field_info *hfi_vlan = NULL;
#define VLAN_HFI_INIT HFI_INIT(proto_vlan)
@@ -184,6 +187,9 @@ static header_field_info hfi_vlan_trailer VLAN_HFI_INIT = {
static gint ett_vlan = -1;
static expert_field ei_vlan_len = EI_INIT;
+static expert_field ei_vlan_too_many_tags = EI_INIT;
+
+#define VLAN_MAX_NESTED_TAGS 10
static gboolean
capture_vlan(const guchar *pd, int offset, int len, capture_packet_info_t *cpinfo, const union wtap_pseudo_header *pseudo_header _U_ ) {
@@ -231,6 +237,7 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
gboolean is_802_2;
proto_tree *vlan_tree;
proto_item *item;
+ guint vlan_nested_count;
col_set_str(pinfo->cinfo, COL_PROTOCOL, "VLAN");
col_clear(pinfo->cinfo, COL_INFO);
@@ -246,8 +253,15 @@ dissect_vlan(tvbuff_t *tvb, packet_info *pinfo, proto_tree *tree, void* data _U_
vlan_tree = NULL;
+ ti = proto_tree_add_item(tree, hfi_vlan, tvb, 0, 4, ENC_NA);
+ vlan_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_vlan, 0));
+ if (++vlan_nested_count > VLAN_MAX_NESTED_TAGS) {
+ expert_add_info(pinfo, ti, &ei_vlan_too_many_tags);
+ return tvb_captured_length(tvb);
+ }
+ p_add_proto_data(pinfo->pool, pinfo, proto_vlan, 0, GUINT_TO_POINTER(vlan_nested_count));
+
if (tree) {
- ti = proto_tree_add_item(tree, hfi_vlan, tvb, 0, 4, ENC_NA);
if (vlan_summary_in_tree) {
if (vlan_version < IEEE_8021Q_2011) {
@@ -364,6 +378,7 @@ proto_register_vlan(void)
static ei_register_info ei[] = {
{ &ei_vlan_len, { "vlan.len.past_end", PI_MALFORMED, PI_ERROR, "Length field value goes past the end of the payload", EXPFILL }},
+ { &ei_vlan_too_many_tags, { "vlan.too_many_tags", PI_UNDECODED, PI_WARN, "Too many nested VLAN tags", EXPFILL }},
};
static const enum_val_t version_vals[] = {
@@ -383,7 +398,6 @@ proto_register_vlan(void)
module_t *vlan_module;
expert_module_t* expert_vlan;
- int proto_vlan;
proto_vlan = proto_register_protocol("802.1Q Virtual LAN", "VLAN", "vlan");
hfi_vlan = proto_registrar_get_nth(proto_vlan);