diff options
author | Michael Mann <mmann78@netscape.net> | 2016-10-09 22:54:03 -0400 |
---|---|---|
committer | Michael Mann <mmann78@netscape.net> | 2016-10-10 13:11:29 +0000 |
commit | e8022a9c7b36b96578a30fc8132def6de8928606 (patch) | |
tree | cbba9c4c0ae25c4fe1a16b16c53c8d09cc212766 | |
parent | 347395147fe91e99d57d14f8769d11eecae2f450 (diff) |
Profinet I/O: Sanity check number of I/O objects
Can prevent really long loops from fuzz testing.
Bug: 12851
Change-Id: I85e00af2c4753ce4c5bcb650a7df188d7f679c9a
Reviewed-on: https://code.wireshark.org/review/18136
Petri-Dish: Michael Mann <mmann78@netscape.net>
Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org>
Reviewed-by: Michael Mann <mmann78@netscape.net>
-rw-r--r-- | plugins/profinet/packet-pn-rtc-one.c | 27 |
1 files changed, 22 insertions, 5 deletions
diff --git a/plugins/profinet/packet-pn-rtc-one.c b/plugins/profinet/packet-pn-rtc-one.c index cd1e27b3e5..66e2ae292e 100644 --- a/plugins/profinet/packet-pn-rtc-one.c +++ b/plugins/profinet/packet-pn-rtc-one.c @@ -71,6 +71,7 @@ #include <epan/packet.h> #include <epan/dissectors/packet-dcerpc.h> #include <epan/proto.h> +#include <epan/expert.h> #include "packet-pn.h" @@ -137,6 +138,7 @@ static gint ett_pn_io_rtc = -1; static gint ett_pn_io_ioxs = -1; static gint ett_pn_io_io_data_object = -1; +static expert_field ei_pn_io_too_many_data_objects = EI_INIT; static const value_string pn_io_ioxs_extension[] = { { 0x00 /* 0*/, "No IOxS octet follows" }, @@ -377,6 +379,7 @@ dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, gboolean outputFlag; gboolean psInfoText; /* Used to display only once per frame the info text "PROFIsafe Device" */ + proto_item *data_item; proto_item *IODataObject_item; proto_item *IODataObject_item_info; proto_tree *IODataObject_tree; @@ -418,12 +421,9 @@ dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, col_set_str(pinfo->cinfo, COL_PROTOCOL, "PNIO"); /* set protocol name */ - if (tree) { - proto_item *data_item; - data_item = proto_tree_add_protocol_format(tree, proto_pn_io_rtc1, tvb, offset, tvb_captured_length(tvb), + data_item = proto_tree_add_protocol_format(tree, proto_pn_io_rtc1, tvb, offset, tvb_captured_length(tvb), "PROFINET IO Cyclic Service Data Unit: %u bytes", tvb_captured_length(tvb)); - data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc); - } + data_tree = proto_item_add_subtree(data_item, ett_pn_io_rtc); /* dissect_dcerpc_uint16(tvb, offset, pinfo, data_tree, drep, hf_pn_io_packedframe_SFCRC, &u16SFCRC); */ if (!(dissect_CSF_SDU_heur(tvb, pinfo, data_tree, NULL) == FALSE)) @@ -499,6 +499,11 @@ dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, /* ---- Input IOData-/IOCS-Object Handling ---- */ objectCounter = number_io_data_objects_input_cr + number_iocs_input_cr; + if (objectCounter > (guint)tvb_reported_length_remaining(tvb, offset)) { + expert_add_info_format(pinfo, data_item, &ei_pn_io_too_many_data_objects, "Too many data objects: %d", objectCounter); + return(tvb_captured_length(tvb)); + } + while (objectCounter--) { /* ---- Input IO Data Object Handling ---- */ if (station_info != NULL) { @@ -694,6 +699,10 @@ dissect_PNIO_C_SDU_RTC1(tvbuff_t *tvb, int offset, /* ---- Output IOData-/IOCS-Object Handling ---- */ objectCounter = number_io_data_objects_output_cr + number_iocs_output_cr; + if (objectCounter > (guint)tvb_reported_length_remaining(tvb, offset)) { + expert_add_info_format(pinfo, data_item, &ei_pn_io_too_many_data_objects, "Too many data objects: %d", objectCounter); + return(tvb_captured_length(tvb)); + } while (objectCounter--) { /* ---- Output IO Data Object Handling ---- */ if (station_info != NULL) { @@ -1073,9 +1082,17 @@ init_pn_io_rtc1(int proto) &ett_pn_io_io_data_object }; + static ei_register_info ei[] = { + { &ei_pn_io_too_many_data_objects, { "pn_io.too_many_data_objects", PI_MALFORMED, PI_ERROR, "Too many data objects", EXPFILL }}, + }; + + expert_module_t* expert_pn_io; + proto_pn_io_rtc1 = proto; proto_register_field_array(proto, hf, array_length(hf)); proto_register_subtree_array(ett, array_length(ett)); + expert_pn_io = expert_register_protocol(proto_pn_io_rtc1); + expert_register_field_array(expert_pn_io, ei, array_length(ei)); } |