)は、もう10年も前ですので、その世界では特に新しい話題というわけではないようですが、私が知ったのは今年のはじめのことでしたので*1、この機会に紹介する文章を書いてみたいと思います。)は、その暴露的な部分(UNIXのloginコマンドにバックドアがあった、とする)の真偽はさておき、もしコンパイラのバイナリが「信用できない」ものだったら、という場合における、潜在的な脅威の可能性を否定することの難しさの指摘でした。*2以下で述べる話題は、直接的な「コンパイラのバイナリを精読する」といった手段と比べると、大幅に省力的で、また、そのような可能性に対してある種の「相対的」安全性という考え方を示すものにもなっています。)となっていて、だいぶ大部ですが(私も全部は追いきれていません)、基本的なアイディアのスケッチは、けっこう以前からUSENETで議論されていたという程度には、簡単なものです。基本的な問題について確認トンプソンさんの講演の詳細を知っている方は、この節は飛ばして問題ありません。オープンソースのプロダクトは、たくさんの目でソースコードがチェックされているのだから安心だ、と主張されます。その当否はともかくとして、その大前提に、コンパイラは絶対に信用できるものだ、という仮定があります。噂では、性能比較に使われるベンチマークプログラムはその目的上、共通のものが広く公開されているので、そのパターンを検出して特別な最適化を掛ける、というチートが仕込まれていたコンパイラがあった、といいます。理屈では、一種の自己再生プログラム(いわゆるクワイン)のテクニックを利用して、ソースコードには何の痕跡も残さずに、コンパイラのバイナリから、それによってコンパイルされた、次の世代のコンパイラのバイナリへ、と、悪意を持ったコード片を「感染」させ続けることが可能です(プログラムのテクニック自体としては、一種のパズルのようなものとして知られていたものではあるものの、そのようにセキュリティに対する深刻な脅威として、可能性があると(広く注目されるような場で)示したのが、トンプソンさんのチューリング賞講演でした)*4*5。思いつく対抗法コンパイラのバイナリを精読してチェックする(ブラックボックスチェック)、あるいはソースコードとの対応が取れているかチェックする(ホワイトボックスチェック)というあたりが、まず思い浮かぶでしょう。それができればそれに越したことはありませんが、たとえばGCCなど、実際に使われているコンパイラはそれなりに大きく、大変な作業です。プログラムでできないか、と考えるかもしれません。いい着目点ではありますが、やはりそのプログラムは信頼できるのか、ということになります。コンパイラではなくインタプリタを使おう、と思うかもしれません。そのインタプリタをコンパイルするコンパイラが、ということになります。問題の場所は移動しますが、必要な作業はそんなに変わらない、ということになります。ここで、GCCの昔話を今では多くのUnixライク環境で、バイナリパッケージによるインストールは当たり前のものとなりました。何らかのプログラミング言語の処理系を「野良ビルド」するにあたり、いわゆるセルフホスティングであったり、そうでなくても自分自身のビルドに自分自身が必要であっても、まずバイナリパッケージを使って簡単に必要な環境を作ることができます。昔は、なんでも野良ビルドが当然であり、わざわざ「野良」などと付けるようになったのもある時代以降ではなかったか、というような記憶があります。難しさの点で大物*6のひとつが「プロプライエタリなUNIX環境へのGCCの導入」でした。普通のやりかたとしては、GCCのバイナリを、同じ環境を使っている他のユーザからGNUの助け合いの精神にもとづきコピーしてもらってくれば良いわけですが、全く同じ環境というのもなかなか無かったりするわけで、いわゆる「言語処理系のブートストラップ」の一種のような作業で「最初のGCCのバイナリ」を得ることになります。今でもGCCのビルドの説明には、ステージという表現が使われていますが、この時代には次のような意味がありました。stage3stage1で得られるのはGCCによるコンパイル結果ではありませんから、バイナリ的にも違ったものなはずです(一種のキメラ的存在と言えるかもしれない)。stage2とstage3は、どちらもGCCによるコンパイル結果ですから、結果は一致するはずです(理論的には一種の「不動点」)。結果が一致しても、必ずしも問題が無いとは言い切れませんが、結果が一致しなければ高い確率で問題が存在するはずです。ここで注目すべきなのは、このプロセスは「何らかの既存のGCCバイナリ」に依存していない、という点です。攻撃への対抗だ、ということになります。中央の四角がコンパイルプロセスを表現していて、上からの矢印がそのコンパイルに使用するコンパイラのバイナリ、左からの矢印がコンパイル対象のソースコード、右からの矢印がコンパイルオプションなどの「ソースコード以外」のコンパイル結果に影響を与える要素(以下では省略します)、下に出ている矢印がコンパイル結果であるバイナリ生成物、という感じになります。この図法で、前節で話題にした、プロプラUNIX環境へのGCCの導入をあらわすと、次のようになります。Double-Compiling提案手法では、次の図のような手続きで、調査対象のコンパイラの2種類のバイナリを作ります。右側は、自分自身をコンパイルできる(セルフホスティングな)コンパイラの、通常のコンパイル手続きです。対称性のために2回コンパイルしていますが、原理を示す上では1回でかまいません(2回とも、同じ結果が得られているはずです。説明のため、ここではGCCとします)。左側は、GCCの導入において「プロプライエタリUNIX付属のcc」であった部分を「何らかの信頼できるコンパイラ」に変えたもの、という感じになります。最初のコンパイラが信頼できるコンパイラですから、stage1のコンパイラはソースコードときちんと対応しているはずです。stage2のコンパイラは、(ソースコードがGCCだとすれば)最初の「信頼できるコンパイラ」と「GCCのソースコード」を信じられる限りにおいて、信じられるはず、ということになります。この信じられるコンパイラは、右のほうのプロセスで作られたコンパイラと、バイナリ的に一致するはずです。一致しなければ、何らかのおかしな仕掛けが仕込まれている可能性がある、ということになります(もちろん、これまで触れてきませんでしたが、コンパイルされた時刻を埋め込む、などといった特異な要因が無ければ*7*8)。ここで大事なことは、GCCのような大きなCコンパイラのバイナリコードをチェックする、というような大変な仕事ではなく、「信頼できて、GCCをとにかくコンパイルできれば良い(コンパイルが遅くても、最適化が全く無くても)コンパイラを用意すること」と「2つのファイルの単なるバイナリ比較」という、(比較すればそれなりに)単純な仕事で、問題点の検出が可能になった、ということです。clangをビルドする、といったようなプロセスで、「絶対に信頼できるCコンパイラ」が無くても、ある程度相対的には信頼できると確認できる、ということも示しています。Trust」攻撃に対して、(世界的なセキュリティ界隈では以前から知られていたもののようですが)有効な対抗手段があることを紹介しました。世界にコンパイラの実装が1種類ではまずく、少なくとも2つ以上、できればもっと多数あるべき、という「多様性の善」を示すものにもなっているように思います。セルフホスティングができると、自分の非標準なオレオレ拡張を、自分自身の実装に使いたくなるんじゃないか、という気がしますが、それをやってしまうとこのような検証ができなくなる、ということもわかります*9。最後の段落で、話題自体は読んでいたようです。*2:(2018年8月追記)また、講演録を読むと最後のほうで、クラッカー(特に、今で言ういわゆる「スクリプトキディ」)について、きつい語が並んでいますが、それも背景の説明が必要なようです。受賞は1983年で、その当時は、本格的なパーソナルコンピュータが広まる前である一方、映画『ウォー・ゲーム』が公開された年でもあり、フィクションとないまぜの「コンピュータを操る少年」像がしばしば「神童」的に扱われ、マスコミを賑わしていた、というような背景があります。いわゆる「ハッカーはクラッカーじゃない」問題の源流の一つでもあり、講演後に(以下出典未確認)CACM誌でRMSと論争になった、という話もあります。*3:BW変換のWであるデイヴィッド・ホイーラーさんとは特に無関係のようです。いう文献だとネットの情報にはあります。*5:余談ですが、Multicsは高水準言語をOSの記述に使おうとしたという点でも先進的でした(言語はPL/I)。TSSも、PL/IWというPL/IのサブセットをPL/IWで書いて、人力コンパイルでブートストラップしたと伝えられていますから、この記事とも少々関係があります。*6:現代と違って、昔はC言語処理系の標準準拠もいろいろ怪しかったりすると、けっこう一筋縄ではなかったりした。*7:あるいは、近年のセキュリティ技術という観点からは、アドレスを決め打ちするような攻撃に対抗するべくランダム化を掛ける手法がありますが、そういうのとも相性が悪いでしょう。Debianプロジェクトなどによる、ReproducibleBuilds(日本語解説)として、バイナリ再現性の重視について推進するプロジェクトがあります。指摘されているのを、どこかで覚えていたようです。月別アーカイブMathJax読み込みはてなブログをはじめよう!metanestさんは、はてなブログを使っています。ブログを報告するスターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。