Skip to content

[QUIC] Managed Access Violation in MsQuicStream finalizer #52048

@CarnaViire

Description

@CarnaViire

Repro:

        [Fact]
        public async Task ManagedAVE_MinimalFailingTest()
        {
            async Task GetStreamIdWithoutStartWorks()
            {
                using QuicListener listener = CreateQuicListener();
                using QuicConnection clientConnection = CreateQuicConnection(listener.ListenEndPoint);

                ValueTask clientTask = clientConnection.ConnectAsync();
                using QuicConnection serverConnection = await listener.AcceptConnectionAsync();
                await clientTask;

                using QuicStream clientStream = clientConnection.OpenBidirectionalStream();
                Assert.Equal(0, clientStream.StreamId);

                // TODO: stream that is opened by client but left unaccepted by server may cause AccessViolationException in its Finalizer
            }

            await GetStreamIdWithoutStartWorks();

            GC.Collect();
        }

For me it now fails on every run, with a stacktrace

Fatal error. System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
   at System.Net.Quic.Implementations.MsQuic.Internal.SafeMsQuicStreamHandle.ReleaseHandle()
   at System.Runtime.InteropServices.SafeHandle.InternalRelease(Boolean)
   at System.Runtime.InteropServices.SafeHandle.Dispose(Boolean)
   at System.Runtime.InteropServices.SafeHandle.Dispose()
   at System.Net.Quic.Implementations.MsQuic.MsQuicStream.Dispose(Boolean)
   at System.Net.Quic.Implementations.MsQuic.MsQuicStream.Finalize()

As mentioned before in TODO comment, the stream that is being finalized is the one left inside connection's Channel<MsQuicStream> AcceptQueue - it was created and put there on PEER_STREAM_STARTED event, but was never claimed by calling AcceptStreamAsync. I didn't find an easy way to dispose what's inside AcceptQueue on connection's Dispose. But maybe that's not the only problem - users might easily leave QuicStreams undisposed, but it shouldn't lead to AVE.

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions