TYPEBOUNSとマルチスレッド

SELinux: add boundary support and thread context assignment

先月から議論を続けていたパッチがカーネルにマージされた。
linux-next経由2.6.28行きという形になるだろう。
このパッチの目的は、WebサーバやAPサーバがクライアントのリクエストを処理する際に、リクエストハンドラ(例えばPHPスクリプト)をクライアントに応じた適切な権限で実行する事である。

Apacheに手を入れ、PHPスクリプトを呼び出す前にSELinuxのセキュリティコンテキストを設定すれば良いではないかと思うなかれ。スそう単純でない問題があるのである。
近頃のWeb/APサーバはマルチスレッド化で性能を稼ぐ事が多々あるが、SELinuxはスレッド単位でのドメイン付与を認めていない。1プロセス=1ドメインなのである。

しかし、そんな事を言っていては埒が開かないのでと考えた末に出てきたアイデアが『元々のドメインに比べて、権限が完全に縮退している場合に限り、スレッド単位のドメイン遷移を認める』というものであった。

スレッドはメモリ空間を共有しており、OSが捕捉する事なく他のスレッドが読み出した情報を参照できるが、元のドメインよりも弱い権限で動いている限り、当該メモリ空間に存在してはならない情報がドメインの内部に入ってくる事はない。

上の図は、各ドメインの権限をベン図で示したもの。
httpd_php_tドメインは、完全にhttpd_tドメインに包含されており、この場合 httpd_t → httpd_php_t への遷移は可能。一方、httpd_perl_tドメインはhttpd_tに無い権限を持っているため、ドメイン遷移は認められない。

このドメイン間の強弱関係を規定するのが、新しくポリシー構文に追加した TYPEBOUNDS 文である。

書式:
TYPEBOUNDS <境界ドメイン> <被制約ドメイン> [, <被制約ドメイン> ... ] ;
例:
TYPEBOUNDS httpd_t httpd_php_t ;
この一文を追加する事で、httpd_php_tドメインの権限は、決してhttpd_tドメインを越える事は無くなる。無理やりパーミッションを与えても、実行時にマスクされるので無駄。

で、スレッドにドメインを設定する際には、既存のlibselinuxのAPIである setcon() を利用するが、この時、呼出しプロセスがマルチスレッド化されている場合、『新しいドメインが、元のドメインを境界ドメインとして持つ』事がドメイン遷移の条件になる。

これを使う事で、Web/APサーバがユーザのリクエストを処理する際に、ユーザに応じた適切な権限を割り当てる事が可能になる。

大仰に言えば、SELinuxがWeb Application Flawの悪夢に対して処方箋となるための第一歩。技術の普及という点でも、今まで全く関係の無かったWeb2.0の人たちとの接点を作ると言うのは大きい。
SELinuxの普及にはキラーアプリケーションが必要だとかねがね言ってきたが、Webとの連携はブレークスルーとなり得るか。今後の展開を乞うご期待。