学位論文要旨



No 120519
著者(漢字) 大岩,寛
著者(英字)
著者(カナ) オオイワ,ユタカ
標題(和) 安全なANSI C コンパイラの実装手法
標題(洋) Implementation of a Fail-Safe ANSI C Compiler
報告番号 120519
報告番号 甲20519
学位授与日 2005.03.24
学位種別 課程博士
学位種類 博士(情報理工学)
学位記番号 博情第32号
研究科 情報理工学系研究科
専攻 コンピュータ科学専攻
論文審査委員 主査: 東京大学 教授 萩谷,昌己
 東京大学 助教授 石川,裕
 東京大学 講師 細谷,晴夫
 情報学研究所 教授 高野,明彦
 東京大学 助教授 佐藤,周行
内容要旨 要旨を表示する

C言語で書かれたプログラムは、迷子ポインタやバッファ溢れなどによる厄介なバグの影響を受けがちであることはよく知られている。とりわけ、インターネット上のサーバプログラムにおけるそのようなバグは、悪意の攻撃者によってシステム全体を乗っ取るための攻撃の対象となりがちで、最近では社会的な問題にすらなっている。このような厄介なバグは元をたどれば、メモリ上の配列の境界を越えたアクセスにより、データ構造が破壊されることである。最近の言語、例えば Java、C#、Lisp、ML などの言語はこのような境界を越えたアクセスに対して保護機構を用意しているが、C言語にはそのような機構はない。しかし、これはC言語のデザイン上の欠陥とは言えない。なぜなら、C言語は元々アセンブラ言語の置き換えとして、つまりは柔軟で直接的なメモリ操作を高級言語で記述するためにデザインされたものだからである。言い替えれば、このような保護機構の欠如は「わざと」導入されたものである。また、C言語がデザインされた30年前には、当時の計算機能力に対して、このような保護機構を導入するのが現実的でなかったという点もある。過ちとされるべきはむしろ、そのようなC言語を現代の日常のプログラミング言語として、実際には直接的なメモリアクセスが必要とされない場合にも用いていることにある。けれども今日において、C言語を直ちに放棄してしまうことは現実的ではない。C言語で書かれた既存のプログラムは多く存在し、またC言語やそのプログラミングスタイルに慣れ親しんだ「既存のプログラマ」も数多いからである。

このようなジレンマを解決するために、C言語を安全に実装する多くの試みが提案され実際に実装されてきた。しかし、我々の知る限りそれらのすべては、危険な操作の全てを拒否し、同時に全ての ANSI C のプログラムを処理できるという目標を達成していない。C. Cowan による StackGuard に代表される実装のグループは、場当たり的な検査手法でプログラムに出現する特定の形の誤りを検出するだけのものであるし、他方 SafeC に代表されるグループは、C言語の仕様の一部分のみを入力として受け付けるものである。G. Necula によって提案されている CCured が、我々の知る限りでは現時点でもっとも目標に近いものであるが、これも完璧であるとはいえない。

本論文は、この問題に対するもっとも強力な解を提案する。本論文で提案する Fail-Safe C は、メモリ安全な ANSI C の完全な実装である。この実装は、全ての危険な操作を禁止しつつ、キャストや共用体を含む全てのANSI C 標準に準拠し、かつ ANSI C の範囲を越えたプログラムに頻出するいわゆる「汚いトリック」の多くをも許容する。同時に、本実装は、コンパイル時と実行時双方で行なわれるさまざまな最適化によって、実行時検査の負荷の削減をはかっている。Fail-Safe C コンパイラを用いることで、プログラマは簡単に、自らの書いたプログラムに変更を加えることなしに、また移植作業をすることなしに、安全に実行することが可能となる。論文中では、実在する有名なプログラムに存在するセキュリティー上の脆弱性を用いて、実際に Fail-Safe C を適用して安全性を保証する実験を例示している。

この論文で述べられているいくつかの重要なアイディアは以下の通りである。

・ メモリブロックの特殊な表現により、動的な境界検査と型検査を実現すること、

・ オブジェクト指向の概念を用いてメモリブロックを表現し、全てのメモリブロックにアクセスメソッドを付加することにより、ポインタのキャストなどの静的型によらないアクセスの安全な実行をサポートすること、

・ 「virtual offset」と名付けたメモリのアドレスづけの特殊な方法により、既存のプログラムの互換性の向上とキャスト操作の安全性を同時に実現していること、

・ そして、ポインタがキャストされているかどうかを自らに記録するような、ポインタ (と整数) の賢い表現により、安全にキャストを実装すると同時に通常のポインタの高速な使用を実現したこと。

Fail-Safe C の環境下では、プログラム中の値がポインタとして参照に用いられるたびに、参照先ブロックのサイズと型との整合性を検査される (コンパイラが検査を省いても安全であることを確実に判定できた場合を除く)。ポインタが参照先ブロックのサイズを超過したメモリを参照している場合、実行時エラーが報告されプログラムは直ちに停止される。ポインタの型と参照先ブロックの型が整合しない場合は、アクセスハンドラメソッドが参照に用いられ、プログラムの実行の安全性を保証する。どちらでもない場合は、プログラムが直接メモリを参照することで、高速な実行を実現する。ポインタがキャストされたか否かの情報は、コンパイラによって正確に維持され、ポインタの型整合の判定を高速に行なえるようにしている。また、virtual offset の概念は、先に述べた一連の動作をプログラムから隠し、「舞台裏でこっそり行なわれるもの」にする。つまり、実行中のプログラムは、Fail-Safe C の監視下で実行されているということを認知することは、安全でないプログラムが突然終了させられることを除いてはできない。このことは、さまざまな「汚いトリック」を用いたプログラムがそのままプログラムを変更せずに動くことを可能にし、また同時にそのようなプログラムが安全に動作することを示唆している。

審査要旨 要旨を表示する

 C言語においては、柔軟なポインタ操作が可能であるため、プログラムに対して意図しない入力を与えることにより、メモリ上の配列の境界を越えたアクセスを行わせ、その上のデータ構造を破壊することが可能である。このような欠点により、C言語で書かれた各種のプログラムは常にネットワークからの攻撃に晒されている。本論文は、メモリへの意図しないアクセスを許さないC言語の実装手法を提案し、実際に実装した処理系の効率に関する評価を行っている。

 第1章では、本論文の背景と目的について詳述してある。Java、C#、Lisp、ML等の現代的な言語においては、メモリへのアクセスに対して保護機構が用意されているが、C言語にはそのような機構はない。これは、C言語がアセンブラ言語を代替する高級言語として柔軟で直接的なメモリ操作を特徴としていたことと、C言語が設計された30年前にはこのような保護機構を導入することが現実的でなかったためである。その後、計算機環境は激変したが、C言語で書かれた既存のプログラムは多く存在し、C言語やそのプログラミングスタイルに慣れ親しんだプログラマも数多い。本論文では、メモリに対する全ての危険な操作を禁止しつつ、キャストや共用体を含む全ての ANSI C 標準に準拠し、しかも実行効率の十分高いC言語の処理系 Fail-Safe C を実装することを目標としている。

 第2章においては、Fail-Safe C の基本的な概念について解説してある。すなわち、ポインタの表現方法(fat pointer)、型の情報を含むメモリブロック、メモリ管理、構造体と共用体の実現方法、関数の表現方法について解説し、Fail-Safe C の設計に関する基本的な考え方を説明してある。

 第3章においては、実装した Fail-Safe C 処理系における各種の技法に関して詳述してある。メモリブロックの特殊な表現により、動的な境界検査と型検査を実現している。オブジェクト指向の概念を用いてメモリブロックを表現し、全てのメモリブロックにアクセスメソッドを付加することにより、ポインタのキャストなどの静的型によらないアクセスの安全な実行をサポートしている。「virtual offset」と名付けたメモリのアドレスづけの特殊な方法により、既存のプログラムの互換性の向上とキャスト操作の安全性を同時に実現している。ポインタがキャストされているかどうかを自らに記録するような、ポインタ (と整数) の賢い表現により、安全にキャストを実装すると同時に通常のポインタの高速な使用を実現している。

 第4章では、実装した処理系の効率を、いくつかの小規模なプログラムと、BYTEmarkのベンチマークに対して評価している。通常のC言語の実装と比較して、プログラムによっては数十%のオーバーヘッド、悪くても数倍のオーバーヘッドで実行できることが示されている。また、実在する有名なプログラムに存在するセキュリティ上の脆弱性を用いて、実際に Fail-Safe C を適用して安全性を保証する実験を例示している。

 第5章では、本論文の貢献をまとめ、C++への拡張など、今後の課題について述べている。

 本論文は、以上に述べたように、Fail-Safe C 処理系の設計と実装により、C言語の新しい実装技術を開発したものであり、ネットワークにおけるセキュリティ技術としても貢献が大きい。よって、本論文は博士(情報理工学)の学位請求論文として合格と認められる。

UTokyo Repositoryリンク