FreeBSD 4.11-RELEASE への ProPolice の導入

[Powered by FreeBSD]

FreeBSD 4.11-RELEASE に ProPolice (Stack Smashing Protector / SSP) を導入しました。導入にあたり気づいた点などをまとめておきます。

[ コメント ] [ トップページ ]


1. あらまし

当サイトではFreeBSD 機がインターネット直付けの状態で運用されています。 もちろんセキュリティパッチの類は常時監視しており、 更新も極力自動化してはいるのですが、未知もしくは未公開の脆弱性をついた 攻撃を受けた場合には無力です。 特にありがちな攻撃のひとつである stack-smashing attack 対策のために、 ProPolice を導入することにしました。

ProPolice はバッファーオーバーランなどのバグを突いて スタックを書き換える類の攻撃に対する耐性をつける機構であり、 gcc とライブラリへのパッチで構成されています。 IBM 東京研究所の江藤博明氏が開発しました。


2. ベースシステムへの導入

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 以上の最適化をかけたときにも無効になります。


3. アプリケーションコンパイル時の注意

(1) Xサーバ (ports/x11-servers/xorg-server)

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 */

(2) Firefox (ports/www/firefox)

ProPolice を有効にしてコンパイルした Firefox 1.0.1 が起動時に signal 11 でコアダンプしました。 原因追求の元気はないので、現在はスタック保護を無効にして使っています。 コンパイル方法は ports なら以下の通り。

# make WITH_OPTIMIZED_CFLAGS=yes CFLAGS=-fno-stack-protector

(3) cvsup + make world

多くの人は 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

私はこれでちょっとだけハマりました。


4. 使用感

ProPolice を導入した機械をデスクトップ・サーバ機として使っていますが、 今のところ上記を除けば導入にともなう不具合等はありません。 不具合などが見つかった場合は随時追記します。


5. リンク


6. 変更履歴


$Date: 2006/03/16 20:49:12 $