Cコンパイラをゼロからコンパイルし、Unix / Linuxをゼロからコンパイルする方法


64

アメリカ/イギリス以外の大規模なサービス組織で働いているとしましょう。UNIXサーバーとLinuxサーバーを幅広く使用しています。

この記事を読むと、Cコンパイラにバックドアを簡単に挿入でき、そのコンパイラでコンパイルされたコードにもバックドアが含まれることに言及しています。すべての暗号化方法、ハードウェア、およびソフトウェアにバックドア/弱点を置くというNSA / GCHQの命令に関する最近のリークを考えると、コンパイラは障害の重大なポイントになりました。すべての標準UNIX / Linixディストリビューションが危険にさらされる可能性があります。システム、データ、および顧客データを不正な政府によって侵害することはできません。

この情報を基に、信頼できるコンパイラをゼロから構築したいと考えています。その後、そのコンパイラを使用してソースコードからオペレーティングシステムとアプリケーションを構築できるように、安全な基盤を構築します。

質問

ソースコードからコンパイラをコンパイルし(一見鶏卵のシナリオ)、信頼できるUnix / Linuxディストリビューションをゼロからコンパイルするための正しい(そして安全な方法)は何ですか?

私や他の人がセキュリティ欠陥のソースコードを読んで理解する能力を持っていると仮定できるので、ソースコードはコンパイルする前に最初に吟味されます。私が本当に望んでいるのは、このコンパイラをゼロから安全に作成し、カーネル、OSのその他の部分、およびアプリケーションをコンパイルするために使用できる作業ガイドです。

セキュリティスタックは、そのスタックで実行されているオペレーティングシステムまたはアプリケーションに自信がある場合、ベースレベルで開始する必要があります。はい、ハードウェアのバックドアがあり、ビルド中にコンパイラにマイクロコードを挿入する可能性があることを理解しています。現時点では、米国で設計されていないチップを使用することを除いて、私たちができることはあまりありません。このレイヤーを最初にソートして、バックドアが挿入される前に古いコンピューターで構築できると仮定します。

ブルース・シュナイアーが言うように:「エンジニアに対して、私はこう言います。私たちはインターネットを構築し、私たちの何人かはそれを破壊するのを助けました。今、自由を愛する私たちはそれを直さなければなりません。」

追加リンク:


7
くそー、これは非常に興味深い質問であり、私はそれを移行したくありませんが、私はそれがここで話題になっているとは本当に思いません。あなたの基本的な質問は、ほとんどOSに依存せず、プログラミングの質問であるコンパイラをゼロからコンパイルする方法に関するものなので、stackoverflow.comに適しています。しばらくしてここで回答が得られない場合は、質問のタグの下にある「フラグ」リンクを使用し、これをSOに移動するようモデレーターに依頼することを検討してください。
テルドン

2
@terdon特定の開発問題よりも一般的なプログラミングの問題に関するものであるため、実際にはProgrammers.SEに適している場合があります。実際、それはそこで重複している可能性があります。
CVn

2
GCCはオープンソースですが、バックドアはどのように挿入されますか?
マイケルパンコフ

2
Thompsonの安定した悪用には、ログインプログラムまたはコンパイラーがコンパイルされていることを認識できるコードが必要であることに注意してください。これらのプログラムの1つとしてコンパイラーが認識できない形式にソースを手動で変換できる場合、バックドアは伝達されません。
ラッセルボロゴーブ

2
@Constantius-最初の行にリンクされているThompsonの記事を読んでください。誰がコンパイラをコンパイルしますか?
ラッセルボロゴーブ

回答:


30

知る限り、セキュリティを完全に保証する唯一の方法は、アセンブリ言語でコンパイラを記述することです(または、ディスクを直接自分で変更すること)。その場合にのみ、コンパイラがバックドアを挿入していないことを確認できます。これは、実際にコンパイラを完全に削除しているため機能します。

そこから、スクラッチコンパイラを使用して、GNUツールチェーンなどのブートストラップを実行できます。その後、カスタムツールチェーンを使用してLinux From Scratchシステムをコンパイルできます。

自分で物事を簡単にするために、C(または他の言語)で記述された2番目の中間コンパイラを使用できることに注意してください。したがって、コンパイラAをアセンブリで記述し、そのコンパイラをC / C ++ / Python / Brainfuck / whateverで書き換えてコンパイラBを取得し、コンパイラAを使用してコンパイルします。次に、コンパイラBを使用してgccおよびフレンドをコンパイルします。


13
それでも、これは悪意のあるコンパイラからのみ保護します。コンパイラが実行されるシステムを信頼する必要があります。分離されたソフトウェアは存在しません
CVn

3
自律的なものはすべて本質的に危険です。あなたは効果的にツールチェーンコンパイラを提案しています(奇妙なものではありますが)。つまり、回避しようとしている方法で正確に変更できる可能性があります。さらに良いことに、MitMを介して転送中に変更できます。
strugee

1
皆さんは、この答えが15歳からのものであることを理解する必要があります。頑張ってください!
mtahmed

3
プリコンパイルされた<code> vim </ code>または<code> vim </ code>が感染した場合にのみ監査したソースから適切なコンパイラでコンパイルしたかどうかを知っている人は、コードエディタをゼロから作成することも忘れないでください<code> vim </ code>は信頼できますか?
ハーゲンフォンアイゼン14

1
最初のマシンコード(アセンブリではなく実際のマシンコード)を個人的に作成し、手に負えないセキュリティホールを認識し、コンパイルしているコードのすべての行を読んでチェックするか、少なくとも知っている場合を除き、決して忘れないでください。個人的それをした人、そして彼がこれをすること信頼する…。これはまったく役に立ちません。だからこそ、これをキックスターターにしようとすると、全体のポイントが台無しになってしまいます。高い信頼性。
Evi1M4chine

22

1つの可能な方法は、実際には非常に長い時間がかかりますが、根本に戻ることです。GNUの開発は1984年に始まり、Minixのオリジナルバージョン(初期のLinux開発中にブートストラップ目的で使用されていた)が1987年にリリースされました。

この答え全体は、「[あなた]または他の人がセキュリティ上の欠陥のソースコードを読んで理解する能力があるため、コンパイルする前にソースコードを最初に吟味する」という前提に基づいており、そのような分析の結果を信頼できる。それなしでは、この答えは価値のないものよりも恐らく悪いでしょう。何の利益もまったく得られないために膨大な時間を費やしているからです。

ソースコード付きの元のMinixブックのコピーを見つけることができる場合は、ブックから入力できます。コンパイルしてから、別のシステムで別のデコンパイラを使用して、コンパイラが予想されるマシン言語のバイナリ出力を生成することを確認します。(コードはたった12,000行で、おそらくCなので、そうするのは時間がかかりますが、そのようなプロジェクトに真剣に取り組んでいるなら、それでも理にかなっています。)独自の逆アセンブラーを書くことさえできます。それはそれほど難しくないはずです。

おそらく手に入れることができるGNUユーティリティの最も古いバージョンを入手し(おそらくそれらはコードが少なく、外部ライブラリへの依存性が少ないので)、コードを調べてMinix用にビルドします(ただし、これには多少の作業が必要です;絶対に避けたいのは、ソースコードを調整することです。これにより、後でパッチを追加するとエラーが発生しやすくなります。その時点でOSとツールチェーンを信頼しているので、パッチセットのソースコードを通過するだけで済みます(パッチセットに含まれていないものはすべて既に信頼されています)が、ツールは使用しているものに比べて非常に原始的で粗雑です今日まで。たとえば、システムツールの最も基本的な機能が動作すること以外は期待しないでください。たくさんのXKCDを読んでください。

ある時点で、Linuxカーネルの初期バージョンをコンパイルしてブートストラップできるシステムができます。これは、Linuxがハッカーの間で勢いをつけ始めた1990年代初期に行われたのと同じです。その時点でLinuxに移行することをお勧めします(Linuxに対してシステムライブラリとツールチェーンを再構築し、Linuxカーネルを構築し、Linuxを起動し、Linux内でLinuxカーネルとGNUツールチェーンを再構築することができます。最後に、システムが自己ホスティング)が、それは主にあなた次第です。最新バージョンに到達するまで、パッチの検証、カーネル、ライブラリ、基本的なGNUツールへのパッチ適用、再構築を続けます。

それは、最新のソフトウェアを構築するために使用できる信頼できる基本的なOSとコンパイラを持っているときです。それまでに、たとえばLinux From Scratchガイドに従って、有用なタスクを実行できるシステムを構築できます。

「コンパイラ」システムをネットワークに接続することは決してできません(ネットワーク化されたホスト上のVMを含む)。カーネルを含むネットワーク対応コンポーネントに侵入する危険があります。Thompsonコンパイラの攻撃を心配している場合は、VMホストも侵害される可能性があることを予想する必要があります。sneakernetを使用して、物事をコンパイルしている物理ホストにソースコードとバイナリを取得します。USB大容量記憶装置のサポートが実装された時点に到達する前に、少なくともファイルをシステムに出し入れするのに問題があることを期待してください。本当に妄想している場合は、ソースコードのリストを印刷して、手で入力します(プリンタードライバーとプリンターに同様のコードが含まれいないことを期待します)、または1台のコンピューターモニターでコードを読み取り、物理的に隣にあるが接続されていない別のコンピューターに入力する。

はい、これには多くの時間がかかります。しかし、このアプローチの利点は、各ステップが増分であるということです。つまり、多くのバージョンの期間にわたって非常に徐々に導入されない限り、悪意のあるものがすり抜けるのははるかに困難です。これは、各ステップでの一連の変更が比較的小さいため、見やすくなっているためです。パッチセットを変更ログと比較し、どの変更ログエントリがソースコードのすべての変更に対応するかを正確に判断できることを確認します。繰り返しますが、これはあなたがそのような変更は、コードベースに潜入されていないことを確認するために、(おそらくあなたが信頼できる人を介して)能力を持っていることを前提としない、しかしそれは、専用のソフトウェアexcept-などの信頼できるシステムに近いについてあなたを取得する必要がありますファームウェアのアプローチができます。


dissassemble-verifyメソッドには、検証マシンが完全に信頼できるという大きな仮定がまだあるため、非常に欠陥があります。そのマシンとそのソフトウェアをゼロから構築した場合、または個人的に信頼して彼女を信頼した人を知っている場合を除き、これは起こりません。したがって、これはまだ安全ではありません。ごめんなさい。……また、これらの問題では、「…に近い」とは、ポイント全体を台無しにするのに信頼できない1つの場所しか必要としないため、依然として「安全でない」ことを意味します。
Evi1M4chine

9

信頼できるコンパイラーが必要な場合は、compcertプロジェクトなどの学術研究をご覧ください。これは、INRIA(フランスのIT公的研究所)が「認定」するように設計されたコンパイラです。つまり、コードと意味的に完全に同等の実行可能ファイルを生成します(そしてもちろん、数学的に証明されています)。


1
誰もが信頼できるコンパイラを必要としています。「信頼できる」コンパイラを作成できる数学はどのように機能しますか?
デビッドJ

@DavidJブートストラップ、ほとんどの場合。完全に検証して正しいことを証明できる小さなピースを作成し、それを基礎として使用して、より複雑なコンパイラを作成します。
CVn

1
"" "CompCert Cを他のプロダクションコンパイラと一線を画すのは、マシン支援の数学的な証明を使用して、コンパイルの問題を免除するために正式に検証されていることです。" " compcert.inria.fr/compcert-C.html コンパイルかつてほど経験的ではありません。
lgeorget

1
@MichaelKjörlingはおそらく、コンパイラによって読み取られたときにコンパイラソースにバックドアを含めるためにカーネルが危険にさらされる可能性があることを考慮していない
ラチェットフリーク

1
私もこのリンクを見つけました。
デビッドJ

2

開始点として独自のコンパイラを手動で作成するのが最も安全ですが、別のオプションは、これらのエクスプロイトが存在する前に作成された信頼できる5(または10)歳のインストールCDからシステムをインストールすることです。次に、それを基盤として使用して、新しい監査ソースをコンパイルします。


5
攻撃は1984年以来公に知られています。おそらく、トンプソンがその可能性について最初に考えたのではないでしょう。ここまで戻ると、今日私たちが当たり前のことと考えているもののほとんどは、周辺にはなかったことを意味します。20年前にコンピューターで実行できたことを検討し、現在の状態と比較します。オリジナルのLinuxブートストラップシステムMinixでさえ、87年までリリースされず、GNUの開発は84年に始まりました。したがって、理論的にはこれが質問に答える可能性がありますが、実際には答えとしてはほとんど役に立ちません。
CVn

2
潜在的に手に入れることができる最初のコンピューターは286です。祖父母がまだ持っているかどうかを確認する必要があります。
デビッドJ

1
実際にそれを考慮した場合のボーナスポイント:-)。@DavidJ
11684

@MichaelKjörling:そうでもない。ブートストラップのチェーンが長くなるだけだからです。しかし、機械語でゼロから独自のコンパイラを書くほど長くないかもしれません。
Evi1M4chine
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.