From fbfb87a2439dd18f2318586b8e5a2f6db410ba6a Mon Sep 17 00:00:00 2001 From: Pascal Quantin Date: Mon, 19 Jun 2017 20:06:06 +0200 Subject: PROFINET IO: define an arbitrary recursion depth limit Bug: 13811 Change-Id: I52bffd4a79dcdad9da23f33e1fc6a868472390bf Reviewed-on: https://code.wireshark.org/review/22232 Petri-Dish: Pascal Quantin Tested-by: Petri Dish Buildbot Reviewed-by: Anders Broman --- plugins/profinet/packet-dcerpc-pn-io.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) (limited to 'plugins') diff --git a/plugins/profinet/packet-dcerpc-pn-io.c b/plugins/profinet/packet-dcerpc-pn-io.c index 931393773d..a86149f04d 100644 --- a/plugins/profinet/packet-dcerpc-pn-io.c +++ b/plugins/profinet/packet-dcerpc-pn-io.c @@ -847,6 +847,7 @@ static expert_field ei_pn_io_ar_info_not_found = EI_INIT; static expert_field ei_pn_io_iocr_type = EI_INIT; static expert_field ei_pn_io_frame_id = EI_INIT; static expert_field ei_pn_io_nr_of_tx_port_groups = EI_INIT; +static expert_field ei_pn_io_max_recursion_depth_reached = EI_INIT; static e_guid_t uuid_pn_io_device = { 0xDEA00001, 0x6C97, 0x11D1, { 0x82, 0x71, 0x00, 0xA0, 0x24, 0x42, 0xDF, 0x7D } }; static guint16 ver_pn_io_device = 1; @@ -11413,14 +11414,20 @@ dissect_RecordDataWrite(tvbuff_t *tvb, int offset, return offset; } +#define PN_IO_MAX_RECURSION_DEPTH 100 static int dissect_IODWriteReq(tvbuff_t *tvb, int offset, - packet_info *pinfo, proto_tree *tree, guint8 *drep, pnio_ar_t **ar) + packet_info *pinfo, proto_tree *tree, guint8 *drep, pnio_ar_t **ar, guint recursion_count) { guint16 u16Index = 0; guint32 u32RecDataLen = 0; + if (++recursion_count >= PN_IO_MAX_RECURSION_DEPTH) { + proto_tree_add_expert(tree, pinfo, &ei_pn_io_max_recursion_depth_reached, + tvb, 0, 0); + return tvb_captured_length(tvb); + } /* IODWriteHeader */ offset = dissect_block(tvb, offset, pinfo, tree, drep, &u16Index, &u32RecDataLen, ar); @@ -11428,7 +11435,7 @@ dissect_IODWriteReq(tvbuff_t *tvb, int offset, /* IODWriteMultipleReq? */ if (u16Index == 0xe040) { while (tvb_captured_length_remaining(tvb, offset) > 0) { - offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, ar); + offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, ar, recursion_count++); } } else { tvbuff_t *new_tvb = tvb_new_subset_length(tvb, offset, u32RecDataLen); @@ -11460,10 +11467,11 @@ dissect_IPNIO_Write_rqst(tvbuff_t *tvb, int offset, packet_info *pinfo, proto_tree *tree, dcerpc_info *di, guint8 *drep) { pnio_ar_t *ar = NULL; + guint recursion_count = 0; offset = dissect_IPNIO_rqst_header(tvb, offset, pinfo, tree, di, drep); - offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar); + offset = dissect_IODWriteReq(tvb, offset, pinfo, tree, drep, &ar, recursion_count); if (ar != NULL) { pnio_ar_info(tvb, pinfo, tree, ar); @@ -14822,6 +14830,7 @@ proto_register_pn_io (void) { &ei_pn_io_iocr_type, { "pn_io.iocr_type.unknown", PI_UNDECODED, PI_WARN, "IOCRType undecoded!", EXPFILL }}, { &ei_pn_io_localalarmref, { "pn_io.localalarmref.changed", PI_UNDECODED, PI_WARN, "AlarmCRBlockReq: local alarm ref changed", EXPFILL }}, { &ei_pn_io_nr_of_tx_port_groups, { "pn_io.nr_of_tx_port_groups.not_allowed", PI_PROTOCOL, PI_WARN, "Not allowed value of NumberOfTxPortGroups", EXPFILL }}, + { &ei_pn_io_max_recursion_depth_reached, { "pn_io.max_recursion_depth_reached", PI_PROTOCOL, PI_WARN, "Maximum allowed recursion depth reached - stopping dissection", EXPFILL }} }; module_t *pnio_module; -- cgit v1.2.3