AppArmorのドメイン遷移

seeditのドメイン遷移簡略化を考えるにあたってAppArmorのドメイン割り当てを見てみる。
AppArmorのドメイン(プロファイル)割り当ては、次のようになっているようだ。

プロファイルが割り当てられる場合

  • unconfinedなプロセスから起動され、プロファイルが存在する場合
    • 例:システム起動時

システム起動時、カーネルやinitスクリプトはunconfined。
そこから/usr/sbin/named(プロファイル存在)を実行すると、namedにプロファイルが割り当てられる

  • プロファイル割り当て済みのプロセスが「px」パーミッションでプロファイルが存在するプログラムを実行した場合(日本語がわかりにくい。。)
    • 例:

  /usr/sbin/foo(プロファイル割り当て済みで動作)のプロファイル設定が以下のようになっている
/usr/sbin/hoge px,
/usr/sbin/hogeのプロファイルが存在した場合、fooがhogeを実行すると,hogeにプロファイルが割り当てられる。
/usr/sbin/hogeのプロファイルが存在しない場合は、実行拒否。

プロファイルが割り当てられない場合

  • ixパーミションで実行した場合

 /usr/sbin/foo(プロファイル割り当て済みで動作)のプロファイル設定が以下のようになっている
/usr/sbin/hoge ix,
/usr/sbin/hogeのプロファイルが存在した場合、fooがhogeを実行しても、hogeはfooの権限のまま動作。
/usr/sbin/hogeのプロファイルが存在しない場合も同様。

seeditではどうしよう?

昨日作ったprogram文で定義されたドメインでは、
ドメイン遷移設定を簡略化することができるが、どうしようか?
昨日は、全てのドメインから、program文で定義されたドメインに遷移できたが、
心配なのは、設定ミスで「権限の昇格」が起こること。
● 例:
{
program /sbin/insmod;
allowpriv insmod;
}
とあると、/sbin/insmod(insmod_t)は、カーネルモジュールのインストール許可。
で,
{
program /foo/bar;
allow /usr/sbin/**;
}
と「面倒だから/usr/sbin全部許可してしまえ」としてしまうと、/foo/bar(bar_tドメイン)は,/usr/sbin/insmodが実行可能。
で、insmodは、insmod_tドメインで動作してしまう。insmodにセキュリティホールがあったらジエンド。
なので、昨日つくった振舞では駄目。

AppArmorの事例を踏まえ、再考。
ー1)unconfinedなプロセス(allowpriv allが記述されたプロセス)から起動の場合→ドメイン割り当て
この振舞は安全。unconfinedから、別のドメインに遷移したところで、権限の昇格の起こりようがない(unconfinedが「最大」の権限だから)。

  • 2)ドメイン割り当て済みのプロセスから起動の場合

デフォルトは、ドメイン変わらない
ドメインを割り当てたい場合、「遷移先で、domain_trans」を使うか「pxパーミッション相当のもの(dx?)」を使うようにする。

seeditでの実装

1)の実装
allowpriv allが記述されたドメインにunconfined_domain属性付与するようにし、
domain foo_t;
program /foo/bar;

domain_auto_trans(unconfined_domain,foo_bar_t, foo_t)
と変換されるようにした。

が、login_t,su_t,gdm_tにunconfined_domainが付与されると、PAMのSELinux拡張のせいで、
問題が発生する。例えば,login_tからのドメイン遷移は、unconfined_tだけでないと、変な振舞をする。
なので、これらにunconfined_domain属性を付与しないために、
converter.confのauthentication_domainというフィールドに困るドメインを列挙しておくように。

2) dxパーミッションについては後で。

ついでに、何がunconfinedかのリストを簡単にゲットできるようにするため、
converterに-uオプションを追加。allowpriv allされてるドメイン一覧をファイルに出力。
make reloadと共に、
/etc/selinux/seedit/policy/unconfined_domains
にインストール。
/etc/selinux/seedit/policy/unconfined_domains
を見ることで、どのドメインがunconfiedなのかが一目瞭然。
seedit版unconfinedコマンドでも作ろうかな。