abcdefGets

ゲッツ!

ブラウザベンダーのSpectre and Meltdown対応

Spectre and Meltdownについては前回書いたが、
各ブラウザベンダーがとっている対応について今回は書く。

といっても大したことではないのだが。

対応一覧

  • Google Chrome
    • SharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を下げる(どこまでかは不明)
    • Per Site Isolationを有効化
  • Firefox
    • SharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を20μsまで下げる
  • Safari
    • SharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を1msまで下げる

SharedArrayBufferとPerformance.nowの関係

なぜブラウザベンダーがSharedArrayBufferのデフォルト無効化とPerformance.nowの解像度を下げるかというと、今回の脆弱性の攻撃手法に関係がある。
SpectreとMeltdownは両方共、攻撃時にL1キャッシュメモリの推測を行う必要がある。(具体的には、メモリアクセスを行い、かかった時間を計測してキャッシュされている値を推測する。これをSide-Channel-Attackと呼ぶ。)

このSide-Channel-AttackSharedArrayBufferperformance.nowを使うことでかなり効率化できる。

// Worker

self.on('message', (e) => {
  const buf = new SharedUint32Array(e.data.buffer);
  do {
    Atomic.store(buf, 0, performance.now() - buf[0]);
  } while(true)
});

// main

// Create worker before.

const sab = new SharedUint32Array(1);
sab[0] = peformance.now();
worker.postMessage({buffer: sab.buffer}, [sab.buffer]);

// do memory access.

console.log(Atomic.load(buf, 0)); // Get high resolution relative time.

こんな感じでワーカースレッドでクロックを実装し、performance.nowの高精度タイマーでSharedArrayBufferに結果を書き込むことで、高精度なクロックを実装することができる。
このクロックを使うことで、そこそこ正確なメモリアクセスの相対時間を計測することができ、キャッシュメモリのチェックに利用することが可能であった。
このソフトウェアクロックの実装精度を下げるためにSharedArrayBufferの無効化とperformance.nowの精度変更が行われた。

それ以外

Per Site Isolation

ドメインレンダリングプロセスを分離する。ただしメモリ使用量が20%ほど増える。

それ以外の部分での対応、BTBの制御やOut-of-orderの抑制は不可能かパフォーマンスペナルティがでかすぎるため、Side-Channel-Attackを非効率化することにとりあえず重点が置かれている。

まとめ

これも完全な対応ではない上に、
SharedArrayBufferが使えなくなるというWebの後退が起きてしまった。