web-dev-qa-db-ja.com

Cコンパイラを最初からコンパイルし、次にUnix / Linuxを最初からコンパイルする方法

私が米国/英国以外の大規模なサービス組織で働いているとしましょう。 UNIXサーバーとLinuxサーバーを幅広く使用しています。

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

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

質問

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

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

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

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

追加リンク:

64
David J

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

そこから、from-scratchコンパイラーを使用してbootstrap例GNUツールチェーン。次にカスタムツールチェーンを使用して Linux From Scratch システム。

自分で物事を簡単にするために、C(またはその他の言語)で記述された2つ目の中間コンパイラーを用意することもできます。したがって、アセンブリでコンパイラAを記述し、C/C++/Python/Brainfuck /何でもコンパイラを書き直して、コンパイラBを取得します。コンパイラBは、コンパイラAを使用してコンパイルします。次に、コンパイラBを使用して、gccとその仲間をコンパイルします。

30
strugee

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

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

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

GNUユーティリティの最も古いバージョンを入手してください(おそらく、これらのコードは少なく、外部ライブラリへの依存性が少ないため)。コードを調べ、Minix用にビルドします(これはただし、多少の作業が必要になる可能性があります。絶対に避けたいのは、ソースコードを調整することです。これにより、後でパッチを追加するとエラーが発生しやすくなります。)GNUツール。その時点でOSとツールチェーンを信頼しているので、パッチセットのソースコードを確認するだけで済みます(パッチセットにないものはすでに信頼されています)が、ツールは依然として非常に原始的であり、現在使用しているものと比較して粗雑です。たとえば、システムツールの最も基本的な機能以外は機能しないと期待してください。次に、すべてをMinixに転送して移行し、パッチの適用を1バージョンずつ開始します。時間、各バージョン間で影響を受けるすべてを再構築し、新しい次回バージョン。 XKCDをたくさん読んでください。

ある時点で、Linuxカーネルの初期バージョンをコンパイルしてbootstrapとすることができます。Linuxがハッカーの間で牽引され始めた1990年代初頭に行われたように。その時点でLinuxに移行することをお勧めします(Linuxに対してシステムライブラリとツールチェーンを再構築し、Linuxカーネルを構築し、Linuxを起動し、Linuxカーネルを再構築して、GNU Linux内でツールチェーンを再構築します。最後のシステムが現在セルフホスティングであることを証明しますが、それは主にあなた次第です。最新バージョンに到達するまで、パッチの検証、カーネル、ライブラリへのパッチ適用、および基本的なGNUツール、そして再構築を続けます。

それは、最新のソフトウェアを構築するために使用できる、信頼できる基本的なOSとコンパイラがある場合です。それまでに、あなたはフォローすることができます。 Linux From Scratch は、便利なタスクを実行できるシステムを構築するためのガイドです。

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

はい、これにはたくさんの時間がかかります。しかし、このアプローチの利点は、各ステップが段階的に行われることです。つまり、多くのバージョンの期間にわたって非常に徐々に導入されない限り、悪意のあるものをすり抜けることははるかに困難です。これは、各ステップでの一連の変更が比較的小さく、見やすくなっているためです。パッチセットと変更ログを比較し、ソースコードのすべての変更に対応する変更ログエントリを正確に特定できることを確認してください。繰り返しますが、これは、そのような変更がコードベースに忍び込まれていないことを確認する能力(おそらく信頼できる誰かを介して)を持っていることを前提としていますが、ファームウェア以外のソフトウェアのみのアプローチとして信頼できるシステム

23
a CVn

信頼できるコンパイラが必要な場合は、 compcert プロジェクトのような学術研究を見ることができます。これは、INRIA(フランスのIT公的研究所)によって構築されたコンパイラーであり、「認定」されるように設計されています。

9
lgeorget

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

2
sambler