runtime: Crash on WindowsCryptographicException on net60 GA
Description
System.AggregateException: One or more errors occurred. (Unknown error (0xc1000008)) —> Internal.Cryptography.CryptoThrowHelper+WindowsCryptographicException: Unknown error (0xc1000008) at Internal.Cryptography.HashProviderCng.AppendHashData(ReadOnlySpan`1 source) at Internal.Cryptography.HashProvider.AppendHashData(Byte[] data, Int32 offset, Int32 count) at System.Security.Cryptography.SHA256.Implementation.HashCore(Byte[] array, Int32 ibStart, Int32 cbSize) at System.Security.Cryptography.HashAlgorithm.ComputeHash(Byte[] buffer) at Host.CLI.Program.<>c__DisplayClass9_2.<<BuildAsync>b__3>d.MoveNext() in C:\work\curiosity\curiosity-ai-website\tools\host\Program.cs:line 280 — End of stack trace from previous location — at Host.CLI.Program.BuildAsync(String path, String buildPath, String templatePath, String translationPath) in C:\work\curiosity\curiosity-ai-website\tools\host\Program.cs:line 296 — End of inner exception stack trace — at System.Threading.Tasks.Task.ThrowIfExceptional(Boolean includeTaskCanceledExceptions) at System.Threading.Tasks.Task.Wait(Int32 millisecondsTimeout, CancellationToken cancellationToken) at System.Threading.Tasks.Task.Wait() at Host.CLI.Delayed.<CreateScheduledQueueChecker>g__CheckBacklog|5_1() in C:\work\curiosity\curiosity-ai-website\tools\host\Delayed.cs:line 71 at Host.CLI.Delayed.<>c.<CreateScheduledQueueChecker>b__5_0(Object _) in C:\work\curiosity\curiosity-ai-website\tools\host\Delayed.cs:line 49 at System.Threading.TimerQueueTimer.<>c.<.cctor>b__27_0(Object state) at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) — End of stack trace from previous location — at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state) at System.Threading.TimerQueueTimer.CallCallback(Boolean isThreadPool) at System.Threading.TimerQueueTimer.Fire(Boolean isThreadPool) at System.Threading.TimerQueue.FireNextTimers() at System.Threading.TimerQueue.AppDomainTimerCallback(Int32 id)
Reproduction Steps
The app in question is a simple web host, accessing the page via the edge browser.
Expected behavior
No crash
Actual behavior
Process crashes hard with an uncaught exception
Regression?
Yes. The issue never happen till I installed the net60 GA SDK installed this morning.
Known Workarounds
No response
Configuration
Window x64
dotnet --list-sdks
2.1.526 [C:\Program Files\dotnet\sdk]
2.1.617 [C:\Program Files\dotnet\sdk]
2.1.701 [C:\Program Files\dotnet\sdk]
2.1.818 [C:\Program Files\dotnet\sdk]
2.2.101 [C:\Program Files\dotnet\sdk]
2.2.301 [C:\Program Files\dotnet\sdk]
3.0.100-preview8-013656 [C:\Program Files\dotnet\sdk]
3.0.100 [C:\Program Files\dotnet\sdk]
3.1.200 [C:\Program Files\dotnet\sdk]
3.1.301 [C:\Program Files\dotnet\sdk]
3.1.415 [C:\Program Files\dotnet\sdk]
5.0.104 [C:\Program Files\dotnet\sdk]
5.0.209 [C:\Program Files\dotnet\sdk]
5.0.303 [C:\Program Files\dotnet\sdk]
5.0.403 [C:\Program Files\dotnet\sdk]
6.0.100-rc.1.21458.32 [C:\Program Files\dotnet\sdk]
6.0.100 [C:\Program Files\dotnet\sdk] <---- App is running on this now
Other information
No response
About this issue
- Original URL
- State: closed
- Created 3 years ago
- Comments: 20 (11 by maintainers)
Hi @vcsjones, I’ve not observed the issue anymore! Nice to hear it uncovered another issue nevertheless! Thanks!
It looks like you are using an instance of
SHA256concurrently. You have a property, field, or local instance namedSha256that is concurrently (Task.WhenAll) computing the file hashes.If you are targeting
net5.0or higher, you can change it to this:HashDatawas introduced in .NET 5. It is a static method and it is thread safe.To round things out here:
@vcsjones I have a repro case for a similar, if not identical, issue:
This breaks:
If you want things to break in .NET6 just leave the 4th line commented. If you want it to not break, uncomment line 4.
If you re-initialize a hasher after calling TransformBlock and before calling TransformFinalBlock, you corrupt the hasher and it fails.
EDIT: Thanks to @EvgeniyZ-ru for bringing this issue to my attention, and working with me to provide the information I needed to distill a testcase 😃
A few guesses, since I don’t have a lot to go on.
I suspect it is might be because the
HMACSHA512encryptorfield is being accessed from multiple threads. Instances ofHMACSHA512are not thread safe.I can reproduce this exception by using an
HMACSHA512instance between threads:That will quickly give me the same issue as described in the original post.
At this point I can only suggest that you confirm with the library author that no instance of a hash or HMAC algorithm is being used by two or more threads, concurrently.
If that is indeed the case, I would recommend creating a new instance of the hash / HMAC algorithm per-thread, or just always as-needed. Alternatively, using the
HMACXYZ.HashDataone-shot static methods that were introduced in .NET 5 for digests, and .NET 6 for HMACs.