From e1518daf9d6c198ea50ebfc6cb9aaddc748387e6 Mon Sep 17 00:00:00 2001 From: Rodrigo Kumpera Date: Wed, 16 Aug 2017 16:43:11 -0700 Subject: [PATCH] [corlib] When parsing the ECMA key, don't produce a public key. Fixes #58637 The key was incorrectly encoded and triggered heap corruption. --- .../System.Reflection/AssemblyNameTest.cs | 20 ++++++++++++++++++ mono/metadata/assembly.c | 21 +++++++------------ 2 files changed, 28 insertions(+), 13 deletions(-) diff --git a/mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs b/mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs index b707567f1de..ceac114da71 100644 --- a/mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs +++ b/mcs/class/corlib/Test/System.Reflection/AssemblyNameTest.cs @@ -1862,6 +1862,26 @@ public class AssemblyNameTest { Assert.AreEqual ("", an.CultureName); } + + [Test] + public void TestDecodingEcmaKey () + { + var x = new AssemblyName( "System, PublicKey=00000000000000000400000000000000" ); + Assert.IsNull (x.GetPublicKey (), "#1"); + Assert.IsNotNull (x.GetPublicKeyToken (), "#2"); + + var t = x.GetPublicKeyToken (); + Assert.AreEqual (8, t.Length, "#3"); + + Assert.AreEqual (0xB7, t [0], "#4.0"); + Assert.AreEqual (0x7A, t [1], "#4.1"); + Assert.AreEqual (0x5C, t [2], "#4.2"); + Assert.AreEqual (0x56, t [3], "#4.3"); + Assert.AreEqual (0x19, t [4], "#4.4"); + Assert.AreEqual (0x34, t [5], "#4.5"); + Assert.AreEqual (0xE0, t [6], "#4.6"); + Assert.AreEqual (0x89, t [7], "#4.7"); + } } } diff --git a/mono/metadata/assembly.c b/mono/metadata/assembly.c index adfab7def01..6f1de9964a3 100644 --- a/mono/metadata/assembly.c +++ b/mono/metadata/assembly.c @@ -2372,17 +2372,18 @@ parse_public_key (const gchar *key, gchar** pubkey, gboolean *is_ecma) const gchar *pkey; gchar header [16], val, *arr, *endp; gint i, j, offset, bitlen, keylen, pkeylen; - + + //both pubkey and is_ecma are required arguments + g_assert (pubkey && is_ecma); + keylen = strlen (key) >> 1; if (keylen < 1) return FALSE; /* allow the ECMA standard key */ if (strcmp (key, "00000000000000000400000000000000") == 0) { - if (pubkey) { - *pubkey = g_strdup (key); - *is_ecma = TRUE; - } + *pubkey = g_strdup (key); + *is_ecma = TRUE; return TRUE; } *is_ecma = FALSE; @@ -2427,10 +2428,6 @@ parse_public_key (const gchar *key, gchar** pubkey, gboolean *is_ecma) bitlen = read32 (header + 12) >> 3; if ((bitlen + 16 + 4) != pkeylen) return FALSE; - - /* parsing is OK and the public key itself is not requested back */ - if (!pubkey) - return TRUE; arr = (gchar *)g_malloc (keylen + 4); /* Encode the size of the blob */ @@ -2509,10 +2506,8 @@ build_assembly_name (const char *name, const char *version, const char *culture, } if (is_ecma) { - if (save_public_key) - aname->public_key = (guint8*)pkey; - else - g_free (pkey); + aname->public_key = NULL; + g_free (pkey); g_strlcpy ((gchar*)aname->public_key_token, "b77a5c561934e089", MONO_PUBLIC_KEY_TOKEN_LENGTH); return TRUE; } -- 2.25.1