第1回「投機実行の隙を突くSpectre/Meltdownの仕組みを知る」はコチラ

根本対策への第1歩となるSafeSpec

このような状況で、カリフォルニア大リバーサイド校のKhaled Khasawneh氏、Esmaeil Koruyeh氏、Chengyu Song氏、College of William and MaryのDmitry Evtyushkin氏、Binghamton大のDmitry Ponomarev氏、カリフォルニア大リバーサイド校のNael Abu-Ghazaleh教授が「SafeSpec」という論文を発表した。

SafeSpecは、Speculation(投機実行)を安全(Safe)に行えるメカニズムを意味している。投機実行は今日のプロセサの高性能化の基礎をなすもので、使わない訳にはいかない。このため、どうしたら投機実行を安全に行えるかを考えたのが、この論文である。

SafeSpecの基本的な考え方は、投機的に作られた状態と投機でなく、確実となった状態を分離して管理するというものである。そして、投機的な状態の情報は、投機的に実行される命令では扱えるが、投機的でなく実行される命令では投機的な情報を使うことは出来ないという仕掛けになっている。

前の例で言うと、投機的なロード命令でキャッシュに読み込まれたデータは、投機的な情報である。したがって、投機的に実行される命令は、この情報を扱うことができるが、その結果は投機が間違っていたことが判明すると消されてしまい、取り消されずに残る結果に影響を与えることはできない。

具体的には、次の図に示すように、命令とデータキャッシュ、さらにiTLB、dTLBにシャドウバッファを追加する。そして、投機的な実行の結果、変更されるキャッシュやTLBの情報はシャドウキャッシュやシャドウTLBに格納し、その時点では本物のキャッシュやTLBには格納されない。

そして、シャドウキャッシュやシャドウTLBにデータを書き込んだ命令がコミットされて確定した時点で、シャドウから本物のキャッシュやTLBにデータが移動される。

  • SafeSpecでは、i-cache、iTLB、d-cache、dTLBに投機的データを保持するシャドウ構造を追加する

    SafeSpecでは、i-cache、iTLB、d-cache、dTLBに投機的データを保持するシャドウ構造を追加する (出典:この連載のすべての図は、Khasawneh氏らのSafeSpecの論文の図の引用である)

SpectreやMeltdownは、データキャッシュを使った攻撃であるが、SafeSpecでは命令側のi-cacheにもシャドウキャッシュが設けられている。これは、投機状態の分離という観点で考えると、命令キャッシュを使う攻撃が考えられ、実際にProof-of-Conceptのコードを作り、命令キャッシュを使った攻撃が可能であることを示している。

そして、iTLBやdTLBを使う攻撃も考えられるのであるが、実際に投機状態のデータを盗み出すことはできなかったという。TLBミスの処理には長い時間が掛かるので、投機状態のデータがそれまでに、コミットあるいは投機ミスの修正で消えてしまうのではないかと見ているという。

このシャドウd-cacheのサイズであるが、最大のキャッシュミスの回数はロードストアキューの長さで制限される。また、シャドウi-cacheのサイズは投機実行している命令を保持するリオーダバッファのサイズが最大値である。

次の2つの棒グラフは、上側がシャドウi-cache、下側がシャドウd-cacheのもので、SPECintベンチマークの各プログラムを実行しているなかで99.99%のアクセスではエントリが不足しないキャッシュエントリ数を示している。

WFCとWFBという2本のグラフがあるが、WFCはWait For Commitで、キャッシュに読み込みを起こした命令がコミットしたらシャドウから本物のキャッシュにデータを移動するというやり方をした場合。WFBはWait for Branchで、キャッシュにデータを書き込む命令までに予測要素が無くなり、実行されることが確実になった時点でデータを移動するというやり方をした場合である。

シャドウi-cacheの使用エントリ数は最大でも25程度である。また、シャドウd-cacheの使用エントリ数はプログラムに大きく依存し、20エントリ程度で十分なプログラムから60エントリを超えるものも存在する。

当たり前であるが、コミットまで待つという青色のWFCのグラフの方が長く、WFCの方が多くのエントリを必要とする。しかし、これらのグラフからみられるようにWFCとWFBで必要エントリ数に大きな差は見られない。

必要なシャドウ構造のエントリ数には、もう1つ、重要な考慮すべき点がある。シャドウエントリがいっぱいになった場合は、コミットによりシャドウエントリが本来のキャッシュに移動されて空きができるのを待つか、あるいは、シャドウエントリの内容を捨てて、新しいエントリ情報で上書きしてしまうかする必要がある。投機状態の情報であるので、内容を捨ててしまっても、実行の正しさには影響しないが、投機状態にある命令の間でシャドウバッファを使って情報を伝達できる可能性がある。このとき、送り手の命令は投機誤りでコミットされないが、受け手の命令はコミットされるとすると、受け手の命令が秘密情報を運び出すことができてしまう。

したがって、シャドウエントリが枯渇することは極力さける必要がある。このため、この論文ではシャドウ構造のサイズを、理論的に最大の投機アクセス回数に耐えられる数とした場合とSPEC2017ベンチマークを実行したときの99.99%の投機アクセス数に耐えられるサイズにした場合の2通りでハードウェアオーバヘッドを評価している。

  • 99.99%のアクセスではエントリが不足しないシャドウキャッシュのサイズ

    99.99%のアクセスではエントリが不足しないシャドウキャッシュのサイズ。上はshadow i-cache、下はShadow d-cache

(次回は6月28日に掲載します)