IPC名前空間を調べる(2)

IPC名前空間の初期化で、名前空間のリソース初期化をするこれらの関数は特にこれと言った処理はありません。

各リソースがシステムコールが呼ばれた時にどのように使われるのか?というところに関しては以前読んだので(バージョンは多少違いますが)今回は読みません。

kernhack.hatenablog.com

そうすると、見るところがほとんどなくなるので、とりあえずsetns(2)で使うipcns_install()でも見ておきます。

155 static int ipcns_install(struct nsproxy *nsproxy, struct ns_common *new)
156 {
157         struct ipc_namespace *ns = to_ipc_ns(new);
158         if (!ns_capable(ns->user_ns, CAP_SYS_ADMIN) ||
159             !ns_capable(current_user_ns(), CAP_SYS_ADMIN))
160                 return -EPERM;
161 
162         /* Ditch state from the old ipc namespace */
163         exit_sem(current);
164         put_ipc_ns(nsproxy->ipc_ns);
165         nsproxy->ipc_ns = get_ipc_ns(ns);
166         return 0;
167 }

最初に権限のチェックを行います。次にexit_sem()を呼んでIPCセマフォの取り消し処理が行われます。これはIPC名前空間が変更されるので元の名前空間に変なデータを残さないために必要ですね。 そして、put_ipc_ns()名前空間の参照数を減らし(他に使用者がいなくなればリソースのクリアもする)、最後にsetns()で作成した新しい名前空間のIPC名前空間の参照数を増やします。

ipcns_install()はこのように呼ばれます。

comm(nsenter) pid(18634)
 0xffffffff81279fc0 : ipcns_install+0x0/0x90 [kernel]
 0xffffffff81094d8b : SyS_setns+0xab/0xd0 [kernel]
 0xffffffff8158f36e : entry_SYSCALL_64_fastpath+0x12/0x71 [kernel]

おまけ。setns()でfdからIPC名前空間ns_common構造体はこの流れで取得します。

comm(nsenter) pid(14866)
 0xffffffff81279d20 : ipcns_get+0x0/0x60 [kernel]
 0xffffffff812156d7 : ns_get_path+0x137/0x1d0 [kernel]
 0xffffffff81254420 : proc_ns_follow_link+0x90/0xb0 [kernel]
 0xffffffff811edb07 : trailing_symlink+0x207/0x250 [kernel]
 0xffffffff811ef298 : path_openat+0x158/0x10c0 [kernel]
 0xffffffff811f16d1 : do_filp_open+0x91/0x100 [kernel]
 0xffffffff811e11a6 : do_sys_open+0x146/0x230 [kernel]
 0xffffffff811e12ae : sys_open+0x1e/0x20 [kernel]
 0xffffffff8158f36e : entry_SYSCALL_64_fastpath+0x12/0x71 [kernel]

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考

サイバーセキュリティプログラミング ―Pythonで学ぶハッカーの思考