どこまでも続くアクセスベクタ解析。

オブジェクトクラスnode, netif

意味はアクセスベクタ名のまま。
一つ,netifの「enforce_dest」は使われてない。

IPC関連のオブジェクトクラスの意味。

shm, msgq, semはそのまま,プロセス間通信の共有メモリ,メッセージキュー,セマフォ
こいつらには,プロセス間通信オブジェクトを作成したドメインと同じタイプが付与。
例えばhttpd_tが共有メモリを作ったら,そのタイプはhttpd_t。

問題は,msg。
これの詳細は,NSAの文書を見てもよく分からない。
こういうときは,ソースを解析。
徹底ガイド書くときにも解析したような気もしてきたが,
解析メモが残ってないじゃん。
自分および物好きな人のためメモ残しとこう。

オブジェクトクラスmsgの解析

これは,メッセージキュー内のメッセージの意味。
メッセージをメッセージキューに送信する際,メッセージに別途ラベル付けがされる。問題は,メッセージにどんなラベルが付くか。
ソースを順番に解析してみた。
(1) まず,メッセージの作成時に呼ばれるフック。

static int msg_msg_alloc_security(struct msg_msg *msg)
{
        struct msg_security_struct *msec;

        msec = kmalloc(sizeof(struct msg_security_struct), GFP_KERNEL);
        if (!msec)
                return -ENOMEM;

        memset(msec, 0, sizeof(struct msg_security_struct));
        msec->magic = SELINUX_MAGIC;
        msec->msg = msg;
        msec->sid = SECINITSID_UNLABELED; →ここでラベル付け
        msg->security = msec;

この段階では,unlabeled_t

(2)メッセージをキューに送信する時に呼ばれるフック

static int selinux_msg_queue_msgsnd(struct msg_queue *msq, struct msg_msg *msg,
int msqflg)
…
        tsec = current->security;
        isec = msq->q_perm.security;
        msec = msg->security;
…
       if (msec->sid == SECINITSID_UNLABELED) {
                /*
                 * Compute new sid based on current process and
                 * message queue this message will be stored in
                 */
                rc = security_transition_sid(tsec->sid,    //プロセスのドメイン
                                             isec->sid,// メッセージキューのドメイン
                                             SECCLASS_MSG,
                                             &msec->sid);

メッセージを実際にキューに送信しようというときにラベル付けがされる。
security_transition_sidというので,ラベル付けをしているらしい。

(3) というわけで,seurity_transition_sidのソース ss/service.cを見る

int security_transition_sid(u32 ssid,
                            u32 tsid,
                            u16 tclass,
                            u32 *out_sid)
{
        return security_compute_sid(ssid, tsid, tclass, AVTAB_TRANSITION, out_si
d);
}

static int security_compute_sid(u32 ssid,
                                u32 tsid,
                                u16 tclass,
                                u32 specified,
                                u32 *out_sid)
{
        struct context *scontext = NULL, *tcontext = NULL, newcontext;
        struct role_trans *roletr = NULL;
        struct avtab_key avkey;
        struct avtab_datum *avdatum;
        struct avtab_node *node;
        unsigned int type_change = 0;
        int rc = 0;

        if (!ss_initialized) {
                switch (tclass) {
                case SECCLASS_PROCESS:
                        *out_sid = ssid;  ★1
                        break;
                default:
                        *out_sid = tsid;  ★2
                        break;

…

この関数は,ドメイン遷移,タイプ遷移で,どんなタイプを割振るか計算をするために呼ばれる。
メッセージ関連の遷移設定は,デフォルトでは行われない。
遷移が設定されていない場合のデフォルトは★印。
プロセスが生成される時は,「★1」。つまり,親プロセスのドメインがそのまま受け継がれる。これはおなじみのふるまい。
プロセス以外の場合は,「★2」。「 *out_sid = tsid;」となってる。
今回のsecurity_transition_sidの呼び出しは,

security_transition_sid(tsec->sid,    //プロセスのドメイン
                                             isec->sid,// メッセージキューのドメイン
                                             SECCLASS_MSG,
                                             &msec->sid);

で,tsidは「isec->sid」となってる。
ということは,

(4) 結論
「メッセージには,送信先のメッセージキューと同じドメインが割振られる」
合ってるかな??
例を見てみる。

msg, msgqのラベリング,アクセス制御の具体例

hoge_t foo_tドメイン間のメッセージキュー通信。

(1) hoge_tが,メッセージキューを作成。
メッセージキューには「hoge_t」ドメインが割り当てられる。

(2) hoge_tがメッセージキューにメッセージ送信。
メッセージには,メッセージキューと同じ,hoge_tが割り当てられる。
msgq hoge_t へのenqueue, write
msg hoge_t へのsend
権限が必要。

(3) foo_tが,メッセージキューから受信
msgq hoge_tへのread 
msg hoge_tへのreceive
権限が必要。

(4) foo_tがメッセージキューにメッセージ送信
メッセージには,メッセージキューと同じ,hoge_tが割り当てられる。
msgq hoge_t へのenqueue, write
msg hoge_t へのsend
権限が必要。


以下同様

こう見てみると,msgのラベリングの必要性を感じないなぁ。
msgのラベルが,「メッセージ送信元のドメインと同じ」
ならば,まだ別だが。
MLに聞いてみようかな。

にしても,Linux kernelのソースは,mozillaよりかなり読みやすい…
Cに慣れてるせいだけかもしれないけど。
mozillaは,コンポーネントの塊で,コンポーネントのヘッダファイルが動的に生成されるからlxrでひっかからないし,コンポーネントの実装クラスがどこにあるか分からんし,あるクラスからあるクラスへデータ変換しなきゃだけど,変換方法わけわからんしで,大変です。オブジェクト指向もやり過ぎはいけないのかも??それか,コンポーネントの粒度が細かすぎる?「コード生成」も,ソース解析の罠になりがち。