KNOWLEDGE - COLUMN ナレッジ - コラム

【エバンジェリスト・ボイス】忘れたころに振り返るCPUの脆弱性

サイバー・セキュリティ・ソリューション(CSS)部
エバンジェリスト 松岡 政之


はじめまして。CSS部に所属するエバンジェリストの松岡です。

4月からエバンジェリストを拝命致しまして、本コラムにはこれが初登場です。
宜しくお願いします。

例年より早いですが、東京も梅雨入りしましたね。私は雨の日は出かけるのが億劫で、家で一日中パソコンをいじっています。私の初コラムは趣味も交えてパソコンの頭脳であるCPUの話をちょっと深堀りしたいと思います。

CPUといっても、普段パソコンを使われている方でもあまり存在を意識することなく使われているかと思いますが、今年の年始に脆弱性(Meltdown, Spectre)が公表され一躍有名になりました。IT運用担当者やサーバ管理者の方の中には、対応に頭を悩ませた方もいらっしゃるのではないでしょうか。今回は「脆弱性というけれど一体何が問題なの?どうして起きているの?」といったところに焦点を当てていきます。

まず、一般的に Meltdown, Spectre と呼ばれている脆弱性ですが、細かく分けると以下3つに分かれます。

 ・Variant1: bounds check bypass (CVE-2017-5753)
 ・Variant2: branch target injection (CVE-2017-5715)
 ・Variant3: rouge data cache load (CVE-2017-5754)

このうちVariant1とVariant2がSpectre、Variant3がMeltdownです。いずれもCPUの高速化技術の穴をついて本来見せてはいけないデータが見えてしまう、といった脆弱性となります。それではこれらについて簡単に説明します。

Spectre
Spectreは分岐予測による投機的実行により、本来は読み出せないエリアにあるメモリの値を知ることができる脆弱性です。まずは「分岐予測による投機的実行」がこの脆弱性の必須ワードとなります。

投機的実行はCPUの高速化技術の1つで、その名の通り条件が確定する前に先んじて実行します。その動作としては、例えば次のような条件分岐があったとします。

--------------------------------------
 [Aは1より大きい]
  (↑がYesの場合)[処理①]
 [処理②]
--------------------------------------

通常は、Aが1以下の場合は処理①は実行されずに処理②が開始されます。しかし、[Aは1より大きい]という条件部分が評価に時間のかかる条件だった場合、次の流れを予測して条件の評価が終わる前に次の処理を開始します。これが投機的実行です。
 ※予測については「分岐予測(Branch Prediction)」というCPUの仕組みがあるのですが今回は割愛します。

よって、「Yes」であると予測されると条件が評価される前に処理①が実行され、結果がキャッシュされます。その後、条件評価の結果Yesではなかった場合、処理①の実行結果はキャッシュから削除されます。投機的実行についてはなんとなく理解できましたでしょうか。予測がヒットすれば条件を評価している時間を待たずに処理を進められるのでCPUの処理時間が短くなるという機能です。

Spectreは、この分岐予測で実行された結果のキャッシュが削除されるまでの間にいろいろと悪さができてしまう、といった脆弱性です。このいろいろの部分ですが、Variant1はキャッシュされた内容の一部にアクセスし、アクセスの可否によりその内容を推察するものです。Variant2は分岐予測で使われる特性を利用し、誤った分岐先に誘導しそのデータを読み出すといったものです。

Spectreの非常に恐ろしい点は、攻撃が実施された際攻撃の痕跡が残らない点です。また、JavaScriptをブラウザで実行させることにより、ブラウザに保存されているパスワードを読み取ることや、クラウドなどの仮想環境ではゲストOSからホスト環境や他のゲストOSに対して攻撃することが可能です。ただし、攻撃を成功させるには非常に難易度が高く、現時点でまだ被害の報告はありません。
(痕跡が残らないため、知らないところで攻撃されている可能性は否定できませんが…)

Meltdown
Meltdownはアウト・オブ・オーダー実行により、本来アクセスできないカーネル空間のデータを知ることができる脆弱性です。「アウト・オブ・オーダー実行」ですが、これもCPU高速化技術の一つです。その動作を簡単に説明すると、例えば次のような命令があったとします。

--------------------------------------
 A=B+1
 C=D+1
--------------------------------------

この命令で、Bの読み込みに時間がかかっていたとします。その場合、通常は上から順番どおりに実行していくのですが、アウト・オブ・オーダー実行ではその名の通り順序を無視して「C=D+1」を実行します。上記の例では問題なさそうですが、2行目が「C=A+1」の場合など、アウト・オブ・オーダー実行の結果2行目が間違っていたり不要になったりした場合は、分岐予測による投機実行と同様にアウト・オブ・オーダー実行された結果は破棄されます。こちらも分岐予測による投機的実行と同様にCPUの待機時間を減らすことができるため、CPUの処理時間を減らすことができます。

Meltdownの脆弱性をつくには、まずユーザ権限のプログラムからカーネルメモリアドレスを呼び出します。この場合、通常ではユーザ権限でカーネルメモリにはアクセスできないためアクセス違反となりますが、その違反が確定するまでの間にアウト・オブ・オーダー実行により読み込まれたカーネルデータを使ってカーネルメモリのアドレスを推定します。

Meltdownについても、Spectreほどではないものの攻撃難易度が高く、現時点ではまだ被害の報告はありません。また、Linux等で実装されたKPTI (Kernel Page-Table Isolation) というユーザ領域とカーネル領域のメモリページテーブルを完全に分離してしまう対策等、OS側での対策が有効です。

SpectreもMeltdownも、実際は読み込んではいけないデータを読み込んではいけないとわかる前に読み込んでしまう、というところに起因した問題となります。しかし、CPUのアーキテクチャに起因するハードウェア上の問題であり、さらにCPU高速化技術に起因する問題のためこの機能自体を無効化してしまうと性能が著しく低下してしまうということもあり、一朝一夕に完全な対策がなされるといったことは難しい問題です。現時点ではOSやブラウザ等のソフトウェア、BIOS(CPUマイクロコード)へのパッチによる対策がなされていますが、対策により一部性能低下が発生する等の問題もあります。

本問題の根本原因であるCPUアーキテクチャレベルでの対策は、Intelが2018年後半に投入予定の第8世代Coreプロセッサ、AMDが2019年に投入予定のRyzenプロセッサ(Zen2アーキテクチャ)にて行われる予定となっています。私自身は個人的にはRyzenプロセッサを2つ(1800X, 1950X)、FXを2つ(8350, 8120)、ノートパソコンでE2シリーズ(E2-1800)を持っているため、2019年のRyzen(Zen2)を首を長くして待っているところです。

ここまで、脆弱性の概要について簡単に解説してきました。脆弱性の概要というよりCPUの機能説明の方が長くなってしまったような気もしますが、いかがでしたでしょうか。もともとはVariantごとに少し詳しい解説も入れようとしていたのですが、書けば書くほど脆弱性を発見したGoogle Project Zeroの翻訳記事みたいになってしまったので割愛しました。本気で詳しく知りたい方は、Google Project Zeroのページで実証コードを含め、詳しく記載されていますでそちらをご参照ください。

 外部リンク: Reading privileged memory with a side-channel (Google Project Zero)


こういった脆弱性の解説を見ると、普段考えもしないような穴を巧妙についており「そんな方法があったのか!」と少し頭が柔らかくなったような気分になれます。セキュリティを担当する身としてはこういった攻撃者の視点を理解し、先回りの防御ができると頼もしいですね!

ではまた、次回のエントリーでお会いしましょう。



当サイトの内容、テキスト、画像等の転載・転記・使用する場合は問い合わせよりご連絡下さい。

エバンジェリストによるコラムやセミナー情報、
IDグループからのお知らせなどをメルマガでお届けしています。

メルマガ登録ボタン

松岡 政之

株式会社インフォメーション・ディベロプメント デジタルソリューション営業部 エバンジェリスト

この執筆者の記事一覧

関連するナレッジ・コラム

ITエンジニアの現地作業 ミスを減らす!作業本番のポイントとは

NTTのIP網移行と、通信の未来とは

ITエンジニアの現地作業 ミスを減らす!事前準備のポイントとは