Observação
O acesso a essa página exige autorização. Você pode tentar entrar ou alterar diretórios.
O acesso a essa página exige autorização. Você pode tentar alterar os diretórios.
Outra área de preocupação é o potencial de falhas de segurança exploradas pelas condições de corrida. Há várias maneiras pelas quais isso pode acontecer. Os subtópicos a seguir descrevem algumas das principais armadilhas que o desenvolvedor deve evitar.
Condições de corrida no método Dispose
Se o método Dispose de uma classe (para obter mais informações, ver Coleta de Lixo) não for sincronizado, é possível que o código de limpeza dentro do Dispose possa 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;
}
}
Como essa implementação de Descarte não está sincronizada, é possível Cleanup ser chamada primeiro por um thread e, em seguida, um segundo thread antes _myObj é definido como nulo. Se essa é uma preocupação de segurança depende do que acontece quando o Cleanup código é executado. Um problema importante com implementações de Descarte não sincronizadas envolve o uso de identificadores de recursos, como arquivos. O descarte inadequado pode levar ao uso de um identificador incorreto, o que costuma causar vulnerabilidades de segurança.
Condições de corrida em construtores
Em algumas aplicações, pode ser possível que outros processos acessem membros da classe antes que seus construtores de classe tenham sido completamente executados. Você deve examinar todos os construtores de classe para garantir que não haja problemas de segurança se isso acontecer ou sincronizar threads, se necessário.
Condições de corrida com objetos armazenados em cache
Código que armazena em cache informações de segurança ou usa a operação assert de segurança de acesso de código também pode estar vulnerável a condições de corrida se outras partes da classe não forem sincronizadas adequadamente, conforme mostra o 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 possam ser chamados de outro thread com o mesmo objeto, um chamador não confiável poderá passar por uma demanda.
Se o código armazenar em cache informações de segurança, verifique se você as revisou para essa vulnerabilidade.
Condições de corrida em finalizadores
As 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 ele libera em seu finalizador. Se vários objetos compartilharem um recurso manipulado no finalizador de uma classe, os objetos deverão sincronizar todo o acesso a esse recurso.