適当和訳
Theo の pledge 更新状況にはプログラムがたくさん載っているが、その中には pledge するのが少しアホくさく思えるものもあるかもしれない。でも、その一見アホくさい努力のおかげで見つかったバグや設計ミスもあるのだ。
おそらく、いくつかのプログラムに pledge は必要ない。「もし id に exploitable なバグがあれば、それどころじゃないだろう」という議論も、さもありなん。しかし、何にでも pledge させるという作業は、pledge というコンセプトが実効性を持つことの証明になっている。テストした最初の 5 つのプログラムが一発で動かなければ、あと 5 つ直そうとする人はいないだろう。それに比べて、100 個までいけたなら、あと 100 個も大したことはないだろうと自信を持って言える。まあ最低でも、「あいつよりデカいぜ」と自慢できる、気分の良い数字にはなる。
その他の場合に pledge は無駄に思えるかもしれないが、ひょっとすると無駄ではない。ksh を使って簡単な cgi スクリプトを書くことを想像してほしい。ksh に何らかのオーバーフロー(shellshock?)が潜んでいるところまで想像しよう。シェルはあまりきつく縛ることができない。当然のことながら、fork して他のプログラムを exec したり、ファイルを作成・変更したりする必要がある。 しかし、最低でもネットワーク関連のシステムコールを無効にすることができる。cgi が小規模な chroot の場合、攻略された ksh は、少数のプログラムを実行することはできるものの、ソケットを開いて内側からネットワークを割り当てることはできない。
他には、設計ミスと言ったほうが良さそうな、ある条件下で fork / exec しようとするプログラムもある。patch は ed 形式の diff を受け取ると、実際に ed を実行する。もちろん ed は「!」コマンドによるシェルエスケープをサポートしているから、diff が任意のプログラムを実行する危険が潜んでいるのだ。patch はそうしたシーケンスを探して未然に防ごうとするが、もし騙されたら……、5.7 の errata 13 になる。pledge を patch に入れることがきっかけで、必要な ed コマンドをエミュレートして一切 exec しないよう設計し直すことになった。もし pledge が 1 年早く来ていたなら、このバグが exploitable になるのを防ぐのみならず、そもそも存在しないようにしてくれただろうに。
iked に pledge を入れたときには、小さなバグが見つかって修正された。chroot 内の子プロセスが、自分の設定を出力しようとして /etc/protocols にアクセスを試みていた。それが失敗して、fatal ではないので、プロトコル名のかわりに数値のまま出力していただけだ。しかしながら、pledge がファイルの open 許可を与えないため子プロセスをクラッシュさせるようになって、そのバグが表面化した。出力コードは別プロセスに移り、今では本来の望みどおりプロトコル名を表示するようになっている。
revoke をコールしたがるプログラムがある。この関数は close の重量級といったところで、あらゆるプロセスのあらゆるファイルインスタンスを閉じることができる。もともとのユースケースは init が端末を安全に再利用できるよう、次のユーザに渡す前に端末を強制的に閉じることだったが、いつしか TTY だけでなく、あらゆる種類のファイルを受け付けるように拡張されたのだ。その revoke に関してカーネルポリシーをどうするか決定する際、この拡張が再検討された。「もしかして、任意のファイルタイプは必要なくない?」そのとおり。
こうした状況がどれも他のセキュリティポリシー機構で検出できなかったなどと言うつもりはない。だが systrace ポリシーが patch にあったとしても、当時の主流な考え方として「通常の動作 (ed の実行) は許可」だったから、おそらく助けにならなかっただろう。patch に対する AppArmor ポリシーは見つからない。他のシステムについてはよくわからない。まあ優先順位の高い標的ではなさそうだけど、内部設計を見直せただけだとしても、セキュリティ改善という成果があるわけで。
Posted 2015-11-20 18:33:58 by tedu Updated: 2015-11-20 18:33:58