はじめに
Linuxの安定カーネルのとりまとめ役、グレッグ・クラーハートマンによるメルトダウンとスペクター問題に関する1/6時点での現況の説明の訳文です。
太字は訳者が主観で独自に付加したものです。
2018/1/19:
対応状況がGreg氏によりアップデートされましたので、追記しました。
ライセンス
原文は当人のブログでby-nc-sa3.0で公開されています。
この文章のライセンスも原文に準じます。
謝辞
-
何よりもまず多忙な中情報をシェアしてくれた原著者のGreg氏に。
-
表記間違いについて指摘ありがとうございます。以下修正しました。
https://twitter.com/KuniSuzaki/status/950888858568163328 -
ライセンスの表記間違いを修正しました。ご指摘ありがとうございました。
-
@7of9 さんより明らかな誤認・誤訳・見落とし箇所への編集リクエストをいただき、マージしました。ありがとうございます。
訳:Meltdown and Spectre Linux Kernel Status
今となっては、誰もがコンピューターセキュリティ上の大事件がアナウンスされたのを知ってる。何せデーリー・メールが報じたくらいだし、なにか悪いことが起きた事は分かるよね・・・。
とにかく、ここでは報道されている問題の詳細は語らない。代わりに、ProjectZeroの素晴らしい執筆論文を示したい。2018年のPwnie賞を今すぐ受賞すべきだ。そのくらい素晴らしい。
カーネルにおける問題解決の技術的詳細を知りたければ、lwn.netの秀逸な記事にまず目を通すべきだ。
加えて、他のたくさんの投稿の良い要約もここにある。複数ベンダからのアナウンスも含まれている。
関係企業の対応は、「Linuxカーネルコミュニティとこのように応酬しあってはダメ」な教科書的実例と言える。関係者と企業は事の経緯を知っているし、結局全ては明らかになるだろう。**が、今は問題解決に注意を向ける必要があり、責任を指摘すべき時ではない。**そうしてやりたい、と思ってもだ。
今何をすべきか
通常のLinuxディストリビューションをシステムで使っているのであれば、カーネルを今すぐアップデートしよう。もうすでにアップデートが用意されているはずだ。数週間はアップデートを続けよう。影響を及ぼすシステムの種類と作業量が膨大なため、テストは複雑である。見つかった大量の例外的なバグへの対応はまだ作業中だ。もし使用中のディストリビューションがカーネルアップデートを提供しないなら、ディストリビューションの変更を今すぐ行う事を勧告する。
理由は様々だが、「通常」のLinuxディストリビューションが動いていないシステムが大量に存在する。(噂によると、「定番」企業のディストリビューションよりたくさんあるとか)。そのようなシステムはLTSか、通常の安定版か、フランケンシュタインのような(パッチだらけの?)自家製カーネルに依存しているだろう。それらの人々に対し、これから使用可能なカーネルにおいて、何が起きているのか状況を説明しよう。
メルトダウン x86の場合
今現在、Linusのカーネルツリーにはx86アーキテクチャに存在するメルトダウン脆弱性を扱うため、既知の事実に基づく修正がすべて含まれている。CONFIG_PAGE_TABLE_ISOLATIONカーネルビルドオプションを有効にし、リビルドして再起動すれば良い。
しかしながら、Linusのツリーは4.15-rc6にいくつかの大きなパッチをあてたものだ。4.15ーrc7は複数の問題解決のための大きなパッチを当てたものだが、明日(※1/6時点)出る。が、大多数の人の「通常」の環境ではrc(リリース候補版)カーネルは運用しないだろう。
x86の開発者たちのページテーブル隔離コード開発の仕事は素晴らしく、rcから最新安定版の4.14への移植はすぐできるだろう。つまり安定版4.14(現時点では4.14.12)を運用すべきという事だ。4.14.13は数日後にリリースされるが、これは4.14.12でいくつかのシステムの起動時の問題を追加修正したものである。(これは明らかに問題なので、もし起動しないなら、上がっているいくつかのパッチを適用してみよう)
僕は個人的に Andy Lutomirski, Thomas Gleixner, Ingo Molnar, Borislav Petkov, Dave Hansen, Peter Zijlstra, Josh Poimboeuf, Juergen Gross, そしてLinus Torvalds各氏にこれら修正と上流カーネルへのマージをまとめてくれた事に感謝を述べたい。おかげで安定版リリースの動作確認に専念するのがとても容易になった。彼らの努力なしには、何が起こるか考えるのさえ放棄していただろう。
それより古いLTSカーネル4.4と4.9には、Hugh Dickins, Dave Hansen, Jiri Kosina そして Borislav Petkov各氏が同様の機能をもたらしてくれた。素晴らしい仕事にとても感謝している。
同様にGuenter Roeck, Kees Cook, Jamie Iles, そしてほかの大勢の人たちにはタチの悪いバグや失われたパッチを追跡してもらった。大変感謝している。またDavid Woodhouse, Eduardo Valentin, Laura Abbott, そして Rik van Riel各氏の移植・統合の際のヘルプも忘れてはならない。彼らのヘルプは、あまたのトリッキーな場面での肝になってくれた。
これらのLTSカーネルには完全なメモリ保護を有効にするCONFIG_PAGE_TABLE_ISOLATIONビルドオプションがある。
この4.4と4.9の移植は4.14と4.15のメインラインバージョンとは大きく相違するので、異なるバグが存在する。現時点ではいくつかのVDSO問題解決に向けて作業中である。いくつかの特殊な仮想マシンのセットアップ時に奇妙なエラーが出ると報告されている。しかし、現時点ではこれらは少数派である。それで、カーネルをアップグレードすることをやめるべきではない。運用して不具合が出たなら、どうか安定版カーネルのメーリングリストに知らせてほしい。
もし4.4, 4.9 または 4.14以外のカーネルツリーに依存しており、ディストリビューションのサポートもない場合はご愁傷様である。 メルトダウンより、君のカーネルバージョンに現在含まれている他の何百もの既知の悪用やバグの方が深刻だ。メルトダウン以上に心配するべき事柄がある。まずシステムを最新にする必要があるだろう。
そして、サポート切れの危険なカーネルを運用するよう指示した人たちを怒鳴ってやれ。本当に無謀なことをしていると気づかせないと。
メルトダウン ARM64の場合
現在ARM64用のメルトダウンのパッチのセットはLinusのカーネルツリーにはマージされていない。数週のうちに4.16-rc1と4.15にマージするためステージングされ、準備中だ。これらのパッチはLinusからリリースされたカーネルではないため、自分は安定版カーネルリリースには移植できない。(なあ、理由があってこういうルールなんだ・・・)
正式にリリースされたカーネルへの修正はまだない。それでもし(アンドロイド等)ARM64のシステムに依存しているなら、現時点ではAndroid Common Kernelツリーの 3.18, 4.4, and 4.9のブランチにARM64用の修正がマージされているのでそれを見てくれ。
安定版とLTSリリースにいつ取り込まれるか現時点では不明だ。それでテストと上流カーネルに取り込まれたものをキャッチアップするために、ブランチに加えられた修正を継続的に確認することを強くお勧めする。
ARM64の4.4、4.9 LTSカーネルでは、必要な多数の前提条件パッチが必要であるため、修正パッチがマージされることはない。前提条件のパッチはすべて、アンドロイド共通カーネルの方ですでに長い間統合・テストされているので、現時点ではARMシステム用のLTSリリースではなく、それらのAndroidのカーネルブランチに依存した方がよいと思う。
もう一つ注釈、自分はLTSカーネルアップデートをブランチにマージするのはアップデートのリリース後1日程度で行っている。ARMシステムを最新かつ安全にするため、是非ともそれらのブランチをこまめに追いかけるべきだ。
スペクターは・・・
こいつは「面白いこと」になってきたぜ・・・
繰り返すが、ディストリビューション提供のカーネルで運用しているなら、複数のパッチがすでにマージ済みであるかもしれない。心配なら、アップデートして自分でテストすることを提案する。
今の状況では、このタイプの問題の修正は開発中カーネルのツリーにまだマージされていない。大量のパッチが異なるメーリングリスト上を漂っており、それぞれが問題解決を提案している。だが、それらは開発が頻繁に行われているため、いくつかのパッチシリーズはビルドに成功しなくなり、既知のツリーに適用もされない。互いに衝突してしまい、一般的に混乱している。
これはスペクター問題が一番最後にカーネル開発者たちに知らされたためである。我々はみなメルトダウン問題にかかりきりで、スペクター問題が何だったのかについて正確な情報を一切持っていなかった。また、(様々な場所で)紹介されていたパッチが公式に投稿されたものよりひどいものであることも知っていなかった。
そのようなわけで、問題を解決し上流カーネルにマージするまでには数週間はかかるだろう。問題の修正がカーネル全体にわたる複数のサブシステムに対して来ている。それらはやがて集められ、マージされ、カーネルの安定バージョンとしてリリースされるだろう。それで繰り返しになるが、ディストリビューションのカーネルリリースかLTS、安定カーネルバージョンを使用し続けるのが最善だ。
良いニュースではないが、でもこれが現実だ。慰めがあるとすれば、この問題に対してほかのどんなOSも完全な解決策を持っていないという事だ。コンピュータ業界全体は同じ船に今乗っていて、開発者たちが問題をできる限り早く修正するのを固唾を呑んで待っているんだ。
提案されている解決策はつまらないものではなく、いくつかはとても良いものだ。Paul TurnerによるRetpolineは、この問題を解決する助けとなるコンセプトで、まだ作成中だ。ハードウェアの実行前予測によって引き起こされる問題を解決する方法で、今後何年にもわたって研究される領域になるだろう。
その他のアーキテクチャ
現時点では、x86とarm64以外のパッチを自分は見ていない。他のプロセッサタイプのエンタープライズディストリビューションではパッチがあるという噂だが、希望的観測ではそれらは数週間で公にされ、上流カーネルにマージされるだろう。自分にはそれがいつになるかわからない。もし特定のアーキテクチャに依存しているなら、特定のマシンのメーリングリストに質問して率直な回答を得ることを提案する。
終わりに
もう一度言うが、カーネルをアップデートしよう。遅れずに、そして継続して行おう。これらの問題を修正するアップデートは長い期間を通じて継続的に行われる。また、これらの問題とは全く関係のないタイプのバグやセキュリティの問題の修正も安定版とLTSカーネルリリースを通して提供される。それで、カーネルをアップデートし続けるのはいつでも良いことだ。
今、過労・イライラ・不眠・怒りを抱えながら、カーネル開発者たちは自分たちに非がないこれらの問題を解決するために、出来る限りを尽くしている。彼らの置かれている状況をどうか考えてみてほしい。出来るだけ早く修正されたシステムを提供するという目標を達成するためにも、開発者はみんなの愛と、支援と、好みのドリンクの無料提供を必要としているし、そうしよう。
1/19 続報
前回、MeltdownとSpectre問題解決のパッチの最新状況について投稿した。そのことについて自分のもとに続々と問い合わせのEmailが来ている。
それらの問い合わせは以下2つに分類されるだろう。
- Spectre問題についてカーネルパッチの対応状況は?
- 自分のマシンには脆弱性があるか?
パッチの状況
いつものことだけど、スペクター問題解決のカーネルパッチの最新状況の技術的詳細はlwn.netがカバーしている。それでこの種の情報を見つけるためにlwn.netを読もう。
お気づきのようにlwn.netでは投稿されてから数週間以上、記事は有料会員限定だ。こういった情報には購読金を支払うべきだし、今すぐそうしよう。
自分のマシンには脆弱性があるか?
この質問に対しては、今や簡潔に答えられるようになった。自分でチェックできるようになったよ!
下記のコマンドをターミナルから実行するだけで自分のマシンの状況を判別出来る。
$ grep . /sys/devices/system/cpu/vulnerabilities/*
自分のラップトップでは現在こんな感じだ。
$ grep . /sys/devices/system/cpu/vulnerabilities/*
/sys/devices/system/cpu/vulnerabilities/meltdown:Mitigation: PTI
/sys/devices/system/cpu/vulnerabilities/spectre_v1:Vulnerable
/sys/devices/system/cpu/vulnerabilities/spectre_v2:Vulnerable: Minimal generic SM retpoline
説明すると、自分のカーネルでは
- Meltdown問題はPTI(ページ隔離)の実装によって問題が確実に緩和されている。
- Spectre-v1についてはまだ脆弱なままだ。
- Spectre-v2については解決に向けて鋭意作業中だが、まだ道半ばである(なぜなら自分はカーネルをRetpoline対応済みコンパイラでビルドしてないから)。
もし君のカーネルで上記システムファイルがないなら、それは明らかに問題だ。今すぐカーネルをアップデートするんだ!
いくつかの「エンタープライズ用」ディストリビューションには上記報告機能が移植されていないようだ。こういったカーネルが動いているなら、**ベンダーに今すぐバグとして報告しよう。**システムの状況を知る統一的な方法が是非とも必要だ。
注釈:現在、x86-64カーネルのみ上記ファイルは有効である。他のプロセッサタイプでは「問題なし」と表示されるだろう。でもご存知のように、Spectre問題についてはかなり古いプロセッサでなければそれはあり得ない。この情報から、カーネルが本当にアップデートされたのか重要な手がかりが得られる。他のプロセッサは、適切なレポートできるよう正しくカーネルフックが実装されるまで数カ月ほど待ってほしい。
そしてそう、これからSpectre-v1の問題の脆弱性を改善するため、自分のラップトップのCPU用に動作可能なマイクロコードのアップデートを探して、修正しなきゃなんない...
所感
- あなたとLinuxカーネル、今すぐアップデート(継続してアップデート)
- サポートが打ち切られたカーネルはメルトダウン以前の問題、論外
- ディストリビューションのカーネルが提供されているならそれを使用
- 自分でカーネルをビルドする場合は4.14、4.4、4.9を使用
- ビルド時CONFIG_PAGE_TABLE_ISOLATIONを有効に
- ARM64は当面公式には無いので、Androidのものを使用する
- Spectre問題に関しては公式では未着手の状況
- 対応が一番進んでいるとされる(発見者たるGoogleが直にコミットしている)Linuxでもこの状況
- その他OS、例えばBSDのMLで問題として挙がったのは年明けから
- FreeBSDのMLでは怨嗟の声が聞かれる
- 各OS開発陣のリソースは少なくとも数カ月この問題に奪われるだろう、、、つらい
- その他OS、例えばBSDのMLで問題として挙がったのは年明けから
- 開発者たちに愛と支援とドリンク(代)を!
(追記分)
-
lwnでは月7ドルで新着記事を読めるようになっている。
- しばらくすればアーカイブされ一般公開されるが、新着情報が必要な人はぜひ有料購読しよう。
- 当然ながら、GregなどLinux開発者に直接問い合わせるのはやめよう。
-
最新のカーネルではCPUの脆弱性対応状況をシステムファイルで照会出来るようになっている。
- 筆者の環境(4.13.0-26-generic #29~16.04.2-Ubuntu SMP)ではまだ有効ではなかった。
- メインストリームのカーネル(4.14系)ではなくディストリビューション提供のカーネルであり、おそらく作業中。
大手ディストリビューションであれば対応状況のページがあると思われるので、それを参照のこと。(例:Ubuntuの対応ページ)
-
Spectre問題を解決するには、Retpoline対応済みコンパイラでカーネルをビルドし直す必要があり、対象プロセッサも膨大なのでもうしばらくかかる。
脆弱性のチェック
1/19 補足:Linuxカーネルの方で公式に脆弱性対策状況をレポートする機能が加えられた。それで、利用可能ならそれを見るのが一番確実である。
1. CONFIG_PAGE_TABLE_ISOLATION有効の確認
アップデートされたカーネルにMeltdown対策がされているかどうかは、configファイルで調べれば良い。例えば、Ubuntu系では/boot以下にconfig-(バージョン名)の様式でビルドオプションが記述されているので、以下のように確かめられる。
cat /boot/config-4.13.0-26-generic | grep CONFIG_PAGE_TABLE_ISOLATION
2. 脆弱性チェックツール
脆弱性チェックツール。makeして実行するだけでチェックできる。
実行は自己責任で。また、結果の妥当性については保証できない。
Spectre-Attack 実行結果
脆弱性を利用して「The Magic Words are Squeamish Ossifrage.」という文字列を読めるかというもの。Spectre Attackツールを筆者の環境(FreeBSD11.1 RELEASE-p4@i5-3230M)上で実行し、以下のようになった。見事に読めてしまっている。
Reading at malicious_x = 0xffffffffffdffc26... Success: 0x54='T' score=2
Reading at malicious_x = 0xffffffffffdffc27... Success: 0x68='h' score=2
Reading at malicious_x = 0xffffffffffdffc28... Success: 0x65='e' score=2
Reading at malicious_x = 0xffffffffffdffc29... Success: 0x20=' ' score=2
Reading at malicious_x = 0xffffffffffdffc2a... Success: 0x4D='M' score=2
Reading at malicious_x = 0xffffffffffdffc2b... Success: 0x61='a' score=2
Reading at malicious_x = 0xffffffffffdffc2c... Success: 0x67='g' score=2
Reading at malicious_x = 0xffffffffffdffc2d... Success: 0x69='i' score=2
Reading at malicious_x = 0xffffffffffdffc2e... Success: 0x63='c' score=2
Reading at malicious_x = 0xffffffffffdffc2f... Success: 0x20=' ' score=2
Reading at malicious_x = 0xffffffffffdffc30... Success: 0x57='W' score=2
Reading at malicious_x = 0xffffffffffdffc31... Success: 0x6F='o' score=2
Reading at malicious_x = 0xffffffffffdffc32... Success: 0x72='r' score=2
Reading at malicious_x = 0xffffffffffdffc33... Success: 0x64='d' score=2
Reading at malicious_x = 0xffffffffffdffc34... Success: 0x73='s' score=2
Reading at malicious_x = 0xffffffffffdffc35... Success: 0x20=' ' score=2
Reading at malicious_x = 0xffffffffffdffc36... Success: 0x61='a' score=2
Reading at malicious_x = 0xffffffffffdffc37... Success: 0x72='r' score=2
Reading at malicious_x = 0xffffffffffdffc38... Success: 0x65='e' score=2
Reading at malicious_x = 0xffffffffffdffc39... Success: 0x20=' ' score=2
Reading at malicious_x = 0xffffffffffdffc3a... Success: 0x53='S' score=2
Reading at malicious_x = 0xffffffffffdffc3b... Success: 0x71='q' score=2
Reading at malicious_x = 0xffffffffffdffc3c... Success: 0x75='u' score=2
Reading at malicious_x = 0xffffffffffdffc3d... Success: 0x65='e' score=2
Reading at malicious_x = 0xffffffffffdffc3e... Success: 0x61='a' score=2
Reading at malicious_x = 0xffffffffffdffc3f... Success: 0x6D='m' score=2
Reading at malicious_x = 0xffffffffffdffc40... Success: 0x69='i' score=2
Reading at malicious_x = 0xffffffffffdffc41... Success: 0x73='s' score=2
Reading at malicious_x = 0xffffffffffdffc42... Success: 0x68='h' score=2
Reading at malicious_x = 0xffffffffffdffc43... Success: 0x20=' ' score=2
Reading at malicious_x = 0xffffffffffdffc44... Success: 0x4F='O' score=2
Reading at malicious_x = 0xffffffffffdffc45... Success: 0x73='s' score=2
Reading at malicious_x = 0xffffffffffdffc46... Success: 0x73='s' score=2
Reading at malicious_x = 0xffffffffffdffc47... Success: 0x69='i' score=2
Reading at malicious_x = 0xffffffffffdffc48... Success: 0x66='f' score=2
Reading at malicious_x = 0xffffffffffdffc49... Success: 0x72='r' score=2
Reading at malicious_x = 0xffffffffffdffc4a... Success: 0x61='a' score=2
Reading at malicious_x = 0xffffffffffdffc4b... Success: 0x67='g' score=2
Reading at malicious_x = 0xffffffffffdffc4c... Success: 0x65='e' score=2
Reading at malicious_x = 0xffffffffffdffc4d... Success: 0x2E='.' score=2