Freigeben über


Sicherheits- und Rennbedingungen

Ein weiterer Bedenkbereich ist das Potenzial von Sicherheitslöchern, die von Rennbedingungen ausgenutzt werden. Es gibt mehrere Möglichkeiten, wie dies passieren kann. Die folgenden Unterthemen skizzieren einige der wichtigsten Fallstricke, die der Entwickler vermeiden muss.

Racebedingungen in der Dispose-Methode

Wenn die Dispose-Methode einer Klasse (weitere Informationen finden Sie unter Garbage Collection) nicht synchronisiert wird, kann der Bereinigungscode innerhalb von Dispose mehrmals ausgeführt werden, wie im folgenden Beispiel gezeigt.

Sub Dispose()  
    If Not (myObj Is Nothing) Then  
       Cleanup(myObj)  
       myObj = Nothing  
    End If  
End Sub  
void Dispose()
{  
    if (myObj != null)
    {  
        Cleanup(myObj);  
        myObj = null;  
    }  
}  

Da diese Dispose-Implementierung nicht synchronisiert wird, ist es möglich Cleanup , dass zuerst ein Thread und dann ein zweiter Thread aufgerufen werden, bevor _myObj er auf NULL festgelegt ist. Ob dies ein Sicherheitsproblem ist, hängt davon ab, was passiert, wenn der Cleanup Code ausgeführt wird. Ein großes Problem mit nicht synchronisierten Dispose-Implementierungen umfasst die Verwendung von Ressourcenhandles wie Dateien. Die unsachgemäße Entsorgung kann dazu führen, dass das falsche Handle verwendet wird, was häufig zu Sicherheitsrisiken führt.

Racebedingungen in Konstruktoren

In einigen Anwendungen können andere Threads u. U. auf Klassenmember zugreifen, bevor die Klassenkonstruktoren vollständig ausgeführt wurden. Überprüfen Sie alle Klassenkonstruktoren, um sicherzustellen, dass keine Sicherheitsprobleme auftreten, falls dies geschehen sollte, oder synchronisieren Sie bei Bedarf Threads.

Rennbedingungen mit zwischengespeicherten Objekten

Code, der Sicherheitsinformationen zwischenspeichert oder den Codezugriffssicherheits-Assert-Vorgang verwendet, kann auch anfällig für Rennbedingungen sein, wenn andere Teile der Klasse nicht ordnungsgemäß synchronisiert werden, wie im folgenden Beispiel gezeigt.

Sub SomeSecureFunction()  
    If SomeDemandPasses() Then  
        fCallersOk = True  
        DoOtherWork()  
        fCallersOk = False  
    End If  
End Sub  
  
Sub DoOtherWork()  
    If fCallersOK Then  
        DoSomethingTrusted()  
    Else  
        DemandSomething()  
        DoSomethingTrusted()  
    End If  
End Sub  
void SomeSecureFunction()
{  
    if (SomeDemandPasses())
    {  
        fCallersOk = true;  
        DoOtherWork();  
        fCallersOk = false;  
    }  
}  
void DoOtherWork()
{  
    if (fCallersOK)
    {  
        DoSomethingTrusted();  
    }  
    else
    {  
        DemandSomething();  
        DoSomethingTrusted();  
    }  
}  

Wenn andere Pfade zu DoOtherWork vorhanden sind, die von einem anderen Thread mit demselben Objekt aufgerufen werden können, kann ein nicht vertrauenswürdiger Aufrufer eine Anforderung umgehen.

Wenn Ihr Code Sicherheitsinformationen zwischenspeichert, stellen Sie sicher, dass Sie sie für diese Sicherheitsanfälligkeit überprüfen.

Racebedingungen in Finalizern

Racebedingungen können auch in einem Objekt auftreten, das auf eine statische oder nicht verwaltete Ressource verweist, die dann in ihrem Finalizer freigegeben wird. Wenn mehrere Objekte eine Ressource gemeinsam nutzen, die im Finalizer einer Klasse bearbeitet wird, müssen die Objekte den gesamten Zugriff auf diese Ressource synchronisieren.

Siehe auch