Googleが公開した脆弱性は3種類

Variant1（CVE-2017-5753） ：配列の境界チェックバイパス

：配列の境界チェックバイパス Variant2（CVE-2017-5715） ：分岐ターゲットインジェクション

：分岐ターゲットインジェクション Variant3（CVE-2017-5754）：不正なデータキャッシュ読み込み

Variant1 ：Intel製の幅広いCPU，Arm製のCPU IPコア，AMD製のCPU

：Intel製の幅広いCPU，Arm製のCPU IPコア，AMD製のCPU Variant2 ：Intel製の幅広いCPU，Arm製のCPU IPコア

：Intel製の幅広いCPU，Arm製のCPU IPコア Variant3：Intel製の幅広いCPU，Arm製のCortex-A75

脆弱性を理解する基礎知識

※コンポーネントの熱暴走など，ハードウェアの異常に起因するOSの異常終了は依然として存在するが，ハードウェアの異常はここでは問題にしない。あるソフトウェアが原因でWindowsが丸ごと使えなくなったりはしないということだ。

Variant1の概要

Variant1による影響の範囲

Variant1に向けた各社の対応

Variant2による影響の範囲

Variant2に向けた各社の対応

mov al, ［カーネルのメモリ領域］→ この命令は特権違反

shl eax, 0xc

mov ebx, ［ユーザーのメモリ領域 ＋ eax］

Variant3による影響の範囲

Variant3に向けた各社の対応

一般メディアにもニュースとして取り上げられたので，2017年末からにわかに騒がれだした「CPUの脆弱性」については，4Gamer読者も多くが聞き及んでいることだろう。海外では，「」（スペクター）や「」（メルトダウン）といったおどろおどろしい名前が付いているので，そちらを目にしたという読者もいると思う。「Intel製のCPUだけが持つ脆弱性で，AMD製のCPUなら問題ない」から始まって，「いやいやAMD製のCPUも同様の脆弱性を抱えている」，さらには「メモリページング方式の仮想記憶を使うCPUのすべてが持つ脆弱性である」などと，情報が錯綜しているので，何を信じたらいいのか分からないという人も多いのではなかろうか。そもそも，メモリページング方式の仮想記憶は，今日（こんにち）のすべてのCPUと，その上で動くOSが使っているので，もし最後の情報が本当なら，現代文明を揺るがしかねない大問題だ。では実際のところ，騒がれている「CPUの脆弱性」とは何であって，ゲーマーの生活にも影響はあるのだろうか？ 今回は，脆弱性の概要と影響の範囲をまとめ，を紹介してみたい。そもそも今回の脆弱性は，Googleのセキュリティ研究チーム「」が北米時間2018年1月3日に 発表したもの だ。情報が錯綜した背景には，Project Zeroの発表したペーパーに，「現代的なCPUアーキテクチャに起因している」という共通点を持ちつつ，それぞれ影響を与えるCPUや影響の範囲が異なる，下に示す3つの脆弱性の存在が挙げられる。冒頭で名前だけ挙げたSpectreはこのうちVariant1とVariant2，MeltdownはVariant3の識別名で，すでに英語の解説ペーパーがpdfとして公開されている。各脆弱性の影響を受けることが確認されているCPUをここで列挙しておこう。これら3つの脆弱性のうち，最も脅威度が高いのは，ユーザープロセスからカーネルメモリ空間を読み出すことができてしまうVariant3（＝Meltdown）と思われる。Variant3の影響を受けるのは上記のとおり「Intel製の幅広いCPU」とArmのCortex-A75 だけだが， Cortex-A75は2017年に発表されたばかりのCPU IPコア なので，最終製品における実装例はまだない。なので実質的に，最も影響を受けるのはIntel製の「幅広いCPU」のみと言い切ってしまっていいかと思う。「『幅広いCPU』と言われても分からん」という話はあるが，実際のところ，Intel製CPUのどこからどこまでが影響の範囲かは，はっきりしていない。GoogleのセキュリティチームではIvy BridgeとHaswell，Skylakeの3世代が影響を受けることを確認済みだそうだが，それ以外のIntel製CPUマイクロアーキテクチャが影響を受けるかどうかは，Intelからの公式発表を待つしかないという状況である。さて，ここで3つの脆弱性を理解するために簡単な予備知識をまとめておこう。現代のOSは簡単に落ちたりしないように設計してある。たとえばゲームが異常終了してしまったとしても，それが原因でWindowsごと停止してしまうということはまずないということを経験的に知っているだろう※。これは，ゲームを含むユーザープログラムから，OSが使っているメモリ領域にアクセスできないよう，「壁」もしくは「バリア」的なものを設けてあるからだ。本稿では以下，便宜的にバリアと呼ぶが，このバリアはCPUの持つ特権機構を利用したものとなっている。ユーザープログラムがOSカーネルのメモリ領域にアクセスしようとすると，「特権違反」（という割り込みの一種）が発生して，アクセスを未然に防ぐのだと考えておけばいい。この特権機構は，セキュリティを担保するためにも重要な役割を果たす。というのも，OSが管理しているメモリ領域は，他のアプリケーションがやり取りしているデータやパスワード，ユーザーアカウントといった情報を含んでいるからだ。これらの情報を，他のアプリケーションが覗き見ないようにするということも，特権機構は実現しているのである。今回明らかになった3つの脆弱性を応用すると，OSが管理しているメモリ領域「カーネルメモリ空間」を，特権機構を超えて覗き見ることができてしまう。これは悪意を持つプログラムがデータやパスワード，ユーザーアカウントを覗き見ることを可能にすることを意味するので，ゲーマーにとっても無視できない問題ということになる。それを踏まえて，以下，3つの脆弱性を1つずつ見ていきたい。Variant1は，あるプログラムが「アクセスが許されているメモリ領域」を超えてデータを読み出せる脆弱性だ。CPUが持つ「命令の投機実行」と「データキャッシュの振る舞い」を応用したものとなっている。CPUは基本的に「メモリに並べられている順」に命令を実行するのだが，現代的なCPUでは，命令実行を高速化するため，複数の命令をメモリから取ってきて，問題がなければ順不同でどんどん実行する「投機実行」という手法が採用されている。投機実行では，条件分岐がある場合でも，条件が成立するか否かはとりあえず横に置いておいて，先に命令を実行してしまう。条件分岐が成立してしまった場合は，先行して実行した結果を捨て，条件が成立したほうの命令を実行し直すのが特徴だ。あるデータが格納されているメモリ範囲があるとしよう。「もしメモリ範囲を超えていたらメモリ範囲からのデータの読み出しを止める」という条件分岐があったとする。投機実行ではメモリ範囲を超えていたとしても，データの読み出しを実行してしまい，「メモリ範囲を超えた」という条件が成立した時点でデータの読み出しを止めるよう，命令実行の結果を捨ててやり直す動作になる。さて，ここで「あるメモリ範囲から読み出した値を使って別メモリの範囲を読み出す」という仕掛けを作っておくことを考えてみる。投機実行ではメモリ範囲を超えていたとしても投機的にデータを読み出すため，「別メモリの範囲を読み出す」ことも実行する結果となり，当然，別メモリの範囲がデータキャッシュに読み出される。なので，「データキャッシュに別のメモリ範囲のデータが存在しているかどうか」は，読み出し速度から測定することが可能だ。つまり「投機実行によって別メモリの範囲を読み出したかどうか」を判定できることになる。こうした振る舞いを巧妙に応用することで，本来なら許されていないメモリ範囲の内容を「推定」できてしまうというのがVariant1の概要だ。Variant1を使って，たとえばカーネルのメモリ範囲の内容を推定するには，カーネルのメモリ空間で動作するプログラムが必要になる。つまり，Variant1だけを使ってユーザープログラムからカーネルのメモリ範囲内にあるデータを読み出すことはできない。なので，Variant1の脆弱性だけに起因する問題がそうそう簡単に生じることはない。ただ，残念ながらというかなんというか，WindowsやLinuxといった現在の高機能なOSでは，ユーザー権限で安全にカーネルプログラムを実行する，一種のプラグインのような仕組みがあったりする。そういったプラグインからVariant1を利用することで，本来なら許されていないカーネルのメモリ範囲を読み出すことは可能で，これは大きな問題になると考えられる。Variant1に対しては，WindowsとLinux用の修正プログラムが配信されているので（ Windows ARMv8用Linux ），適用しさえすればVariant1に関連した攻撃は防げる。また， 修正プログラムを適用することによる性能への影響は軽微とされている ので，その点でも安心度は高いと言えるだろう。また，AppleはiOSとmacOS，tvOS，watchOSに対し，今後のアップデートで対応を行うと 発表している ただ，Linuxカーネルを採用していても，Androidだけは事情が異なる。よく知られているとおり，Android端末では，修正プログラムの配布をメーカーの裁量――国内においては多くの場合，携帯電話キャリアの裁量――で行っているからだ。なので端末によっては，未来永劫，修正プログラムが配信されないという可能性もある。Variant2は，Variant1のように文章で説明するのがかなり困難なので，概要だけ簡単にまとめておきたい。今日（こんにち）のCPUが分岐予測を使って条件分岐の高速化を図っているというのはすでに紹介したが，ここには，やや複雑なアーキテクチャ上のアルゴリズムと，過去の分岐先を格納しておく分岐ターゲットバッファ（Branch Target Buffer，以下 BTB），両者の活用がある。CPUの分岐予測アルゴリズムやBTBの詳細な仕組みはCPUメーカーから公開されていないのだが，GoogleのセキュリティチームはHaswellアーキテクチャのCPUを使って，分岐予測とBTBの働きを調べ上げ，「物理CPUのBTBが1つしかない」という制限を利用することで，論理CPU間で一方のスレッド/プロセスの分岐に影響を与え得ることを発見したそうだ。この振る舞いを使って，他プロセスが割り当てられているメモリを推定することが可能というのがVariant2の概要となる。カーネルや他のプロセス，あるいは仮想マシンの下で動く仮想環境のメモリをVariant2から推定し，攻撃を行うには，Variant1と同じく，カーネルのプラグインのような仕組みを使う必要がある。そのため，Variant1と同じく，Variant2だけを使った攻撃が簡単にできてしまうということはない。ただし，Variant1と2を組み合わせて応用することで，JavaScriptなどからカーネルを攻撃する方法が開発されている。ブラウザからの攻撃が可能になる恐れがあるため，脅威度自体は高いと言っていいだろう。Armはすでに同社のアプリケーションプロセッサでVariant2を防ぐLinuxカーネルの修正を 公開した 。なので，最新の修正プログラムとしてVariant2対策が施されるはずだ。また，Appleも前出のアナウンスに合わせ，Variant2対策を今後のアップデートで行うと予告している。一方のIntelはまだ表だった対応の動きを見せていないが，おそらくはWindowsやLinuxといったOSの修正プログラムといった形で対処されることになるだろう。Androidがメーカーもしくはキャリア次第というのは，ここでも変わらずだ。Variant3はVariant1の応用のような手法だが，ユーザープログラムからカーネルのメモリ領域を読み出せる可能性を持つ点で脅威度が高い。たとえば次のような命令コードがあったとしよう。1行めはカーネルのメモリ領域をレジスタAL（EAXレジスタの下位8bit）に読み出すもので，ユーザープログラムでは「特権違反」となり，例外エラーが発生する。そのためカーネルのメモリ領域は読み出せない，というのが特権機構のキモだ。だが，前出のとおり現在のCPUでは投機実行が行われている。そこで「特権違反に先行して命令を実行しているのではないか？」と着目した結果がVariant3となる。そしてこの発想は実際に正しいようで，上のコードだと3行めまでが実行できてしまう。そのため，「［ユーザーのメモリ領域 ＋ eax］がキャッシュされたかどうか」を確かめることによって，カーネルメモリ領域の内容を推定できてしまうようだ。Variant3はユーザープログラムのレベルでアクセスが許可されていないメモリ領域にアクセスできる可能性を秘めているため，Variant1およびVariant2に比べて脅威度がより高い。実際，Googleのセキュリティチームは，「Mozilla Firefox」ブラウザのパスワードマネージャを，Variant3の手法を応用することでリークさせることができたと主張していたりもする。ArmはすでにVariant3に対してLinuxカーネルの修正プログラムによる対応を行った（ 関連リンク ）。Intel製CPUでもカーネルの修正で対応は可能と考えられる。ただ，「カーネルのメモリ空間をユーザープログラムから」という，Variant3に向けた完璧な対応を行った場合，システムコールのたびにメモリページの切り替えが頻発することになり，いきおい，大幅な性能低下を招くことになるだろう。もっとも，AppleはすでにiOSとmacOS，tvOSで対策済みとしており（ 関連リンク ），性能低下もわずかだという。すでに利用されているカーネルメモリ空間のランダム化を強化することでVariant 3の攻撃をしづらくしているのではないかと思うが，そうした対策がWindowsでも可能ならば，Intel製CPUを使っている環境における性能低下は小幅なもので済むはずである。Androidに対策が入るか否かがメーカーもしくはキャリア次第なのは，やはり変わらない。仮想記憶やCPUの特権機構は，投機実行や分岐予測といった高速化のための手法が考案されるよりも，かなり以前に成立した仕組みだ。今回の脆弱性は，「投機実行や分岐予測に仮想記憶やCPUの特権機構を実装するにあたり，思わぬ落とし穴があった」という点でとても興味深い。プログラマー視点で言えば，CPUの特権機構などは当然のように機能しているという前提があるので，それがすり抜けられるという話はまさに寝耳に水といった感じである。いずれにせよ，プログラマーにとってさえ寝耳に水なのだから，ユーザーレベルでできることというのはさほど多くない。ゲーマーとしては，という鉄則を守ることが肝要だろう。