Как работает состояние гонки в 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 => Ваш инвариант класса больше не действителен
Другие вопросы по тегам