dotnet / runtime

.NET is a cross-platform runtime for cloud, mobile, desktop, and IoT apps.
https://docs.microsoft.com/dotnet/core/
MIT License
15.25k stars 4.73k forks source link

Runtime crash caused by Thread.Join called on resurrected Thread #107473

Open jkotas opened 1 month ago

jkotas commented 1 month ago

Deterministic repro

  1. Build a private coreclr.dll with Sleep(1000) added here: https://github.com/dotnet/runtime/blob/ad430a1d1c6b4016aedd63d15d3089291dced322/src/coreclr/vm/comsynchronizable.cpp#L719
  2. Enable page heap for corerun.exe using gflags
  3. Compile and run the following test using corerun.exe:
    
    using System;
    using System.Threading;
    using System.Runtime.CompilerServices;

Helper.Initialize();

new Thread(Work).Start();

GC.Collect(); GC.WaitForPendingFinalizers();

Thread.Sleep(3000);

static void Work() { for (;;) { if (Helper.ResurectedThread != null) { Helper.ResurectedThread.Join(1); } } }

class Helper { public static volatile Thread ResurectedThread;

Thread _thread;

[MethodImpl(MethodImplOptions.NoInlining)]
public static void Initialize() => GC.KeepAlive(new Helper());

Helper()
{
    _thread = new Thread(() => { });
    _thread.Start();
    _thread.Join();
}

~Helper()
{
    ResurectedThread = _thread;
}

}


(It is also possible to build non-deterministic repro that reproduces the crash on shipping bits.)

### Actual result

Assert failure(PID 23336 [0x00005b28], Thread: 21216 [0x52e0]): Consistency check failed: AV in clr at this callstack:

CORECLR! DoJoin + 0x2C3 (0x00007ffa175c9d83) CORECLR! ThreadNative_Join + 0x15B (0x00007ffa175cd87b)

.AV on tid=0x52e0 (21216), cxr=0000009F9477E6C0, exr=0000009F9477EBB0



The crash is caused by use-after-free of the unmanaged Thread object.

### Expected result

No runtime crash. C# code that does not used `unsafe` blocks and that does not call any memory unsafe APIs should not lead to runtime crash.
jkotas commented 1 month ago

The problem is not limited to Thread.Join. Majority of Thread APIs that are implemented using FCalls or QCalls suffer from this issue.

dotnet-policy-service[bot] commented 1 month ago

Tagging subscribers to this area: @mangod9 See info in area-owners.md if you want to be subscribed.