Poznámka
Přístup k této stránce vyžaduje autorizaci. Můžete se zkusit přihlásit nebo změnit adresáře.
Přístup k této stránce vyžaduje autorizaci. Můžete zkusit změnit adresáře.
Další oblastí zájmu je potenciál bezpečnostních otvorů využívaných podmínkami závodu. Existuje několik způsobů, jak k tomu může dojít. Podtémata, která následují, popisují některá hlavní úskalí, kterým by se měl vývojář vyhnout.
Konkurenční podmínky v metodě Dispose
Pokud metoda Dispose třídy (další informace, viz uvolňování paměti) není synchronizována, je možné, že kód čištění uvnitř Dispose lze spustit více než jednou, jak je znázorněno v následujícím příkladu.
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;
}
}
Vzhledem k tomu, že tato implementace Dispose není synchronizována, je možné, že ji nejprve volá první vlákno a poté druhé vlákno, předtím než je Cleanup
nastaveno na _myObj
. To, jestli se jedná o bezpečnostní problém, závisí na tom, co se stane, když Cleanup
se kód spustí. Hlavním problémem nesynchronizovaných implementací Dispose je používání popisovačů prostředků, jako jsou soubory. Nesprávné odstranění může způsobit použití nesprávného popisovače, což často vede k ohrožením zabezpečení.
Konkurenční podmínky v konstruktorech
V některých aplikacích může být možné, aby ostatní vlákna přistupovala ke členům třídy před tím, než se jejich konstruktory třídy úplně spustily. Měli byste zkontrolovat všechny konstruktory tříd, abyste měli jistotu, že neexistují žádné problémy se zabezpečením, pokud k tomu dojde, nebo v případě potřeby synchronizujte vlákna.
Podmínky časování s objekty uloženými v mezipaměti
Kód, který ukládá informace o zabezpečení do mezipaměti nebo používá operaci Assert zabezpečení přístupu kódu, může být také zranitelný vůči časovacím podmínkám, pokud ostatní části třídy nejsou správně synchronizovány, jak je znázorněno v následujícím příkladu.
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();
}
}
Pokud existují další cesty k DoOtherWork
, které lze volat z jiného vlákna se stejným objektem, může nedůvěryhodný volající překonat požadavek.
Pokud váš kód ukládá informace o zabezpečení do mezipaměti, ujistěte se, že je zkontrolujete pro tuto chybu zabezpečení.
Podmínky závodu v finalizátorech
K závodním podmínkám může dojít také v objektu, který odkazuje na statický nebo nespravovaný prostředek, který pak uvolní ve svém finalizéru. Pokud více objektů sdílí prostředek, který je manipulován s finalizátorem třídy, musí objekty synchronizovat veškerý přístup k danému prostředku.