PaX
POSIXでは、mmap() システムコールはプロセスが指定したオフセットかカーネルが選択したオフセットにメモリを配置する。無名メモリを使えば、中身のないメモリがマッピングされ、ファイルを指定すればその中身がマッピングされる。ダイナミックリンクライブラリは mmap() を使ってロードされ、コード部とライブラリのデータ部がそれぞれマッピングされる。データ部に書き込みがあれば、コピーオンライトの要領で無名メモリへのコピーが行われる。
mmap() では、仮想空間上のマッピングすべきオフセットを指定することもある。オフセットが指定されないと、OSが自動的に選択する。Linux のオフセット計算方法は予測可能であり、事前に定義された「mmap()ベース」を始点として計算される。このため、プロセスを起動したときに必ずロードされる標準Cライブラリ(あるいは libc)は常に同じアドレスにロードされる。
mmap()ベースのランダム化を行う場合、PaX はmmap()ベースをランダムにシフトさせ、全てのライブラリおよび他のmmap()コールでのマッピング位置を変えてしまう。このため、ダイナミックリンクされるコード(共有オブジェクト)は毎回ランダムに異なる位置にマッピングされる。
PaX は、メモリに関する最小特権保護を実装したLinuxカーネル向けコンピュータセキュリティパッチである。最小特権の手法により、プログラムは正しい動作以外は何もできなくなる。PaX は2000年にリリースされた。
PaX はデータ用メモリページを実行不可とし、コード用メモリページを書き込み不可にすると共に無作為な配置を行う。これによりセキュリティを危険にさらす様々な動作が不可能になる(バッファオーバーランの一種など)。データページの実行不可設定により、データをコードとして実行できなくなる。コードページの書き込み不可設定により、不正なライブラリ実行が難しくなる。ただし、変数やポインタの書き換えは防げない。
PaX は The PaX Team が保守しているが、個々の開発者は匿名である。
PaXは実行ファイルやカーネルに潜在する基本的な設計ミスに対処することはできない。それは例えば、原理的に検出不可能な方法で攻撃可能とするような問題である。例えば、スクリプト言語のインタプリタはファイルやネットワークにアクセスできるため、悪意あるスクリプトを使って特権ユーザーのアカウントを通して重要データを盗むことも可能である。PaXは書式文字列攻撃の一部も防げない。書式文字列攻撃では、既存のコードを使って任意のデータ位置の読み書きが可能であり、攻撃者は内部のアドレスを事前に知っておく必要がなく、攻撃用コードを注入する必要もない。
PaXの公式サイトにある文書では、PaXが防ごうとしている攻撃を三種類としている。その文書によれば、PaX はそれらを効果的に防ぐことができるが、それ以外の攻撃は防ぐことはできない。実行コード領域の保護が可能で、そのベースを任意のアドレスにでき、完全なアドレス空間ランダム化が可能であることが前提である。防ぐことができる攻撃は大まかに言えば、次の通りである。
何らかのコードを導入し実行する攻撃。いわゆるシェルコードであることが多い。
プログラマが意図していない不正な順序で既存のコードを実行させる攻撃。return-to-libc攻撃と呼ばれる。
既存のコードを正しい順序で実行させるが、適当なデータを与えることで望みの動作をさせる攻撃。1.1.4-a 以前の zlib にこの問題があることが知られている。
PaX はこれらの攻撃の元となるバグを検出・対処できるわけではなく、単に攻撃によるダメージを防ぐものであるため、あらゆる攻撃を防ぐことができるわけではない。