FreeBSD Daily Topics

2011年8月27日Capsicumを知る - ファイルディスクリプタをケーパビリティへ

9月末または10月のリリースが予定されているFreeBSD 9.0-RELEASEには新しいセキュリティ機能「Capsicum」が登場します。これでFreeBSDにおける主なファイル保護機構は3種類ということになります。Capsicumはケーパビリティの実装系のひとつと分類できるもので、既存の実装と相性がよく、少量のコードでアプリケーションやツールでケーパビリティを実現できるという特徴があります。

保護ドメインやアクセス制御リストなどの保護機構に慣れていると、この「ケーパビリティ」は理解しにくいところがあります。FDTではしばらく、Capsicumを理解するための概念的な説明や、実際の実装例などを紹介して「Capsicum」の機能を紹介していきます。

fd to capability

「Capsicum」で実現されるケーパビリティを理解するには、ソースコードのレベルで機能を理解する必要があります。⁠保護ドメイン」「アクセス制御リスト」がユーザランドのコマンドから設定したり確認できるのと違い、⁠Capsicum」はCのソースコードレベルで実現されるセキュリティ機能、もっといえばサンボドックス機能/コンパートメント機能だからです。

たとえば、次のCのコードを考えてみましょう。

fd = open("COPYRIGHT", O_RDWR);

これはカレントディレクトリにある「COPYRIGHT」というファイルを読み書き許可を指定して開く、という操作となります。返り値が「ファイルディスクリプタ」と呼ばれる番号です。プログラム内ではこのファイルディスクリプタを指定することで、開いたファイルへのアクセスや操作を実施します。たとえば次のようにread()を使えば、ファイルの中身を指定してバッファへコピーすることができます。

len = read(fd, bf, BUFSIZ);

「Capsicum」では、このファイルディスクリプタから、ケーパビリティを作成します(ここでのケーパビリティは、いわば操作の許可情報を設定することができる特別なファイルディスクリプタ、ということになります⁠⁠。作成するときに「読み込みだけを許可する」といった許可情報を与えます。これが基本的なアイディアです。たとえば次のように実装します。

cap = cap_new(dup(fd), CAP_READ | CAP_SEEK);

読み書きの許可で開いたファイルですが、上のようにすると、読み込みだけが許可される特別なファイルディスクリプタ(ケーパビリティ)が生成されます。こうしたあとで次のように処理を実行すると、指定した操作だけが実行できるモードに入ります。

cap_enter();

cap_enter()を実行すると、そのプロセスは「ケーパビリティモード」と呼ばれる状態に入り、設定したケーパビリティが有効になります。ケーパビリティモードに入ると、もはやこのモードを終了することはできません。ケーパビリティをベースに新しく別のケーパビリティを生成することもできますが、権限を広げることはできません。また、ケーパビリティモードに入った状態で子プロセスを生成した場合、その子プロセスもケーパビリティモードにあり、設定された権限を引き継ぎます。

おすすめ記事

記事・ニュース一覧