[gnome-keyring] egg-asn1x: Fix crash when parsing invalid DER files



commit 46e5c1ee631146bddd7f8309ffcc05c4aa8a757f
Author: Stef Walter <stefw gnome org>
Date:   Mon Nov 5 21:24:31 2012 +0100

    egg-asn1x: Fix crash when parsing invalid DER files
    
     * When parsing invalid DER files and more than one sub-TLV is
       encountered we would do a NULL dereference.
     * Catch this condition and test for it.

 egg/egg-asn1x.c       |    8 ++++++++
 egg/tests/test-asn1.c |   47 +++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 55 insertions(+), 0 deletions(-)
---
diff --git a/egg/egg-asn1x.c b/egg/egg-asn1x.c
index 6a1f379..105540f 100644
--- a/egg/egg-asn1x.c
+++ b/egg/egg-asn1x.c
@@ -1181,11 +1181,17 @@ static gboolean
 anode_decode_anything (GNode *node,
                        Atlv *tlv)
 {
+	GNode *prev = NULL;
 	GNode *next;
 	gulong tag;
 	gint flags;
 
+	g_assert (node != NULL);
+
 	while (tlv != NULL) {
+		if (node == NULL)
+			return anode_failure (prev, "encountered extra tag");
+
 		flags = anode_def_flags (node);
 		tag = anode_calc_tag_for_flags (node, flags);
 
@@ -1205,6 +1211,7 @@ anode_decode_anything (GNode *node,
 			if (next == NULL)
 				return anode_failure (node, "decoded tag did not match expected");
 
+			prev = node;
 			node = next;
 			continue;
 		}
@@ -1213,6 +1220,7 @@ anode_decode_anything (GNode *node,
 			return FALSE;
 
 		/* Next node and tag */
+		prev = node;
 		node = g_node_next_sibling (node);
 		tlv = tlv->next;
 	}
diff --git a/egg/tests/test-asn1.c b/egg/tests/test-asn1.c
index 1313099..09645d6 100644
--- a/egg/tests/test-asn1.c
+++ b/egg/tests/test-asn1.c
@@ -1331,6 +1331,51 @@ test_count (Test* test, gconstpointer unused)
 	g_assert_cmpuint (egg_asn1x_count (node), ==, 7);
 }
 
+static void
+test_nested_fails_with_extra (void)
+{
+	gboolean ret;
+	GBytes *bytes;
+	GNode *asn;
+
+	const gchar SEQ_NESTED[] =  "\x30\x0C"
+	                                 "\x04\x03""one"
+	                                 "\x04\x05""extra";
+
+	asn = egg_asn1x_create (test_asn1_tab, "TestData");
+	g_assert ("asn test structure is null" && asn != NULL);
+
+	bytes = g_bytes_new_static (SEQ_NESTED, XL (SEQ_NESTED));
+	ret = egg_asn1x_decode (asn, bytes);
+	egg_asn1x_assert (ret == FALSE, asn);
+	egg_asn1x_assert (strstr (egg_asn1x_message (asn), "encountered extra tag"), asn);
+	g_bytes_unref (bytes);
+
+	egg_asn1x_destroy (asn);
+}
+
+static void
+test_nested_unexpected (void)
+{
+	gboolean ret;
+	GBytes *bytes;
+	GNode *asn;
+
+	const gchar SEQ_NESTED[] =  "\x30\x03"
+	                                 "\x02\x01\x2A";
+
+	asn = egg_asn1x_create (test_asn1_tab, "TestData");
+	g_assert ("asn test structure is null" && asn != NULL);
+
+	bytes = g_bytes_new_static (SEQ_NESTED, XL (SEQ_NESTED));
+	ret = egg_asn1x_decode (asn, bytes);
+	egg_asn1x_assert (ret == FALSE, asn);
+	egg_asn1x_assert (strstr (egg_asn1x_message (asn), "decoded tag did not match expected"), asn);
+	g_bytes_unref (bytes);
+
+	egg_asn1x_destroy (asn);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1365,6 +1410,8 @@ main (int argc, char **argv)
 	g_test_add_func ("/asn1/setof", test_setof);
 	g_test_add_func ("/asn1/setof_empty", test_setof_empty);
 	g_test_add_func ("/asn1/enumerated", test_enumerated);
+	g_test_add_func ("/asn1/nested-fails-with-extra", test_nested_fails_with_extra);
+	g_test_add_func ("/asn1/nested-unexpected", test_nested_unexpected);
 	g_test_add ("/asn1/node_name", Test, NULL, setup, test_node_name, teardown);
 	g_test_add ("/asn1/asn1_integers", Test, NULL, setup, test_asn1_integers, teardown);
 	g_test_add ("/asn1/boolean_seq", Test, NULL, setup, test_boolean_seq, teardown);



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]