(57)【要約】【課題】  システムの外部から受信したデータに組み込まれた悪意あるコードによるセキュリティ攻撃に対処する。【解決手段】  コンパイラ・システムが決定したプログラムのコード・プログラム・セグメントとデータ・プログラム・セグメント間のオフセット制約をプログラム変換により解除し、コード・プログラム・セグメントのみをプロセスの実行可能なセグメントに配置し、データ・プログラム・セグメントは実行禁止セグメントに配置する。オフセット制約の解除により、プログラム・セグメントをランダム配置し、悪意あるコードやデータによるデータ実行と間接実行を防止する。【選択図】  図４
2005157502.tif 000002
【特許請求の範囲】
【請求項１】
メモリ空間上に配置して実行されるプログラムを処理する情報処理装置であって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスにオフセット制約があり、
前記オフセット制約に拘わらず各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換手段と、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置手段と、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理手段と、
を具備することを特徴とする情報処理装置。
【請求項２】
前記プログラム変換手段は、プログラム・セグメント間で参照を行なうためのアダプタを生成して、オフセット制約のないプログラム・セグメントを再構成し、
前記アダプタは、参照元となるプログラム・セグメントから前記オフセット制約を持ち、
前記プログラム配置手段は、参照元となるプログラム・セグメントから前記オフセット制約に従った位置に前記アダプタを配置する、
ことを特徴とする請求項１に記載の情報処理装置。
【請求項３】
前記プログラムは、実行可能な属性が付されたプログラム・セグメントと実行不能の属性が付されたプログラム・セグメントを含み、
前記メモリ管理手段は、実行可能な属性が付されたプログラム・セグメントを実行可能に、実行不能の属性が付されたプログラム・セグメントを実行不能にそれぞれ設定する、
ことを特徴とする請求項１に記載の情報処理装置。
【請求項４】
メモリ空間上に配置して実行されるプログラムを処理する情報処理装置であって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
プログラム・セグメント間で参照を行なうためのアダプタを生成し、オフセット制約のないプログラム・セグメントを再構成し、各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換手段を備える、
ことを特徴とする情報処理装置。
【請求項５】
前記メモリはメモリ・セグメント毎に属性の設定が可能であり、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置手段と、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理手段と、
をさらに備えることを特徴とする請求項４に記載の情報処理装置。
【請求項６】
前記アダプタは、参照元となるプログラム・セグメントから前記オフセット制約を持ち、
前記プログラム配置手段は、参照元となるプログラム・セグメントから前記オフセット制約に従った位置に前記アダプタを配置する、
ことを特徴とする請求項５に記載の情報処理装置。
【請求項７】
前記プログラムは、実行可能な属性が付されたプログラム・セグメントと実行不能の属性が付されたプログラム・セグメントを含み、
前記メモリ管理手段は、実行可能な属性が付されたプログラム・セグメントを実行可能に、実行不能の属性が付されたプログラム・セグメントを実行不能にそれぞれ設定する、
ことを特徴とする請求項５に記載の情報処理装置。
【請求項８】
前記プログラム配置手段は、プログラム変換後の各プログラム・セグメントを、プログラムの起動毎に異なるランダムなアドレスに配置する、
ことを特徴とする請求項１又は５のいずれかに記載の情報処理装置。
【請求項９】
前記プログラム変換手段は、プログラムのインストール時に前記のプログラムの変換処理を行なう、
ことを特徴とする請求項１又は４のいずれかに記載の情報処理装置。
【請求項１０】
前記プログラム変換手段は、プログラムを起動する度に前記のプログラムの変換処理を行なう、
ことを特徴とする請求項１又は４のいずれかに記載の情報処理装置。
【請求項１１】
前記プログラム変換手段は、前記プログラムを命令が入るコード・プログラム・セグメントと、変数が入るデータ・プログラム・セグメントと、変数又は関数への参照情報が入るアダプト・プログラム・セグメントに再分類し、セクションを新規作成する、
ことを特徴とする請求項１又は５のいずれかに記載の情報処理装置。
【請求項１２】
前記プログラム変換手段は、関数呼出し命令をＰＬＴエントリ（ｐｒｏｃｅｄｕｒｅ  ｌｉｎｋａｇｅ  ｔａｂｌｅ）とするテーブルからなるＰＬＴセクションをアダプト・プログラム・セグメントとして構成する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１３】
前記プログラム変換手段は、各ＰＬＴエントリが参照する関数のアドレスが格納されるエントリのテーブルからなるＧＯＴ２セクションをデータ・プログラム・セグメント内に構成する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１４】
前記プログラム変換手段は、プログラムが参照する変数のアドレス並びに関数ポインタの値からなるＧＯＴセクションをアダプト・プログラム・セグメント内に構成する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１５】
前記プログラム変換手段は、ＧＯＴセクションのうち関数呼び出しに使用するエントリをＧＯＴ２セクションとしてデータ・プログラム・セグメント内に構成する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１６】
前記プログラム配置手段は、前記アダプト・プログラム・セグメントを、前記コード・プログラム・セグメントに対し前記オフセット制約に従ったオフセット位置に配置する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１７】
前記メモリ管理手段は、前記コード・プログラム・セグメントを配置したメモリ・セグメントに対し、実行及び読み出し可能、書き込み不可、共有可能の属性を設定する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１８】
前記メモリ管理手段は、前記データ・プログラム・セグメントを配置したメモリ・セグメントに対し、読み出し及び書き込み可能、実行不可、共有不可の属性を設定する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項１９】
前記メモリ管理手段は、前記アダプト・プログラム・セグメントを配置したメモリ・セグメントに対し、実行及び読み出し可能、書き込み不可、共有不可の属性を設定する、
ことを特徴とする請求項１１に記載の情報処理装置。
【請求項２０】
メモリ空間上に配置して実行されるプログラムを処理するための情報処理方法であって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
前記オフセット制約に拘わらず各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換ステップと、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置ステップと、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理ステップと、
を具備することを特徴とする情報処理方法。
【請求項２１】
前記プログラム変換ステップでは、プログラム・セグメント間で参照を行なうためのアダプタを生成して、オフセット制約のないプログラム・セグメントを再構成し、
前記アダプタは、参照元となるプログラム・セグメントから前記オフセット制約を持ち、
前記プログラム配置ステップでは、参照元となるプログラム・セグメントから前記オフセット制約に従った位置に前記アダプタを配置する、
ことを特徴とする請求項２０に記載の情報処理方法。
【請求項２２】
前記プログラムは、実行可能な属性が付されたプログラム・セグメントと実行不能の属性が付されたプログラム・セグメントを含み、
前記メモリ管理ステップでは、実行可能な属性が付されたプログラム・セグメントを実行可能に、実行不能の属性が付されたプログラム・セグメントを実行不能にそれぞれ設定する、
ことを特徴とする請求項２０に記載の情報処理方法。
【請求項２３】
メモリ空間上に配置して実行されるプログラムを処理する情報処理方法であって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
プログラム・セグメント間で参照を行なうためのアダプタを生成し、オフセット制約のないプログラム・セグメントを再構成し、各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換ステップを備える、
ことを特徴とする情報処理方法。
【請求項２４】
前記メモリはメモリ・セグメント毎に属性の設定が可能であり、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置ステップと、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理ステップと、
をさらに備えることを特徴とする請求項２３に記載の情報処理方法。
【請求項２５】
前記アダプタは、参照元となるプログラム・セグメントから前記オフセット制約を持ち、
前記プログラム配置ステップでは、参照元となるプログラム・セグメントから前記オフセット制約に従った位置に前記アダプタを配置する、
ことを特徴とする請求項２４に記載の情報処理方法。
【請求項２６】
前記プログラムは、実行可能な属性が付されたプログラム・セグメントと実行不能の属性が付されたプログラム・セグメントを含み、
前記メモリ管理ステップでは、実行可能な属性が付されたプログラム・セグメントを実行可能に、実行不能の属性が付されたプログラム・セグメントを実行不能にそれぞれ設定する、
ことを特徴とする請求項２４に記載の情報処理方法。
【請求項２７】
前記プログラム配置ステップでは、プログラム変換後の各プログラム・セグメントを、プログラムの起動毎に異なるランダムなアドレスに配置する、
ことを特徴とする請求項２０又は２４のいずれかに記載の情報処理方法。
【請求項２８】
前記プログラム変換ステップでは、プログラムのインストール時に前記のプログラムの変換処理を行なう、
ことを特徴とする請求項２０又は２３のいずれかに記載の情報処理方法。
【請求項２９】
前記プログラム変換ステップでは、プログラムを起動する度に前記のプログラムの変換処理を行なう、
ことを特徴とする請求項２０又は２３のいずれかに記載の情報処理方法。
【請求項３０】
前記プログラム変換ステップでは、前記プログラムを命令が入るコード・プログラム・セグメントと、変数が入るデータ・プログラム・セグメントと、変数又は関数への参照情報が入るアダプト・プログラム・セグメントに再分類し、セクションを新規作成する、
ことを特徴とする請求項２０又は２４のいずれかに記載の情報処理方法。
【請求項３１】
前記プログラム変換ステップでは、関数呼出し命令をＰＬＴエントリ（ｐｒｏｃｅｄｕｒｅ  ｌｉｎｋａｇｅ  ｔａｂｌｅ）とするテーブルからなるＰＬＴセクションをアダプト・プログラム・セグメントとして構成する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３２】
前記プログラム変換ステップでは、各ＰＬＴエントリが参照する関数のアドレスが格納されるエントリのテーブルからなるＧＯＴ２セクションをデータ・プログラム・セグメント内に構成する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３３】
前記プログラム変換ステップでは、プログラムが参照する変数のアドレス並びに関数ポインタの値からなるＧＯＴセクションをアダプト・プログラム・セグメント内に構成する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３４】
前記プログラム変換ステップでは、ＧＯＴセクションのうち関数呼び出しに使用するエントリをＧＯＴ２セクションとしてデータ・プログラム・セグメント内に構成する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３５】
前記プログラム配置ステップでは、前記アダプト・プログラム・セグメントを、前記コード・プログラム・セグメントに対し前記オフセット制約に従ったオフセット位置に配置する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３６】
前記メモリ管理ステップでは、前記コード・プログラム・セグメントを配置したメモリ・セグメントに対し、実行及び読み出し可能、書き込み不可、共有可能の属性を設定する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３７】
前記メモリ管理ステップでは、前記データ・プログラム・セグメントを配置したメモリ・セグメントに対し、読み出し及び書き込み可能、実行不可、共有不可の属性を設定する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３８】
前記メモリ管理ステップでは、前記アダプト・プログラム・セグメントを配置したメモリ・セグメントに対し、実行及び読み出し可能、書き込み不可、共有不可の属性を設定する、
ことを特徴とする請求項３０に記載の情報処理方法。
【請求項３９】
メモリ空間上に配置して実行されるプログラムの処理をコンピュータ・システム上で実行するようにコンピュータ可読形式で記述されたコンピュータ・プログラムであって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
前記オフセット制約に拘わらず各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換ステップと、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置ステップと、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理ステップと、
を具備することを特徴とするコンピュータ・プログラム。
【請求項４０】
メモリ空間上に配置して実行されるプログラムの処理をコンピュータ・システム上で実行するようにコンピュータ可読形式で記述されたコンピュータ・プログラムであって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
プログラム・セグメント間で参照を行なうためのアダプタを生成し、オフセット制約のないプログラム・セグメントを再構成し、各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換ステップを備える、
ことを特徴とするコンピュータ・プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、複数のプログラム・セグメントからなるプログラムをメモリ空間にロードして実行する情報処理装置及び情報処理方法、並びにコンピュータ・プログラムに係り、特に、各プログラム・セグメントをメモリ空間上の異なる保護属性が設定されているセグメントにそれぞれロードしてプログラムの実行を行なう情報処理装置及び情報処理方法、並びにコンピュータ・プログラムに関する。
【０００２】
さらに詳しくは、本発明は、システムの外部から受信したデータに組み込まれた悪意あるコードによりコンピュータに不正に実行させるセキュリティ攻撃に対処する情報処理装置及び情報処理方法、並びにコンピュータ・プログラムに係り、特に、セグメント毎に実行可能か否かを管理するメモリの保護機能を利用して、プログラムのデータ・セクションに不正に置かれた命令の実行を防止する情報処理装置及び情報処理方法、並びにコンピュータ・プログラムに関する。
【背景技術】
【０００３】
昨今、情報処理や情報通信などのコンピューティング技術が飛躍的に向上し、コンピュータ・システムが広汎に普及してきている。さらに、コンピュータどうしを相互接続するネットワーク・コンピューティング技術に対する要望も高まってきている。ネットワーク接続環境下では、コンピュータ資源の共有や、情報の共有・流通・配布・交換などの協働的作業を円滑に行なうことができる。
【０００４】
コンピュータ同士を相互接続するネットワークの形態はさまざまである。例えば、イーサネット（登録商標）のような局所に敷設されたＬＡＮ（Ｌｏｃａｌ Ａｒｅａ Ｎｅｔｗｏｒｋ）や、さらには、ネットワークどうしの相互接続を繰り返し行った結果として文字通り世界規模のネットワークへ成長を遂げた「インターネット」（Ｔｈｅ Ｉｎｔｅｒｎｅｔ）などさまざまである。
【０００５】
最近では、電話回線（ＡＤＳＬ（Ａｓｙｍｍｅｔｒｉｃ Ｄｉｇｉｔａｌ Ｓｕｂｓｃｒｉｂｅｒ Ｌｉｎｅ）など）やケーブル・テレビなどの高速なネットワーク回線の敷設に伴い、常時接続環境の充実してきている。また、今後普及が見込まれるＩＰｖ６により、数多くの機器がインターネットに接続されることが予想される。
【０００６】
しかしながら、このような広域ネットワークの普及と同時に、安全性に対する不安も生じている。何故ならば、ネットワークを介することで知らないうちに機器に不正にアクセスされ、システム内のデータを不正に模倣・盗用、改ざんしたり、ウィルス感染などによりシステムを使用不能にしたりするなど、人手を介さずに攻撃を受ける可能性があるからである。このため、インターネットの利用者は、幾つかのセキュリティ対策を講じなければならない。
【０００７】
勿論、ウィルスは、ネットワークからだけでなく、メモリカードやＣＤ−ＲＯＭなどの記録媒体を経由してデータをコンピュータ・システムに読み込むことによっても侵入する。
【０００８】
ウィルスは、プログラムの動作を悪用して不正な動作を行なう攻撃である。プログラムのバグを利用した不正実行は、プログラムの認証では防御することができない。ウィルスの動作方法はさまざまであるが、主な方法として「データ実行」と「間接実行」が挙げられる。本明細書では、この２つの方法によるセキュリティ攻撃のことを併せて「不正実行」と呼ぶ。
【０００９】
データ実行：
データ実行とは、プログラム外からの実行コードの注入、すなわちプロセスのデータ領域に実行コードを展開し実行することで不正な動作を行なうセキュリティ攻撃方法である。具体的には、ウィルスがプログラム上のバグなどを利用してプログラムのデータ、ヒープ、スタック領域に不正な命令列を書き込み、それを実行することにより、攻撃を行なう。
【００１０】
ウィルスが不正な命令列を書き込む方法としては、例えば、プログラムがスタック上に配置された配列操作のバグを利用するものがある。スタック上に配置された配列にデータを順番にプログラムが書き込む部分にバグがあると、配列の大きさを超えてデータを書き込んでしまう（バッファ・オーバーフロー）。すると、配列に隣接したスタックに保存されている関数の戻りアドレスの値をも書き換えてしまうことができる。バッファ・オーバーフロー攻撃の例を以下に示す。
【００１１】
void vul(char* str)
{
char buffer[64];
strcpy(buffer, str);
}
【００１２】
ウィルスは、アプリケーション・プログラムに不正な長さのデータを渡すなどすることによって、プログラムのこのバグを利用する。ウィルスがプログラムに渡したデータによって関数の戻りアドレスが書き換えられると、関数がその呼び出し元に戻ろうとしたときに、本来戻るべきアドレスとは異なるアドレスから実行を再開してしまう。このため、ウィルスが不正データとして渡した不正な命令列の先頭アドレスの値を関数の戻りアドレスの値として上書きすることによって、関数が呼び出し元に戻るときに、不正な命令列の実行を開始させることが可能となってしまう。不正な命令列を実行開始した後は、コンピュータ・システムのセキュリティは損なわれてしまう（図１４を参照のこと）。
【００１３】
ここで示したバッファ・オーバーフロー以外にも、多様なウィルスの進入方法が存在する。ウィルスは、プログラムのバグや動作を利用して進入するため、原理的には、プログラムのバグや動作を変更することによってウィルスの進入を防ぐことができる。しかし、アプリケーション・プログラムは高度に複雑であり、また、さまざまなベンダの開発したライブラリやコンポーネントの集合体として構成されるため、アプリケーション・プログラムのすべてのバグやウィルス進入に使用される可能性のある動作を修正することは困難である。
【００１４】
間接実行：
間接実行とは、既存の実行コードを利用して不正な動作を行なう攻撃方法であり、ウィルスがプログラムやライブラリなどのコンピュータ・システムに既に存在する命令列を不正に利用することでセキュリティ攻撃を行なう。関数ポインタなどを不正に書き換えれば、プログラム外から実行コードを注入することなく、既存の実行コードを利用して不正な動作を行なわせることができる。例えば、プログラム中のバッファ・オーバーフローのバグ（前述）を利用すると、関数の戻りアドレスの値を任意の値に書き換えることが可能となる。これを利用して、プログラムやライブラリの関数のうち攻撃に利用できる関数の先頭アドレスに関数の戻りアドレスの値を書き換えることによって、本来実行を再開するべき命令とは異なる地点から命令を実行させるように、処理の流れを変更できてしまう。
【００１５】
間接実行は、典型的には、スタック・オーバーフローを利用して、スタック上の戻りアドレス（Ｒｅｔｕｒｎ  Ａｄｄｒｅｓｓ）を書き換え、ｒｅｔ命令実行時に関数を呼び出すことにより攻撃を行なう（図１５を参照のこと）。ＵＮＩＸ（登録商標）においては、ｌｉｂｃライブラリ内にあるｓｙｓｔｅｍ関数を呼び出すことが多く行なわれるため、「ｒｅｔｕｒｎ−ｉｎｔｏ−ｌｉｂｃ攻撃」とも呼ばれる。ｓｙｓｔｅｍ関数を呼び出すことが攻撃目標とされるのは、ｓｙｓｔｅｍ関数が任意のコマンドの実行ができることから、不正利用に適しているためである。
【００１６】
不正利用できる関数の実行が行なわれると、コンピュータ・システムのセキュリティは損なわれてしまう。間接実行は、データ実行と異なり、不正な命令列を書き込むことなく、セキュリティ攻撃ができる点に特徴がある。このため、データ実行が困難である場合にも攻撃が可能となる。
【００１７】
データ実行の防止方法：
データ実行を防止する有効な方法として、プロセッサのメモリ保護機構を利用する方法が挙げられる。メモリ管理ユニット（ＭＭＵ：Ｍｅｍｏｒｙ Ｍａｎａｇｅｍｅｎｔ Ｕｎｉｔ）に代表されるプロセッサ内のメモリ保護機構は、プログラムが利用する仮想アドレスを物理アドレスに変換するアドレス変換機能を装備するとともに、メモリ・アクセスの制御を行なう。メモリ保護機構は、特定の管理単位に分割したメモリ領域に対して、読み出し権と書き込み権を設定する。そして、プログラムのメモリ・アクセスが設定した権利以外であった場合（例えば、読み出しのみが設定されたメモリ領域への書き込みアクセスが発生したとき）には、例外を発生してオペレーティング・システム（ＯＳ）に通知することができる。
【００１８】
以前のプロセッサが持つメモリ保護機構では、メモリへの読み出し権は、データの読み出しと命令の実行の両方のアクセスを１つのアクセス権としてしか設定できなかった。これに対し、最近のプロセッサでは、読み出しと命令実行の各実行権を独立に設定できるものが出現してきている。後者によれば、命令の実行権が設定されていないメモリ領域にデータを配置することで、データ実行を防止することができる。
【００１９】
ところが、現在主流となっている、米インテル社製のｘ８６系プロセッサや、米アイ・ビー・エム社及び米モトローラ社のＰｏｗｅｒＰＣプロセッサでは、実行権を設定できるメモリ単位が、読み出し権や書き込み権を設定できるページ単位ではなく、非常に大きな単位すなわち粗粒度となっている。例えば、ページ・サイズが通常４ＫＢであるのに対して、ＰｏｗｅｒＰＣプロセッサのセグメントは２５６ＭＢのサイズである。また、ｘ８６系プロセッサのセグメント・サイズは可変であるが、メモリ領域上で実行権を設定できるセグメントは１つしか設定できないため、必然的に大きなサイズで設定を行なうことになる。このため、プロセッサのメモリ保護機構を利用してデータ実行防止を行なうには、特別な方法を採る必要がある。
【００２０】
以下では、メモリ・システム並びに不正実行防止に関連する用語について説明しておく。
【００２１】
セクション：
セクションは、コンパイラ・システムがプログラムのファイルを構成するデータの単位のことである。例えば、命令が入るテキスト・セクション（．ｔｅｘｔ）や、グローバル変数などが入るデータ・セクション（．ｄａｔａ）がある。
【００２２】
プログラム・セグメント：
プログラム・セグメントとは、セクションの集合で、プロセスのアドレス空間にプログラムのファイルをマッピングするときの単位のことである。１つのプログラム・セグメントは１以上のセクションで構成される。１つのセグメントは、プロセスのアドレス空間で同じメモリ・アクセス権が設定される。ここで言うメモリ・アクセス権とはメモリの読み出し権、書き込み権、実行権などのメモリ（保護）属性のことである。特に、プロセッサの実行コードが主に保持されるプログラム・セグメントを「コード・プログラム・セグメント」、データが保持されるプログラム・セグメントを「データ・プログラム・セグメント」と呼ぶ。
【００２３】
セグメント：
セグメントは、プロセスがメモリ保護を実現する単位のうち、実行権を設定できる単位のことである。一般に、セグメントはページよりも大きな粗粒度の単位となる（前述）。
【００２４】
ページ：
ページは、プロセスがメモリ保護を実現する単位のうち、書き込み権と読み出し権を設定できる単位のことであり、セグメントより小さな単位となる。
【００２５】
ＳＥＧＭＥＸＥＣ：
ＳＥＧＭＥＸＥＣは、ｘ８６アーキテクチャのプロセッサのセグメント機構を利用して、コード・セグメント（ＣＳ）とデータ・セグメント（ＤＳ）の分離によりデータ実行を防止する技術である（例えば、非特許文献１を参照のこと）。
【００２６】
図１６には、ＳＥＧＭＥＸＥＣのメカニズムを図解している。ｘ８６系のＵＮＩＸ（登録商標）は、ユーザ領域（アプリケーション・プロセスのアドレス空間）として３ＧＢを提供する。ＳＥＧＭＥＸＥＣは、このアドレス空間を半分に分割し、それぞれ１．５ＧＢの大きさを持つ２つの領域、すなわちコード・セグメント（ＣＳ）とデータ・セグメント（ＤＳ）を設定する。図１６において、上半分のＣＳで示される１．５ＧＢの領域はコード・セグメントであり、下半分のＤＳで示される領域はデータ・セグメントである。ｘ８６系プロセッサでは、命令フェッチは必ずコード・セグメントから行なわれる。したがって、コード・セグメントにデータを配置しないことで、データ上に不正に置かれた命令の実行を防止することができる。データ・セグメントにデータと合わせてコード（ｂ）が配置されているのは、コードをデータとして参照する場合に対応するためである。
【００２７】
ｘ８６系プロセッサのメモリ保護機構によるアドレス変換は、仮想アドレスをリニア・アドレスに変換し、それをさらに物理アドレスに変換する。仮想アドレスからリニア・アドレスへの変換は、セグメント・ベース・アドレスを仮想アドレスに加算することで行なう。逆言すれば、仮想アドレスは対応するセグメント・ベース・アドレスからのオフセットである。このため、図１６中のコード（ａ）のセグメント・ベース・アドレスからのオフセットとコード（ｂ）のデータ・セグメント・ベース・アドレスからのオフセットを同じにすることによって、プログラムからは同じ仮想アドレスで命令フェッチと命令をデータとした場合の参照を行なうことができる。なお、ｘ８６系プロセッサでは「論理アドレス」という用語を一般に使用するが、本明細書ではＰｏｗｅｒＰＣプロセッサと同一の用語として「仮想アドレス」と呼ぶことにする。
【００２８】
ここで、ＳＥＧＭＥＸＥＣはｘ８６のリニア・アドレスが異なるセグメント間でも仮想アドレスが同じ値になるように設定できる特徴を利用して互換性を実現しているため、ＰｏｗｅｒＰＣなど他のプロセッサへの適用が難しいという問題がある。
【００２９】
ＰｏｗｅｒＰＣでは、セグメント（同じ用語であるが、ｘ８６のセグメントとは異なる）という２５６ＭＢの大きさの単位に対して実行権の設定が可能となっているが、セグメントは仮想アドレスの上位ビット（３２ビット・アーキテクチャの場合は４ビット) で決定されるために、異なるセグメントを同一の仮想アドレスとして設定することはできない。また、ＳＥＧＭＥＸＥＣでは、ユーザ領域が通常の半分の大きさに制限されてしまう。このため、大量のデータを利用するマルチメディア・アプリケーションやデータベース・アプリケーションではアドレス空間が不足する可能性がある。
【００３０】
Ｅｘｅｃ−Ｓｈｉｅｌｄ：
ＰｏｗｅｒＰＣのように異なるセグメント間で仮想アドレスを同一にできないプロセッサでも、セグメント単位での実行権の設定を利用できる方法として、Ｅｘｅｃ−Ｓｈｉｅｌｄが挙げられる（例えば、非特許文献２を参照のこと）。図１７には、Ｅｘｅｃ−Ｓｈｉｅｌｄの仕組みを図解している。
【００３１】
Ｅｘｅｃ−Ｓｈｉｅｌｄは、ユーザのアドレス空間上で、コード・セグメントとデータ・セグメントをオーバーラップするように配置をする。但し、コード・セグメントはデータ・セグメントの一部分となるようにし、データ・セグメントのみがマップするエリアを設ける。同図中のＣＳ ｌｉｍｉｔは、テキスト・アドレスの最大値である。このような設定は、コード・セグメント・ベース・アドレスとデータ・セグメント・ベース・アドレスを同じ値とし、コード・セグメント・リミットＣＳ  ｌｉｍｉｔをデータ・セグメント・リミットよりも小さな値として設定することで実現することができる。
【００３２】
ｘ８６系プロセッサでは、命令フェッチは必ずコード・セグメントから行なわれる。また、コード・セグメントで指定できる範囲はコード・セグメント・リミットの範囲内である。このため、コード・セグメント・リミットの範囲外でデータ・セグメントのみがマップするアドレス空間にデータを配置することで、データ上に不正に置かれた命令の実行を防止することができる。
【００３３】
図１７にはｘ８６系プロセッサのセグメントを利用した例を示しているが、同様の効果を持つ設定をＰｏｗｅｒＰＣプロセッサのメモリ保護機構を利用して実現することができる。ＰｏｗｅｒＰＣプロセッサの場合には、コード・セグメントの代わりに実行許可が設定されたセグメント（２５６ＭＢ単位）を複数配置し、データ・セグメントの代わりに実行許可が設定されていないセグメントを複数配置することで実現できる。
【００３４】
通常、アプリケーション・プログラムは、プログラム本体に加えて、複数の共有ライブラリやコンポーネント（以下、「モジュール」と呼ぶ）から構成されている。そして、各モジュールはそれぞれコードとデータのプログラム・セグメントを含んでいる。モジュールをアドレス空間に配置する際には、プログラム本体（ＥＸＥ）はプログラムの静的リンク時に決定されたアドレスにロードを行なう必要がある。また、共有ライブラリやコンポーネントは任意のアドレスにロードを行なうことが可能であるものの、モジュール内のコード・プログラム・セグメントとデータ・プログラム・セグメントは、コンパイラ・システムが決定した一定の距離（オフセット）を保って配置する必要がある。すなわち、コード・プログラム・セグメントとデータ・プログラム・セグメントの間には、メモリへ配置する際に、所定の「オフセット制約」がある。このため、あるモジュールのコード・プログラム・セグメントのアドレスを決定すると、データ・プログラム・セグメントのアドレスは任意に設定することができない。
【００３５】
このオフセット制約があるために、Ｅｘｅｃ−Ｓｈｉｅｌｄの方法でコード・プログラム・セグメントを実行可能領域に配置しようとすると、対応するデータ・プログラム・セグメントも実行可能領域に配置せざるを得ない状況が生じる。図１７に示す例では、ＥＸＥ Ｄａｔａがこれに相当し、この結果、実行可能領域に配置されたデータは実行可能となってしまう。つまり、Ｅｘｅｃ−Ｓｈｉｅｌｄでは、すべてのデータの実行を完全に禁止することができない、という大きな問題がある。ウィルスがこの領域に不正なコードを侵入させた場合には、Ｅｘｅｃ−Ｓｈｉｅｌｄでは防御できない。
【００３６】
ＡＳＬＲ：
間接実行を防止する方法として、ＡＳＬＲという方法が挙げられる。この方法によれば、スタック、ヒープ、プログラム、共有ライブラリなどのプログラム・セグメントのアドレスをランダムに配置する（図１８を参照のこと）。間接実行では、関数の戻りアドレスなどのポインタの値を、プログラムやライブラリの関数のうち攻撃に利用できる関数の先頭アドレスで書き換えることによって、セキュリティ攻撃を行なう。すなわち、間接実行は、書き換える場所のアドレスと書き換える値のアドレスを知る必要がある。これに対し、ＡＳＬＲでは、モジュールの配置をランダム化することによって、書き換える関数の先頭アドレスを推定することを困難にする（例えば、非特許文献３を参照のこと）。
【００３７】
ここで、Ｅｘｅｃ−ｓｈｉｅｌｄとＡＳＬＲの組み合わせについて考察してみる（図１９を参照のこと）。データ実行を完全に禁止するには、モジュールのコード・プログラム・セグメントを実行可能に設定したＰｏｗｅｒＰＣのセグメントに配置するとともに、データ・プログラム・セグメントを実行禁止に設定したＰｏｗｅｒＰＣのセグメントに配置する必要がある。したがって、１つのモジュールは実行可能セグメントと実行禁止セグメントの２つのメモリ・セグメントをまたぐ形でマップする必要があることになる。
【００３８】
しかしながら、セグメントはページと比較して粗い粒どの単位であり（前述）ＰｏｗｅｒＰＣでは１６個、ｘ８６系プロセッサでは２個しかないため、実行可能セグメントと実行禁止セグメントをまたぐ形でのモジュールのマッピングを、PowerPCでは８通り、ｘ８６系プロセッサでは１通りの選択肢しか提供できない。
【００３９】
これに対し、モジュールを２つのセグメントにまたがらないように配置した場合、ランダム配置の制約は無くなり、配置可能な選択肢を多くできるため、アドレス推定防御の能力は高まるものの、データ実行を禁止できないデータ・プログラム・セグメントが数多く出てきてしまい、今度はデータ実行防止能力が低下してしまう。
【００４０】
つまり、完全なデータ実行の防止とランダム配置の両立が困難である、という問題がある。
【００４１】
なお、ＳＥＧＭＥＸＥＣは、既に説明した通り、ｘ８６系プロセッサ以外での利用が困難であるため、そもそもＰｏｗｅｒＰＣなどのその他のプロセッサ・アーキテクチャと組み合わせることができない。
【００４２】
ＳＳＰ：
ＳＳＰは、データ実行攻撃の原因の１つであるスタック・オーバーフローの書き換えを、プログラムの実行時に検出する技術である。すなわち、コンピュータ・システムがプログラムを実行する際の関数呼び出し後におけるこのメモリ装置のメモリ・パターンとして、実行中の関数の呼び出し元へのリターン・アドレスを格納する領域と、この実行中の関数の呼び出し元へのプレヴィアス・フレームポインタを格納する領域と、このリターンアドレスを格納する領域とこのプレヴィアス・フレームポインタを格納する領域との後方に位置し、ローカル変数を格納する領域とを備え、このローカル変数を格納する領域は、このローカル変数を格納する領域に配列が格納されている場合に、この配列よりも前に、実行中の関数のリターン処理において破壊されていないかどうかを確認する対象であるガード変数を格納したメモリ・パターンを有することを特徴としている。このような構成とすれば、リターンアドレスと共にプレヴィアス・フレームポインタをも保護することにより、スタックスマッシング攻撃を用いたシステムへの侵入を確実に阻止することができる。さらに、ガード変数を用いたスタック保護処理の対象を、ローカル変数を格納する領域に配列が格納されている場合に限定することにより、システム全体のオーバーヘッドを低減させることができる（例えば、特許文献１、又は比特許文献４を参照のこと）。
【００４３】
ＳＳＰでは、スタック上のローカル変数エリアと関数の戻りアドレスやフレーム・ポインタを格納するエリアの間にカナリア・コードと呼ぶ特別な値を配置する特別なコンパイラを使用する。スタック・オーバーフローは、スタック上のローカル変数をその範囲を超えて上書きすることで関数の戻りアドレスを変更するため、オーバーフローが発生するとカナリア・コードも書き換えられることになる。そこで、関数の戻り時にカナリア・コードの変更の有無をチェックすることで、スタック・オーバーフローの書き換えを検出することができる。
【００４４】
しかしながら、ＳＳＰは、スタック・オーバーフローが防止できるだけであり、その他のヒープ・オーバーフローなどによる戻りアドレスを書き換える侵入と、それから発生するデータ実行や間接実行を防止することはできない。
【００４５】
上述した他、例えばＯＡＫ言語のバイト・コードを命令がスタック上で扱う型を制約し、型毎に異なる命令を用意することで、バイト・コード実行前のベリファイアが仮想スタックを作成することを可能にし、仮想スタックの整合性を検査することで異なる型への操作、スタック・オーバーフローの防止を実行時に検査を行なうことなく実現する手法について提案されている（例えば、特許文献２を参照のこと）。すなわち、データ・タイプに関し制約を有する一連のバイト・コードを含むプログラムをメモリに格納する過程と、プログラムを実行する前にプログラム内のいずれかのバイト・コードの実行がそのバイト・コードに対するデータ・タイプの制約に違反することがないかどうか判定し、データ・タイプの制約に違反するものがある場合にはプログラム・フォールト信号を生成する過程と、前の過程でプログラム・フォールト信号が生成されなかった場合、プログラムの実行をイネーブルする過程と、プログラム・フォールト信号が生成された場合、プログラムの実行を禁止する過程を含んでいる。
【００４６】
この方法は、独自に命令セットを定義できるインタプリタでは有効であるが、既に多く利用されているプロセッサの命令セットでは利用できない。また、仮に利用できたとしても、スタック・オーバーフローが防止できるだけであり、その他のヒープ・オーバーフローなどによる侵入と、それから発生するデータ実行や間接実行を防止することはできない。
【００４７】
また、コンピュータ・システムの外部から入手したデータは直接実行できない形式に変換してからメモリに配置して、データ利用時には元の内容に逆変換してから利用する手法について提案されている（例えば、特許文献３を参照のこと）。すなわち、外部ソースからデータを受信し、データ中にコード化されているコンピュータ命令を実行不可能にする変換を、そのデータについて実施する。データを変換した後で、システムは、このデータをコンピュータ・システム中のメモリ中に記憶する。データが必要となったときに、システムはメモリからデータを取り出し、逆変換する。このようにして、外部ソースからのデータは、コンピュータ・システムが実行できない形態でメモリに記憶され、これにより、そのデータに組み込まれた悪意のあるコードを実行することができなくなる。
【００４８】
この方法では、データが利用されていないときには実行できない形式でメモリ中に置かれるために、データ実行を防止できる。しかしながら、データ参照中にプログラムのバグなどが存在するとデータ実行が可能となってしまう。多くのセキュリティ攻撃はプログラムのバグを利用したものであるため、プログラムが正しく記述されることを前提としたセキュリティ防止方法は現実的に効果がない。また、この手法は、プログラムが外部データをどこで扱うかについてＯＳに通知を行なうか、特定の方法で外部データを扱うようにプログラムを修正する必要がある。このような修正をすべてのプログラムに対して徹底して行なうことは困難であり、また、プログラムのすべての外部データを扱う部分を漏れなく特定の方法に書き換えることも困難である。さらに、この方法はデータ実行に対しては機能するものの、間接実行に関しては効果がない。
【００４９】
【特許文献１】特開２００１−２１６１６１号公報
【特許文献２】特開平８−２３４９９４号公報
【特許文献３】特開２０００−２２２２０２
【非特許文献１】ｈｔｔｐ：／／ｐａｇｅｅｘｅｃ．ｖｉｒｔｕａｌａｖｅ．ｎｅｔ／（２００３年５月現在）
【非特許文献２】ｈｔｔｐ：／／ｐｅｏｐｌｅ．ｒｅｄｈａｔ．ｃｏｍ／ｍｉｎｇｏ／ｅｘｅｃ−ｓｈｉｅｌｄ／，２００３年４月現在
【非特許文献３】ｈｔｔｐ：／／ｗｗｗｐａｇｅｅｘｅｃ．ｖｉｒｔｕａｌａｖｅ．ｎｅｔ／（２００３年５月現在）
【非特許文献４】ｈｔｔｐ：／／ｒｅｓｅａｒｃｈｅｂ．ｗａｔｓｏｎ．ｉｂｍ．ｃｏｍ／ｔｒｌ／ｐｒｏｊｅｃｔｓ／ｓｅｃｕｒｉｔｙ／ｓｓｐ／
【発明の開示】
【発明が解決しようとする課題】
【００５０】
本発明の目的は、プログラムの脆弱性などを悪用して挿入されたコードをシステムがデータ実行や間接実行しないようにすることができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することにある。
【００５１】
本発明のさらなる目的は、セグメント毎に実行可能か否かを管理するメモリの保護機能を利用して、プログラムのデータ・セクションに不正に置かれた命令の実行を好適に防止することができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することにある。
【００５２】
本発明のさらなる目的は、プロセッサがセグメントなどの粗い粒度のメモリ単位でしか実行権を設定できないようなシステム環境において、データ・セクションの完全な実行禁止セグメントへの配置機能と、データ・セクションと命令列セクションの自由度の高いランダム配置機能の両立を実現することができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することにある。
【課題を解決するための手段】
【００５３】
本発明は、上記課題を参酌してなされたものであり、その第１の側面は、メモリ空間上に配置して実行されるプログラムを処理する情報処理装置であって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
前記オフセット制約に拘わらず各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換手段と、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置手段と、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理手段と、
を具備することを特徴とする情報処理装置である。
【００５４】
ここで、前記プログラム変換手段は、プログラム・セグメント間で参照を行なうためのアダプタを生成して、オフセット制約のないプログラム・セグメントを再構成する。
【００５５】
前記アダプタは、参照元となるプログラム・セグメントからオフセット制約を持つ。したがって、前記プログラム配置手段は、参照元となるプログラム・セグメントから前記所定のオフセットの制約に従った位置に前記アダプタを配置するようにする。
【００５６】
また、前記プログラムは、実行可能な属性が付されたプログラム・セグメント（コード・プログラム・セクション）と、実行不能の属性が付されたプログラム・セグメント（データ・プログラム・セクション）などで構成されているが、前記メモリ管理手段は、実行可能な属性が付されたプログラム・セグメントを実行可能に、実行不能の属性が付されたプログラム・セグメントを実行不能にそれぞれ設定することで、データ実行を防止する。
【００５７】
そして、前記プログラム配置手段は、プログラム変換後の各プログラム・セグメントを、プログラムの起動毎に異なるランダムなアドレスに配置することができる。
【００５８】
前記プログラム変換手段は、プログラムのインストール時に前記のプログラムの変換処理を行なうようにしてもよい。あるいは、プログラムを起動する度に前記のプログラムの変換処理を行なうようにしてもよい。
【００５９】
本発明では、コンパイラ・システムが決定したプログラムのコード・プログラム・セグメントとデータ・プログラム・セグメント間のオフセット制約を、プログラム変換を行なうことで解除し、プログラムのコード・プログラム・セグメントのみをプロセスの実行可能なセグメントに配置し、データ・プログラム・セグメントはすべて実行禁止セグメントに配置するようにする。また、オフセット制約を解除することで、プログラム・セグメントのランダム配置の制約を除去し、自由なランダム配置を行なうことで、悪意あるコードやデータによるデータ実行と間接実行を併せて防止する。
【００６０】
また、本発明では、コード・プログラム・セグメント（実行と読み出し可能、書き込み不可、共有可能）とデータ・プログラム・セグメント（実行と読み出しと書き込み可能、共有不可）から構成されるプログラムを、コード・プログラム・セグメント（実行と読み出し可能、書き込み不可、共有可能）とデータ・プログラム・セグメント（読み出しと書き込み可能で、実行不可、共有不可）とアダプト・プログラム・セグメント（実行と読み出し可能、書き込み不可、共有不可）に再分類し、セクションを新規生成することで変換を行なう。
【００６１】
また、本発明の第２の側面は、メモリ空間上に配置して実行されるプログラムの処理をコンピュータ・システム上で実行するようにコンピュータ可読形式で記述されたコンピュータ・プログラムであって、
前記プログラムを構成する少なくとも２つのプログラム・セグメント間では前記メモリ空間上に配置したときの各アドレスに所定のオフセット制約があり、
前記オフセット制約に拘わらず各プログラム・セグメントを前記メモリ空間上に自由に配置できるようにプログラムを変換するプログラム変換ステップと、
変換処理後のプログラムを前記メモリ空間上に配置するプログラム配置ステップと、
配置されたプログラム・セグメントに応じてメモリ・セグメント毎に属性を設定するメモリ管理ステップと、
を具備することを特徴とするコンピュータ・プログラムである。
【００６２】
本発明の第２の側面に係るコンピュータ・プログラムは、コンピュータ・システム上で所定の処理を実現するようにコンピュータ可読形式で記述されたコンピュータ・プログラムを定義したものである。換言すれば、本発明の第２の側面に係るコンピュータ・プログラムをコンピュータ・システムにインストールすることによって、コンピュータ・システム上では協働的作用が発揮され、本発明の第１側面に係る情報処理と同様の作用効果を得ることができる。
【発明の効果】
【００６３】
本発明によれば、プログラムの脆弱性などを悪用して挿入されたコードをシステムがデータ実行や間接実行しないようにすることができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することができる。
【００６４】
また、本発明によれば、セグメント毎に実行可能か否かを管理するメモリの保護機能を利用して、プログラムのデータ・セクションに不正に置かれた命令の実行を好適に防止することができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することができる。
【００６５】
また、本発明によれば、プロセッサがセグメントなどの粗い粒度のメモリ単位でしか実行権を設定できないようなシステム環境において、データ・セクションの完全な実行禁止セグメントへの配置機能と、データ・セクションと命令列セクションの自由度の高いランダム配置機能の両立を実現することができる、優れた情報処理装置及び情報処理方法、並びにコンピュータ・プログラムを提供することができる。
【００６６】
本発明によれば、外部ソースからプログラム中に進入した悪意のあるコードをシステムがデータ実行してしまうことを完全に防止することができる。また、悪意あるコードがコンピュータ・システムに既に存在する命令列を不正に利用する間接実行も併せて防止することができる。
【００６７】
本発明のさらに他の目的、特徴や利点は、後述する本発明の実施形態や添付する図面に基づくより詳細な説明によって明らかになるであろう。
【発明を実施するための最良の形態】
【００６８】
本発明は、プログラムをメモリ空間上にロードして実行する情報処理装置に関するものである。ここで言う、情報処理装置は、メモリにロードされたプログラム・コードをプロセッサが実行するタイプの一般的なコンピュータ・システムである。ここで、プログラムは、データやコードなど複数のプログラム・セグメントで構成される。また、メモリ空間はセグメント単位で保護属性が設定される。
【００６９】
本発明では、外部からプログラムの脆弱性などを悪用して挿入されたコードをシステムがデータ実行や間接実行しないようにする効率的な方法を提供する。特に、プロセッサがセグメントなどの粗粒度のメモリ単位で実行権が設定できる機能を持つ場合に、データの完全な実行禁止セグメントへの配置機能とデータとテキストの自由度の高いランダム配置機能の両立を実現する方法を提供する。さらに、データ実行を禁止する際に、従来は問題となっていた、異なるセグメント間で仮想アドレスを同一にできる機能を必要とする点、プロセスのアドレス空間が半分に減少してしまう点を解決する。
【００７０】
また、本発明は、以下の点も満足することができる。１つは、コード共有可能とすることである。ＵＮＩＸ（登録商標）などの共有ライブラリ・システムでは、異なるプロセスが同じ共有ライブラリを使用する場合、共有ライブラリのコードは異なるプロセス間で共有される。これによって、使用メモリ量を削減できる。このコード共有が阻害されてはならない。２つ目は、コンパイラの改変を必要としないことである。一般に、コンパイラを修正すると、その影響はそれを利用して作成するすべてのアプリケーションに及ぶため、検証作業が大きな負担となる。また、１つの言語ですべてのアプリケーションを開発する訳ではないため、複数のコンパイラを修正する必要が生じる。また、同じプログラム言語に対して複数のコンパイラが存在することは一般的で、それらに対しても同様の修正を行なう必要があり、その検証作業は多岐にわたる。
【００７１】
以下、図面を参照しながら本発明の実施形態について詳解する。
【００７２】
システム構成：
図１には、本発明の一実施形態に係る情報処理装置の構成を模式的に示している。
【００７３】
このシステムは、プロセッサ１０を中心に構成されている。プロセッサ１０は、オペレーティング・システム（ＯＳ）が提供するプログラム実行環境下で、メモリに記憶されたプログラムに基づいて各種の処理を実行する。また、プロセッサ１０は、外部バス・インターフェース１４及びバス３０を介して接続されている各種の周辺機器を制御している。バス３０に接続された周辺機器は次のようなものである。本実施形態では、プロセッサ１０は、米アイ・ビー・エム社及び米インテル社のプロセッサＰｏｗｅｒＰＣ、あるいは同種のアーキテクチャを持つプロセッサ・チップで構成されているものとする。
【００７４】
メモリ２０は、例えばＤＲＡＭ（Ｄｙｎａｍｉｃ ＲＡＭ）などの半導体メモリで構成され、プロセッサ１０において実行されるプログラム・コードをロードしたり、実行プログラムの作業データを一時格納したりするために使用される。メモリ２０は、プロセッサ１０のメモリ空間を構成する。
【００７５】
ディスプレイ・コントローラ２１は、プロセッサ１０から送られてくる描画命令に従って表示画像を生成し、表示装置２２に送る。ディスプレイ・コントローラに接続された表示装置２２は、ディスプレイ・コントローラ２１から送られた表示画像情報に従い、その画像を画面に表示出力する。
【００７６】
入出力インターフェース２３は、キーボード２４やマウス２５が接続されており、キーボード２４やマウス２５からの入力信号をプロセッサ１０へ転送する。
【００７７】
ネットワーク・インターフェース２６は、ＬＡＮやインターネットなどの外部ネットワークに接続されており、インターネットを介したデータ通信を制御する。すなわち、プロセッサ１０から送られたデータをインターネット上の他の装置へ転送するとともに、インターネットを介して送られてきたデータを受け取りプロセッサ１０に渡す。例えば、プログラムやデータなどをネットワーク経由で外部から受信することができる。
【００７８】
ハード・ディスク装置（ＨＤＤ：Ｈａｒｄ Ｄｉｓｋ Ｄｒｉｖｅ）コントローラ２７には、ＨＤＤなどの大容量外部記憶装置２８が接続されており、ＨＤＤ コントローラ２７が接続されたＨＤＤ２８へのデータの入出力を制御する。ＨＤＤ２８には、プロセッサが実行すべきオペレーティング・システム（ＯＳ）のプログラム、アプリケーション・プログラム、ドライバ・プログラム、さらにはプログラムによって参照又は再生処理が行なわれるデータやコンテンツなどが格納されている。本実施形態では、各プログラムは、ＨＤＤ２８上に実行可能形式でインストールされる。
【００７９】
なお、パーソナル・コンピュータなどの情報処理装置を構成するためには、図１に示した以外にも多くの電気回路などが必要である。但し、これらは当業者には周知であり、また、本発明の要旨を構成するものではないので、本明細書中では省略している。また、図面の錯綜を回避するため、図中の各ハードウェア・ブロック間の接続も一部しか図示していない点を了承されたい。
【００８０】
図２には、情報処理システム上でプログラムをプロセスとして実行する際の仕組みを図解している。
【００８１】
同図において、ＯＳはＵＮＩＸ（登録商標）などのオペレーティング・システムであり、プロセスに実行環境やファイル・システム、システム・コールなどのサービスを提供している。
【００８２】
ＯＳ中のメモリ管理部は、プロセスのメモリを管理する部分である。メモリ管理部は、プロセスのアドレス空間をページ又はセグメントを単位としてメモリを管理し、プロセスへのメモリ割り当て要求や削除要求に従って、プロセッサのＭＭＵを制御して、メモリを割り当てる処理を行なう。また、メモリ割り当て要求時には、ＭＭＵを制御して、指定された読み込み、書き込み、実行の権限を設定するようになっている。これらの機能は、通常のオペレーティング・システムでの機能と同様であるが、実行権の設定をＰｏｗｅｒＰＣのセグメントに対して設定できる機能が追加されている。
【００８３】
また、ＯＳの中のランダム・アドレス決定部は、プロセスのアドレス空間を管理し、アドレス空間にマップするコード、データ、アダプト・プログラム・セグメント、ヒープ、スタックなどのアドレスを決定する機能を持つ。アドレス空間の決定は、未使用のアドレスの中からカーネルの乱数機能を利用してランダムに生成するようになっている。また、スタックやヒープのようにプロセスの実行に応じて大きさが変化する領域に関しては、プロセスに許されたリソース最大値を考慮して決定を行なうようになっている。
【００８４】
ランタイム・リンカは、プログラム・ファイルやライブラリをプロセスのアドレス空間にマップし、関数や変数などのアドレスを決定し正しく参照が行なえるようにする機能を持つ。ランタイム・リンカのリンク処理部は、通常のランタイム・リンカの機能を持つ。ユーザがプログラムの実行をＯＳに指示すると、ＯＳは、プロセスのアドレス空間を生成し、プログラムの実行情報をランタイム・リンカのリンク処理部に渡すようになっている。リンク処理部はＯＳから渡された実行情報を基に、プロセスを構成するプログラムやライブラリなどの複数のモジュールを特定し、それらをアドレス空間にマップし、関数や変数などのアドレスを決定し正しく参照が行なえるようにする。
【００８５】
本実施形態では、リンク処理部は、モジュールをアドレス空間へマップするときに、ＯＳのランダム・アドレス決定部の決定したアドレスを使用するようになっている。
【００８６】
リンク処理部のアドレス解決関数は、関数や変数などのシンボルのアドレスを計算する関数である。アドレス解決関数は、リンク処理部が上述したプロセスの初期化を行なうときに使用される他、後述するようにｌａｚｙ ｂｉｎｄ（プログラム実行時のオンデマンドのアドレス解決）のときにも使用される。
【００８７】
ランタイム・リンカのプログラム・セグメント変換部は、本発明を実現するための中心となる機能を実現する。すなわち、モジュールのコード・プログラム・セグメントとデータ・プログラム・セグメント間のオフセット制約を解除する変換をプログラム・セグメントに対して行ない、さらにアダプト・プログラム・セグメントを生成する。プログラム・セグメント変換部の詳細については後述に譲る。
【００８８】
プロセスは、プログラムの実行形態である。１つのプログラムは複数のモジュールで構成される。プロセスは、アプリケーション・プログラム、共有ライブラリ、コンポーネントなどのモジュールで構成される。アプリケーション・プログラムは、ＯＳがリンク処理部に渡す実行情報に記述されている。ライブラリは、アプリケーション・プログラムのファイル中にプログラムが依存するモジュールとして記述されている。コンポーネントは、プログラム・ファイル中に記述されてはいないが、プログラムが明示的にＡＰＩ（Ａｐｐｌｉｃａｔｉｏｎ  Ｐｒｏｇｒａｍｍｉｎｇ  Ｉｎｔｅｒｆａｃｅ）を呼び出すなどで、プロセス内にロードを要求する。例えば、ＵＮＩＸ（登録商標）では“ｄｌｏｐｅｎ”のような外部関数へのインターフェースを用いてプログラムがコンポーネントを要求することができる。本実施形態では、プログラム、ライブラリ、コンポーネントの区別は重要ではなく、以下ではすべて同じものとして扱う。
【００８９】
プログラム構成：
図３には、プロセスを構成するモジュールのファイル構成を模式的に示している。
【００９０】
本実施形態では、ＰｏｗｅｒＰＣ のプログラムはｅｘｅ形式ではなくｄｙｎａｍｉｃ 形式を使用するようになっている。ｄｙｎａｍｉｃ形式は、通常は共有ライブラリで使用する形式で、ランタイム・リンカにより動的にアドレスを決定できる情報を保持しているが、本実施形態ではアプリケーション・プログラムもこの形式を使用する。また、ｄｙｎａｍｉｃ形式のコードにはさらにＰＩＣと ｎｏｎＰＩＣが存在するが、本実施形態ではすべてのモジュールがＰＩＣである場合について説明する。ここで、ＰＩＣとは、“Ｐｏｓｉｔｉｏｎ Ｉｎｄｅｐｅｎｄｅｎｔ Ｃｏｄｅ”のことで、変数や関数のアドレスをコンパイラ・システムが静的に決定したアドレスで行なうのではなく、実行時に動的に決定したアドレスを使用するようにコンパイラ・システムがコード生成と必要な情報を定義した形式のことである。
【００９１】
なお、図３では、説明の簡略化のため、すべてのプログラムのセクションやヘッダ情報は示していない。実際のプログラムの構成では、図で示した以外にも多くのセクションやヘッダから構成される。この構成はＰｏｗｅｒＰＣのコンパイラ・システムで生成される形式そのものであり、本実施形態ではコンパイラ・システムの生成したプログラム・フォーマットをそのまま利用する。
【００９２】
「．ｔｅｘｔ」セクションは、関数などのプログラムの命令列を保持する。また、「．ｄａｔａ」セクションは、プログラムのグローバル変数やファイル・スコープの変数を保持する。また、「．ｇｏｔ」はＰＩＣコードが変数や関数ポインタのアドレスを得るときに参照するテーブルである。
【００９３】
セクション・ヘッダ（Ｓｅｃｔｉｏｎ ｈｅａｄｅｒ）は、プログラムを構成する各セクションに関する情報を保持する。セクション・ヘッダの各エントリが保持する情報は、対応するセクションのサイズ、プログラム・ファイル内でのオフセットといた情報である。図３に示す例では、プログラム・ファイル中に含まれる「．ｔｅｘｔ」セクションと「．ｄａｔａ」セクション、「．ｇｏｔ」セクション以外に、プログラム・ファイル中には含まれない「．ｐｌｔ」（ｐｒｏｃｅｄｕｒｅ  ｌｉｎｋａｇｅ  ｔａｂｌｅ）セクションの情報がプログラム・ヘッダ（Ｐｒｏｇｒａｍ ｈｅａｄｅｒ）に保持されている。このセクションは、プログラム・ファイル中にはなく、プロセス生成時にランタイム・リンカによって動的に生成される。
【００９４】
プログラム・ヘッダには、プログラムをプロセスのアドレス空間にマップするときに利用する情報が保持されている。同ヘッダ内の各エントリが保持する情報は、プログラム・セグメントのファイル上でのサイズとメモリにマップしたときのサイズ、マップするアドレス、メモリのアクセス権などである。ここで指定されるアドレスは、ｄｙｎａｍｉｃ形式の場合は必ずそのアドレスにマップしなければならないという意味ではない。しかし、コード・プログラム・セグメントとデータ・プログラム・セグメント間のアドレスの差（すなわちオフセット）はここに記述された値の差と同じである必要がある。これが、オフセット制約を発生させている。
【００９５】
図３に示した例では、２つのプログラム・セグメントが定義されている。プログラム・セグメントは１つ以上のセクションから構成される。図３に示す例では、コード・プログラム・セグメントは「．ｔｅｘｔ」セクションから構成され、データ・プログラム・セグメントは「．ｄａｔａ」、「．ｐｌｔ」、「．ｇｏｔ」の３つのセクションから構成される。
【００９６】
プログラム・セグメント変換：
次に、本実施形態に係るランタイム・リンカのプログラム・セグメント変換部が行なう処理について説明する。
【００９７】
プログラム・セグメント変換部は、コード・プログラム・セグメントとデータ・プログラム・セグメントの２つを、コード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントという３つのプログラム・セグメントに再分類する変換機能を持つ。
【００９８】
図４には、本実施形態に係るプログラム・セグメントの変換の仕組みを模式的に示している。
【００９９】
従来のプログラム・セグメント構成では、コンパイラ・システムが決定したプログラムのオフセット制約により、コード・プログラム・セグメントとデータ・プログラム・セグメントのオフセット（ａ）を変更してメモリ空間に配置することはできない。
【０１００】
データ・プログラム・セグメントは、「．ｄａｔａ」、「．ｐｌｔ」、「．ｇｏｔ」の３つのセクションが一体として構成されている。このうち、プログラムのグローバル変数やファイル・スコープの変数を保持する「．ｄａｔａ」セクションは、プログラムの命令列である「．ｔｅｘｔ」セクションからのオフセットは固定的でない。これに対し、ＰＩＣである命令列が変数や関数ポインタのアドレスを得るための参照テーブルである「．ｇｏｔ」セクションや「．ｐｌｔ」セクションは、「．ｔｅｘｔ」セクションからのオフセットは固定的である。結果として、「．ｇｏｔ」セクションや「．ｐｌｔ」セクションと一体である「．ｄａｔａ」セクションは、オフセット制約を受けることになる。
【０１０１】
これに対し、本実施形態では、プログラム・セグメントの変換後は、プログラムは、前述したように、コード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントというという３つのプログラム・セグメントにより構成される。
【０１０２】
ここで、コード・プログラム・セグメントとアダプト・プログラム・セグメントのオフセット（ｂ）は（ａ）と同じオフセット制約に従う必要がある（オフセット（ａ）＝（ｂ））。一方、プログラム変換により「．ｄａｔａ」セクションが「．ｇｏｔ」セクションや「．ｐｌｔ」セクションから切り離されることにより、コード・プログラム・セグメントとデータ・プログラム・セグメントのオフセット（ｃ）は、任意のオフセットを取ることができ、ランダムなアドレスを決定することができるようになる。この結果、データとコードの自由度の高いランダム配置が可能となる。
【０１０３】
オフセット（ｂ）（＝（ａ））は、コンパイラがプログラム・ヘッダ内の記述に従って決定する。これに対し、オフセット（ｃ）は、メモリ・ロード時にＯＳが動的に決定する。あるいは、コンパイル以降にオフセット（ｃ）を生成しておくようにしてもよい。
【０１０４】
そして、コード・プログラム・セグメントのアクセス権は読み出しと実行が可能で書き込みは禁止となり、また共有は可能となる。また、データ・プログラム・セグメントのアクセス権は読み出しと書き込みが可能で実行が禁止になり、共有は不可となる。また、アダプト・プログラム・セグメントのアクセス権は、コード・プログラム・セグメントのアクセス権と同様に、実行と読み出し可能で書き込み不可であるが、プロセス間での共有が不可な点が異なる。
【０１０５】
以下、プログラム・セグメントの変換処理の詳細について説明する。
【０１０６】
ＰＬＴセクション：
既に説明したように、データ・プログラム・セグメントはＤａｔａ、ＰＬＴ、ＧＯＴの各セクションから構成される。プログラム・セグメント変換部では、ＰＬＴとＧＯＴをアダプト・プログラム・セグメントとして構成する。ここでは、ＰＬＴセクションの処理について説明する。
【０１０７】
ＰＬＴセクションは、関数呼び出しのＰＩＣを実現する機能を持つ。ＰＩＣでは、呼び出す関数の実際のアドレスはプロセス生成時まで分からない。そこで、コンパイラ・システムは、関数呼び出しをＰＬＴのエントリを呼び出す命令として生成する。ＰＬＴのエントリの呼び出しは、相対アドレッシングの関数呼び出し命令を使用する。このため、コード・プログラム・セグメントの絶対アドレスをコンパイル時に決定する必要がなくなるものの、コード・プログラム・セグメントとＰＬＴセクションの入っているデータ・プログラム・セグメント間のオフセットはコンパイル時に決定された値となっている必要がある。
【０１０８】
従来は、データ・プログラム・セグメント内にＰＬＴセクションが入っていたことから、コード・プログラム・セグメントに対するＰＬＴセクションのオフセットがすなわちデータ・セクションに対するオフセット制約となっていた。
【０１０９】
これに対し、本実施形態では、ランタイム・リンカが、プロセスの初期化時に、ＰＬＴセクションをアダプト・プログラム・セグメント内に生成する。ＰＬＴセクションはＰＬＴエントリのテーブルで構成される。各ＰＬＴエントリは関数と１対１に対応する２命令が入っている。ＰＩＣの関数呼び出しは、ＰＬＴエントリの実行を経由して、対応する関数を呼び出すようになっている。
【０１１０】
図５には、本実施形態に係るＰＬＴエントリの構成を模式的に示している。同図において、ｉは関数を識別する番号である。図中のＰＬＴエントリを実行することにより、関数の識別番号を４倍した値をｒ１１レジスタに設定して、ＰＬＴｒｅｓｏｌｖｅ（ＰＬＴ解決）に実行を遷移するようになっている。
【０１１１】
図６には、本実施形態に係るＰＬＴｒｅｓｏｌｖｅの構成を模式的に示している。図示のＰＬＴｒｅｓｏｌｖｅでは、ＧＯＴ２のアドレスにｒ１１レジスタの値を足したアドレスの値を取り出し、そこにジャンプするようになっている。ｒ１１レジスタには、ＰＬＴ エントリの命令の実行により、関数の識別番号を４倍した値が代入されている。４倍した値になっているのは、ＧＯＴ２のエントリが４バイトであるためであり、結局ＰＬＴｒｅｓｏｌｖｅはＧＯＴ２のい番目のエントリの値を取ってきて、その値をアドレスとしてジャンプすることになる。このとき、ｒ１１レジスタには、関数の識別番号を４倍した値が代入されたままとなる。また、ＧＯＴ２の０番目のエントリの値をｒ１２レジスタに設定してジャンプを行なう。本実施形態では、ＧＯＴ２の０番目のエントリにはモジュール識別番号が格納されている。本実施形態では、ＰＬＴｒｅｓｏｌｖｅはＰＬＴセクションの先頭に配置される。
【０１１２】
このようにすることで、ＰＬＴセクションの内容をプロセス初期化時にすべて確定させることができるため、ＰＬＴセクションを書き込み不可であるアダプト・プログラム・セグメントに入れることが可能となる。そして、ＰＬＴセクションがデータ・プログラム・セグメントから切り離される結果、データ・プログラム・セグメントは、コード・プログラム・セグメントによるオフセット制約から解放される。
【０１１３】
ＰＬＴセクションをコード・プログラム・セグメントに入れることができない理由は、ＰＬＴの内容がプロセス毎に変化し、異なるプロセス間で共有ができないためである。具体的には、ＧＯＴ２（後述）のアドレスを本実施形態では毎回異なるアドレスに配置するため、ＰＬＴの内容が毎回変化することになる。また、本実施形態のように毎回異なるアドレスに配置しない場合でも、実行可能や実行不可の設定を確実に行なうためには、異なるプロセスで同じ相対位置にＧＯＴ２を置ける保証がないため、共有はできない。
【０１１４】
なお、ｌａｚｙ ｂｉｎｄを使用しない設定の場合、ランタイム・リンカは、アプリケーションの実行開始前にすべての関数呼び出しについてアドレス解決を行なう。このため、本実施形態ではｌａｚｙ ｂｉｎｄを使用しない設定の場合にＧＯＴ２は生成されないようになっている。関数呼び出しで使用するアドレスは、ＧＯＴのエリアを拡張して、そこに保存する。そして、図６に示したＰＬＴｒｅｓｏｌｖｅは、ＧＯＴ２の代わりにＧＯＴの拡張したエリアを参照する命令として生成されるようになっている。
【０１１５】
ＧＯＴセクション：
次に、アダプト・プログラム・セグメントを構成するもう１つのセクションであるＧＯＴセクションの処理について説明する。
【０１１６】
ＧＯＴセクションは、変数のアドレスと関数ポインタを使用したコードのＰＩＣを実現する機能を持つ。ＰＩＣではプログラムが参照する変数のアドレスや関数ポインタの値はプロセス生成時まで分からない。そこで、コンパイラ・システムは、変数や関数ポインタの参照をＧＯＴに格納されたアドレスを使う命令として生成する。ＧＯＴのアドレスは関数のプロローグで、実際に関数が置かれたアドレスに定数のオフセットを加算することで計算を行なうようになっている。このため、変数のアドレスや関数ポインタの値をコンパイル時に決定する必要はなくなるものの、コード・プログラム・セグメントとＧＯＴセクションの入っているデータ・プログラム・セグメント間のオフセットはコンパイル時に決定された値となっている必要がある。
【０１１７】
従来は、データ・プログラム・セグメント内にＧＯＴセクションが入っていることから、コード・プログラム・セグメントに対するＧＯＴセクションのオフセットがすなわちデータ・プログラム・セグメントに対するオフセット制約が発生となっていた。
【０１１８】
これに対し、本実施形態では、ランタイム・リンカが、プロセスの初期化時に、ＧＯＴセクションをアダプト・プログラム・セグメント内に生成する。ＧＯＴセクションの各エントリが対応する変数や関数のアドレスを保持するようになっている。これらのアドレスは、関数のアドレス解決をｌａｚｙ ｂｉｎｄする設定 （関数呼び出し時にオンデマンドで関数のアドレスを計算する設定） であってもすべてプロセスの初期化時に決定する必要がある。このため、本実施形態ではＧＯＴセクションの内容をプロセス初期化時にすべて確定させ、ＧＯＴセクションを書き込み不可であるアダプト・プログラム・セグメントに入れるようになっている。そして、ＧＯＴセクションがデータ・プログラム・セグメントから切り離される結果、データ・プログラム・セグメントは、コード・プログラム・セグメントによるオフセット制約から解放される。
【０１１９】
ＧＯＴセクションをコード・プログラム・セグメントに入れることができない理由は、ＧＯＴの内容はプログラム毎あるいはプロセスの起動毎に異なり共有できないためである。
【０１２０】
図７には、本実施形態において、プログラムが変数のアドレスや関数ポインタの値を参照する仕組みを図解している。図示のように、コード・プログラム・セグメント内のあるエントリのコードを実行時に、変数のアドレスや関数ポインタの値を参照する場合、所定のオフセットで配置されているアダプト・プログラム・セグメント内で、該当するＧＯＴエントリを参照し、そこに保持されている変数や関数のアドレスを獲得することができる。図示の通り、コードとＧＯＴセクションの間にはオフセット制約があるが、ＧＯＴセクションとデータ・セクションの間にはオフセット制約はない。
【０１２１】
コンパイラ・システムが決定したコード・プログラム・セグメントとデータ・プログラム・セグメント間のオフセット制約を、プログラム変換を行なうことで解除し、プログラムのコード・プログラム・セグメントのみをプロセスの実行可能なセグメントに配置し、データ・プログラム・セグメントはすべて実行禁止セグメントに配置することができる。
【０１２２】
ＧＯＴ２セクション：
図４に示したように、データ・プログラム・セグメントには、新たにＧＯＴ２セクションが、プログラム・セグメント変換部により生成される。以下、ＧＯＴ２セクションの処理について説明する。
【０１２３】
ＧＯＴ２セクションは、ＰＬＴの各エントリが参照する関数のアドレスが格納されるテーブルである。ＧＯＴ２の０番目を除くすべてのエントリの値は、プロセスの初期化時に、ランタイム・リンカによって、ランタイム・リンカのアドレス解決関数のアドレスに設定される。０番目のエントリはこのモジュールの識別番号で初期化される。
【０１２４】
図８には、本実施形態において、プログラムが関数を呼び出す仕組みを図解している。上述したように、ＰＬＴエントリの実行を経由して、対応する関数を呼び出すことができる。コード・プログラム・セグメント内のあるエントリのコードを実行時に、ある関数を始めて呼び出すと、所定のオフセットで配置されているアダプト・プログラム・セグメント内で、ＰＬＴエントリとＰＬＴｒｅｓｏｌｖｅを実行することにより、関数に対応するＧＯＴ２エントリのアドレスに実行が遷移する。図示の通り、コードとＰＬＴセクションの間にはオフセット制約があるが、ＰＬＴセクションとＧＯＴ２セクションの間にはオフセット制約はない。
【０１２５】
ＧＯＴ２エントリはランタイム・リンカのアドレス解決関数のアドレスに設定されているため、アドレス解決関数が実行されることになる。アドレス解決関数は、ｒ１２レジスタで指定されたモジュールのｒ１１レジスタで指定された関数のアドレスを計算した後、そのアドレスをＧＯＴ２の対応するエントリに書き込む。このため、同じ関数を２回目以降呼び出した場合には、アドレス解決関数に実行が遷移することなく、目的の関数を呼び出すことができるようになっている。
【０１２６】
ＧＯＴ２はプログラムの実行中に書き込みが行なわれるため、データ・プログラム・セグメント中に配置され、書き込み可能に設定される。
【０１２７】
なお、本実施例ではｌａｚｙ ｂｉｎｄを使用しない設定の場合はＧＯＴ２は生成されず、ＰＬＴエントリはプロセスの初期化時に決定した関数へのジャンプ命令ですべて埋められる。
【０１２８】
オフセット制約を解除することで、プログラム・セグメントのランダム配置の制約を除去し、自由なランダム配置を行なうことで、悪意あるコードやデータによるデータ実行と間接実行を防止することができる。
【０１２９】
プログラム・セクションのマップ：
次に、本実施形態におけるプログラム・セグメントのマップ処理について説明する。このマップ処理は、ランタイム・リンカのリンク処理部とＯＳのメモリ管理部により行なわれる。
【０１３０】
本実施形態では、ランタイム・リンカのプログラム・セグメント変換部によって、プログラムは、コード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントという３つのプログラム・セグメントから構成されるように変換される。既に説明したように、コード・プログラム・セグメントの保護属性は、アクセス権は読み出しと実行が可能で書き込みは禁止で、共有は可能となる。また、データ・プログラム・セグメントの保護属性は、アクセス権は読み出しと書き込みが可能で実行が禁止になり、共有は不可となる。また、アダプト・プログラム・セグメントの保護属性は、アクセス権は実行と読み出し可能で書き込み不可であるが、プロセス間での共有が不可となる。
【０１３１】
これらのプログラム・セグメントをアドレス空間にマップするとき、ＯＳのメモリ管理部はプロセッサ（本実施形態ではＰｏｗｅｒＰＣとする）のページとセグメントを併用して、プログラム・セグメントのアクセス権を実現するようになっている。ＰｏｗｅｒＰＣプロセッサでは、読み出しと書き込みの権限はページ単位で指定が可能であるが、実行の権限はセグメント単位で指定することになる。そこで、コード・プログラム・セグメントとアダプト・プログラム・セグメントの保護属性は、読み出し可能に設定されたページを実行可能に設定したセグメント内に配置することで実現する。一方、データ・プログラム・セグメントの保護属性は、読み出しと書き込み可能に設定されたページを実行不可に設定したセグメント内に配置することで実現する。
【０１３２】
プロセス間での共有の可否はＰｏｗｅｒＰＣプロセッサではなくＯＳのメモリ管理部が管理するページの管理情報に設定される。メモリ管理部は、新規にプロセスのモジュールをマップする際に、そのページが参照するファイルと同じファイルが既に別のプロセスでマップされている場合、そのデータを共用する。具体的には、ページに対応する物理メモリを共有する。これによって、同じデータを保存するために余分な物理メモリを消費することを回避できる。コード・プログラム・セグメントを構成するページはメモリ管理部が管理するページの管理情報にすべて共有可能で設定され、データ・プログラム・セグメント並びにアダプト・プログラム・セグメントを構成するページは共有不可に設定される。
【０１３３】
ランタイム・リンカのリンク処理部は、プログラム・セグメントのマップを、システム・コールを利用してＯＳに要求するようになっている。
【０１３４】
ランタイム・リンカの処理手順：
次に、ランタイム・リンカの処理手順について説明する。ランタイム・リンカの処理として、プロセス初期化時の処理と、プロセス実行時のＰＬＴエントリ呼び出し時の処理の２つに分けられる。
【０１３５】
プロセス初期化時の処理：
図９には、プロセス初期化時に行なわれる処理手順をフローチャートの形式で示している。
【０１３６】
プログラムの実行がユーザから要求されると、ＯＳはプロセスのアドレス空間を生成し、プログラムの実行情報をランタイム・リンカのリンク処理部に渡す。プログラムの実行情報には、プログラム・ファイルやアドレス空間等の情報が入っている。プログラム・ファイルには、そのプログラムが使用するライブラリが記述されているため、ランタイム・リンカはライブラリを順番にプロセスのアドレス空間にマップすることができる。
【０１３７】
ランタイム・リンカは、ＯＳからプログラムの実行情報を受け取ると（ステップＳ１）、プログラム本体を構成するプログラム・セグメントのアドレスをＯＳのランダム・アドレス決定部により決定する（ステップＳ２）。ランダム・アドレス決定部へのサービスの要求はシステム・コールにより行なう。
【０１３８】
アドレスを決定する際には、コード、データ、アダプトの各プログラム・セグメントのサイズが必要になる。このため、ランタイム・リンカのプログラム・セグメント変換部は、変換の結果生成される、これらプログラム・セグメントのサイズをそれぞれ計算し、リンク処理部を経由してランダム・アドレス決定部にサイズを通知する。また、プログラム本体の場合には、コード・プログラム・セグメントやデータ・プログラム・セグメントに加えて、ヒープとスタックのアドレスもランダム・アドレス決定部を使用して決定される。
【０１３９】
ここで、ランタイム・リンカは、各プログラム・セグメントをマッピングするための領域をメモリ空間上に割り当てるよう、ＯＳに要求する。ＯＳ内では、メモリ管理部でセグメント毎の実行可能／実行不可という属性を管理している。ランタイム・リンカからのメモリ要求の割り当て要求に対し、ランダム・アドレス決定部は、メモリ空間上の保護属性が合致するセグメント内で、各プログラム・セグメントのアドレスを決定する。
【０１４０】
次に、ラインタイム・リンカのプログラム・セグメント変換部は、上述した方法で、モジュールのコード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントを生成する（ステップＳ３）。
【０１４１】
アダプト・プログラム・セグメントはプログラム・セグメント変換部の作成したＰＬＴセクションとＧＯＴセクションで構成される（前述）。ＰｏｗｅｒＰＣプロセッサの場合、ここでＰＬＴが生成される。
【０１４２】
また、ｌａｚｙ ｂｉｎｄ の設定であれば、データ・プログラム・セグメントは、ＧＯＴ２とデータ・セクションにより構成されるので、ＧＯＴ２を生成する。ＧＯＴ２の内容は、ランタイム・リンカのアドレス解決関数のアドレスで０番目を除くすべてのエントリが初期化される。０番目のエントリはこのモジュールの識別番号で初期化される。また、ＰＬＴはＧＯＴ２のエントリを参照する命令で生成される。一方、ｌａｚｙ ｂｉｎｄの設定でない場合には、データ・プログラム・セグメントはデータ・セクションにより構成されるので、ＧＯＴ２は生成されない。
【０１４３】
以上の処理が、プロセスを構成するすべてのモジュールに対して行なわれると（ステップＳ４）、続いてリンク処理が行なわれる（ステップＳ５）。
【０１４４】
ランタイム・リンカのリンク処理部は、ランダム・アドレス決定部により決定されたプログラム・セグメントのアドレスに基づいて関数や変数などのシンボルのアドレスを計算することができる。各モジュールのＧＯＴが持つ変数や関数ポインタのアドレスはこのリンク処理ステップで計算され、シンボルの対応するＧＯＴエントリに格納される。ｌａｚｙ ｂｉｎｄの設定でない場合には、ＰＬＴ エントリをＰＬＴｒｅｓｏｌｖｅへのジャンプ命令ではなく、対応する関数へのジャンプ命令となる。このため、ＰＬＴエントリの命令が直接参照する関数のアドレスもこのリンク処理ステップで計算される。
【０１４５】
すべてのリンク処理が終了すると、プログラム・セグメントのメモリ・アクセス権を指定されたアクセス権に設定して、プログラムの実行を開始させる（ステップＳ６）。
【０１４６】
ＰＬＴエントリ呼び出し時の処理：
ｌａｚｙ ｂｉｎｄの設定である場合、関数呼び出しの対象となる関数のアドレス解決はプロセスの初期化時には行なわれずに、実際に関数呼び出しが発生した段階まで遅延される。図１０には、ある関数がプロセス実行開始後に初めて呼び出されたときの処理手順をフローチャートの形式で示している
【０１４７】
関数呼び出しは（ステップＳ１１）、関数に対応するＰＬＴエントリを呼び出しにより行なわれる（前述）。本実施形態では、ＰＬＴエントリはアダプト・プログラム・セグメントにあり、その位置はコード・プログラム・セグメントとのオフセット制約を維持しているので（図４を参照のこと）、コンパイラ・システムが生成した命令列を変更することなく、ＰＬＴエントリへ正しく実行が遷移する（ステップＳ１２）。
【０１４８】
ＰＬＴエントリはＰＬＴｒｅｓｏｌｖｅをさらに実行することで、ＧＯＴ２の対応するエントリに格納されたアドレスに実行が遷移する。ＧＯＴ２のエントリは、ランタイム・リンカによるプロセスの初期化でランタイム・リンカのリンク処理部にあるアドレス解決関数のアドレスが格納されている。このため、ＧＯＴ２エントリが解決済みでない（ステップＳ１３）、すなわち１回目の関数呼び出しの実行はアドレス解決関数へ遷移する。
【０１４９】
アドレス解決関数は、ｒ１１レジスタで指定されたシンボル識別番号（４倍された値になっている）とｒ１２レジスタで指定されたモジュール識別番号を使用して関数を特定し、その関数のこのプロセスでのアドレスを計算する（ステップＳ１４）。
【０１５０】
アドレス解決関数は、計算したアドレスをＧＯＴ２のエントリに格納する（ステップＳ１５）。最後に、計算したアドレス、つまり呼び出した関数の実行を再開する（ステップＳ１６）。
【０１５１】
２回目以降の同じ関数の呼び出しでは、アドレス解決関数によりＧＯＴ２エントリが解決されているので（ステップＳ１３）、アドレス解決関数に実行が遷移することなく、直接関数呼び出しが行なわれる。
【０１５２】
ｘ８６系プロセッサにおける実装例：
これまでは、ＰｏｗｅｒＰＣプロセッサを用いたシステムにおける本発明の適用例について説明してきたので、続いてｘ８６系プロセッサにおける実装例について説明する。
【０１５３】
システム構成：
ｘ８６系プロセッサのシステム構成は、ＰｏｗｅｒＰＣの場合と同様に、図２に示したとおりである。但し、ＯＳのメモリ管理部は、ＰｏｗｅｒＰＣのセグメントではなく、ｘ８６のセグメントを制御する機能が追加されている。
【０１５４】
プログラム構成：
図１１には、プロセスを構成するモジュールのファイル構成を模式的に示している。同図は、図２における１つのモジュールを構成するファイルの構造に相当する。
【０１５５】
この場合のプログラムも、ＰｏｗｅｒＰＣの場合（図３を参照のこと）と同様に、ｄｙｎａｍｉｃ形式でＰＩＣを使用するようになっている。図示の構成は、ｘ８６のコンパイラ・システムで生成される形式そのものであり、本実施形態ではコンパイラ・システムの生成したプログラム・フォーマットをそのまま利用する。
【０１５６】
ファイルの基本的な構成はＰｏｗｅｒＰＣと同様であるので説明は省略する。コード・プログラム・セグメントとデータ・プログラム・セグメントにオフセット制約が存在する点も同様である。但し、ＰｏｗｅｒＰＣの場合と異なり、ｘ８６ではファイル中に「．ｐｌｔ」セクションがコンパイラ・システムによって生成されている。コンパイル・システムにより生成されるコード・プログラム・セグメントは「．ｔｅｘｔ」と「．ｐｌｔセクション」の２つのセクションから構成され、また、データ・プログラム・セグメントは「．ｄａｔａ」と「．ｇｏｔ」の２つのセクションから構成される。
【０１５７】
プログラム・セグメント変換：
次に、本実施形態に係るランタイム・リンカのプログラム・セグメント変換部が行なう処理について説明する。プログラム・セグメント変換部は、コード・プログラム・セグメントとデータ・プログラム・セグメントの２つを、コード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントの３つのプログラム・セグメントに変換機能を持つ。本実施形態によるプログラム・セグメントの変換は、基本的には図４に示したＰｏｗｅｒＰＣプロセッサによる場合と同様である。以下、ｘ８６プロセッサにおける変換について詳細を説明する。
【０１５８】
ＰＬＴセクション：
既に述べたように、ＰＬＴセクションは、コード・プログラム・セグメントの一部としてコンパイラ・システムにより生成されている。本実施形態に係る手法では、コンパイラ・システムの生成したＰＬＴセクションを使用する代わりに、プログラム・セグメント変換部が生成したＰＬＴセクションを使用するようになっている。
【０１５９】
ＰＬＴセクションは、ＰＬＴエントリのテーブルで構成され、各ＰＬＴエントリは関数と１対１に対応する最大１６バイトの命令が入っている（同上）。ＰＩＣの関数呼び出しは、ＰＬＴエントリの実行を経由して、対応する関数を呼び出すようになっている。
【０１６０】
図１２には、本実施形態に係るＰＬＴエントリの構成例を示している。ここで、ｉは関数を識別する番号であり、ｉ_ＧＯＴ２はＧＯＴ２セクションのｉ番目のエントリのアドレスである。図示のＰＬＴエントリを実行することにより、関数の識別番号に対応したＧＯＴ２エントリが持つアドレスに実行が遷移する。
【０１６１】
ＧＯＴ２は、後述するように、プロセスの初期化時には、対応するＰＬＴエントリの次の命令のアドレスが格納されている。このため、ＰＬＴエントリの１番目の命令は事実上何も行なわずに、次の命令が実行されることになる。２番目の命令と３番目の命令では、関数識別番号ｉをスタックにプッシュして、ＰＬＴの０番目のエントリにジャンプする。
【０１６２】
図１３には、本実施形態に係るＰＬＴテーブルの０番目のエントリを示している。ＰＬＴの０番目のエントリは、特殊なエントリで対応する関数はなく、これ以外のＰＬＴエントリから実行される共通のコードが格納されている。ＰＬＴの０番目のエントリでは、ＧＯＴ２のアドレスをスタックにプッシュし、ＧＯＴ２の１番目のエントリに格納されているアドレスに実行を遷移させる。
【０１６３】
本実施形態では、ＧＯＴ２の０番目と１番目のエントリは特別なエントリで、０番目のエントリはモジュール識別番号が格納されており、１番目のエントリはランタイム・リンカのアドレス解決関数のアドレスが格納されている。このため、関数に対応するＰＬＴのエントリとさらに０番目のエントリを実行することで、アドレス解決関数に実行が遷移する。このとき、スタックにはシンボルの識別番号ｉと、モジュールの識別番号が格納されているアドレスが格納されている。アドレス解決関数はこれらの情報からシンボルのアドレスを計算する。
【０１６４】
このようにすることで、ＰＬＴセクションの内容をプロセス初期化時にすべて確定させることができるので、ＰＬＴセクションを書き込み不可であるアダプト・プログラム・セグメントに入れることが可能となる。一方、ＰＬＴセクションをコード・プログラム・セグメントに入れることができない理由は、ＰＬＴの内容がプロセス毎に変化するので、異なるプロセス間で共有ができないからである。具体的には、ＧＯＴ２のアドレスを本実施形態では毎回異なるアドレスに配置するため、ＰＬＴの内容が毎回変化することになる。また、本実施形態のように毎回異なるアドレスに配置しない場合でも、実行可能や実行不可の設定を確実に行なうためには異なるプロセスで同じ相対位置にＧＯＴ２を置ける保証がないため、共有はできない。
【０１６５】
ＧＯＴセクション：
次に、アダプト・プログラム・セグメントを構成するもう１つのセクションであるＧＯＴセクションの処理について説明する。
【０１６６】
本実施形態では、ランタイム・リンカがプロセスの初期化時にＧＯＴセクションをアダプト・プログラム・セグメント内に生成する。ＧＯＴセクションは１エントリが対応する変数や関数のアドレスを保持するようになっている（同上）。
【０１６７】
従来のＧＯＴセクションは、アドレスは関数呼び出しで使用するアドレスも保持していた。このため、ｌａｚｙ ｂｉｎｄの設定時にはこれらのアドレスがプロセス初期化時には未定であるため、ＧＯＴセクションを書き込み不可のプログラム・セグメントに入れることはできなかった。
【０１６８】
これに対し、本発明では、ＧＯＴセクションは変数のアドレスと関数ポインタの値のみを保持する。そして、関数呼び出しに使用するエントリはすべてＧＯＴ２セクションを使用するように変換される。このため、ＧＯＴセクションの内容をプロセス初期化時にすべて確定させ、ＧＯＴセクションを書き込み不可であるアダプト・プログラム・セグメントに入れることができる。一方、ＧＯＴセクションをコード・プログラム・セグメントに入れることができない理由は、ＧＯＴの内容はプログラム毎あるいはプロセスの起動毎に異なり、共有できないためである。
【０１６９】
ＧＯＴ２セクション：
データ・プログラム・セグメントには、新たにＧＯＴ２セクションが生成される。ＧＯＴ２セクションの処理について以下に説明する。
【０１７０】
ＧＯＴ２セクションは、ＰＬＴの各エントリが参照する関数のアドレスが格納されるテーブルである。ＧＯＴ２の０番目と１番目のエントリは特別なエントリで、０番目のエントリはモジュール識別番号で初期化され、１番目のエントリはランタイム・リンカのアドレス解決関数のアドレスで初期化される。それ以外のエントリは、対応するＰＬＴエントリの２番目の命令のアドレスで初期化される。
【０１７１】
このため、プログラム実行時にある関数を始めて呼び出すと、ＰＬＴエントリとＰＬＴの０番目のエントリを実行することにより、ＧＯＴ２の１番目のエントリのアドレスに実行が遷移する。１番目のエントリはアドレス解決関数のアドレスに設定されているため、アドレス解決関数が実行されることになる。
【０１７２】
アドレス解決関数は、スタックにプッシュされたＧＯＴ２のアドレスよりＧＯＴ２の０番目のエントリの値、つまり、モジュール識別番号と、シンボルの識別番号で指定された関数のアドレスを計算した後、そのアドレスをＧＯＴ２の対応するエントリに書き込む。このため、同じ関数を２回目以降呼び出した場合には、アドレス解決関数に実行が遷移することなく、目的の関数を呼び出すことができる。
【０１７３】
以上のように、ＧＯＴ２はプログラムの実行中に書き込みが行なわれるため、データ・プログラム・セグメント中に配置され、書き込み可能に設定される。なお、本実施形態では、ｌａｚｙ ｂｉｎｄの設定の場合、ＧＯＴ２は生成されず、ＰＬＴエントリはプロセスの初期化時に決定した関数へのジャンプ命令ですべて埋められる。
【０１７４】
プログラム・セクションのマップ：
次に、本実施形態に係るランタイム・リンカのリンク処理部とＯＳのメモリ管理部により行なわれる、プログラム・セグメントのマップ処理について説明する。
【０１７５】
本実施形態では、ランタイム・リンカのプログラム・セグメント変換部により、プログラムは３つのプログラム・セグメントから構成されるように変換される。既に説明したように、コード・プログラム・セグメントの保護属性は、アクセス権は読み出しと実行が可能で書き込みは禁止となり、また共有は可能となる。また、データ・プログラム・セグメントの保護属性は、アクセス権は読み出しと書き込みが可能で実行が禁止になり、共有は不可となる。また、アダプト・プログラム・セグメントの保護属性は、アクセス権は実行と読み出し可能で書き込み不可であるが、プロセス間での共有が不可となる。
【０１７６】
これらのプログラム・セグメントをアドレス空間にマップするとき、ＯＳのメモリ管理部は、ｘ８６のページとセグメントを併用して、プログラム・セグメントのアクセス権を実現するようになっている。ｘ８６では、読み出しと書き込みの権限はページ単位で指定が可能であるが、実行の権限は１つのコード・セグメントに置くことで実行可能とできる。そこで、本実施形態に係るメモリ管理部は、ｘ８６とＯＳにより、アプリケーション・プログラムに提供されるアドレス空間３ＧＢのうち、前半の１．５ＧＢをコード・セグメントとして設定する。つまり、コード・セグメントのベース・アドレスは０、セグメント・リミットは１．５ＧＢのアドレスを指すように設定する。また、データ・セグメントは３ＧＢすべてを設定する。つまり、ベース・アドレスは０、セグメント・リミットは３ＧＢのアドレスを指すように設定する。
【０１７７】
このようにすることで、前半の０ＧＢ〜１．５ＧＢの領域は実行可能に、後半の１．５ＧＢ〜３ＧＢの領域は実行禁止に設定される。読み込みと書き込みの権限の設定は、ｘ８６のページを利用して、ページ単位で設定される。また、前半の０ＧＢ〜１．５ＧＢの領域のページに対して、読み出し可能で書き込み不可と設定することで、コード・プログラム・セグメントとアダプト・プログラム・セグメントを配置することができる。後半の１．５ＧＢ〜３ＧＢの領域のページに対して、読み出しと書き込みを可能に設定することで、データ・プログラム・セグメントを配置することができる。
【０１７８】
プロセス間での共有の処理は、ＰｏｗｅｒＰＣプロセッサの場合と同様に、ＯＳのメモリ管理部により実現される。
【０１７９】
ランタイム・リンカのリンク処理部は、プログラム・セグメントのマップを、システム・コールを利用してＯＳに要求するようになっている。
【０１８０】
ランタイム・リンカの処理手順：
本実施例のランタイム・リンカの処理手順は、ＰｏｗｅｒＰＣプロセッサの場合と大筋で変わらず、基本的には図８並びに図９に示される手順でそれぞれ行なわれる。以下では、上記と異なる部分を中心に説明する。
【０１８１】
プロセス初期化時の処理：
プロセス初期化時の処理は、図８に示されるフローチャートに従った手順で行なわれる。プログラム・セグメントを生成する手順がｘ８６では相違する。
【０１８２】
プログラム・セグメントの生成のステップＳ３では、コード・プログラム・セグメント、データ・プログラム・セグメント、並びにアダプト・プログラム・セグメントを生成する。モジュールのアダプト・プログラム・セグメントはプログラム・セグメント変換部の作成したＰＬＴとＧＯＴセクションで構成される。
【０１８３】
データ・プログラム・セグメントは、ｌａｚｙ ｂｉｎｄ の設定であればＧＯＴ２とデータ・セクションにより構成され、ＧＯＴ２の０番目のエントリはモジュール識別番号で初期化され、１番目のエントリはランタイム・リンカのアドレス解決関数のアドレスで初期化される。それ以外のエントリは対応するＰＬＴエントリの２番目の命令のアドレスで初期化される。また、ＰＬＴは、ＧＯＴ２のエントリを参照する命令で生成される。ｌａｚｙ ｂｉｎｄ の設定でない場合には、データ・プログラム・セグメントはデータ・セクションのみで構成される。
【０１８４】
ｌａｚｙ ｂｉｎｄの設定でない場合には、次のリンク・ステップで、ＰＬＴのエントリが直接対応する関数へのジャンプ命令で生成され、ＧＯＴ２は生成されない。
【０１８５】
ＰＬＴエントリ呼び出し時の処理：
ｌａｚｙ ｂｉｎｄの設定である場合、関数呼び出しの対象となる関数のアドレス解決は、プロセスの初期化時には行なわれず、実際に関数呼び出しが発生した段階まで遅延される。ある関数がプロセス実行開始後に初めて呼び出された時の処理は、図１０にフローチャートで示した手順に従って行なわれる。
【０１８６】
関数呼び出しでは、関数に対応するＰＬＴエントリを呼び出す（ステップＳ１１）。本実施形態では、ＰＬＴエントリはアダプト・プログラム・セグメントにあり、その位置はコード・プログラム・セグメントとのオフセット制約を維持しているので、コンパイラ・システムが生成した命令列を変更することなく、ＰＬＴエントリへ正しく実行が遷移する。
【０１８７】
ＰＬＴエントリは、ＰＬＴの０番目のエントリをさらに実行することで、ＧＯＴ２の１番目のエントリに格納されたアドレスに実行が遷移する。ＧＯＴ２の１番目のエントリは、ランタイム・リンカによるプロセスの初期化でランタイム・リンカのリンク処理部にあるアドレス解決関数のアドレスが格納されているため、実行はアドレス解決関数へ遷移する。
【０１８８】
アドレス解決関数は、スタックにプッシュされたＧＯＴ２のアドレスとシンボルの識別番号を使用して関数を特定し、その関数のこのプロセスでのアドレスを計算する（ステップＳ１４）。
【０１８９】
計算したアドレスをＧＯＴ２のエントリに格納するとともに（ステップＳ１５）、そのアドレスから実行を再開する（ステップＳ１６）。
【０１９０】
ＧＯＴ２のエントリが変更されるため、２回目以降の同じ関数の呼び出しでは（ステップＳ１３）、アドレス解決関数に実行が遷移することなく、直接関数呼び出しが行なわれる。
【０１９１】
以上のように、本発明によれば、プログラムを構成するコード・プログラム・セグメントとデータ・プログラム・セグメントを変換し、コード・プログラム・セグメント、データ・プログラム・セグメント、アダプト・プログラム・セグメントを生成することで、コンパイラ・システムにより決定されるコード・プログラム・セグメントとデータ・プログラム・セグメントのオフセット制約を解除することができる。この結果、コード・プログラム・セグメントは実行可能セグメントに、データ・プログラム・セグメントは実行禁止セグメントに、それぞれ完全に配置することと、ランダムに配置することを、コンパイラシステムを変更することなく両立させるができる。したがって、外部ソースからシステムに送り込まれたデータに組み込まれた悪意あるコードやデータによるデータ実行と間接実行を好適に防止することができる。
【０１９２】
現在セキュリティ攻撃に用いられる手法の約７割は、データ実行や間接実行に基づくスタック・オーバーフローやヒープ・オーバーフローで構成される（図２０を参照のこと）。言い換えれば、本発明によりデータ実行や間接実行からなるセキュリティ攻撃を防止することにより、ウィルス被害の大部分を駆除することができる訳である。
【産業上の利用可能性】
【０１９３】
以上、特定の実施形態を参照しながら、本発明について詳解してきた。しかしながら、本発明の要旨を逸脱しない範囲で当業者が該実施形態の修正や代用を成し得ることは自明である。
【０１９４】
本明細書では、本発明をＰｏｗｅｒＰＣプロセッサやｘ８６系プロセッサに適用した場合を中心にして説明してきたが、本発明の要旨はこれに限定されるものではない。例えば、セグメントなど比較的粗い粒度のメモリ単位で実行権を設定することができる他のアーキテクチャからなるプロセッサに適用しても（勿論、細かい劉殿メモリ単位で実行健を設定可能なプロセッサでもよい）、同様に、コード・プログラム・セグメントとデータ・プログラム・セグメント間のオフセット制約をプログラム変換により解除し、コード・プログラム・セクションのみを実行可能なセグメントに配置するとともに、データ・プログラム・セグメントを実行禁止セグメントに配置し、不正実行を防止することができる。また、オフセット制約を解除することで、自由なランダム配置を行ない、悪意のあるコードやデータによるデータ実行と間接実行を防止することができる。
【０１９５】
要するに、例示という形態で本発明を開示してきたのであり、本明細書の記載内容を限定的に解釈するべきではない。本発明の要旨を判断するためには、冒頭に記載した特許請求の範囲の欄を参酌すべきである。
【図面の簡単な説明】
【０１９６】
【図１】図１は、本発明の実施に供される情報処理装置のハードウェア構成を模式的に示した図である。
【図２】図２は、情報処理システム上でプログラムをプロセスとして実行する際の仕組みを説明するための図である。
【図３】図３は、プロセスを構成するモジュールのファイル構成を模式的に示した図である（但し、ＰｏｗｅｒＰＣの場合）。
【図４】図４は、本発明に係るプログラム・セグメントの変換の仕組みを説明するための図である。
【図５】図５は、ＰＬＴエントリの構成を模式的に示した図である（但し、ＰｏｗｅｒＰＣプロセッサの場合）。
【図６】図６は、ＰＬＴｒｅｓｏｌｖｅの構成を模式的に示した図である。
【図７】図７は、ＧＯＴセクションを用いてプログラムが変数のアドレスや関数ポインタの値を参照する仕組みを説明するための図である。
【図８】図８は、ＰＬＴセクション及びＧＯＴ２セクションを用いてプログラムが関数を呼び出す仕組みを説明するための図である。
【図９】図９は、プロセス初期化時に行なわれる処理手順を示したフローチャートである。
【図１０】図１０は、ｌａｚｙ  ｂｉｎｄの設定である場合に関数がプロセス実行開始後に初めて呼び出されたときの処理手順を示したフローチャートである。
【図１１】図１１は、プロセスを構成するモジュールのファイル構成を模式的に示した図である（但し、ｘ８６プロセッサの場合）。
【図１２】図１２は、ＰＬＴエントリの構成例を示した図である（但し、ｘ８６プロセッサの場合）。
【図１３】図１３は、ＰＬＴテーブルの０番目のエントリを示した図である。
【図１４】図１４は、バッファ・オーバーフロー攻撃の例を示した図である。
【図１５】図１５は、間接実行の例を示した図である。
【図１６】図１６は、ＳＥＧＭＥＸＥＣのメカニズムを説明するための図である。
【図１７】図１７は、Ｅｘｅｃ−Ｓｈｉｅｌｄの仕組みを説明するための図である。
【図１８】図１８は、ＡＳＬＲの仕組みを説明するための図である。
【図１９】図１９は、Ｅｘｅｃ−ｓｈｉｅｌｄとＡＳＬＲの組み合わせを説明するための図である。
【図２０】図２０は、攻撃手法の比率を示した図である。
【符号の説明】
【０１９７】
１０…プロセッサ
２０…メモリ
２１…ディスプレイ・コントローラ
２２…表示装置
２３…入出力インターフェース
２４…キーボード
２５…マウス
２６…ネットワーク・インターフェース
２７…ＨＤＤコントローラ
２８…ＨＤＤ
３０…バス
【図１】
2005157502.tif 000003
【図２】
2005157502.tif 000004
【図３】
2005157502.tif 000005
【図４】
2005157502.tif 000006
【図５】
2005157502.tif 000007
【図６】
2005157502.tif 000008
【図７】
2005157502.tif 000009
【図８】
2005157502.tif 000010
【図９】
2005157502.tif 000011
【図１０】
2005157502.tif 000012
【図１１】
2005157502.tif 000013
【図１２】
2005157502.tif 000014
【図１３】
2005157502.tif 000015
【図１４】
2005157502.tif 000016
【図１５】
2005157502.tif 000017
【図１６】
2005157502.tif 000018
【図１７】
2005157502.tif 000019
【図１８】
2005157502.tif 000020
【図１９】
2005157502.tif 000021
【図２０】
2005157502.tif 000022