Fix double dispose of GCHandle in BrowserWebSocket#113464
Fix double dispose of GCHandle in BrowserWebSocket#113464pavelsavara merged 3 commits intodotnet:mainfrom
Conversation
MemoryHandle is a struct, so passing it into an IDisposable parameter creates a box. This causes two copies of GCHandle to exist which are no longer synchronized and can be double disposed. This happened when passing pinBuffer into CancellationHelper in ReceiveAsyncCore and SendAsyncCore. In both cases the caller does the Dispose itself inside a finally, so there's no need to pass the pinBuffer to CancellationHelper at all.
|
This has been reported downstream in NativeAOT-LLVM where the double-free of the GCHandle causes an assert (in Debug) or a corruption. (/cc @yowl for the original report) |
|
Tagging subscribers to 'arch-wasm': @lewing |
This comment was marked as duplicate.
This comment was marked as duplicate.
|
A minimal repro for the issue Filip was tracing: using System.Buffers;
ThreadPool.QueueUserWorkItem(_ => GC.Collect());
for (int i = 0; i < 100; i++)
{
Memory<byte> bufferMemory = new byte[100];
MemoryHandle mh = bufferMemory.Pin();
IDisposable d = mh;
d.Dispose();
mh.Dispose();
}Fails for me on the Checked runtime with: When we clone @jkotas is it something that shouldn't happen or just an UB on double-free? |
|
Double free of GCHandle is faulty. See also #112727 |
It is just an UB on double-free. |
|
This will need 9.0 backport. Net8 doesn't have this issue. |
|
/ba-g know CI timeouts |
|
/backport to release/9.0-staging |
|
Started backporting to release/9.0-staging: https://github.com/dotnet/runtime/actions/runs/13860807379 |
MemoryHandle is a struct, so passing it into an IDisposable parameter creates a box. This causes two copies of GCHandle to exist which are no longer synchronized and can be double disposed.
This happened when passing pinBuffer into CancellationHelper in ReceiveAsyncCore and SendAsyncCore. In both cases the caller does the Dispose itself inside a finally, so there's no need to pass the pinBuffer to CancellationHelper at all.