-
Notifications
You must be signed in to change notification settings - Fork 4.8k
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
Possible memory leak in ECDiffieHellmanOpenSsl #57528
Comments
I couldn't figure out the best area label to add to this issue. If you have write-permissions please help me learn by adding exactly one area label. |
Tagging subscribers to this area: @bartonjs, @vcsjones, @krwq, @GrabYourPitchforks Issue DetailsProblemCreating DescriptionFirst found when memory consumption kept rising in linux docker container using the base image Since the Or have I missed something with the scenarios showcased below? Memory leak console test classusing System;
using System.Globalization;
using System.Security.Cryptography;
namespace MemLeakTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("Starting test...");
if (args[0] == "namedCurve")
TestCreatingECDHWithNamedCurve();
else if (args[0] == "ecParameters")
TestCreatingECDHWithECParams();
else if (args[0] == "publicKey")
TestCustomPublicKeyImplementation();
else
Console.WriteLine("Invalid params: " + args[0]);
Console.WriteLine("Exiting test.");
}
/// <summary>
/// NO MEMORY LEAK
/// Looks like it ends up calling this:
/// https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcKey.cs#L31
/// </summary>
private static void TestCreatingECDHWithNamedCurve()
{
Console.WriteLine("Testing creating ECDH with NamedCurves.");
for (int i = 0; i < 500000; i++)
{
using var serverEcdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);
}
Console.WriteLine("Done!");
Console.ReadLine();
}
/// <summary>
/// GROWING WORKING SET WHILE EXECUTING.
/// Looks like it ends up calling this:
/// https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs#L22
/// </summary>
private static void TestCreatingECDHWithECParams()
{
Console.WriteLine("Testing creating ECDH with ECParameters.");
for (int i = 0; i < 500000; i++)
{
// Creating the ECDiffieHellman object causes a memory leak
using var serverEcdh = ECDiffieHellman.Create(CustomECDiffieHellmanPublicKey.BuildECParameters());
}
Console.WriteLine("Done!");
Console.ReadLine();
}
/// <summary>
/// GROWING WORKING SET WHILE EXECUTING.
/// Looks like it ends up calling this:
/// https://github.com/dotnet/runtime/blob/57bfe474518ab5b7cfe6bf7424a79ce3af9d6657/src/libraries/Common/src/Interop/Unix/System.Security.Cryptography.Native/Interop.EcDsa.ImportExport.cs#L22
/// </summary>
private static void TestCustomPublicKeyImplementation()
{
Console.WriteLine("Testing DeriveKeyFromHmac with custom ECDiffieHellmanPublicKey.");
using (var userAgentPublicKey = new CustomECDiffieHellmanPublicKey())
using (var serverEcdh = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256))
{
for (int i = 0; i < 500000; i++)
{
// Calling DeriveKeyFromHmac causes a memory leak
serverEcdh.DeriveKeyFromHmac(userAgentPublicKey, HashAlgorithmName.SHA256, null);
}
Console.WriteLine("Done!");
Console.ReadLine();
}
}
}
public sealed class CustomECDiffieHellmanPublicKey : ECDiffieHellmanPublicKey
{
public override ECParameters ExportExplicitParameters() =>
BuildECParameters();
public override ECParameters ExportParameters() =>
BuildECParameters();
protected override void Dispose(bool disposing)
{
base.Dispose(disposing);
}
internal static ECParameters BuildECParameters()
{
var parameters = new ECParameters
{
Curve = ECCurve.NamedCurves.nistP256,
Q = new ECPoint
{
X = HexToByteArray("fa719e6b556b83d413969196afdf2b07ce1ad14829f48b4c290fe276925148c7"),
Y = HexToByteArray("984a4a8d4686f162feefee023bc77184ea705e32bc304f0dbd166a2fe2ed204f")
}
};
return parameters;
}
private static byte[] HexToByteArray(string hexString)
{
byte[] bytes = new byte[hexString.Length / 2];
for (int i = 0; i < hexString.Length; i += 2)
{
string s = hexString.Substring(i, 2);
bytes[i / 2] = byte.Parse(s, NumberStyles.HexNumber, null);
}
return bytes;
}
}
}
|
@bartonjs Hi, I'm wondering since the untriaged label has been removed and the issue has been added to the 7.0.0 milestone. Has this issues been accepted and verified? Also, if so, is there any plans to fix and release a fix to this prio to the 7.0.0 milestone? |
follow |
Problem
Creating
ECDiffieHellmanOpenSsl
objects usingECParameters
causes a memory leak with each new object created. Same is true when callingECDiffieHellmanOpenSsl.DeriveKeyFromHmac
with a custom implementation ofECDiffieHellmanPublicKey
. (see test application below)Description
First found when memory consumption kept rising in linux docker container using the base image
mcr.microsoft.com/dotnet/runtime:5.0.4-buster-slim
while creating newECDiffieHellmanOpenSsl
using namedECParameters
with set ECPoint (like inBuildECParameters()
below).Replicated on Ubuntu 20.04 (WSL) using the console application below with SDK Version: 5.0.400. Here to monitor the memory consumption the
dotnet-counters
tool was used. Note that the GC Heap Size does not grow, only the Working Set.Since the
TestCreatingECDHWithECParams()
method does not leak (which uses a named curve to define theECDiffieHellman
object) but bothTestCreatingECDHWithECParams()
andTestCustomPublicKeyImplementation()
does, and one big common difference between the two scenarios is what unmanaged code is called to create theSafeEcKeyHandle
. I suspect the problem is related to theInterop
calls referenced in the method descriptions below. But I might be wrong.Or have I missed something with the scenarios showcased below?
Memory leak console test class
The text was updated successfully, but these errors were encountered: