ブラウザベンダーの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-Attack
をSharedArrayBuffer
とperformance.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の後退が起きてしまった。