Segurança e as condições de corrida
Outra área problemática é o potencial de brechas de segurança explorados por condições de corrida. Há várias maneiras em que isso pode acontecer. Os subtópicos a seguem descrevem algumas das principais armadilhas que o desenvolvedor deve evitar.
Condições de corrida no método Dispose
Se uma classe Dispose método (para obter mais informações, consulte Coleta de Lixo) não é sincronizados, é possível que código de limpeza dentro de Dispose pode ser executado mais de uma vez, conforme mostrado no exemplo a seguir.
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;
}
}
Porque isso Dispose implementação não está sincronizada, é possível Cleanup a ser chamado pelo primeiro um thread e, em seguida, um segundo thread antes de _myObj é definida como Nulo. Se esta é uma preocupação de segurança depende do que acontece quando o Cleanup código é executado. Uma questão importante dessincronizado Dispose implementações envolve o uso de identificadores de recurso, como arquivos. A disposição inadequada pode causar a alça errada ser usado, que geralmente leva a vulnerabilidades de segurança.
Condições de corrida em construtores
Em alguns aplicativos, talvez seja possível para outros segmentos acessar membros de classe antes completamente executaram seus construtores de classe. Você deve examinar todos os construtores de classe para certificar-se de que não há nenhum problema de segurança se isso deve acontecer ou sincronizar segmentos, se necessário.
Condições de corrida com objetos em cache
Código que armazena informações de segurança ou usa a segurança de acesso do código Assert operação também pode ser vulnerável a condições de corrida se outras partes da classe não estiverem sincronizados adequadamente, conforme mostrado no exemplo a seguir.
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();
}
}
Se houver outros caminhos para DoOtherWork que pode ser chamado a partir de outro thread com o mesmo objeto, um chamador não confiável pode ser adiada passado por demanda.
Se o seu código armazena em cache as informações de segurança, certifique-se de que você revise para essa vulnerabilidade.
Condições de corrida finalizadores
Condições de corrida também podem ocorrer em um objeto que faz referência a um recurso estático ou não gerenciado que, em seguida, ele libera no seu finalizador. Se vários objetos compartilham um recurso que é manipulado no finalizador da classe, os objetos devem sincronizar todo o acesso a esse recurso.