Примечание.
Для доступа к этой странице требуется авторизация. Вы можете попробовать войти или изменить каталоги.
Для доступа к этой странице требуется авторизация. Вы можете попробовать изменить каталоги.
Еще одной проблемой является потенциал для дыр безопасности, эксплуатируемых условиями гонки. Существует несколько способов, в которых это может произойти. Подтемы, которые приведены ниже и описывают некоторые из основных подводных камней, которых разработчик должен избегать.
Условия гонки в методе Dispose
Если метод Dispose класса (дополнительные сведения см. в разделе "Сборка мусора") не синхронизирован, возможно, что код очистки внутри Dispose может выполняться несколько раз, как показано в следующем примере.
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;
}
}
Так как эта реализация Dispose не синхронизирована, можно Cleanup вызывать сначала одним потоком, а затем вторым потоком, прежде чем _myObj задать значение NULL. Является ли это проблемой безопасности, зависит от того, что произойдет при выполнении кода Cleanup. Основная проблема с несинхронизированными реализациями Dispose включает использование дескрипторов ресурсов, таких как файлы. Неправильное удаление может привести к неправильному использованию управляющего элемента, что часто создает уязвимости в безопасности.
Условия гонки в конструкторах
В некоторых приложениях возможно, что другие потоки могут получить доступ к членам класса до того, как конструкторы классов полностью завершат выполнение. При необходимости необходимо просмотреть все конструкторы классов, чтобы убедиться, что при этом не должно возникнуть никаких проблем безопасности или синхронизации потоков.
Условия гонки с кэшируемыми объектами
Код, который кэширует сведения о безопасности или использует операцию Assert для доступа к коду, также может быть уязвим к условиям гонки, если другие части класса не синхронизированы соответствующим образом, как показано в следующем примере.
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();
}
}
Если существуют другие пути к DoOtherWork, которые могут быть вызваны из другого потока с тем же объектом, ненадежный вызывающий объект может обойти проверку.
Если ваш код кэширует информацию о безопасности, убедитесь, что вы проверяете его на наличие этой уязвимости.
Условия гонки в финализаторах
Условия гонки также могут возникать в объекте, который ссылается на статический или неуправляемый ресурс, который затем освобождается в финализаторе. Если несколько объектов совместно используют ресурс, который манипулируется в финализаторе класса, эти объекты должны синхронизировать весь доступ к этому ресурсу.