Getting “ReleaseHandleFailed” MDA in the finalizer thread after using cryptography

后端 未结 1 765
执念已碎
执念已碎 2021-01-13 15:19

I\'m getting an MDA after running this code for the second time in a loop (with a different file parameter:

byte[] encryptedData = File         


        
相关标签:
1条回答
  • 2021-01-13 15:54

    Clearly the finalizer thread is finalizing a SafeHandle that is already disposed. This is the implementation of the AesCryptoServiceProvider.Dispose(bool) method:

    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);
        }
    }
    

    Three bugs:

    • It doesn't set the m_key field to null after disposing it
    • GC.SuppressFinalize() isn't called, not even by the base class in .NET 3.5
    • The SafeCapiKeyHandle class doesn't invalidate the stored handle in its ReleaseHandle() method.

    The combination of all three bugs is enough to trigger this MDA. It is still bugged in .NET 4.0 but at least GC.SuppressFinalize is being called by SymmetricAlgorithm.Dispose(bool) so that the finalizer won't be used.

    Inspiring to see the framework masters screw up. You can report the problem at connect.microsoft.com. To stop the debugger from nagging you about this use Debug + Exceptions, Managed Debugging Assistants, untick ReleaseHandleFailed. This one is unticked by default, surely the reason you are the first to notice this bug.

    I think the third bug makes this a critical problem btw, it is technically possible for this bug to cause a recycled handle value to be closed. Very small odds though. Rather ironic, given that this is a safe handle class.

    0 讨论(0)
提交回复
热议问题