Skip to content

Fatal CLR error when XML serializing ImmutableArray, related to reflection #66163

Closed

Description

@mungojam

Description

When running the fairly simple program in the reproduction below, the CLR crashes and so asp.net stops receiving requests.

It only happens when using the XML response type to serialize a non-empty ImmutableArray of reference types.

The stack trace is:

Fatal error. Internal CLR error. (0x80131506)
at System.RuntimeMethodHandle.InvokeMethod(System.Object, System.Span1<System.Object> ByRef, System.Signature, Boolean, Boolean) at System.Reflection.RuntimeMethodInfo.Invoke(System.Object, System.Reflection.BindingFlags, System.Reflection.Binder, System.Object[], System.Global ization.CultureInfo) at System.Reflection.MethodBase.Invoke(System.Object, System.Object[]) at System.Xml.Serialization.TempAssembly.InvokeWriter(System.Xml.Serialization.XmlMapping, System.Xml.XmlWriter, System.Object, System.Xml.Serializat ion.XmlSerializerNamespaces, System.String, System.String) at System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, System.Object, System.Xml.Serialization.XmlSerializerNamespaces, System.Str ing, System.String) at System.Xml.Serialization.XmlSerializer.Serialize(System.Xml.XmlWriter, System.Object) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter.Serialize(System.Xml.Serialization.XmlSerializer, System.Xml.XmlWriter, System.Ob ject) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyAsync>d__19.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyA sync>d__19, Microsoft.AspNetCore.Mvc.Formatters.Xml, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<WriteResponseBodyAsync>d__19 B yRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter+<WriteResponseBodyA sync>d__19, Microsoft.AspNetCore.Mvc.Formatters.Xml, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<WriteResponseBodyAsync>d__19 B yRef) at Microsoft.AspNetCore.Mvc.Formatters.XmlSerializerOutputFormatter.WriteResponseBodyAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteCo ntext, System.Text.Encoding) at Microsoft.AspNetCore.Mvc.Formatters.TextOutputFormatter.WriteAsync(Microsoft.AspNetCore.Mvc.Formatters.OutputFormatterWriteContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsyncCore(Microsoft.AspNetCore.Mvc.ActionContext, Microsoft.AspNetCore.Mvc.Obj ectResult, System.Type, System.Object) at Microsoft.AspNetCore.Mvc.Infrastructure.ObjectResultExecutor.ExecuteAsync(Microsoft.AspNetCore.Mvc.ActionContext, Microsoft.AspNetCore.Mvc.ObjectR esult) at Microsoft.AspNetCore.Mvc.ObjectResult.ExecuteResultAsync(Microsoft.AspNetCore.Mvc.ActionContext) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultAsync(Microsoft.AspNetCore.Mvc.IActionResult) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.ResultNext[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, Publ icKeyToken=7cec85d7bea7798e],[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](State ByRef, S cope ByRef, System.Object ByRef, Boolean ByRef) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeResultFilters() at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.Next(State ByRef, Scope ByRef, System.Object ByRef, Boolean ByRef) at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeFilterPipelineAsync() at Microsoft.AspNetCore.Mvc.Infrastructure.ResourceInvoker.InvokeAsync() at Microsoft.AspNetCore.Mvc.Routing.ControllerRequestDelegateFactory+<>c__DisplayClass10_0.<CreateRequestDelegate>b__0(Microsoft.AspNetCore.Http.Http Context) at Microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9.MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9, Micr osoft.AspNetCore.Diagnostics, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<Invoke>d__9 ByRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware+<Invoke>d__9, Micr osoft.AspNetCore.Diagnostics, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<Invoke>d__9 ByRef) at Microsoft.AspNetCore.Diagnostics.DeveloperExceptionPageMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.HostFiltering.HostFilteringMiddleware.Invoke(Microsoft.AspNetCore.Http.HttpContext) at Microsoft.AspNetCore.Hosting.HostingApplication.ProcessRequestAsync(Context) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests>d__2231[[System.__Canon, System.Private.CoreLib, Version=6.0
.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext()
at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests

d__2231[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server.Kest rel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ProcessRequests>d__2231<System.__Canon> ByRef)
at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests
d__2231[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server.Kest rel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](<ProcessRequests>d__2231<System.__Canon> ByRef)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequests[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Cult
ure=neutral, PublicKeyToken=7cec85d7bea7798e]

at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+d__2221[[System.__Canon, System.Private.CoreLib, Versio n=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]].MoveNext() at System.Runtime.CompilerServices.AsyncMethodBuilderCore.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests Async>d__2221[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server
.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](d__2221<System.__Canon> ByRef) at System.Runtime.CompilerServices.AsyncTaskMethodBuilder.Start[[Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol+<ProcessRequests Async>d__2221[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]], Microsoft.AspNetCore.Server
.Kestrel.Core, Version=6.0.0.0, Culture=neutral, PublicKeyToken=adb9793829ddae60]](d__2221<System.__Canon> ByRef) at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http.HttpProtocol.ProcessRequestsAsync[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, PublicKeyToken=7cec85d7bea7798e]](Microsoft.AspNetCore.Hosting.Server.IHttpApplication1<System.__Canon>)
at Microsoft.AspNetCore.Server.Kestrel.Core.Internal.Http2.Http2Stream`1[[System.__Canon, System.Private.CoreLib, Version=6.0.0.0, Culture=neutral, P
ublicKeyToken=7cec85d7bea7798e]].Execute()
at System.Threading.ThreadPoolWorkQueue.Dispatch()
at System.Threading.PortableThreadPool+WorkerThread.WorkerThreadStart()
at System.Threading.Thread.StartCallback()

Process finished with exit code -1,073,741,819.

Reproduction Steps

Run the following program

using System.Collections.Immutable;
using Microsoft.AspNetCore.Mvc;

var builder = WebApplication.CreateBuilder(args);

builder.Services
    .AddControllers(x => x.OutputFormatters.Clear()) //clear the json formatter as only the XML one crashes
    .AddXmlSerializerFormatters();

var app = builder.Build();
app.MapControllers();

var serverTask = app.RunAsync();

var crashTask = CrashServerClr();

await serverTask;
await crashTask;

async Task CrashServerClr()
{
    await Task.Delay(TimeSpan.FromSeconds(5)); //wait for server to be up
    var rootUri = app.Urls.First(x => x.StartsWith("http://"));
    await new HttpClient().GetAsync(rootUri);
}

[Route("/")]
public class HomeController
{
    [HttpGet]
    public ImmutableArray<object> Index() => ImmutableArray.Create(new object());
}

Expected behavior

The CLR presumably shouldn't be crashable in this way. It seems different to a regular exception that would suggest just a bug in the SDK (which there could also be). For one thing, it doesn't return a 5xx error but just hangs the connection.

Actual behavior

The CLR appears to crash with the error given and asp.net never responds to the request.

Regression?

It didn't work in 6.0.1xx either.

Known Workarounds

Switch to ImmutableList which works fine

Configuration

SDK 6.0.200 with associated runtime

At least Windows 10 and 11 x64, haven't tried linux yet.

Other information

No response

Activity

  1. ghost added
    untriagedNew issue has not been triaged by the area owner
    on Mar 3, 2022
  2. KeterSCP commented on Mar 3, 2022

    @KeterSCP

    Here is a shorter console app repro:

    using System.Collections.Immutable;
    using System.IO;
    using System.Xml.Serialization;
    
    var arr = ImmutableArray.Create(new object());
    var serializer = new XmlSerializer(typeof(ImmutableArray<object>));
    
    var memStream = new MemoryStream();
    serializer.Serialize(memStream, arr);

    Btw on .NET5 this code produces System.AccessViolationException

  3. jkotas commented on Mar 4, 2022

    @jkotas
    Member

    This is crashing in the code ref.emited code by the Xml serializer.

  4. mungojam commented on Mar 6, 2022

    @mungojam
    Author

    Does my original reproduction count as a security flaw in asp.net since it could feasibly be used to crash a production asp.net server? It's not too obscure a setup and the serialisation works for JSON so could be in a live service that just had XML as an option

  5. GrabYourPitchforks commented on Mar 6, 2022

    @GrabYourPitchforks
    Member

    Hi @mungojam - hard to say right now. We'll send it around to the larger team for review. But your mixed JSON/XML web service scenario is compelling.

    BTW, thank you for the very clear repro. Much appreciated. :)

  6. StephenMolloy commented on Mar 17, 2022

    @StephenMolloy
    Contributor

    If you try to serialize as an IEnumerable which is backed by the ImmutableArray... would this work then? That might be a way to unblock until this can be addressed.

  7. removed
    untriagedNew issue has not been triaged by the area owner
    on Mar 17, 2022
  8. mungojam commented on Mar 17, 2022

    @mungojam
    Author

    If you try to serialize as an IEnumerable which is backed by the ImmutableArray... would this work then? That might be a way to unblock until this can be addressed.

    Do you mean as a workaround? The easiest one I found was to convert things to immutablelist. I only had a handful of classes in my case.

    The real issue is the crash, not the lack of support for ImmutableArray as there are plenty of other common types that aren't supported either.

  9. ghost added
    in-prThere is an active PR which will close this issue when it is merged
    on Aug 10, 2022
  10. ghost removed
    in-prThere is an active PR which will close this issue when it is merged
    on Aug 13, 2022
  11. ghost locked as resolved and limited conversation to collaborators on Sep 12, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions