From from-tomoyo-users @ I-love.SAKURA.ne.jp Tue Feb 2 21:22:38 2010 From: from-tomoyo-users @ I-love.SAKURA.ne.jp (Tetsuo Handa) Date: Tue, 2 Feb 2010 21:22:38 +0900 Subject: [Tomoyo-dev 1220] =?iso-2022-jp?b?GyRCJVclbSUwJWklYCROPEI5VCRySDwkbyRKJCQlSSVhGyhC?= =?iso-2022-jp?b?GyRCJSQlc0ErMFwkSyREJCQkRhsoQg==?= Message-ID: <201002022122.CDC65833.VPtNZPTSPUNSFGtPT@I-love.SAKURA.ne.jp>  熊猫です。 Apache では高速化のためにスレッドを複数のリクエスト間で使いまわすようになって います。そのため、プログラムの実行(つまり execve() システムコール)を伴わないで 行われる処理(静的なコンテンツの配信や mod_perl などで処理されるCGIプログラム など)に対しては、全て同じ権限で動作するようになっています。 セキュリティを高めるために、リクエスト毎に異なる権限を割り当てて処理しようとした 場合、あるリクエストを処理するために権限を切り替えた後で、次のリクエストを処理 する前に権限を元に戻す処理が必要になります。しかし、自由に権限を元に戻すことが できるようになっていると、そこを攻撃されて権限が不正に元に戻されてしまうことが あるため、それを防ぐための工夫が必要です。 NECの海外さんが mod_selinux という、 Apache でリクエストを異なる権限で動作 させるためのモジュールを開発し、 Fedora 11 以降で利用可能になっています。この モジュールでは、1リクエスト毎に使い捨てのスレッドを作成し、使い捨てスレッドの 中で権限を変更してからリクエストを処理することにより、権限を元に戻すという処理が 不要になるように実装されているという点が特徴です。 TOMOYO Linux においては、権限の切り替えはドメイン遷移という形で実現されて います。権限を元に戻すという処理が不要であるということは、「現在のドメイン名に 要求されたプログラムのパス名を連結したものを遷移先ドメイン名とする」という TOMOYO Linux のドメイン遷移のルールをそのまま適用できるということです。 そのため、 mod_selinux がやっていることは、そのまま TOMOYO Linux においても 適用できます。違いはプログラムの実行(つまり execve() システムコール)を伴うか どうかだけです。 ということで、さっそく TOMOYO Linux 用のモジュールを試作してみました。 添付画像では /etc/httpd/conf/httpd.conf に NameVirtualHost *:80 DocumentRoot /var/www/html/ ServerName dog.example.com DocumentRoot /var/www/html/ ServerName cat.example.com という内容を追加し、バーチャルホスト単位で異なるアクセス許可を与えられるように しています。また、要求されたファイル名に基づいて、パス名単位でも異なるアクセス 許可を与えられるようにしています。 この「プログラムの実行を伴わないドメイン遷移」は様々な可能性を秘めています。 例えば Android では、 UID=0 で動作しているプロセス( zygote )が特定の UID に 変化してから動作(例えば com.android.browser )するようになっています。 ( http://sourceforge.jp/projects/tomoyo/docs/JLS_tomoyo_tutorial.pdf の P32とP34を参照ください。)もし、 fork() 後に //com.android.browser ドメインに遷移するように zygote を修正することができれば、 zygote を /init /system/bin/app_process ドメインで、 com.android.browser を /init /system/bin/app_process //com.android.browser ドメインで 動作させることができるようになります。 ということで、以下の点についてコメント募集です。 (1)ドメイン遷移をするためのインタフェース 現在のプロトタイプでは、 /proc/ccs/self_domain にドメイン名を write() する ことによりドメイン遷移するようになっています。ただし、 /proc/ccs/ は バッファリングのためにカーネルメモリを割り当てているので、デフォルトでは root ユーザだけにしか開放していません。 Apache は一般ユーザ権限で動作するので、 /proc/ccs/self_domain を全てのユーザに開放する必要が生じます。すると、悪意ある ユーザが fork() と open() を繰り返して全てのカーネルメモリを消費してしまうという 攻撃が成立してしまうのではないかと心配しています。 sysctl() のように1回の read() や write() でドメイン名全体を渡すという制約を設ければ、バッファリングが 不要になるのでカーネルメモリを消費しつくす攻撃を防げるので好ましいかも しれませんね。 (2)ドメイン名の表記規則 TOMOYO Linux におけるドメイン名は、「 +0回以上のパス名の繰り返し」 として定義されています。このパス名は / で始まり、 \? や \* などを含まず、 / では終わりません。 セキュリティ上の理由から、 execve() を伴うドメイン遷移と execve() を伴わない ドメイン遷移とを区別できるようにしておく必要があると考えています。もし、区別 できない場合、あるドメインに所属するプロセスは、制御権を保持したまま、その ドメインの任意の子ドメインに自由に遷移できてしまいます。すると、例えば /usr/sbin/sshd /bin/bash ドメインに属している /bin/bash が /usr/sbin/sshd /bin/bash /usr/bin/passwd ドメインに属している /usr/bin/passwd に対して許可されている資源(例えば /etc/shadow )にも アクセスできるようになってしまいます。 現在のプロトタイプでは、 execve() を伴わないドメイン遷移の場合には自動的に / が 付与されるようになっています。例えば /usr/sbin/sshd /bin/bash ドメイン に属している /bin/bash が /usr/bin/passwd という( execve() を伴わない)ドメイン 遷移を要求すると、 /usr/sbin/sshd /bin/bash //usr/bin/passwd ドメインに 遷移するようになっています。 他の方法としては、 allow_execute のように明示的に許可が無いと遷移できないように する方法が考えられます。例えば、   /usr/sbin/sshd /bin/bash  allow_transit /bin/true という許可が与えられている場合に限り /usr/sbin/sshd /bin/bash ドメインから /usr/sbin/sshd /bin/bash /bin/true ドメインへ ( execve() を伴わないで)ドメイン遷移することを許可するという方法です。 将来、(要望が出た場合には)親ドメインへ遷移する   /usr/sbin/sshd /bin/bash  allow_transit .. とか特定のドメインへ遷移する   /usr/sbin/sshd /bin/bash  allow_transit /sbin/mingetty /bin/bash みたいな拡張も可能であることから、こちらの方が好ましいかもしれませんね。 -------------- next part -------------- テキスト形式以外の添付ファイルを保管しました... ファイル名: apache.png 型: image/png サイズ: 15598 バイト 説明: 無し URL: http://lists.sourceforge.jp/mailman/archives/tomoyo-dev/attachments/20100202/49be23c4/attachment.png From from-tomoyo-users @ I-love.SAKURA.ne.jp Sun Feb 14 16:49:35 2010 From: from-tomoyo-users @ I-love.SAKURA.ne.jp (Tetsuo Handa) Date: Sun, 14 Feb 2010 16:49:35 +0900 Subject: [Tomoyo-dev 1221] =?iso-2022-jp?b?MS43LjEgGyRCJE4lUSVDJUEkciVqJVUlbCVDJTclZSQ3GyhC?= =?iso-2022-jp?b?GyRCJF4kNyQ/ISMbKEI=?= Message-ID: <201002141649.ABH04603.tPGSTPtZVPNUFNPTS@I-love.SAKURA.ne.jp>  熊猫です。  1個の不具合を修正した TOMOYO 1.7.1p2 をアップロードしました。 http://osdn.dl.sourceforge.jp/tomoyo/43375/ccs-patch-1.7.1-20100214.tar.gz MD5: 8888f740cefab03c5fef762bd8768db4 Fix 2010/01/17 @ Use current domain's name for execute_handler audit log. Since 1.6.7 , /proc/ccs/grant_log was by error using next domain's name when auditing current domain's "execute_handler" line. 今回の tar ball には、 2.6.33-rc8 および 2.6.33-rc7-next-20100212 用のパッチが 追加されています。また、 Silicon Linux の CAT760 ( SH4 アーキテクチャ)用の パッチも追加されています。 From from-tomoyo-users @ I-love.SAKURA.ne.jp Thu Feb 18 21:43:35 2010 From: from-tomoyo-users @ I-love.SAKURA.ne.jp (Tetsuo Handa) Date: Thu, 18 Feb 2010 21:43:35 +0900 Subject: [Tomoyo-dev 1222] Re: =?iso-2022-jp?b?GyRCJVclbSUwJWklYCROPEI5VCRySDwkbyRKJCQbKEI=?= =?iso-2022-jp?b?GyRCJUklYSUkJXNBKzBcJEskRCQkJEYbKEI=?= In-Reply-To: <201002022122.CDC65833.VPtNZPTSPUNSFGtPT@I-love.SAKURA.ne.jp> References: <201002022122.CDC65833.VPtNZPTSPUNSFGtPT@I-love.SAKURA.ne.jp> Message-ID: <201002182143.JIE69707.PZSPPGtPTNNStUTVF@I-love.SAKURA.ne.jp>  熊猫です。  今までのドメイン遷移には execve() が必要でした。そのため、 execve() を 伴わないで実行される Apache のCGIでは、ドメイン遷移が行われないため、 権限を分割することができませんでした。 しかし、バーチャルホストやCGIに対応して欲しいという意見が出てきています。 そこで、 execve() を伴わないでドメイン遷移を行う仕組みについて検討しています。 <実装案> ・アトミックな書込み操作で行う  Apache は一般ユーザの権限で動作します。そのため、 root 以外のユーザに対しても  execve() を伴わないドメイン遷移を認める必要があります。  ドメイン遷移を行うには、遷移先を指定する文字列をカーネルが受け取る必要が  あります。文字列を複数回の呼び出しに分けて受け取ることを認めた場合、カーネル  内でメモリを割り当てる必要が生じます。すると、悪意あるユーザが文字列の  一部だけを渡すことにより、カーネル内のメモリを消費させるという攻撃が成立して  しまいます。  このような攻撃を回避するために、文字列は1回の呼び出しで受け取るように  制限をかけようと思います。具体的には、「文字列+'\0'」という形式で1回の  write() で渡すようにしたいと思います。  疑問点としては、ライブラリなどが提供するバッファリング機構により、  ユーザに対しては1回の書き込み要求として処理されても、カーネルに対しては  複数回の write() システムコールとして処理されてしまう可能性がある点です。  write() システムコールを呼び出すことができる言語であれば問題ないのですが、  そうではない言語も存在するかもしれません。 write() システムコールではなく、  他のシステムコールを使う方が良いのかもしれません。 ・安全上の理由から、文字列の先頭に // を付与する  /bin/bash が制御を保持したまま /usr/bin/passwd ドメインに遷移することを  認めてしまうと、 /bin/bash に対して /etc/shadow へのアクセスを認めてしまう  ことになり危険です。  そのため、 execve() を伴うドメイン遷移と execve() を伴わないドメイン遷移とを  区別できるようにするべきだと考えています。具体的には、 execve() を伴わない  ドメイン遷移の場合には、カーネル側で自動的に // というプレフィックスを  付与するようにしたいと思います。 execve() を伴うドメイン遷移の場合には  正規化されたパス名が用いられるため、( aggregator キーワードを用いて  マッピングしない限り) // で始まることはありません。 ・ keep_domain や initialize_domain の適用対象外とする  ドメイン遷移を行うことが目的ですので、 keep_domain キーワードにより  ドメイン遷移が抑制されてしまっては意味がありません。  また、 initialize_domain キーワードによりドメイン遷移を初期化する価値が  見当たらないので、とりあえず適用対象外にしようと思います。 <使用方法>  ccs-patch-1.7.1-20100214.tar.gz に対するカーネルパッチが http://sourceforge.jp/projects/tomoyo/svn/view/branches/transit3.diff?root=tomoyo&revision=3463 にあります。 # ccs-patch-1.7.1-20100110.tar.gz に対するパッチが #(パッチのURL) #にあります。  この機能を Apache 2.x で使うと、 http://sourceforge.jp/projects/tomoyo/svn/view/branches/apache-1.png?root=tomoyo&revision=3463 http://sourceforge.jp/projects/tomoyo/svn/view/branches/apache-2.png?root=tomoyo&revision=3463 のようにバーチャルホスト名やCGIアプリケーション名単位で権限を分割することが できるようになります。 # wget -O mod_ccs.c 'http://sourceforge.jp/projects/tomoyo/svn/view/branches/mod_ccs.c?root=tomoyo&revision=3463' # apxs -c mod_ccs.c # apxs -i -a mod_ccs.la でインストールできます。(環境によっては apxs ではなく apxs2 を使います。) そして、 /usr/share/horde3/\* appname=horde /usr/share/horde3/\{\*\}/\* appname=horde /var/www/cgi-bin/main.cgi /var/www/cgi-bin/main.cgi /var/www/cgi-bin/\* appname=cgi-bin /var/www/cgi-bin/\{\*\}/\* appname=cgi-bin /\{\*\}/\*.pl appname=perl-programs /\{\*\}/\*.php appname=php-programs /\{\*\}/\* default /\* default のように、 要求されたパス名のパターン1 遷移先のドメイン名1 要求されたパス名のパターン2 遷移先のドメイン名2 要求されたパス名のパターン3 遷移先のドメイン名3  ・  ・  ・ というリストを /etc/apache_domain_map.conf として保存すれば準備完了です。  この機能を Android で使うためには --- mydroid.orig/dalvik/vm/native/dalvik_system_Zygote.c +++ mydroid/dalvik/vm/native/dalvik_system_Zygote.c @@ -25,6 +25,8 @@ #include #include #include +#include /* open() */ +#include /* open() */ #if defined(HAVE_PRCTL) # include @@ -358,6 +360,16 @@ static pid_t forkAndSpecializeCommon(con LOGW("cannot setuid(%d) errno: %d", uid, errno); } + { + const int fd = open("/proc/ccs/.transition", O_WRONLY); + if (fd >= 0) { + char buffer[128]; + memset(buffer, 0, sizeof(buffer)); + snprintf(buffer, sizeof(buffer) - 1, "uid=%d/gid=%d", uid, gid); + write(fd, buffer, strlen(buffer) + 1); + close(fd); + } + } /* * Our system thread ID has changed. Get the new one. */ という修正を行います。すると、 http://sourceforge.jp/projects/tomoyo/svn/view/branches/android-1.png?root=tomoyo&revision=3463 http://sourceforge.jp/projects/tomoyo/svn/view/branches/android-2.png?root=tomoyo&revision=3463 のようにユーザIDやグループIDを単位として権限を分割できるようになります。 com.android.browser のような名前による分割には未対応ですが、名前が判明している 場所からこの機能を呼び出すようにしてやればできるはずです。 <質問/意見募集> (1) AppArmor のように元のドメインに戻れる機能が必要ですか?   mod_ccs のように clone() + wait() を使えば戻れなくても問題ないはずです。   制御を渡さないのであれば、戻れるようにしておくと便利な場合があります。   しかし、戻れるようにする場合には不正に戻されないようにするための工夫が   必要になります。 AppArmor では64ビットの乱数を用いて防御していますが、   TOMOYO 1.x で実現する場合にはタスク構造体に変数を追加しないと実現   できません。 (2)子ドメインへの遷移以外に、親ドメインや任意のドメインに遷移できる機能も  必要ですか?   親ドメインや任意のドメインに遷移できる機能はセキュリティ上好ましくないので   実装しない方が良いと考えています。親ドメインや任意のドメインに遷移できると   便利になる実例をお持ちでしたら検討しますのでお知らせください。 (3) mod_ccs について、バーチャルホスト名によるドメイン遷移はバーチャル  ホスト名を自動的に使うようにしますか?それとも、バーチャルホスト名とドメイン  名とのマッピングテーブルを参照するようにしますか?   バーチャルホスト名をそのまま使うようにした場合、バーチャルホストの数が   2つとか3つであれば問題ないでしょうが、バーチャルホストの数だけドメインが   作成されるので、100とか1000とかある場合にはグループ化できないと   困るかもしれません。 (4)その他なんでも From from-tomoyo-users @ I-love.SAKURA.ne.jp Thu Feb 25 13:31:29 2010 From: from-tomoyo-users @ I-love.SAKURA.ne.jp (Tetsuo Handa) Date: Thu, 25 Feb 2010 13:31:29 +0900 Subject: [Tomoyo-dev 1223] Re: =?iso-2022-jp?b?GyRCJUQhPCVrJVElQyUxITwlOCRyJSIlQyVXJUcbKEI=?= =?iso-2022-jp?b?GyRCITwlSCQ3JF4kNyQ/ISMbKEI=?= In-Reply-To: <201001152203.BJD13013.FVtUPNNTZSPPtTGPS@I-love.SAKURA.ne.jp> References: <201001102119.BJB95355.GPPTNtVPUTSNStPZF@I-love.SAKURA.ne.jp> <201001152203.BJD13013.FVtUPNNTZSPPtTGPS@I-love.SAKURA.ne.jp> Message-ID: <201002250431.o1P4VTQD011543@www262.sakura.ne.jp>  熊猫です。  カーネル 2.6.33 がリリースされたので、 tomoyo-tools パッケージを アップデートしました。カーネル 2.6.33 で利用できるようになった 再帰的にディレクトリに一致する演算子である /\{dir\}/ への対応が追加されたほか、 カーネル 2.6.34 で制限できるようになる ioctl/chmod/chown/chgrp/mount/unmount/chroot/pivot_root キーワードへの 対応も追加されています。 http://osdn.dl.sourceforge.jp/tomoyo/41908/tomoyo-tools-2.2.0-20100225.tar.gz MD5: 5555fb8541e9924bc75e2eda6b5c2c9a カーネル 2.6.34 ではガベージコレクタが搭載され、不要になったメモリを解放できる ようになります。また、読み書きセマフォを使って行われていた排他制御がSRCUで 行われるようになります。