連載「OSS脆弱性ウォッチ」では、さまざまなオープンソースソフトウェアの脆弱性に関する情報を取り上げ、解説していく。2018年の上半期は、「Meltdown」「Spectre」とその変異(Variant)の脆弱性に悩まされた。今回はいつもとは異なり、上半期のまとめも兼ねて、Meltdown/Spectreの各変異をバージョンを追いかけながら整理する。
「OSSセキュリティ技術の会」の面和毅です。本連載「OSS脆弱性ウォッチ」では、さまざまなオープンソースソフトウェア(OSS)の脆弱(ぜいじゃく)性に関する情報を取り上げ、解説しています。
2018年の上半期は、「Meltdown」「Spectre」とその変異(Variant)の脆弱性に悩まされました。さらに今なお新しくVariantが発見され、修正情報が更新されている状況です。今回はいつもとは異なり、上半期のまとめも兼ねて、Meltdown/Spectreの各変異をバージョンを追いかけながら整理します。
なお、実際にSpectreおよび変異に関する情報は詳しい情報が各所から出ているので、本記事では大まかな説明とLinuxでの対応を中心に触れます。
2018年7月9日現在までで公開されている、SpectreのVariant(変異)は表1のようになります。公開された日時はNISTのNVD(National Vulnerability Database)を参考にしています。
名前 | Variant | CVE | NVD公開日時 | 修正 |
---|---|---|---|---|
Bound Check Bypass(BCB) | 1 | CVE-2017-5753 | 2018年1月4日 | カーネル |
Branch Target Injection(BTI) | 2 | CVE-2017-5715 | 2018年1月4日 | カーネル、マイクロコード |
Rogue Data Cache Load(RDCL) | 3 | CVE-2017-5754 | 2018年1月4日 | |
Rogue System Register Read(RSRE) | 3a | CVE-2018-3640 | 2018年5月22日 | |
Speculative Store Bypass(SSB) | 4 | CVE-2018-3639 | 2018年5月22日 | |
Lazy Floating Point State Restore(LazyFP) | 5 | CVE-2018-3665 | 2018年6月14日 | |
これ以降も出てくるSpectreのVariantの脆弱性は、全て「処理速度を速めるために実装されている、ハードウェア由来(正確にはCPU由来)のもの」となっています。そのため、単にLinuxやOSの問題ではなく「脆弱性があるCPUを使っている全ての機器のソフトウェア」に関わる問題です。
以下に、大まかな流れと内容を書きます。
Variant 1〜3は、一般的に「Meltdown」「Spectre」と呼ばれているものです。公開日時は2018年1月4日となっており、日本ではいまだお正月気分に浸っている時期でした。公開後、影響の範囲の広さと対処のし難さから、お正月休みの間のITに関するニュースは、この話題で持ちきりでした。セキュリティエンジニアでお正月をゆっくり過ごせた方は少ないのではないでしょうか?
詳しい説明は、下記記事が非常に分かりやすいので、ここでは割愛し、ざっくりとした説明だけに留めます。
図1のようなコードでxの値を攻撃者がコントロールできるとします。まず、「xがarra1_size内に収まってる」という確認を【1】で行い、その後【2】が実行されます。
ここでxの値を攻撃者がコントロールして、【1】の条件が真になるような処理を何回も行います(覚えさせる)。その上で、xの値を「範囲外」にした処理を行うと、CPUは高速化のため【1】の処理が完了する前に【2】の処理を行いキャッシュに入れます。その後【1】の結果が偽になるため、CPUはエラーを検出し、状態を元に戻しますがキャッシュ状態の変更は元に戻りません。これを利用して、攻撃者はキャッシュの中身を分析することが可能です。
プログラムが分岐予測をする際に使用するテーブルが、同一CPUコア上で共有されることを利用します。プログラムAが条件分岐で【1】に行くような処理を何度も行います。その後同一CPUコア上でプログラムBが処理されると、分岐予測で【1】を先行して処理するので、これを悪用するものです。
いわゆる「Meltdown」と呼ばれるものです。プログラムが処理を高速化するために「アウトオブオーダー実行」という手法を行うことを悪用し、「ユーザーランド」のプログラムが、カーネルモードで動作しているプログラムのメモリにアクセスできるようにします。
Spectreの話も大分沈下してきたなぁと感じられてきた2018年5月22日に、今度は2つのVariant(3a、4)が発表されました。
Variant 3aに関してはARM独自の問題で他のCPUには被害が及ばないこと、Variant 4に関しては現実的にあまり悪用できるものではないことなどから、いずれも深刻度はそれほど大きくありませんでした。また、これらVariant 3a、4に関しては、前述のVariant 1〜3と類似するため 「SpectreNG」という名称で報じられました。
このVariant 3aはArmプロセッサに限定された脆弱性です。詳しい内容は、Armの開発者向けPDFに載っているので概略だけ触れます。
幾つかのArmプロセッサではシステムレジスタの読み出しを投機的に行う際に、除外レベルを超えたアクセスに対してエラーを返しますが、その際に戻されたデータを利用して、システムレジスタの値を推測できてしまう問題です。Variant 3と似ているため、「Variant 3a」となっています。
図3のようなコードがあるとします。当然これはエラーになるわけですが、この場合、4行目のシフト量(imm)値を動かすことで、戻り値からX3に格納されていた「TTBR0_EL_1」の値を推測できてしまうというものです。
Variant 4に関しては、Microsoftの解説や、Red HatのブログおよびYouTube動画(英語)を見るのが一番分かりやすいでしょう。以下の説明もMicrosoft/Red Hatのものに準じます。
Variant 4の「Speculative Store Bypass」では、CPUがメモリからデータのLoad/Storeをする処理に関して、投機的予測を使った最適化に関わる部分を狙ったものです。
図4のように命令を実行する際、1行目で保存(Store)する際の[rdi+rcx]の計算が別の処理待ちになって時間がかかる場合があります。この場合、2行目のr8レジスタへのロード処理を先に行います。この結果、r8レジスタには[rsi+rcx]のアドレス内の情報が渡り、さらに3〜4行目を通じて他のプログラムに渡る可能性があります。
5月にVariant 3a、4が公開され、その影響がまだ話されていた段階の2018年6月14日に、またもやIntelからVariant 5の「Lazy FP state restore」が公開されました。
Variant 5はMeltdownに似た脆弱性で、FPUのコンテキストスイッチの際にレジスタの情報が漏えいする可能性があるというものです。しかしこの脆弱性はMeltdownよりも条件が厳しいため、悪用される可能性はMeltdownよりもさらに少ないだろうと言われています。
Variant 5に関しては、こちらのRed Hatの解説記事、およびCYBERUS TECHNOLOGYのブログが分かりやすいので、詳しくはそれらを参照してください。
下記で簡単にまとめます。
しかし、このLazy FPU Stateの脆弱性は、Linux Kernelでは比較的古い段階(Kernel 4.9で修正されている)でOSレベルでの修正が導入されていたため影響はなく、Windowsなどにだけ影響がありました。
表2に、それぞれのSpectre VariantがどのLinuxカーネル(コミュニティーが提供している安定板のカーネル)で修正されたかをまとめています。
Variant | 修正されたカーネルバージョン |
---|---|
1 | 4.14.14/4.9.77/4.4.113 |
2 | 4.15.9/4.14.26/4.9.87/4.4.121 |
3 | 4.14.11/4.9.75/4.4.110 |
3a | 4.16.11/4.14.43/4.9.102 |
4 | 4.16.11/4.14.43/4.9.102 |
5 | 4.6/4.4.138(4.6は2016年) |
一連のSpectreのVariantでは、条件分岐の箇所で確認の項目を挟むなど、全体的に処理がかなり増えています。そのため、Spectre対応済みのカーネルにアップグレードすると、システムが重くなったという話がよく聞こえてきます。では、実際にどの程度パフォーマンス劣化が発生するのかを見てみましょう。
システムのベンチマークを取るために、一般的なベンチマークツール「UnixBench」を使ってテストを行います。今回は、下記のようなシステムを使用しました。
表3にUnixBenchの結果をまとめています。カーネルは下記を選び、それぞれで劣化がどれくらいだったかをまとめています。
UnixBench項目 | 4.14.10 | 4.14.26 | 4.14.43 | 4.17.9 |
---|---|---|---|---|
Dhrystone 2 using register variables | 100.00 | 97.68 | 98.41 | 98.67 |
Double-Precision Whetstone | 100.00 | 99.84 | 100.31 | 100.44 |
Execl Throughput | 100.00 | 92.93 | 91.99 | 93.50 |
File Copy 1024 bufsize 2000 maxblocks | 100.00 | 95.63 | 93.21 | 93.31 |
File Copy 256 bufsize 500 maxblocks | 100.00 | 100.54 | 97.88 | 97.07 |
File Copy 4096 bufsize 8000 maxblocks | 100.00 | 104.83 | 102.86 | 102.20 |
Pipe Throughput | 100.00 | 43.37 | 43.40 | 42.94 |
Pipe-based Context Switching | 100.00 | 68.06 | 66.68 | 66.80 |
Process Creation | 100.00 | 91.42 | 90.48 | 91.57 |
Shell Scripts (1 concurrent) | 100.00 | 96.37 | 96.00 | 96.02 |
Shell Scripts (8 concurrent) | 100.00 | 96.16 | 96.03 | 96.19 |
System Call Overhead | 100.00 | 19.28 | 19.15 | 19.01 |
特に著しく劣化した部分(Pipe Throughput、Pipe-based Context Switching、System Call Overheadの3つ)を抜き出してグラフ化したのが、図5です。
特にOSのシステムコール呼び出しやプロセスのコンテキストスイッチの箇所で性能劣化が顕著になっています。そのためOSでの対処はやはりワークアラウンドである側面が大きく、本質的にはCPU/ハードウェアのレベルでの解決が望まれます。
今後もSpectreのVariantは発見されると思われるので、しばらくは情報をつかみながら、OS、マイクロコード、ファームウェアなどをなるべく最新にして、システムの安全性を担保しましょう。
略歴:OSSのセキュリティ専門家として20年近くの経験があり、主にOS系のセキュリティに関しての執筆や講演を行う。大手ベンダーや外資系、ユーザー企業などでさまざまな立場を経験。2015年からサイオステクノロジーのOSS/セキュリティエバンジェリストとして活躍し、同社でSIOSセキュリティブログを連載中。
CISSP:#366942
近著:『Linuxセキュリティ標準教科書』(LPI-Japan)
Copyright © ITmedia, Inc. All Rights Reserved.