■
オブジェクトクラス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時にシグナルハンドラをクリア。
ただ,ドメイン遷移が起こってないとチェックされない。
getsession,getpgidの意味
プロセスの「セッションID, プロセスグループID」を得る。これらは,http://japan.linux.com/kernel/internal24/node19.shtml, http://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」がセットされる。