Refpolicyに新規ポリシを追加してみる

新たなアプリ用のポリシを作ってみる。
Tresysのドキュメント
http://serefpolicy.sourceforge.net/index.php?page=getting-started
の例でうまくいくか?
と思ったけど,駄目。適当な例をソースから探してやるしかない。

テスト用のアプリ作成

#vi /usr/bin/test.sh
*1

#!/bin/sh
read $hoge

単に入力待ちするだけのアプリ。
こいつに,tresysのドキュメントに従ってドメインmyapp_tをあたえてみる。
とりあえず,ドメイン遷移だけさせるのが目標。

作業場所は
# pwd
/etc/selinux/refpolicy/src/policy

teファイル作成。

policy_module(myapp,1.0.0)

type myapp_t;
type myapp_exec_t;
role system_r types myapp_t;

domain_type(myapp_t)
domain_entry_file(myapp_t, myapp_exec_t)

ここでは,myapp_tがどんな権限を持つか?
というのを記述。
それとともに,ポリシモジュールも作る。
policy_module(myapp,1.0.0)
マクロでmyappモジュールの宣言をしてる。

ドメインで宣言されたタイプを使う場合は,
かならず,「interface」というマクロを使う。
そうすれば,「require」セクションをかかずにすむ。
interface以外に「template」っていうマクロもある。これは単なるマクロのことらしいが。modularityを乱してしまう気がする。

interfaceの意味は,
http://serefpolicy.sourceforge.net/api-docs/interfaces.html
で大体分かる。
make htmlすれば、doc/htmlに上の最新版が常に生成される。
普通のマクロは,
policy/support以下のファイルをgrep

if ファイル

ifファイルはrefpolicyの新要素。
teファイルで定義したタイプに,他のドメインがアクセスする場合の,マクロ(interfaceと呼ばれる)を記述する。

XMLによって,コメントを記述可能。XMLからinterfaceの意味のドキュメントが自動生成される。ちなみに,国際化は考慮されておりませぬorz
なので,英語でコメント書きましょう。

以下に最低限のifファイルを示す。

#   policy/modules/services/myapp.if
## <summary>Myapp example policy</summary>
## <summary>
##	Execute a domain transition to run myapp.
## </summary>
## <param name="domain">
##	Domain allowed to transition.
## </param>
interface(`myapp_domtrans',`
	gen_requires(`
		type myapp_t, myapp_exec_t;
	')

	domain_auto_trans($1,myapp_exec_t,myapp_t)

	allow $1 myapp_t:fd use;
	allow myapp_t $1:fd use;
	allow $1 myapp_t:fifo_file rw_file_perms;
	allow $1 myapp_t:process sigchld;
')

myapp_domtransという,interfaceが定義されている。
myapp_domtrans(a_t)とすると、a_t -> myapp_t
ドメイン遷移が設定できる。

モジュール登録、設定反映テスト

とりあえず,設定反映ができるかテスト。
policy/modules.confに
myapp = module
を追加。これでmyappモジュールが登録。
ダミーのfcファイル作成
#touch policy/modules/services/myapp.fc

# make load
で設定を反映
# semodule -l
myapp 1.0.0
素晴らしい。いま設定した内容が、モジュールとして反映された。

fcファイル作成

policy/modules/services/myapp.fc

/usr/bin/test.sh --  gen_context(system_u:object_r:myapp_exec_t,s0)

gen_contextの中にsecurity contextを記述。
なぜこんなものを使うかというと,MLS,MCS,MLS無効の場合全てに有効なcontextを書くため。s0というのは,MLSのclearanceだが,MCSの場合は「s0」として問題ない。

ドメイン遷移設定

myapp.teに以下を追加。
domain_auto_trans(unconfined_t, myapp_exec_t, myapp_t)

設定反映

#make myapp.pp
#semodule -i myapp.pp
#restorecon /usr/bin/test.sh
これは昔より早くて素晴らしい。

確認

#/usr/bin/test.sh
別の端末から
#ps -eZ
root:system_r:myapp_t:s0-s0:c0.c255 3974 pts/2 00:00:00 test.sh

うまくいった。グレイト!

モジュールらしくする

実は今書いたポリシはモジュールとしては甘い。
本当は,依存関係を.teファイルに書かなくてはいけない。
が,依存関係をどこまで細かく書けばいいのかはよくわかっていない。。
全部書くとえらいことになる。自動生成できる気もするのだが。
例えば,
require {
type unconfined_t;
};
のように依存関係を記述する。

と,最低限のポリシ書くだけでも、作法が増えている。
mozillaで学んだことだが、
クロスプラットフォーム」にしようとすることによるオーバーヘッドだと思われる。
Refpolicyは、全てのディストリ、MCS,MLSなどをカバーしようとしているので。
クロスプラットフォームといえばmozillaだが,
mozillaでは、なんでもかんでもcomponentにしていった。
その結果、開発者になるための敷居があがってしまったそうだ。
reference policyは、どうなっていくのかな。
今のところは、まさに「コア開発者向け」だが。

*1:当初、/root/test.shにしたが、なぜかrestoreconでラベルがつかない。。