gpt4 book ai didi

c# - 使用加密后在终结器线程中获取 "ReleaseHandleFailed"MDA

转载 作者:太空狗 更新时间:2023-10-30 00:45:16 24 4
gpt4 key购买 nike

我在循环中第二次运行此代码后得到了一个 MDA(使用不同的 file 参数:

byte[] encryptedData = File.ReadAllBytes(file); // before this line it throws, see exception below
long dataOffset;

using (var stream = new MemoryStream(encryptedData))
using (var reader = new BinaryReader(stream))
{
// ... read header information which is not encrypted
}


using (var stream = new MemoryStream(encryptedData))
{
stream.Seek(dataOffset, SeekOrigin.Begin);

using (var aesAlg = new AesCryptoServiceProvider())
using (var decryptor = aesAlg.CreateDecryptor(key, iv))
using (var csDecrypt = new CryptoStream(stream, decryptor, CryptoStreamMode.Read))
using (var reader = new BinaryReader(csDecrypt))
{
decrypted = reader.ReadBytes((int)(encryptedData.Length - dataOffset));
}
}

MDA 如下:

A SafeHandle or CriticalHandle of type 'Microsoft.Win32.SafeHandles.SafeCapiKeyHandle' failed to properly release the handle with value 0x000000001BEA9B50. This usually indicates that the handle was released incorrectly via another means (such as extracting the handle using DangerousGetHandle and closing it directly or building another SafeHandle around it.)

堆栈跟踪信息量不大:

mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Dispose(bool disposing) + 0x10 bytes mscorlib.dll!System.Runtime.InteropServices.SafeHandle.Finalize() + 0x1a bytes

我怀疑其中一个流或 CryptoServiceProvider 出于某种原因未发布。除此之外,该代码运行良好并且符合预期。 MDA 发生在控件到达方法的第一行之前。

我怎样才能正确地做到这一点?问题的根本原因是什么?

最佳答案

很明显,终结器线程正在终结一个已经释放的 SafeHandle。这是 AesCryptoServiceProvider.Dispose(bool) 方法的实现:

protected override void Dispose(bool disposing)
{
try {
if (disposing) {
if (this.m_key != null) this.m_key.Dispose();
if (this.m_cspHandle != null) this.m_cspHandle.Dispose();
}
}
finally {
base.Dispose(disposing);
}
}

三个错误:

  • 在处理后不会将 m_key 字段设置为 null
  • GC.SuppressFinalize() 未被调用,即使是 .NET 3.5 中的基类也未调用
  • SafeCapiKeyHandle 类不会使其 ReleaseHandle() 方法中存储的句柄无效。

所有三个错误的组合足以触发此 MDA。它在 .NET 4.0 中仍然存在漏洞,但至少 GC.SuppressFinalize 被 SymmetricAlgorithm.Dispose(bool) 调用,因此不会使用终结器。

看到框架大师搞砸了很鼓舞人心。您可以在 connect.microsoft.com 上报告该问题。要阻止调试器就此问题唠叨您,请使用 Debug + Exceptions、Managed Debugging Assistants,取消勾选 ReleaseHandleFailed。默认情况下未选中此选项,这肯定是您第一个注意到此错误的原因。

我认为第三个错误使这成为一个关键问题,顺便说一句,这个错误在技术上有可能导致回收的句柄值被关闭。虽然几率很小。具有讽刺意味的是,这是一个安全的句柄类。

关于c# - 使用加密后在终结器线程中获取 "ReleaseHandleFailed"MDA,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/5927654/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com