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