FreeBSD Daily Topics
2011年9月12日 Capsicumを知る - ケーパビリティモードはfork()したプロセスにも継承
この記事を読むのに必要な時間:およそ 2 分
9月末または10月のリリースが予定されているFreeBSD 9.
- Capability mode going into a child process
ケーパビリティモードに入ったプロセスから子プロセスを生成した場合,
その子プロセスもケーパビリティモードが引き継がれます。たとえば, これまで使ってきたソースコードを子プロセスを生成して, 子プロセス側でファイルの読み込みを標準出力へ書きだすようにすると次のようになります。 「read-cap-process. c」 として用意しておきます。 #include <stdlib.
h> #include <stdio. h> #include <fcntl. h> #include <unistd. h> #include <err. h> #include <errno. h> #include <sysexits. h> #include <sys/ capability. h> #include <sys/ types. h> #include <sys/ wait. h> int main(void) { int fd, cap, len, stat; char bf[BUFSIZ]; pid_ t pid; fd = open("COPYRIGHT", O_ RDWR); if (-1 == fd) err(EX_ NOPERM, "open error: %d", errno); cap = cap_ new(dup(fd), CAP_ READ | CAP_ SEEK); if (-1 == cap) err(EX_ NOPERM, "cap_ new error: %d", errno); close(fd); cap_ enter(); // 子プロセスを作ります pid = fork(); if (-1 == pid) err(EX_ NOPERM, "fork error: %d", errno); if (0 == pid) { // 子プロセス側で出力処理をします。 len = read(cap, bf, BUFSIZ); if (-1 == len) err(EX_ NOPERM, "read error: %d", errno); printf("%s\n", bf); fflush(NULL); sleep(10); } else if (0 < pid) { // 親プロセスはその間スリープ sleep(10); } return 0; } ただ処理を子プロセスへ振っただけですので,
このサンプルはそのまま動作します。 % clang read-cap-process.
c % ./ a. out | head -3 # $FreeBSD: head/ COPYRIGHT 216848 2010-12-31 18:07:16Z bz $ # @(#)COPYRIGHT 8. 2 (Berkeley) 3/ 21/ 94 % 今度は子プロセス側で読み込みではなく,
書き込みを実施するように処理を変更してみます。 「read-cap-process2. c」 として用意しました。 #include <stdlib.
h> #include <stdio. h> #include <fcntl. h> #include <unistd. h> #include <err. h> #include <errno. h> #include <sysexits. h> #include <sys/ capability. h> #include <sys/ types. h> #include <sys/ wait. h> int main(void) { int fd, cap, len, stat; char bf[BUFSIZ], bf2[] = "a"; pid_ t pid; fd = open("COPYRIGHT", O_ RDWR); if (-1 == fd) err(EX_ NOPERM, "open error: %d", errno); cap = cap_ new(dup(fd), CAP_ READ | CAP_ SEEK); if (-1 == cap) err(EX_ NOPERM, "cap_ new error: %d", errno); close(fd); cap_ enter(); pid = fork(); if (-1 == pid) err(EX_ NOPERM, "fork error: %d", errno); if (0 == pid) { // 子プロセス側で書き込みを試みます。 len = write(cap, bf2, 1); if (-1 == len) err(EX_ NOPERM, "write error: %d", errno); sleep(10); } else if (0 < pid) { sleep(10); } return 0; } 実行すると次のようにケーパビリティにおいてエラーが発生することが確認できます。
% clang read-cap-process2.
c % ./ a. out | head -3 a. out: write error: 93: Capabilities insufficient % 一度ケーパビリティモードに入ったプロセスはケーパビリティモードを抜け出すことはできません。ちなみに,
プロセスの親子関係はps(1)コマンドに 「-d」 のオプションを指定すると視覚的に判断できるようになります。便利なので覚えておくといいでしょう。
バックナンバー
FreeBSD Daily Topics
- 2011年9月30日 FreeBSD 1.x系とFreeBSD 10.x系ダブルディジット問題について
- 2011年9月29日 FreeBSD 9.0-BETA3登場
- 2011年9月28日 FreeBSD 10.0-CURRENT登場,ベータ版は3の登場間もなく
- 2011年9月27日 ZFS活用シリーズ - より詳しい情報と説明
- 2011年9月22日 ZFS活用シリーズ - scrubで直らない問題の修正(zdb - 修復編)
- 2011年9月21日 ZFS活用シリーズ - scrubで直らない問題の修正(zdb - 状況調査編)
- 2011年9月20日 ZFS活用シリーズ - scrubで直らない問題の修正(zdb版)
- 2011年9月16日 ZFS活用シリーズ - scrubで直らない問題の修正(アドホック版)
- 2011年9月15日 ZFS活用シリーズ - scrubを使う
- 2011年9月14日 Capsicumを知る - 積極的なセキュリティ強化