【コラム】

セカンド・オピニオン

197 OS小論:OSの構造をもう少し考えてみる(3)

    大原雄介  [2007/03/12]

    まずいくつか補足説明と訂正など。初回で「VAX/VMSは仮想記憶をインプリメントした初めてのOS」と書きましたが、Burroughs(現在のUnisys)のB5000が最初ではないか、というご指摘をいただきました。確かにそういわれてみればB5000の事はすっかり忘れてました。厳密には「ミニコンでは初めて」と書くべきでした。ちなみに同様にIBMのCP-67/CMSも仮想記憶を実装しているのでは? とご指摘いただきましたが、個人的にはあれば仮想マシンの一部として仮想記憶が提供されていると理解しています。

    あと、4レベルのProtection Ringの大本はData GeneralのEclipse MV/8000(ハードウェア的実装)とかMultics(ソフトウェア的実装)ではないか? というご指摘もいただきましたが、これはもうちょっと話が複雑なので連載の中で順次触れてゆく予定です。

    4 level privilegeその2

    では何故こんな具合に4レベルに分けたか、というとこれはひとえにシステムの堅牢性を高めるという一点に尽きる。たとえば最近は何かと脆弱性を利用してOSを乗っ取るだのカーネルに進入するだのといった話が出てくるが、これはそもそもKernel Modeで稼動するサービスが簡単にアクセスできてしまう事も一因である。ちょっと古い話だが、MicrosoftのMS04-028「JPEG 処理 (GDI+) のバッファ オーバーランにより、コードが実行される」という脆弱性が有名になったことがある。この脆弱性は、Kernel Modeで動作するGDI/GDI+の中にあるJPEGのヘッダ処理部分にBuffer Overrunを起こす箇所があり、これを悪用するようなコードをJPEGヘッダに埋め込む事により、ユーザー権限を奪取できるというものだ。この脆弱性の直接の問題は、Buffer Overrunを起こしうるCodeが含まれていたという話だが、本質的な問題はそもそも「JPEGのヘッダを処理する」などという、普通ならアプリケーションライブラリで提供される(=User Modeで動作する)ような処理がKernel Modeで提供されていた事にある。

    勿論、これは一種のトレードオフである。よく知られている話だが、Windows NTはVersion 3.51までDisplay DriverやGDIはUser Modeで動作していた(上巻P67)。ところがこれだと描画の際にオーバーヘッドが大きく、性能が出ないということでWindows NT 4からDisplay DriverやGDIはKernel Modeに移行してしまった。ここでGDIの内部を分離して、JPEGのヘッダの処理とかはUser ModeのStubでやらせておき、もっとプリミティブな処理のみをKernel Modeに移すとかしていれば、この脆弱性の影響はもっと少なかっただろう。ただこうしたやり方では、オーバーヘッドを十分に減らせない可能性があっただろうし、そもそもUserとKernelの2つしかモードが無いから、Userから分離するとKernelに持ってゆくしかなかったともいえる。

    もしここでWindowsがVMS並にModeを分離していたらどうだったか、を考えるとちょっと面白い。恐らくGDIの大半はExective Modeで動き、直接ハードウェアを叩く部分だけがKernel Modeで動作したであろう(*1)。従ってJPEGヘッダの脆弱性は、Exective Modeにおける権限を奪取された可能性はあるが、少なくともKernel Modeでの権限は奪えなかっただろうと想像できる。ではその代償は? というと、間違いなく性能の低下である。VMSの場合、このModeの切り替えにはCHMx/REIという命令が用意されていた。CHMx(xにはS/E/Kが付き、それぞれSupervisor / Executive / Kernelに昇格できる)を使って必要なレベルまで権限を上げ、処理が終わったらREIを発行して元のレベルに戻るという仕組みだ。当然これはそれなりのOverheadとなる。Windows NTはKernelとUserの切り替えしかないのにかなりオーバーヘッドが大きかった(だからこそDisplay DriverをKernel Modeに移した)のだから、レベルが更に増えたらModeの移動の回数は更に多くなる。

    実際UNIXとか、同じDECのVAXの上で動くVAXELNというリアルタイムOSでは、こんなに複雑な機構は使っていない。これらはいずれもKernel/Userの2つしかModeを使っておらず、その分オーバーヘッドを削減することに成功している。勿論これらのOSは、ワークステーションとか、VAXELNに至っては組み込み用途だったから、メインフレームレベルの信頼性は不要だという割り切りがあった。有名な「闘うプログラマー」を読むと、Windows NTの開発時期に信頼性を重視した事は記載されているが、それがどの程度の信頼性か、については明快に記されてはいない。ただ、設計時点でたとえばWindows Server Datacenter Editionの様な大規模システムまで発展することをどの程度考えていたのか、はちょっと疑問である。(続く)

    (*2) VAX/VMSは基本的にグラフィックドライバなんてものが無く、その後Bitmap Displayなども出てきたが、本格的なグラフィックアクセラレータが搭載されるようになったのはAlpha AXP以降であると記憶している(ビットマップディスプレイはもうちょっと前に出現したが)。詳しくはドライバの話をするときにまた説明するが、ドライバルーチンの中でKernel Modeで動作できるのは事実上ISR(Interrupt Service Routine)だけで、この中に複雑なアクセラレーション処理のコードを入れる余地は少なかった。だから、仮にVMSでグラフィックアクセラレータボードを扱う必要があった場合、Kernel Modeに全部持ってゆくのは事実上不可能に近かった、というのが正しい表現だろう。逆にディスプレイドライバをVMS上でどうしてもNTの様に扱うとなると、ドライバ周りの構造が変わったかもしれない。

    新着記事

    特設サイトの情報

      人気記事

      一覧

        新着記事

        特別企画

        マイナビニュースマガジン