降低计时器的分辨率以缓解 Meltdown 和 Spectre

信息安全 linux javascript 火狐 崩溃 幽灵
2021-08-27 01:43:43

我已经读到 Firefox 当前对 Meltdown 和 Spectre 的缓解(来自 57.x)包括以下内容:

  • performance.now() 的分辨率将降低到 20µs。
  • 默认情况下禁用 SharedArrayBuffer 功能。

假设大幅减少可从时间获得的信息量(例如在这种情况下将分辨率降低到 20µs)是解决 JavaScript 运行时问题的一种非常有效的方法是否正确,但是这会引入大量(太多)在将这种“锤子”应用到 Linux 内核时(因此需要额外的KPTI等)产生不必要的副作用?

1个回答

它仅应用于浏览器的原因是因为无法从本机执行的代码中完全消除高分辨率时序信息。例如,该RDTSC指令为任何进程提供精确的亚纳秒级分辨率时序信息。虽然可以通过仅通过特权代码(通过设置该CR4.TSD位)使其可执行来禁用该指令,但大部分用户空间都依赖于它。但是,即使您确实成功地禁用了它而没有损坏,也可以通过在快速循环中增加一个变量来随意操纵具有类似分辨率的计时器。用户空间代码将始终具有纳秒精度的计时信息。这样的计时器可以很容易地实现:

register volatile unsigned long counter;

void counter_thread(void)
{
    while (1) counter++;
}

counter_thread()函数将在其自己的线程中运行,并且在另一个线程中,counter可以在任意时间对 的值进行采样。由于计数器的递增速率将非常高且相当恒定,因此它将提供类似于 的高分辨率计时器RDTSC

因此,无法对直接在 CPU 上执行的任何进程隐藏精确的时序信息。只有在 JavaScript 中才有可能,因为它是一种托管的高级语言,不能对 CPU 指令进行原始访问,而且计时必须通过专用的 API,例如performance.now(),可以通过修改 JavaScript 引擎来调整其粒度。