Blame SOURCES/wireshark-0012-CVE-12086.patch

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");