110 lines
4.5 KiB
Diff
110 lines
4.5 KiB
Diff
|
diff --git a/plugins/epan/opcua/opcua.c b/plugins/epan/opcua/opcua.c
|
||
|
index fc26d9f30d..4ca68a9e83 100644
|
||
|
--- a/plugins/epan/opcua/opcua.c
|
||
|
+++ b/plugins/epan/opcua/opcua.c
|
||
|
@@ -38,7 +38,7 @@ void proto_reg_handoff_opcua(void);
|
||
|
/* declare parse function pointer */
|
||
|
typedef int (*FctParse)(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOffset);
|
||
|
|
||
|
-static int proto_opcua = -1;
|
||
|
+int proto_opcua = -1;
|
||
|
static dissector_handle_t opcua_handle;
|
||
|
/** Official IANA registered port for OPC UA Binary Protocol. */
|
||
|
#define OPCUA_PORT_RANGE "4840"
|
||
|
diff --git a/plugins/epan/opcua/opcua_simpletypes.c b/plugins/epan/opcua/opcua_simpletypes.c
|
||
|
index a787f21c35..ab006b7552 100644
|
||
|
--- a/plugins/epan/opcua/opcua_simpletypes.c
|
||
|
+++ b/plugins/epan/opcua/opcua_simpletypes.c
|
||
|
@@ -20,6 +20,7 @@
|
||
|
#include <epan/packet.h>
|
||
|
#include <epan/expert.h>
|
||
|
#include <epan/dissectors/packet-windows-common.h>
|
||
|
+#include <epan/proto_data.h>
|
||
|
#include "opcua_simpletypes.h"
|
||
|
#include "opcua_hfindeces.h"
|
||
|
#include "opcua_statuscode.h"
|
||
|
@@ -80,6 +81,7 @@
|
||
|
|
||
|
/* Chosen arbitrarily */
|
||
|
#define MAX_ARRAY_LEN 10000
|
||
|
+#define MAX_NESTING_DEPTH 100
|
||
|
|
||
|
static int hf_opcua_diag_mask = -1;
|
||
|
static int hf_opcua_diag_mask_symbolicflag = -1;
|
||
|
@@ -168,6 +170,9 @@ int hf_opcua_resultMask_displayname = -1;
|
||
|
int hf_opcua_resultMask_typedefinition = -1;
|
||
|
|
||
|
static expert_field ei_array_length = EI_INIT;
|
||
|
+static expert_field ei_nesting_depth = EI_INIT;
|
||
|
+
|
||
|
+extern int proto_opcua;
|
||
|
|
||
|
/** NodeId encoding mask table */
|
||
|
static const value_string g_nodeidmasks[] = {
|
||
|
@@ -526,6 +531,7 @@ void registerSimpleTypes(int proto)
|
||
|
|
||
|
static ei_register_info ei[] = {
|
||
|
{ &ei_array_length, { "opcua.array.length", PI_UNDECODED, PI_ERROR, "Max array length exceeded", EXPFILL }},
|
||
|
+ { &ei_nesting_depth, { "opcua.nestingdepth", PI_UNDECODED, PI_ERROR, "Max nesting depth exceeded", EXPFILL }},
|
||
|
};
|
||
|
|
||
|
proto_register_field_array(proto, hf, array_length(hf));
|
||
|
@@ -802,9 +808,19 @@ void parseDiagnosticInfo(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gi
|
||
|
guint8 EncodingMask;
|
||
|
proto_tree *subtree;
|
||
|
proto_item *ti;
|
||
|
+ guint opcua_nested_count;
|
||
|
|
||
|
subtree = proto_tree_add_subtree_format(tree, tvb, *pOffset, -1, ett_opcua_diagnosticinfo, &ti, "%s: DiagnosticInfo", szFieldName);
|
||
|
|
||
|
+ /* prevent a too high nesting depth */
|
||
|
+ opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
|
||
|
+ if (++opcua_nested_count > MAX_NESTING_DEPTH)
|
||
|
+ {
|
||
|
+ expert_add_info(pinfo, ti, &ei_nesting_depth);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
|
||
|
+
|
||
|
/* parse encoding mask */
|
||
|
EncodingMask = tvb_get_guint8(tvb, iOffset);
|
||
|
proto_tree_add_bitmask(subtree, tvb, iOffset, hf_opcua_diag_mask, ett_opcua_diagnosticinfo_encodingmask, diag_mask, ENC_LITTLE_ENDIAN);
|
||
|
@@ -912,6 +928,16 @@ void parseVariant(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, gint *pOf
|
||
|
gint iOffset = *pOffset;
|
||
|
guint8 EncodingMask;
|
||
|
gint32 ArrayDimensions = 0;
|
||
|
+ guint opcua_nested_count;
|
||
|
+
|
||
|
+ /* prevent a too high nesting depth */
|
||
|
+ opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
|
||
|
+ if (++opcua_nested_count > MAX_NESTING_DEPTH)
|
||
|
+ {
|
||
|
+ expert_add_info(pinfo, ti, &ei_nesting_depth);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
|
||
|
|
||
|
EncodingMask = tvb_get_guint8(tvb, iOffset);
|
||
|
proto_tree_add_item(subtree, hf_opcua_variant_encodingmask, tvb, iOffset, 1, ENC_LITTLE_ENDIAN);
|
||
|
@@ -1167,10 +1193,20 @@ void parseExtensionObject(proto_tree *tree, tvbuff_t *tvb, packet_info *pinfo, g
|
||
|
guint32 TypeId;
|
||
|
proto_tree *extobj_tree;
|
||
|
proto_item *ti;
|
||
|
+ guint opcua_nested_count;
|
||
|
|
||
|
/* add extension object subtree */
|
||
|
extobj_tree = proto_tree_add_subtree_format(tree, tvb, *pOffset, -1, ett_opcua_extensionobject, &ti, "%s: ExtensionObject", szFieldName);
|
||
|
|
||
|
+ /* prevent a too high nesting depth */
|
||
|
+ opcua_nested_count = GPOINTER_TO_UINT(p_get_proto_data(pinfo->pool, pinfo, proto_opcua, 0));
|
||
|
+ if (++opcua_nested_count > MAX_NESTING_DEPTH)
|
||
|
+ {
|
||
|
+ expert_add_info(pinfo, ti, &ei_nesting_depth);
|
||
|
+ return;
|
||
|
+ }
|
||
|
+ p_add_proto_data(pinfo->pool, pinfo, proto_opcua, 0, GUINT_TO_POINTER(opcua_nested_count));
|
||
|
+
|
||
|
/* add nodeid subtree */
|
||
|
TypeId = getExtensionObjectType(tvb, &iOffset);
|
||
|
parseExpandedNodeId(extobj_tree, tvb, pinfo, &iOffset, "TypeId");
|