オブジェクトクラスprocessのアクセスベクタのうち分かりにくいもの。

前提知識:fork,cloneで何が継承されるか

ソース見てもいいけど,
http://www.linux.or.jp/JM/html/LDP_man-pages/man2/clone.2.html
を見たほうが早い。
fork,cloneともファイルディスクリプタ,シグナル関係(sighand_struct, signal_struct)は継承されるのだな。
ただ,cloneだと,clone先で上記情報が,共有されるので,例えばclone先でファイル閉じると,clone元でも閉じちゃう?
なお,signal_structの中にrlimit情報が入ってるので,rlimitに関する情報も継承される。

siginhの意味

fork,clone,execすると,シグナルハンドラ,シグナル(signal_struct)が継承されるが,これを拒否するためのパーミッション
これが拒否されると,fork,clone,exec時にシグナルハンドラをクリア。
ただ,ドメイン遷移が起こってないとチェックされない。

rlimitinhの意味

fork,clone,exec時に,rlimit情報の継承を拒否するためのパーミッション
ドメイン遷移が起こってないとチェックされない。

getsession,getpgidの意味

プロセスの「セッションID, プロセスグループID」を得る。これらは,http://japan.linux.com/kernel/internal24/node19.shtmlhttp://www.freebsd.org/doc/ja_JP.eucJP/books/design-44bsd/overview-process-management.html あたりが参考になる。

shareの意味

Implementing the SELinux moduleを見ても分からない。詳細な解析が必要。
まず結論から。

  • shareの意味:clone -> execを許可する

以下,解析。
完全に自分用のメモなので,私以外には,分からないと思われます…
まず,hooks.cを見る。

1685 static void selinux_bprm_apply_creds(struct linux_binprm *bprm, int unsafe)
1686 {
1687         struct task_security_struct *tsec;
1688         struct bprm_security_struct *bsec;
1689         u32 sid;
1690         int rc;
1691 
1692         secondary_ops->bprm_apply_creds(bprm, unsafe);
1693 
1694         tsec = current->security;
1695 
1696         bsec = bprm->security;
1697         sid = bsec->sid;
1698 
1699         tsec->osid = tsec->sid;
1700         bsec->unsafe = 0;
1701         if (tsec->sid != sid) {
1702                 /* Check for shared state.  If not ok, leave SID
1703                    unchanged and kill. */
1704                 if (unsafe & LSM_UNSAFE_SHARE) {
1705                         rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS,
1706                                         PROCESS__SHARE, NULL);

これは,昨日見たexecシステムコールの中で呼ばれるSELinuxのフック。
tsec->sid, と bsec->sidが異なる時(つまりドメイン遷移が発生している時)
かつ,unsafeの「LSM_UNSAFE_SHARE」フラグが立ってるとき,shareのチェックが発生する。

LSM_UNSAFE_SHAREフラグはどんな時に立つのか?
do_execから呼ばれるcompute_creds(昨日の解析にソースがある)

unsafe = unsafe_exec(current);
にて,フラグが立つ。
unsafe_execを見てみる

fs/exec.c
973 static inline int unsafe_exec(struct task_struct *p)
974 {
975         int unsafe = 0;
976         if (p->ptrace & PT_PTRACED) {
977                 if (p->ptrace & PT_PTRACE_CAP)
978                         unsafe |= LSM_UNSAFE_PTRACE_CAP;
979                 else
980                         unsafe |= LSM_UNSAFE_PTRACE;
981         }
982         if (atomic_read(&p->fs->count) > 1 ||
983             atomic_read(&p->files->count) > 1 ||
984             atomic_read(&p->sighand->count) > 1)
985                 unsafe |= LSM_UNSAFE_SHARE;
986 
987         return unsafe;
988 }

タスク構造体の
fs->count ,files->count, sighand->countが1より大きいときに
フラグが立つらしい。
これは何を意味するのだろう?

kernel/fork.c, do_fork(fork,cloneのソース)を見てみると,
cloneシステムコールで,ファイルディスクリプタ,シグナルハンドラ,カレントディレクトリ等を,コピーではなく,共有した場合に,cloneの呼び出し元の「count」が1増えて,1以上になるらしい。
さらに厳密に言うと,CLONE_FSまたはCLONE_FILESまたはCLONE_SIGHANDフラグをセットしてcloneを実行した場合に,上記の「count」が1増える。
つまり,この後execを実行すると,LSM_UNSAFE_SHAREフラグも立って,
「share」アクセスベクタもチェックされる。

shareの例

これでもまだピンとこない。例を考えてみたらやっと分かった。
strictポリシを見てると,一行だけ「share」が使われてる。
allow kernel_t init_t:process share;

kernel_tはカーネルドメイン,init_tは/sbin/initのドメイン
1)カーネルが,cloneでプロセス生成。
プロセスA,Bの2つのプロセスができる。そして,A,B両方の「count」が1増えて,「2」になる。
2)プロセスBで,execv /sbin/initを実行。
3)countが「2」なので,LSM_UNSAFE_SHAREフラグが立つ。
なので,下のように,shareもチェックされる。
rc = avc_has_perm(tsec->sid, sid, SECCLASS_PROCESS, PROCESS__SHARE, NULL);
平たく言うと,clone->exec(でドメイン遷移)するとチェックされるパーミッションであることが分かる。

なお,この際「tsec->sid」はまだ「kernel_t」のまま。sidは「init_t」。
なので,kernel_t, init_t, process:share のチェックとなる。
ちなみに,昨日の解析によると,この後「tsec->sid」に「init_t」がセットされる。