Как работает состояние гонки в TOCTOU?
Следующий код должен быть уязвимым для атаки TOCTOU:
public Period(final Date start, final Date end) {
if (start.compare(end) > 0) {
throw new IllegalArgumentException("");
}
this.start = start;
this.end = end; // Class period has 2 private final member
// variables Date start & end.
}
Что я не понимаю, так это то, как будут работать условия гонки? Скажем, есть 2 потока T1 и T2, где T1 имеет действительный набор аргументов и должен пройти проверку, а T2 - хакер, который хочет установить недопустимые значения в классе.
Если два потока участвуют в гонке, и этот фрагмент кода является нашим критическим разделом, то, скажем, T1 работает, проходит проверку и спит. Теперь, когда T2 начнет работать, не пройдет ли он проверку снова (и потерпит неудачу)??
1 ответ
Проблема в том, что Date
изменяемый, поэтому другой поток может изменить дату окончания: end.setTime(0);
после того, как вы проверили это start.after(end)
(более простой способ написать ваше состояние).
Так это будет выглядеть так:
- T1:
start.after(end)
=> возвращает false, все выглядит хорошо - T2:
end.setTime(0);
=> подлый поток 2 меняет дату - T1:
this.start = start; this.end = end; //boom
=> Ваш инвариант класса больше не действителен