FreeBSD Daily Topics

2011年9月13日Capsicumを知る - ケーパビリティモードはfork()したプロセスにも継承 その2

9月末または10月のリリースが予定されているFreeBSD 9.0-RELEASEには新しいセキュリティ機能「Capsicum」が登場します。FDTではしばらく概念的な説明や、実際の実装例などを紹介して「Capsicum」の機能を紹介していきます。

Capability mode going into a child process

Capsicumの実装例としてもう1つだけ紹介しておきます。昨日掲載したソースコードで、今度は子プロセスでケーパビリティの権限を拡張しようとしてみます。ここでは「read-cap-process3.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, cap2, 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(1) error: %d", errno);

    close(fd);

    cap_enter();

    pid = fork();
    if (-1 == pid)
        err(EX_NOPERM, "fork error: %d", errno);

    if (0 == pid) {
        // 権限を広げる方向へケーパビリティを作成してみる
        cap2 = cap_new(dup(cap), CAP_READ | CAP_WRITE | CAP_SEEK);
        if (-1 == cap2)
            err(EX_NOPERM, "cap_new(2) error: %d", errno);

        close(cap2);

         len = read(cap2, 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-process3.c 
% ./a.out | head -3
a.out: cap_new(2) error: 93: Capabilities insufficient
%

数回に渡ってCapsicumの実装例を紹介してきました。実施、実装するのはcap_new(2)とcap_enter(2)くらいのもので、その実装はとてもシンプルなものです。

おすすめ記事

記事・ニュース一覧