PaX
関連記事
PaX は grsecurity パッチのサブセットとして開発されており、公式リポジトリの linux-grsec パッケージに含まれています。スタンドアロンのパッケージとして AUR の linux-paxAUR でインストールすることも可能です。
PaX にはメモリ破損を利用する攻撃から身を守る grsecurity の機能のほとんどが含まれています。完全なアドレス空間配置のランダム化、カーネルとユーザー空間のコード/データの分離の強化、情報を漏洩する恐れがある様々なクラスの排除など、PaX は様々な方法でカーネルやユーザー空間のプロセスを堅牢化します。カーネルのハードニング機能はユーザーには大きな影響がありませんが、MPROTECT / RANDMMAP 機能はいくつかのアプリケーションを別扱いにする必要を生じさせます。
PaX だけを使用するのは推奨されません。他の grsecurity の機能と一緒に使うことによる相乗効果が重要だからです。例えば、完全な PaX の ASLR でも、攻撃者がファイルシステムにアクセスできる場合は、GRKERNSEC_PROC_MEMMAP 機能 がないと打破される可能性があります。
目次
パフォーマンス
調整可能パラメータ
pax_sanitize_slab=0
オプションを kernel 行に設定することでスラブオブジェクトサニタイズを無効化することができます。この設定をするとカーネルから情報が漏洩する危険性が増えますが、CONFIG_PAX_MEMORY_SANITIZE
によるパフォーマンスの影響が減ります (デフォルトのカーネルコンパイルなら ~3%)。
pax_nouderef
オプションを kernel 行に設定することで UDEREF を無効化することができます。i686 ではあまり意味がありません。メモリのセグメンテーションを利用できるようになり仮想環境によってはパフォーマンスに大きな問題を発生させることがあるからです。x86_64 では、UDEREF の実装は3つあります:
- 遅くて脆弱なレガシーな実装 (~10% ほどカーネルコンパイルが遅くなります)
- Sandy Bridge 以降で使える強固な実装 (サポートされている場合はデフォルト、
nopcid
でレガシーな実装が使えます) - Sandy Bridge 以降で使える高速で脆弱な実装 (使用するには
pax_weakuderef
と設定します)
カスタムカーネル
カスタムカーネルをビルドすることで、パフォーマンスとセキュリティの妥協点を自由にコントロールすることができます。ビルド済みの linux-grsec パッケージはパフォーマンスよりもセキュリティを優先しています。i686 では、CONFIG_PAX_MEMORY_SANITIZE
と CONFIG_PAX_MEMORY_STACKLEAK
を無効化することでパフォーマンスへの影響を抑えられます。x86_64 では、前記のオプションと共に CONFIG_PAX_MEMORY_UDEREF
を無効化することで同じことになります。ただし、上で説明したように pax_nouderef
で実行時に変えることもできます。
PaX 例外
PaX による脆弱性攻撃の緩和機能には特定のアプリケーションを実行できなくしてしまうものも含まれており、実行可能ファイルを例外として指定する必要があります。拡張属性を使って実行可能ファイルから機能の適用を除外することが可能です。例えば、MPROTECT と RANDMMAP 機能を無効化するには:
$ setfattr -n user.pax.flags -v "emr" /usr/bin/問題のバイナリ
様々な機能の中でも MPROTECT 機能が一番問題を起こしやすく、linux-grsec ではデフォルトでカーネルログに違反を記録しています。Grsecurity の PaX サブセットだけではこうした問題を判断するのは困難です。
pax-utils パッケージに便利なツールが含まれています。例えば、pspax
ユーティリティはカーネルのパースペクティブとケーパビリティから PaX のパーミッションを表示することができます。scanelf
ツールを使えばバイナリの属性を確認できます。
One might also use getfattr to retrieve extended attributes set above (or set by paxd described below) if they choose not to run pax-utils or if they want to check the attributes of a process not running:
$ getfattr -n user.pax.flags /usr/bin/problematic_binary
paxd パッケージを使う
公式リポジトリの paxd パッケージには、実行可能ファイルが更新されたり設定ファイルが修正されたときに自動で /etc/paxd.conf
から PaX の例外を適用するデーモンが入っています。パッケージによって提供されているバイナリに例外を適用する方法として、公式でサポートされています。
ユーザーの例外
A user service is provided for users to apply exceptions, primarily to files in their home directory. It can be started / enabled with systemctl --user
and will apply exceptions from $XDG_CONFIG_HOME/paxd.conf
(falling back to ~/.config/paxd.conf
).
ソフトモード
sysctl で kernel.pax.softmode=1
を設定すると、例外を設定する代わりに、脆弱性対策の許諾を設定するようになります。サーバーで動作するウェブサービスなど、リスクが高い特定のバイナリだけに対策を課したいときに使うことができます。ただし、脆弱性緩和機能の例外を設定するほうがセキュリティ上効果が高く、paxd を使えば大体の作業は自動化することが可能です。
ユーザー空間の機能のテスト
paxtest ツールを使うことで、ユーザー空間の脆弱性攻撃の緩和機能をテストすることができます。
Vanilla kernel (x86_64)
Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable shared library bss : Killed Executable shared library data : Killed Executable anonymous mapping (mprotect) : Vulnerable Executable bss (mprotect) : Vulnerable Executable data (mprotect) : Vulnerable Executable heap (mprotect) : Vulnerable Executable stack (mprotect) : Vulnerable Executable shared library bss (mprotect) : Vulnerable Executable shared library data (mprotect): Vulnerable Writable text segments : Vulnerable Anonymous mapping randomisation test : 28 quality bits (guessed) Heap randomisation test (ET_EXEC) : 13 quality bits (guessed) Heap randomisation test (PIE) : 28 quality bits (guessed) Main executable randomisation (ET_EXEC) : 28 quality bits (guessed) Main executable randomisation (PIE) : 28 quality bits (guessed) Shared library randomisation test : 28 quality bits (guessed) VDSO randomisation test : 11 quality bits (guessed) Stack randomisation test (SEGMEXEC) : 28 quality bits (guessed) Stack randomisation test (PAGEEXEC) : 28 quality bits (guessed) Arg/env randomisation test (SEGMEXEC) : 20 quality bits (guessed) Arg/env randomisation test (PAGEEXEC) : 20 quality bits (guessed) Randomization under memory exhaustion @~0: 28 bits (guessed) Randomization under memory exhaustion @0 : 28 bits (guessed) Return to function (strcpy) : paxtest: return address contains a NULL byte. Return to function (memcpy) : Killed Return to function (strcpy, PIE) : paxtest: return address contains a NULL byte. Return to function (memcpy, PIE) : Killed
PaX kernel (x86_64 without UDEREF)
Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable shared library bss : Killed Executable shared library data : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 33 quality bits (guessed) Heap randomisation test (ET_EXEC) : 22 quality bits (guessed) Heap randomisation test (PIE) : 40 quality bits (guessed) Main executable randomisation (ET_EXEC) : 33 quality bits (guessed) Main executable randomisation (PIE) : 33 quality bits (guessed) Shared library randomisation test : 33 quality bits (guessed) VDSO randomisation test : 33 quality bits (guessed) Stack randomisation test (SEGMEXEC) : 40 quality bits (guessed) Stack randomisation test (PAGEEXEC) : 40 quality bits (guessed) Arg/env randomisation test (SEGMEXEC) : 44 quality bits (guessed) Arg/env randomisation test (PAGEEXEC) : 44 quality bits (guessed) Randomization under memory exhaustion @~0: 33 bits (guessed) Randomization under memory exhaustion @0 : 33 bits (guessed) Return to function (strcpy) : paxtest: return address contains a NULL byte. Return to function (memcpy) : Killed Return to function (strcpy, PIE) : paxtest: return address contains a NULL byte. Return to function (memcpy, PIE) : Killed
PaX kernel (x86_64 with UDEREF)
Executable anonymous mapping : Killed Executable bss : Killed Executable data : Killed Executable heap : Killed Executable stack : Killed Executable shared library bss : Killed Executable shared library data : Killed Executable anonymous mapping (mprotect) : Killed Executable bss (mprotect) : Killed Executable data (mprotect) : Killed Executable heap (mprotect) : Killed Executable stack (mprotect) : Killed Executable shared library bss (mprotect) : Killed Executable shared library data (mprotect): Killed Writable text segments : Killed Anonymous mapping randomisation test : 29 quality bits (guessed) Heap randomisation test (ET_EXEC) : 22 quality bits (guessed) Heap randomisation test (PIE) : 35 quality bits (guessed) Main executable randomisation (ET_EXEC) : 29 quality bits (guessed) Main executable randomisation (PIE) : 29 quality bits (guessed) Shared library randomisation test : 29 quality bits (guessed) VDSO randomisation test : 29 quality bits (guessed) Stack randomisation test (SEGMEXEC) : 35 quality bits (guessed) Stack randomisation test (PAGEEXEC) : 35 quality bits (guessed) Arg/env randomisation test (SEGMEXEC) : 39 quality bits (guessed) Arg/env randomisation test (PAGEEXEC) : 39 quality bits (guessed) Randomization under memory exhaustion @~0: 29 bits (guessed) Randomization under memory exhaustion @0 : 29 bits (guessed) Return to function (strcpy) : paxtest: return address contains a NULL byte. Return to function (memcpy) : Killed Return to function (strcpy, PIE) : paxtest: return address contains a NULL byte. Return to function (memcpy, PIE) : Killed