TOCTOU的竞争条件如何运作?

use*_*840 3 java security multithreading race-condition secure-coding

以下代码应该容易受到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.

 }
Run Code Online (Sandbox Code Playgroud)

我不明白的是,这种竞争条件将如何运作?假设有2个线程T1和T2,其中T1有一组有效的参数,应该通过检查,T2是一个想要在类中设置无效值的黑客.

如果2个线程正在竞争并且这段代码是我们的关键部分,则说T1运行通过检查并休眠.现在,当T2开始运行时,它是否会再次通过检查(并且失败)?

ass*_*ias 7

问题是它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=>你的班级不变量不再有效

  • 它比那更糟。你根本不需要线程。对手可以覆盖 `compare`、`after` 等。使用 `new Date(date.getTime)` 或 `java.time` 更好。(没有 `Date(Date)` 构造函数。不要在这里使用可覆盖的方法!) (2认同)
  • @ user1071840将传入的`Date`s的本地`clone()`分配给字段变量,_then_检查顺序将有所帮助.`final`s _do完全没有帮助_. (2认同)
  • 我明白那个。事实上,使用 `clone()` 也是不安全的,因为 Date 不是最终类,并且 clone() 将允许设置 Date 的不安全子类。像 this.start = new Date(start.getTime()) 这样的新防御副本应该可以工作。 (2认同)