From f9056b85390bf6e81a1b37e7d8bf928a5f8c0777 Mon Sep 17 00:00:00 2001 From: Ap0k Date: Mon, 24 May 2021 20:52:47 +0400 Subject: [PATCH] Fix #53181. AssemblyLoadContext incorrectly validates name of dynamic assembly when returned from Load --- .../Loader/AssemblyLoadContext.CoreCLR.cs | 2 +- .../Runtime/Loader/AssemblyLoadContext.cs | 2 +- .../AssemblyLoadContext30Extensions.cs | 32 +++++++++++++++++++ 3 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs b/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs index 2b992fe017ee8..7b663d443bb34 100644 --- a/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs +++ b/src/coreclr/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.CoreCLR.cs @@ -147,7 +147,7 @@ private static IntPtr ResolveUnmanagedDllUsingEvent(string unmanagedDllName, Ass AssemblyLoadContext? loadContextForAssembly = null; - RuntimeAssembly? rtAsm = assembly as RuntimeAssembly; + RuntimeAssembly? rtAsm = GetRuntimeAssembly(assembly); // We only support looking up load context for runtime assemblies. if (rtAsm != null) diff --git a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs index e990d5e491869..5dea6b34f3f8c 100644 --- a/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs +++ b/src/libraries/System.Private.CoreLib/src/System/Runtime/Loader/AssemblyLoadContext.cs @@ -657,7 +657,7 @@ private static Assembly ValidateAssemblyNameWithSimpleName(Assembly assembly, st // Derived type's Load implementation is expected to use one of the LoadFrom* methods to get the assembly // which is a RuntimeAssembly instance. However, since Assembly type can be used build any other artifact (e.g. AssemblyBuilder), // we need to check for RuntimeAssembly. - RuntimeAssembly? rtLoadedAssembly = assembly as RuntimeAssembly; + RuntimeAssembly? rtLoadedAssembly = GetRuntimeAssembly(assembly); if (rtLoadedAssembly != null) { loadedSimpleName = rtLoadedAssembly.GetSimpleName(); diff --git a/src/tests/Loader/AssemblyLoadContext30Extensions/AssemblyLoadContext30Extensions.cs b/src/tests/Loader/AssemblyLoadContext30Extensions/AssemblyLoadContext30Extensions.cs index c80e03bea852f..67e53e1e77cb8 100644 --- a/src/tests/Loader/AssemblyLoadContext30Extensions/AssemblyLoadContext30Extensions.cs +++ b/src/tests/Loader/AssemblyLoadContext30Extensions/AssemblyLoadContext30Extensions.cs @@ -2,8 +2,11 @@ // The .NET Foundation licenses this file to you under the MIT license. using System; using System.Reflection; +using System.Reflection.Emit; using System.Runtime.Loader; using System.IO; +using System.Linq; +using My; namespace My { @@ -200,6 +203,33 @@ public static void CustomName() } } + public static void GetLoadContextForDynamicAssembly(bool isCollectible) + { + try + { + Console.WriteLine($"{nameof(GetLoadContextForDynamicAssembly)}; isCollectible={isCollectible}"); + + AssemblyLoadContext alc = new AssemblyLoadContext($"ALC - {isCollectible}", isCollectible); + AssemblyBuilder assemblyBuilder; + AssemblyName assemblyName = new AssemblyName($"DynamicAssembly_{Guid.NewGuid():N}"); + + using (alc.EnterContextualReflection()) + { + assemblyBuilder = AssemblyBuilder.DefineDynamicAssembly(assemblyName, AssemblyBuilderAccess.RunAndCollect); + } + + AssemblyLoadContext? context = AssemblyLoadContext.GetLoadContext(assemblyBuilder); + + Assert(context != null); + Assert(alc == context); + Assert(alc.Assemblies.Any(a => AssemblyName.ReferenceMatchesDefinition(a.GetName(), assemblyName))); + } + catch (Exception e) + { + Assert(false, e.ToString()); + } + } + public static int Main() { foreach (AssemblyLoadContext alc in AssemblyLoadContext.All) @@ -216,6 +246,8 @@ public static int Main() AssemblyLoadByteArrayName(); CustomWOName(); CustomName(); + GetLoadContextForDynamicAssembly(true); + GetLoadContextForDynamicAssembly(false); foreach (AssemblyLoadContext alc in AssemblyLoadContext.All) {