Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

BCryptGenRandom causing High CPU Usage #28366

Closed
AdamRiddick opened this issue Jan 10, 2019 · 2 comments
Closed

BCryptGenRandom causing High CPU Usage #28366

AdamRiddick opened this issue Jan 10, 2019 · 2 comments

Comments

@AdamRiddick
Copy link

Using .NET Core 2.0 we are experiencing high CPU usage which seems to be caused by a call into BCryptGenRandom on a Windows 2012 R2 server.

One of the threads in question has been alive for 31 minutes;
30:1420 0 days 0:31:01.062

And the call stack reveals this is coming from a call to use the RandomNumberGenerator which seemingly gets stuck on BCryptGenRandom.

000000fe8789d1e8 00007ffea348079a [InlinedCallFrame: 000000fe8789d1e8] Interop+BCrypt.BCryptGenRandom(IntPtr, Byte*, Int32, Int32)
000000fe8789d1e8 00007ffe355dbd41 [InlinedCallFrame: 000000fe8789d1e8] Interop+BCrypt.BCryptGenRandom(IntPtr, Byte*, Int32, Int32)
000000fe8789d1c0 00007ffe355dbd41 DomainBoundILStubClass.IL_STUB_PInvoke(IntPtr, Byte*, Int32, Int32)
000000fe8789d270 00007ffe92533c84 System.Security.Cryptography.RandomNumberGeneratorImplementation.GetBytes(Byte*, Int32)
000000fe8789d2b0 00007ffe92533c51 System.Security.Cryptography.RandomNumberGeneratorImplementation.GetBytesInternal(Byte[], Int32, Int32)
000000fe8789d2e0 00007ffe92533a57 System.Security.Cryptography.RandomNumberGeneratorImplementation.GetBytes(Byte[])
000000fe8789d310 00007ffe35b99af8 iSAMS.Auth.Common.Security.SecureRandomNumberGenerator.Next(Int32, Int32)

This is being called from a transient class which is only instantiated once in the request;

public class SecureRandomNumberGenerator : ISecureRandomNumberGenerator
    {
        private readonly RandomNumberGenerator _randomNumberGenerator;

        public SecureRandomNumberGenerator()
        {
            this._randomNumberGenerator = RandomNumberGenerator.Create();
        }

        public int Next(int min, int max)
        {
            // Generate four random bytes
            var fourBytes = new byte[4];
            this._randomNumberGenerator.GetBytes(fourBytes);

            // Convert the bytes to a UInt32
            var scale = BitConverter.ToUInt32(fourBytes, 0);

            // And use that to pick a random number >= min and < max
            return (int)(min + (max - min) * (scale / (uint.MaxValue + 1.0)));
        }
    }

The problem is that over time the CPU usage of the dotnet process increases but isn't coming back down - which ultimately leads to the process being unavailable for the clients use.

Is there something glaringly obvious that we are doing wrong, or could this be an issue with the internal implementation?

Please note this occurs with a client-server and we have not been able to reproduce this elsewhere - and isn't something we can easily toggle on and off as it will affect their day to day operations.

@bartonjs
Copy link
Member

The only thing I see is that if you're compiling against netcoreapp (instead of netstandard) you could do better by calling RandomNumberGenerator.Fill(fourBytes) and avoid an object creation.

BCryptGenRandom isn't normally slow (that I've ever seen), but it's also not something that we really have control over... my only guess is you have another thread that keeps asking for more and more randomness and keeps winning in a lock (and this one is in a spinwait because it's not supposed to be a long lock)

@GrabYourPitchforks
Copy link
Member

I'm resolving this as No Repro since it's not currently actionable by us. If you believe this to be incorrect or you have more information you can add to the report, please reopen and we'll take a look. Thanks!

@msftgits msftgits transferred this issue from dotnet/corefx Feb 1, 2020
@msftgits msftgits added this to the 3.0 milestone Feb 1, 2020
@ghost ghost locked as resolved and limited conversation to collaborators Dec 14, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Projects
None yet
Development

No branches or pull requests

4 participants