AMD64で行われたIA-32に対する拡張はいろいろありますが、最も重要なのは実メモリ空間の拡張です。AMDはこの際、ページング機構で用いられるページテーブルエントリ(PTE)などの拡張にIntelがPAE(物理アドレス拡張)で行った拡張を流用しました。
IA-32のメモリ管理機構(MMU)が持つページング機構はここにあるような構造をしています(原書で言えば3.6あたり)。各ページではPTEによって書き込み許可/拒否とユーザ/スーパバイザの2種類の保護機構を利用することができます。PentiumProで導入されたPAEでは、ここにあるように(原書なら3.6.1や3.8あたり)、物理アドレスの拡張のために各テーブルのエントリは64bit化されています(といっても拡張32bit分のうち4bitしか使ってませんが)。AMD64では、このPTEなどの構造はほぼそのままに上位ビットをさらに使います。この辺はやはり原書:AMD64 Architecture Programmer's Manual Volume 2: System Programmingの5.1あたりを参照してください。
で、このアドレス拡張と同時に、もうひとつ保護機能に関して重要な拡張が行われています。それはPTEなどの最上位にNXビット(実行不許可ビット)という定義がされていることです。このビットがセットされたエントリに対応するページにあるコードをCPUが実行しようとすると保護例外が発生するもので、スタックやヒープに割り当てたメモリ領域にOSがセットすることを想定したものです。この拡張により、現在のOSやネットワークサービスプログラムが残してしまうセキュリティホールの主なものである「バッファオーバーフロー」攻撃に対し、不正コードを送り込まれて実行される可能性を激減させることができます(バッファオーバーフロー攻撃はそもそもこの種のデータ領域の境界チェックの不備を突いてデータ領域に不正コードを展開することから始まるのですから)。しかもこの機能、AMD64であれば64bitモードで実行していなくても、PAEが有効にされているだけで利用できるので、旧来の32bitOSでも利用できてしまいます。実際、AMDとマイクロソフトはWindows XPのSP2およびWindows Server 2003のSP1からこの機能を生かすことを発表しました。
この機能の威力は絶大です。特にCやC++が主流言語として残っている現状ではバッファオーバーフロー脆弱性なんて世の中から消すことは絶望的だったわけですが、たとえ脆弱性が残っていてもせいぜいDoS攻撃に使えるだけ(*)で侵入されないということになるとシステム管理者としてもプログラマとしてもずいぶん気分が楽になります。SlammerやBlasterのようなワームも原理的には動作しえませんし、OpenSSH/SSLの穴にビクビクする必要もないはず。このOSの変更によって影響を受けるプログラムもJavaのJITなど、自己書き換えや動的コード生成を含むようなごく一部のもので済みます。多分OSの設定で、特定のプログラムだけこの機能を殺すようにしたり、あるいはアプリケーション側で特定のヒープ領域だけ実行可能にするようなAPIを呼び出すようにするんでしょうね。
ということでこの話、私にとっては待ちに待った、もっと早くやってほしかった機能拡張です。もっと大きく取り上げられてもよいと思うんですが、まだその重要性がよく理解されていないのでしょうか。残念です。
他のOSの状況はまだよく調べてませんが、FreeBSD/AMD64はまだこれからみたいです(machdep.cのほうにはSince we don't use PG_NX yet,...なんて書いてありました)。前に見たときはstackを実行不可にしようとしてたみたいに読めたのですが動いてなかったのかなぁ・・・Linuxはどうなんでしょう?誰か教えてください。とにかく、Intelの参入によってAMD64/IA-32eは主流になりますから、あともう少し我慢すればOSのサポートも進んで、全てのパソコンやサーバがバッファオーバーフロー攻撃から解放される日が来るのでしょう。
ちなみにIA-32のMMUで特定のアドレス領域を実行不能にすることは今まででもできましたが、セグメントディスクリプタを使う必要がありましたので、現在のUNIXやWindowsの仮想記憶機構の構造ではかなりトリッキーなことをしないと使えません(昔FreeBSDで実現したらどうなるだろうとずいぶん考えたことがあるんですがあきらめました)。すっかり忘れがちですがIA-32はPaged segmentationが利用できる数少ないMMUを持っています(だからこそ32bitアドレスはリニアアドレスと呼ばれます。仮想アドレスとしてはセグメント指定をあわせて48bitになります。)し、そのセグメント機構をちゃんと使っていたOS/2はちゃんとデータやスタックはセグメントで分離されてて実行不可にされていました。私はMultics以来のセグメント機構を愛していましたのでOS/2 ver.3あらためOS/2 NTあらためWindows NTが、32bitリニアアドレスを採用すると聞いたときにずいぶん残念に思ったものです。もちろんその時には、あるメモリ領域を実行不可にすることの効果がセキュリティにまで及ぶとは夢想だにできなかったのですが。
(*)追記:首藤さんの指摘でちょっと言い過ぎたかと思い直しました。詳しくはコメントを。
(2004.03.06)
元麻布さんの64bitへ動き出したIAサーバの胎動ここでもちょっと触れられていたりします。しかしこれ見てあわてたのですが、確かにIA-32eではまだNXビットに対応するところがReservedにされていて、有効かどうか明らかじゃないのですね。しかし特許などの問題がないのなら(クロスライセンスしてるはずですよね)是非ここもあわせていただきたいものです。IA-64でもMMUに実行不許可機能つけてたはずですから、重要性を認識していないはずがないと思うのですが。
それにしてもこのページあちこちにlinkはられたみたいでご訪問者急増。
Recent Comments