FreeBSD 4.11-RELEASE に ProPolice (Stack Smashing Protector / SSP) を導入しました。導入にあたり気づいた点などをまとめておきます。
当サイトではFreeBSD 機がインターネット直付けの状態で運用されています。 もちろんセキュリティパッチの類は常時監視しており、 更新も極力自動化してはいるのですが、未知もしくは未公開の脆弱性をついた 攻撃を受けた場合には無力です。 特にありがちな攻撃のひとつである stack-smashing attack 対策のために、 ProPolice を導入することにしました。
ProPolice はバッファーオーバーランなどのバグを突いて スタックを書き換える類の攻撃に対する耐性をつける機構であり、 gcc とライブラリへのパッチで構成されています。 IBM 東京研究所の江藤博明氏が開発しました。
How to build FreeBSD with stack protection (ibm.com) に書かれている手順に従い、 1. パッチをあて、2. コンパイラとライブラリを作成し、 3. カーネルとユーザーランドをビルドするだけです。 リンク先に置いてあるパッチは 4.8用ですが、 4.11-RELEASE にもそのまま適用できます。
FreeBSD のコンパイルが終了し、再起動したら動作確認をします。 以下のような簡単なスタック破壊プログラムを実行してみます。
main() { char a[10]; strcpy(a, "abcdefghijklmn"); }
syslog に以下のように記録されれば成功です。
sample: stack overflow in function main /kernel: pid 53682 (sample), uid xxxx: exited on signal 6 (core dumped)
以後コンパイルしたプログラムはデフォルトでスタック保護が有効になります。 あえてスタック保護を無効にしたいときは、コンパイルオプションに -fno-stack-protector を指定します。 また、-O3 以上の最適化をかけたときにも無効になります。
Xサーバのコンパイル時に、site.def 等で #define HasGccStackProtector YES を指定する必要があります。さもないと、
Symbol __guard from module /usr/X11R6/lib/modules/drivers/mga_drv.o is unresolve d! Symbol __stack_smash_handler from module /usr/X11R6/lib/modules/drivers/mga_drv. o is unresolved!
といったエラーが出力されXサーバの起動に失敗します。
ports で Xサーバをコンパイルする場合は、以下のパッチを /usr/ports/x11-servers/xorg-server/files/patch-local-propolice というファイル名で置いておくと良いでしょう。
--- config/cf/site.def.orig Fri May 7 00:08:25 2004 +++ config/cf/site.def Sat Mar 19 02:04:53 2005 @@ -143,6 +143,11 @@ #endif */ +/* + * ProPolice + */ +#define HasGccStackProtector YES + #include <host.def> #endif /* AfterVendorCF */
ProPolice を有効にしてコンパイルした Firefox 1.0.1 が起動時に signal 11 でコアダンプしました。 原因追求の元気はないので、現在はスタック保護を無効にして使っています。 コンパイル方法は ports なら以下の通り。
# make WITH_OPTIMIZED_CFLAGS=yes CFLAGS=-fno-stack-protector
多くの人は cvsup でソースコードを更新してから make buildworld buildkernel していると思いますが、 以前 ProPolice パッチをあてたソースツリーを cvsup で更新したら、 もう一度 ProPolice パッチを当てるまえに、 以下のファイルを削除するのを忘れないように。
/usr/src/contrib/gcc/protector.c /usr/src/contrib/gcc/protector.h /usr/src/lib/libc/sys/stack_protector.c /usr/src/sys/libkern/stack_protector.c /usr/src/sys/boot/common/stack_protector.c
私はこれでちょっとだけハマりました。
ProPolice を導入した機械をデスクトップ・サーバ機として使っていますが、 今のところ上記を除けば導入にともなう不具合等はありません。 不具合などが見つかった場合は随時追記します。