書いて覚えるSwift入門

第35回 Meltdown and Spectre

この記事を読むのに必要な時間:およそ 3 分

「嘘つきな」現代電脳

現代のコンピュータは,この問題も次のように解決しています。

  • プログラムをカーネルプロセスとユーザプロセスに分ける
  • ユーザプロセスから読み書きできるのはレジスタとメモリだけで,他プロセスを含めほかには何も存在しないふりをしている
  • ユーザプロセスがレジスタとメモリ以外の何かにアクセスしたいときには,カーネルにお願いする(システムコール)⁠カーネルにやってほしいことをレジスタとメモリに書いたうえで,CPUをカーネルプロセスに明け渡す
  • CPUを明け渡されたカーネルプロセスはプロセスのお願いを実行したあと,その結果をレジスタとメモリに書いてCPUをユーザプロセスに戻す
  • CPUにはカーネルにしか実行できない(特権)命令が用意されており,ユーザプロセスがそれを実行しようとするとエラーになる。もう少し厳密には,エラーであることを示すデータをレジスタとメモリに書いてからCPUをユーザプロセスに戻す

これを1秒間に何千回と繰り返すことで,何十何百,場合によっては何千というプロセスが同時に動いているように人間には見えるのですが,実際のところユーザ専用CPUもカーネル専用CPUも存在せず,その場その場で「今の自分はユーザ」⁠今の自分はカーネル」という「演技」をしているに過ぎません。そしてどちらも同じ舞台=CPUを使っているのです。

もし「幕間」=コンテキスト・スイッチで前の演者が自分の小道具を片付け忘れたら?

当然,次の演者にそれが渡ってしまいます。

「えいえい! おこった?」

こういう問題が存在すること自体はずっと以前――本誌Software Design創刊以前――から知られていましたが,なぜそれが今頃になって問題になったのでしょう?

コードから見えるCPUと実際のCPUの乖離が大きくなったのが一番の原因でしょう。今回問題となったのは,投機的実行とキャッシュ(cache)です。Raspberry Piがこの脆弱性を免れたのも,この2つが貧弱だったおかげ。

投機的実行の好例は,ポプテピピック(アニメ第1話)」⁠ポプ子の「えいえい! おこった?」にピピ美が「おこってないよ♥」と答えるというやりとりを二度繰り返したあと,ポプ子が寸止めしたのにピピ美が「おこっ」まで言ってしまいますが,ピピ美はまさに投機的実行していたわけです。

「とりあえずやっておいて,不要だったらやらなかったことにする」というのが投機的実行なのですが,問題は「やらなかったことにする」部分。今までは「やった結果を無視する」だけで十分だと思われていたのが,やった結果を別の誰かが盗み見てしまうという問題が今回顕在化したわけです。ピピ美の「おこっ」ですね。ちなみに原作第1話ではポプ子の寸止めはなかったのですが,これが投機的実行の成功例なのか否かは不明です。

次にキャッシュ。⁠プロセスにはレジスタとメモリしか見えない」と前述しましたが,かつては実際のプロセッサもそうでした。しかし現在のCPUでは,レジスタとメモリの間に何段階ものキャッシュが立ちはだかっています。なぜそうなったかといえば,演算回路の速度向上にメモリのアクセス速度が追いつかなかったから。

そのメモリより外部記憶はさらに遅く,その外部記憶よりネットはさらに遅い。結果外部記憶はメモリにキャッシュされ,ネットの向こうのWebコンテンツが外部記憶にキャッシュされ,そのおかげでネット社会が成立しているのですが,実に興味深いことにCPUのキャッシュはずっとプログラマから隠蔽されてきました。プログラムで挙動をコントロールすることは基本できないのです。アドレス0xdeadbeefの内容がどこにあるかは神ならぬCPUぞ知るなのです。

そしてCPUと同様,キャッシュもまたプロセスたちによって使いまわされます。使いまわされる以上,前のプロセスが片付け忘れたデータは次のプロセスが読めてしまいます。

これを防ぐには「キャッシュにもフラグを付けてアクセスコントロールする」「きちんと上書きして後片付けする」かのどちらかなのですが,前述のとおりキャッシュはプログラムからは見えない。それがMeltdownとSpectreを実際に悪用するのが困難になっているのと同時にデバッグも難しくしています。とくに「フラグを付ける」のはCPUにしかできない仕事で,その機能がないCPUに対してソフトウェア側でできることは「上書きして片付ける」しかなく,脆弱性対策を施すと3割もパフォーマンスが落ちる事例が出るのもうなづけます。

余談ですがmacOSはv10.13.2でMeltdownの,v10.13.3でSpectreの対策が施されたのですが,パフォーマンス低下が数%で済んでいるのはサポート対象のMacのほとんどが「フラグが立てられる」⁠正確にはPCIDをサポートしている)CPUを搭載しているからだと推測されます。

「計算機科学に難問は二つだけ。名前付けとキャッシュ無効化だ」とはPhil Karltonの名言ですが,プログラマが直接関与できないキャッシュにまでそれが及ぶとは……。

ソフトウェアではデザインしきれない時代

プログラマから見えるCPUが30年前からほとんど進歩していないことを我々は呆れるべきなのか褒めるべきなのか。そこにはキャッシュも存在しなければ,SSDも「Macintosh HD」のまま。それがないスマホとて,一皮剥けばただのUnixマシン。なぜそうなったか100人に尋ねたら100万通りの答えが返ってきそうですが,筆者の答えはプログラマがハードウェアに「甘えていたから」⁠今までと同じようにプログラムすれば,新しいハードウェアでも同じように動く……とくにx86は生みの親のIntelの挑戦すらはねのけて今に至りました。その牙城を攻略しつつあるARMすら,その点においては50歩100歩であることをMeltdownとSpectreは示しました。高性能化時代の覇者Wintel,省電力化時代の覇者ARMスマホの次の時代の覇者は誰なのか? それが誰であれ,セキュア化がその鍵となるのは確かだと断言しておきます。Coincheckに預けたビットコインにかけて;-)

Software Design

本誌最新号をチェック!
Software Design 2019年9月号

2019年8月17日発売
B5判/176ページ
定価(本体1,220円+税)

  • 第1特集
    気になるとこだけまとめて知りたいGoogle Cloud Platform
    開発・分析・人工知能のサービスを一挙解説
  • 第2特集
    ひとりで始めるPythonプログラミング入門
    コーディングと機械学習環境の作り方

著者プロフィール

小飼弾(こがいだん)

1969年生まれ,東京都出身。元ライブドア取締役の肩書きよりも,最近はPokemon GOのガチトレーナーのほうが有名になりつつある……かもしれない永遠のエンジニアオヤジ。

活躍の場はIT業界だけでなく,サブカルからアカデミックまで多方面にわたり,ネットからの情報発信は気の向くまま毎日毎秒! https://twitter.com/dankogai,ニコニコチャンネルは,http://ch.nicovideo.jp/dankogai,blogはhttp://blog.livedoor.jp/dankogai/

当社刊行書籍は『小飼弾のアルファギークに逢ってきた』『小飼弾のコードなエッセイ』など。他にも著書多数。