PR
(注:記事は執筆時の情報に基づいており,現在では異なる場合があります)

64ビット版では標準対応

 このNX機能を利用すれば,特定のメモリー領域でのプログラム実行を禁止できる。スタックやヒープ領域を実行禁止領域として設定することで,バッファ・オーバーフローが発生したとしても,これを悪用しにくくするのである*2

表1●LinuxカーネルのNX対応機能の設定オプション
起動時のカーネル・オプションとして,これらの設定を渡すことでNX機能を操作できる。

 x86-64アーキテクチャ対応のLinuxカーネルは,バージョン2.4/2.6のどちらもNX機能に標準対応している。残念ながら標準では,メモリー・ページにmprotect()関数などで明示的に実行許可属性(PROT_EXEC)を取り除いた場合にしか,プログラム実行を禁止しない。スタックやヒープ領域などでのプログラム実行を標準で禁止する場合は,起動時のカーネル・オプションに「noexec=on」を渡す必要がある。また,32ビット・プロセスについては,「noexec32=on」という別のオプションを指定する必要がある。両オプションに設定可能な値とその意味を表1[拡大表示]に挙げた。

 通常のx86プロセッサ向けのLinuxカーネルも,バージョン2.6.8からNX機能に標準対応している。

 そのため,バージョン2.6.8以降のカーネルを利用すれば,Sempron 3100+やCeleron D 340,Efficeon TM8800といったNX対応の32ビット・プロセッサの機能を生かせる。同機能を利用する場合には,「CONFIG_HIGHMEM64G」というカーネル設定を有効にし,動作をPAEモードに切り替える必要がある。

 なお,32ビット・プロセッサ向けのNX対応機能は,米Red Hat社のIngo Molnar氏が開発した。同氏のWebページ(http://people.redhat.com/mingo/nx-patches/)で,修正差分(パッチ)が公開されている。

 ただし同氏はカーネル2.6に対するパッチしか開発していない。そのせいもあり,バージョン2.4.27までの2.4系列カーネルでは,32ビット・プロセッサのNX機能は利用できない。データ記憶領域におけるプログラム実行を禁止するには,「Exec-Shield」などの別の機構を利用する必要がある(Exec-Shieldについては,p.70の別掲載記事「NX非対応環境でも有効なExec-Shield」を参照)。


NX非対応環境で有効なExec-Shield

図A-1●プログラム実行可能なセグメントの上限を設定
プログラムを実行可能なセグメントをアドレス空間の下位に限定することで,上位にあるスタック領域等のデータ記憶領域を保護できる。
表A-1●Exec-Shieldの設定数値とその意味
数値は/proc/sys/kernel/exec-shieldファイルに書き込む。

 Red Hat LinuxやFedora Coreといったディストリビューションは「Exec-Shield」という,データ記憶領域でのプログラム実行を禁止する機構を標準で備える。Exec-Shieldの特徴は,NXをサポートしないx86プロセッサでプログラム実行を禁止できる点である。

 Exec-Shieldでは,「セグメント」と呼ばれるメモリー・ページとは別のメモリー管理単位を利用する。基本的に固定サイズで互いに重なり合わないメモリー・ページとは違って,セグメントはサイズや配置を自由に設定できる,利用用途などによって複数のセグメントをメモリー空間に配置できる,互いのセグメントが重なり合っても構わないなどの特徴がある。また,NXをサポートしないx86プロセッサでも,セグメントには実行権限を独立に設定できる。

 これを利用すれば,NX非対応のプロセッサでもデータ記憶領域でのプログラム実行を禁止できる。具体的には,データ記憶領域とプログラム・コードを格納するセグメントを分離し,データ記憶領域のセグメントから実行権限を取り除くのである。スタック領域はメモリー空間の上位に配置することになっているため,Exec-Shieldでは,プログラム・コードをアドレス空間の下位に限定し,スタックやヒープ領域とできるだけ重ならないようにする(図A-1[拡大表示])。

 これにより,データ記憶領域ではまずプログラムを実行できなくなる。ただしセグメントを利用する方法では,プログラム・コードを格納するセグメントとヒープ領域を完全に分離できない。そのため,一部攻撃の可能性を残す点に注意が必要である。もっともNX機能を使った場合も,攻撃のすべてを防御できるわけではない。

 Exec-Shieldの機能は,/proc/sys/kernel/exec-shieldファイルに書き込む数値で制御できる。数値と機能の対応を表A-1[拡大表示]に挙げた*1。また,/proc/sys/kernel/exec-shield-randomファイルに「1」を書き込むとスタック・セグメントの配置をランダムにする。これにより,一層攻撃に対する耐性を高められる*2

 なお,Exec-Shieldと同種の機構に「PaX」(http://pax.grsecurity.net/)がある。PaXも,Exec-Shieldと同様にセグメントを使ったデータ記憶領域の保護と,ランダム化の機能を提供する。ただし両者に設定などの互換性はない。

 PaXは,Debian GNU/Linuxをベースに開発されているセキュリティ強化ディストリビューション「Adamantix」(http://www.trusteddebian.org/)で標準採用されている。