1 .\" Copyright (c) 2013, 2014 by Michael Kerrisk <mtk.manpages@gmail.com>
2 .\" and Copyright (c) 2012, 2014 by Eric W. Biederman <ebiederm@xmission.com>
4 .\" %%%LICENSE_START(VERBATIM)
5 .\" Permission is granted to make and distribute verbatim copies of this
6 .\" manual provided the copyright notice and this permission notice are
7 .\" preserved on all copies.
9 .\" Permission is granted to copy and distribute modified versions of this
10 .\" manual under the conditions for verbatim copying, provided that the
11 .\" entire resulting derived work is distributed under the terms of a
12 .\" permission notice identical to this one.
14 .\" Since the Linux kernel and libraries are constantly changing, this
15 .\" manual page may be incorrect or out-of-date. The author(s) assume no
16 .\" responsibility for errors or omissions, or for damages resulting from
17 .\" the use of the information contained herein. The author(s) may not
18 .\" have taken the same level of care in the production of this manual,
19 .\" which is licensed free of charge, as they might when working
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
27 .\"*******************************************************************
29 .\" This file was generated with po4a. Translate the source file.
31 .\"*******************************************************************
32 .TH USER_NAMESPACES 7 2014\-09\-21 Linux "Linux Programmer's Manual"
34 user_namespaces \- Linux ユーザー名前空間の概要
36 名前空間の概要については \fBnamespaces\fP(7) を参照。
38 .\" FIXME: This page says very little about the interaction
39 .\" of user namespaces and keys. Add something on this topic.
41 .\" ============================================================
43 ユーザー名前空間は、 セキュリティに関連する識別子や属性、 特にユーザー ID やグループ ID (\fBcredentials\fP(7) 参照)、
44 root ディレクトリ、 キー (\fBkeyctl\fP(2) 参照)、 ケーパビリティを分離する。 プロセスのユーザー ID とグループ ID
45 はユーザー名前空間の内部と外部で異なる場合がある。 特に、 あるプロセスがユーザー名前空間の外部では通常の非特権ユーザー ID を持つが、
46 同時にユーザー名前空間の内部ではユーザー ID 0 を持つという場合がある。 言い換えると、
47 そのプロセスはそのユーザー名前空間の内部での操作に対してすべての特権を持つが、 名前空間の外部での操作では特権を持たない。
48 .SS ネストされた名前空間、名前空間のメンバー
49 ユーザー名前空間は入れ子にすることができる。 つまり、 最初の ("root") 名前空間以外の各名前空間は親のユーザー名前空間を持ち、 0
50 個以上のユーザー名前空間を持つということである。 親のユーザー名前空間は、 \fBCLONE_NEWUSER\fP フラグを指定して
51 \fBunshare\fP(2) や \fBclone\fP(2) を呼び出してユーザー名前空間を作成したプロセスのユーザー名前空間である。
53 .\" commit 8742f229b635bf1c1c84a3dfe5e47c814c20b5c8
54 .\" FIXME Explain the rationale for this limit. (What is the rationale?)
55 カーネルにより (バージョン 3.11 以降では) ユーザー名前空間のネスト数に 32 という上限が課される。 \fBunshare\fP(2) や
56 \fBclone\fP(2) の呼び出しでこの上限を超えてしまう場合はエラー \fBEUSERS\fP で失敗する。
58 各プロセスは必ず 1 個のユーザー名前空間のメンバーとなる。 \fBCLONE_NEWUSER\fP フラグを指定せずに \fBfork\fP(2) や
59 \fBclone\fP(2) でプロセスを作成した場合、 そのプロセスは親プロセスと同じユーザー名前空間のメンバーとなる。 シングルスレッドのプログラムは、
60 変更先のユーザー名前空間で \fBCAP_SYS_ADMIN\fP を持っていれば、 \fBsetns\fP(2)
61 を使って別のユーザー名前空間に参加することができる。 変更時に、 変更後の名前空間ですべてのケーパビリティを獲得する。
64 .\" ============================================================
66 \fBCLONE_NEWUSER\fP を指定して \fBclone\fP(2) や \fBunshare\fP(2) を呼び出すと、 新しいプロセス
67 (\fBclone\fP(2) の場合) や呼び出したプロセス (\fBunshare\fP(2) の場合)
68 がその呼び出しで作成された新しいユーザー名前空間のメンバーとなる。
70 \fBCLONE_NEWUSER\fP フラグが指定された \fBclone\fP(2) で作成された子プロセスは、
71 新しい名前空間ですべてのケーパビリティを持った状態で開始される。 同様に、 \fBunshare\fP(2) を使って新しいユーザー名前空間を作成したり、
72 \fBsetns\fP(2) を使って既存のユーザー名前空間に参加したりしたプロセスは、 その名前空間ですべてのケーパビリティを獲得する。 一方、
73 そのプロセスは、親のユーザー名前空間 (\fBclone\fP(2) の場合) や直前のユーザー名前空間 (\fBunshare\fP(2) や
74 \fBsetns\fP(2) の場合) では、 root ユーザー (root 名前空間のユーザー ID 0 のプロセス)
75 により新しい名前空間の作成や参加が行われた場合であっても、 ケーパビリティを全く持たない。
77 \fBexecve\fP(2) の呼び出しでは、 プロセスのケーパビリティは通常の方法 (\fBcapabilities\fP(7) 参照) で再計算され、
78 通常は、 名前空間内でユーザー ID 0 を持つ場合や実行ファイルが空でない継承可能ケーパビリティマスクを持っている場合を除くと、
79 すべてのケーパビリティを失うことになる。 下記の、ユーザー ID やグループ ID のマッピングの議論を参照。
81 \fBCLONE_NEWUSER\fP フラグを使って \fBclone\fP(2), \fBunshare\fP(2), \fBsetns\fP(2) を呼び出すと、
82 子プロセス (\fBclone\fP(2) の場合) や呼び出し元 (\fBunshare\fP(2) や \fBsetns\fP(2) の場合) では
83 "securebits" フラグ (\fBcapabilities\fP(7) 参照) がデフォルト値に設定される。 呼び出し元は \fBsetns\fP(2)
84 の呼び出し後は元のユーザー名前空間ではケーパビリティを持たないので、 \fBsetns\fP(2) を 2
85 回呼び出して一度別のユーザー名前空間に移動して元のユーザー名前空間に戻ることで、 プロセスが元のユーザー名前空間にとどまりつつ自身の
86 "securebits" フラグを再設定することはできない。
88 ユーザー名前空間内部でケーパビリティを持つというのは、 そのプロセスがその名前空間の支配下にあるリソースに対してのみ (特権を必要とする)
89 操作を実行できるということである。 プロセスが特定のユーザー名前空間でケーパビリティを持つかどうかを判定するルールは以下の通りである。
91 .\" In the 3.8 sources, see security/commoncap.c::cap_capable():
92 プロセスがその名前空間のメンバーで、実効ケーパビリティセットにそのケーパビリティがあれば、 そのプロセスはユーザー名前空間内でケーパビリティを持つ。
93 プロセスが実効ケーパビリティセットでケーパビリティを得るにはいくつかの方法がある。 例えば、 set\-user\-ID
94 プログラムや関連するファイルケーパビリティを持った実行ファイルを実行する。 また、 すでに説明したとおり、 プロセスは \fBclone\fP(2),
95 \fBunshare\fP(2), \fBsetns\fP(2) の結果としてケーパビリティを獲得することもできる。
97 プロセスがユーザー名前空間でケーパビリティを持っている場合、 そのプロセスはすべての子供の名前空間 (および削除された子孫の名前空間)
100 .\" * The owner of the user namespace in the parent of the
101 .\" * user namespace has all caps.
102 .\" (and likewise associates the effective group ID of the creating process
103 .\" with the namespace).
104 .\" See kernel commit 520d9eabce18edfef76a60b7b839d54facafe1f9 for a fix
106 .\" This includes the case where the process executes a set-user-ID
107 .\" program that confers the effective UID of the creator of the namespace.
109 .\" ============================================================
111 ユーザー名前空間が作成された際、 カーネルはその名前空間の「所有者」として作成したプロセスの実効ユーザー ID を記録する。
112 親のユーザー名前空間に属するプロセスで、 そのプロセスの実効ユーザー ID が名前空間の所有者と一致する場合、
113 そのプロセスはその名前空間ですべてのケーパビリティを持つ。 一つ前のルールも合わせて考えると、
114 このプロセスはすべての削除された子孫のユーザー名前空間ですべてのケーパビリティを持つことを意味する。
115 .SS ユーザー名前空間と他の名前空間の関係
116 Linux 3.8 以降では、 非特権プロセスがユーザー名前空間を作成することができる。 また、 呼び出し元のユーザー名前空間で
117 \fBCAP_SYS_ADMIN\fP ケーパビリティを持っているだけで、 マウント名前空間、 PID 名前空間、 IPC 名前空間、 ネットワーク名前空間、
120 ユーザー名前空間以外の名前空間が作成された場合、 その名前空間は呼び出したプロセスが名前空間の作成時にメンバーであったユーザー名前空間により所有される。
121 ユーザー名前空間以外の名前空間における操作には、 対応するユーザー名前空間でのケーパビリティが必要である。
123 一つの \fBclone\fP(2) や \fBunshare\fP(2) の呼び出しで \fBCLONE_NEWUSER\fP が他の \fBCLONE_NEW*\fP
124 フラグと一緒に指定された場合、 そのユーザー名前空間が最初に作成されることが保証され、 子プロセス (\fBclone\fP(2) の場合) や呼び出し元
125 (\fBunshare\fP(2) の場合) はその呼び出しで作成される残りの名前空間で特権を持つ。 したがって、
126 特権を持たない呼び出し元がフラグを組み合わせて指定することができる。
129 .\" ============================================================
131 新しい IPC 名前空間、 マウント名前空間、 ネットワーク名前空間、 PID 名前空間、 UTS 名前空間が \fBclone\fP(2) や
132 \fBunshare\fP(2) で作成される際、 カーネルは新しい名前空間に対して作成したプロセスのユーザー名前空間を記録する
133 (この関連付けは変更できない)。 その新しい名前空間のプロセスがその後名前空間で分離されたグローバルリソースに対して特権操作を行う場合、
134 カーネルが新しい名前空間に対して関連付けたユーザー名前空間でのプロセスのケーパビリティに基づいてアクセス許可のチェックが行われる。
137 マウント名前空間に関しては以下の点に注意すること。
139 マウント名前空間は所有者のユーザー名前空間を持つ。 所有者のユーザー名前空間が親のマウント名前空間の所有者のユーザー名前空間と異なるマウント名前空間は、
140 特権が少ないマウント名前空間 (less privileged mount namespace) である。
142 特権が少ないマウント名前空間を作成する場合、 共有マウントは slave マウントに縮小される。 これにより、
143 特権の少ないマウント名前空間で実行されるマッピングが、 より特権を持つマウント名前空間 (more privileged mount
144 namespace) に伝搬しないことが保証される。
147 .\" What does "come as a single unit from more privileged mount" mean?
148 より特権を持つマウントで一つのまとまりとして行われたマウントは一つにまとまったままとなり、 特権が少ないマウント名前空間で分割することはできない。
149 (\fBunshare\fP(2) の \fBCLONE_NEWNS\fP 操作では、 元のマウント名前空間のすべてのマウントは一つのまとまりとして扱われ、
150 マウント名前空間間で伝わる再帰的なマウントでは一つのまとまりとして伝わる。)
152 .\" commit 9566d6742852c527bf5af38af5cbb878dad75705
153 .\" Author: Eric W. Biederman <ebiederm@xmission.com>
154 .\" Date: Mon Jul 28 17:26:07 2014 -0700
156 .\" mnt: Correct permission checks in do_remount
158 より特権を持つマウント名前空間から特権の少ないマウント名前空間に伝わる際に、 \fBmount\fP(2) の \fBMS_RDONLY\fP,
159 \fBMS_NOSUID\fP, \fBMS_NOEXEC\fP フラグと "atime" フラグ (\fBMS_NOATIME\fP,
160 \fBMS_NODIRATIME\fP, \fBMS_REALTIME\fP) 設定はロックされ、 特権の少ないマウント名前空間では変更することはできない。
162 .\" (As of 3.18-rc1 (in Al Viro's 2014-08-30 vfs.git#for-next tree))
163 ある名前空間でマウントポイントとなっているが別の名前空間でのマウントポイントになっていないファイルやディレクトリは、
164 マウントポイントになっていないマウント名前空間では (通常のアクセス許可チェックにもとづいて) rename, unlink, remove
165 (\fBrmdir\fP(2)) を行うことができる。
168 .\" ============================================================
170 以前は、 別のマウント名前空間でマウントポイントとなっていたファイルやディレクトリを rename, unlink, remove しようとすると、
171 エラー \fBEBUSY\fP が返されていた。 この動作は、 (NFS などで) 適用にあたっての技術的な問題があるとともに、
172 より特権を持つユーザーに対してサービス不能攻撃 (denial\-of\-service attack) を許してしまっていた
173 (ファイルをバインドマウントで更新することができなくなっていた)。
174 .SS "ユーザー ID とグループ ID のマッピング: uid_map と gid_map"
175 .\" commit 22d917d80e842829d0ca0a561967d728eb1d6303
176 ユーザー名前空間が作成された際、 その名前空間は親のユーザー名前空間へのユーザー ID (とグループ ID) のマッピングを行わずに開始される。
177 ファイル \fI/proc/[pid]/uid_map\fP と \fI/proc/[pid]/gid_map\fP (Linux 3.5 以降で利用可能)
178 でプロセス \fIpid\fP のユーザー名前空間内でのユーザー ID とグループ ID のマッピングにアクセスできる。
179 これらのファイルを読み出してユーザー名前空間内のマッピングを参照したり、 これらのファイルに書き込んでマッピングを (一度だけ) 定義することができる。
181 以下の段落で \fIuid_map\fP の詳細を説明する。 \fIgid_map\fP に関しても全く同じである。 "user ID" という部分を "group
184 \fIuid_map\fP ファイルで、 プロセス \fIpid\fP のユーザー名前空間から \fIuid_map\fP
185 をオープンしたプロセスのユーザー名前空間にユーザー ID のマッピングが公開される (公開するポリシーの条件については下記を参照)。 言い換えると、
186 別のユーザー名前空間のプロセスでは、 特定の \fIuid_map\fP ファイルを読み出した際に潜在的には別の値が見えることがあるということである。
187 見える値は読み出したプロセスのユーザー名前空間のユーザー ID マッピングに依存する。
189 \fIuid_map\fP ファイルの各行は 2 つのユーザー名前空間間の連続するユーザー ID の範囲の 1 対 1 マッピングを指定する
190 (ユーザー名前空間が最初に作成された際にはこのファイルは空である)。 各行の指定の形式はホワイトスペース区切りの 3 つの数字である。 最初の 2
191 つの数字は 2 つの ユーザー名前空間それぞれの開始ユーザー ID を指定する。 3 つ目の数字はマッピングされる範囲の長さを指定する。
192 詳しくは、各フィールドは以下のように解釈される。
194 プロセス \fIpid\fP のユーザー名前空間におけるユーザー ID の範囲の開始値。
196 1 番目のフィールドで指定されたユーザー ID がマッピングされる先のユーザー ID の範囲の開始値。 2 番目のフィールドがどのように解釈されるかは、
197 \fIuid_map\fP をオープンしたプロセスとプロセス \fIpid\fP が同じユーザー名前空間かどうかに依存する。 以下のとおり。
200 2 つのプロセスが異なるユーザー名前空間に属す場合、 2 番目のフィールドは \fIuid_map\fP
201 をオープンしたプロセスのユーザー名前空間におけるユーザー ID の範囲の開始値である。
203 2 つのプロセスが同じユーザー名前空間に属す場合、 2 番目のフィールドはプロセス \fIpid\fP の親のユーザー名前空間におけるユーザー ID
204 の範囲の開始値である。 この場合、 \fIuid_map\fP をオープンしたプロセス (よくあるのは \fI/proc/self/uid_map\fP
205 をオープンした場合である) は、 このユーザー名前空間を作成したプロセスのユーザー名前空間に対するユーザー ID マッピングを参照することができる。
208 2 つのユーザー名前空間間でマッピングされるユーザー ID の範囲の長さ。
210 ユーザー ID (グループ ID) を返すシステムコール、例えば \fBgetuid\fP(2), \fBgetgid\fP(2) や \fBstat\fP(2)
211 が返す構造体の credential フィールド、は呼び出し元のユーザー名前空間にマッピングされたユーザー ID (グループ ID) を返す。
213 プロセスがファイルにアクセスする場合、 アクセス許可のチェックやファイル作成時の ID 割り当てのために、 そのユーザー ID とグループ ID
214 は初期ユーザー名前空間にマッピングされる。 プロセスが \fBstat\fP(2) を使ってファイルのユーザー ID やグループ ID を取得する際には、
215 上記の反対方向に ID のマッピングが行われ、 プロセスにおける相対的なユーザー ID とグループ ID の値が生成される。
217 初期ユーザー名前空間は親の名前空間を持たないが、 一貫性を持たせるため、 カーネルは初期の名前空間に対してダミーのユーザー ID とグループ ID
218 のマッピングを提供する。 初期の名前空間のシェルから \fIuid_map\fP ファイル (\fIgid_map\fP も同じ) を参照するには以下のようにする。
222 $ \fBcat /proc/$$/uid_map\fP
228 .\" ============================================================
230 このマッピングは、 この名前空間のユーザー ID 0 から始まる範囲が (実際には存在しない) 親の名前空間の 0 から始まる範囲にマッピングされ、
231 範囲の流さは 32 ビットの unsigned integer の最大値である、 と言っている。 (ここで 4294967295 (32
232 ビットの符号付き \-1 の値) は意図的にマッピングされていない。 \fI(uid_t)\ \-\1\fP は (\fBsetreuid\fP(2) など)
233 いくつかのインターフェースで "no user ID" (ユーザー ID なし) を示す手段として使用されているので、 意図的にこのようになっている。
234 \fI(uid_t)\ \-\1\fP をマッピングせず、 利用できないようにすることで、
235 これらのインターフェースを使った際に混乱が起こらないように保証している。)
236 .SS "ユーザー ID とグループ ID のマッピングの定義: uid_map と gid_map への書き込み"
238 新しいユーザー名前空間を作成した後、 新しいユーザー名前空間におけるユーザー ID のマッピングを定義するため、 その名前空間のプロセスの「一つ」の
239 \fIuid_map\fP ファイルに「一度だけ」書き込みを行うことができる。 ユーザー名前空間の \fIuid_map\fP
240 ファイルに二度目以降の書き込みを行おうとすると、 エラー \fBEPERM\fP で失敗する。 \fIgid_map\fP
241 ファイルについては同じルールが適用される。
243 \fIuid_map\fP (\fIgid_map\fP) に書き込む行は以下のルールに従っていなければならない。
245 3 のフィールドは有効な数字でなければならず、最後のフィールドは 0 より大きくなければならない。
249 .\" FIXME(Eric): the restriction "less than" rather than "less than or equal"
250 .\" seems strangely arbitrary. Furthermore, the comment does not agree
251 .\" with the code in kernel/user_namespace.c. Which is correct?
252 ファイルの行数には上限がある。 Linux 3.8 時点では、上限は 5 行である。 さらに、
253 ファイルに書き込むバイト数はシステムページサイズより小さくなければならず、 書き込みはファイルの先頭に対して行わなければならない (つまり、
254 \fBlseek\fP(2) や \fBpwrite\fP(2) を使って 0 以外のファイルオフセットに書き込むことはできない)。
256 .\" commit 0bd14b4fd72afd5df41e9fd59f356740f22fceba
257 各行で指定されるユーザー ID (グループ ID) の範囲は他の行が指定する範囲と重なってはならない。 最初の実装 (Linux 3.8) では、
258 この要件は、 後続行のフィールド 1 とフィールド 2 の両方の値が昇順になっていなければならないという追加の要件を設け、
259 これが満たされなかった場合は有効なマッピングは作成されない、 という単純な実装により満たされていた。 Linux 3.9 以降ではこの制限は修正され、
260 重複がない有効なマッピングであればどんな組み合わせでも指定できるようになった。
262 少なくとも 1 行はファイルに書き込まなければならない。
264 上記のルールを満たさない書き込みはエラー \fBEINVAL\fP で失敗する。
266 プロセスが \fI/proc/[pid]/uid_map\fP (\fI/proc/[pid]/gid_map\fP) ファイルに書き込むためには、
269 書き込みプロセスは、 プロセス \fIpid\fP のユーザー名前空間で \fBCAP_SETUID\fP (\fBCAP_SETGID\fP)
270 ケーパビリティを持っていなければならない。
272 書き込みプロセスは、 プロセス \fIpid\fP のユーザー名前空間もしくはプロセス \fIpid\fP の親のユーザー名前空間に属していなければならない。
274 マッピングされたユーザー ID (グループ ID) は親のユーザー名前空間にマッピングを持っていなければならない。
279 \fIuid_map\fP (\fIgid_map\fP) に書き込まれるデータは、 書き込みを行うプロセスの親のユーザー名前空間でのファイルシステムユーザー ID
280 (グループ ID) をそのユーザー名前空間でのユーザー ID (グループ ID) にマッピングする 1 行で構成されている。
282 オープンしたプロセスが親のユーザー名前空間で \fBCAP_SETUID\fP (\fBCAP_SETGID\fP) ケーパビリティを持っている。 したがって、
283 特権プロセスは親のユーザー名前空間の任意のユーザー ID (グループ ID) に対するマッピングを作成できる。
287 .\" ============================================================
289 上記のルールを満たさない書き込みはエラー \fBEPERM\fP で失敗する。
290 .SS "マッピングされていないユーザー ID とグループ ID"
292 .\" from_kuid_munged(), from_kgid_munged()
293 マッピングされていないユーザー ID (グループ ID) がユーザー空間に公開される場合はいろいろある。
294 例えば、 新しいユーザー名前空間の最初のプロセスが、 その名前空間に対するユーザー ID マッピングが定義される前に \fBgetuid\fP()
295 を呼び出すなどである。 このようなほとんどの場合で、 マッピングされていないユーザー ID はオーバーフローユーザー ID (グループ
296 ID)に変換される。 デフォルトのオーバーフローユーザー ID (グループ ID) は 65534 である。 \fBproc\fP(5) の
297 \fI/proc/sys/kernel/overflowuid\fP と \fI/proc/sys/kernel/overflowgid\fP の説明を参照。
300 マッピングされていない ID がこのようにマッピングされる場合としては、 ユーザー ID を返すシステムコール (\fBgetuid\fP(2),
301 \fBgetgid\fP(2) やその同類)、 UNIX ドメインソケットで渡される ID 情報 (credential)、 \fBstat\fP(2) が返す
302 ID 情報、 \fBwaitid\fP(2)、 System V IPC "ctl" \fBIPC_STAT\fP 操作、 \fI/proc/PID/status\fP
303 や \fI/proc/sysvipc/*\fP 内のファイルで公開される ID 情報、 シグナル受信時の \fIsiginfo_t\fP の \fIsi_uid\fP
304 フィールドで返される ID 情報 (\fBsigaction\fP(2) 参照)、 プロセスアカウンティングファイルに書き込まれる ID 情報
305 (\fBacct\fP(5) 参照)、 POSIX メッセージキュー通知で返される ID 情報 (\fBmq_notify\fP(3) 参照) がある。
307 .\" from_kuid(), from_kgid()
308 .\" Also F_GETOWNER_UIDS is an exception
310 .\" ============================================================
312 マッピングされていないユーザー ID やグループ ID が対応するオーバーフロー ID 値に変換され「ない」重要な場合が一つある。 2
313 番目のフィールドにマッピングがない \fIuid_map\fP や \fIgid_map\fP ファイルを参照した際、 そのフィールドは 4294967295
314 (unsigned integer では \-1) が表示される。
315 .SS "set\-user\-ID や set\-group\-ID されたプログラム"
318 .\" ============================================================
320 ユーザー名前空間内のプロセスが set\-user\-ID (set\-group\-ID) されたプログラムを実行した場合、
321 そのプロセスの名前空間内の実効ユーザー ID (実効グループ ID) は、 そのファイルのユーザー ID (グループ ID) にマッピングされる。
322 しかし、 そのファイルのユーザー ID 「か」グループ ID が名前空間内のマッピングにない場合、 set\-user\-ID (set\-group\-ID)
323 ビットは黙って無視される。 新しいプログラムは実行されるが、 そのプロセスの実効ユーザー ID (実効グループ ID) は変更されないままとなる。
324 (これは \fBMS_NOSUID\fP フラグ付きでマウントされたファイルシステム上にある set\-user\-ID/set\-group\-ID
325 プログラムを実行した場合の動作を反映したものである。 \fBmount\fP(2) を参照。)
329 プロセスのユーザー ID とグループ ID が UNIX ドメインソケットを通して別のユーザー名前空間のプロセスに渡された場合 (\fBunix\fP(7)
330 の \fBSCM_CREDENTIALS\fP の説明を参照)、 ユーザー ID とグループ ID は受信プロセスのユーザー ID とグループ ID
331 のマッピングに基づき対応する値に翻訳される。
334 名前空間は Linux 独自の機能である。
337 .\" ============================================================
339 長年にわたり、Linux カーネルには特権ユーザーに対してだけ利用できる機能が多く追加されて来た。 これは set\-user\-ID\-root
340 アプリケーションを混乱させる潜在的な可能性を考慮してである。 一般的には、 ユーザー名前空間の root
341 ユーザーにだけこれらの機能の使用を許可するのが安全である。 なぜなら、ユーザー名前空間の中にいる間は、 ユーザー名前空間の root
342 ユーザーが持っている以上の特権を得ることはできないからである。
344 ユーザー名前空間を使用するには、 \fBCONFIG_USER_NS\fP オプションが有効になったカーネルが必要である。
345 ユーザー名前空間をカーネルの様々なサブシステムのサポートを必要とする。 サポートされていないサブシステムがカーネルに組み込まれている場合、
346 ユーザー名前空間のサポートを有効にすることはできない。
348 .\" commit d6970d4b726cea6d7a9bc4120814f95c09571fc3
350 Linux 3.8 時点では、 ほとんどの関連するサブシステムはユーザー名前空間に対応しているが、 多くのファイルシステムにユーザー名前空間間でユーザー
351 ID やグループ ID のマッピングを行うのに必要な基盤がなかった。 Linux 3.9 では、
352 残りの未サポートのファイルシステムの多くで必要な基盤のサポートが追加された (Plan 9 (9P), Andrew File System
353 (AFS), Ceph, CIFS, CODA, NFS, OCFS2)。 Linux 3.11 では、最後の主要な未サポートのファイルシステムであった
356 以下のプログラムは、ユーザー名前空間で実験を行えるように設計されている。 他の種類の名前空間も扱える。
357 このプログラムはコマンドライン引き数で指定された名前空間を作成し、作成した名前空間内でコマンドを実行する。 コメントとプログラム内の
358 \fIusage()\fP 関数に、プログラムの詳しい説明が書かれている。 以下のシェルセッションに実行例を示す。
364 $ \fBuname \-rs\fP # Linux 3.8 以降が必要
366 $ \fBid \-u\fP # 非特権ユーザーで実行する
373 新しいユーザー名前空間 (\fI\-U\fP), マウント名前空間 (\fI\-m\fP), PID 名前空間 (\fI\-p\fP) で新しいシェルを開始する。ユーザー ID
374 (\fI\-M\fP) 1000 とグループ ID (\fI\-G\fP) 1000 をユーザー名前空間内で 0 にマッピングしている。
378 $ \fB./userns_child_exec \-p \-m \-U \-M '0 1000 1' \-G '0 1000 1' bash\fP
382 シェルは PID 1 を持つ。このシェルは新しい PID 名前空間の最初のプロセスだからである。
391 ユーザー名前空間内では、シェルのユーザー ID とグループ ID ともに 0 で、すべての許可ケーパビリティと実効ケーパビリティが有効になっている。
395 bash$ \fBcat /proc/$$/status | egrep '^[UG]id'\fP
398 bash$ \fBcat /proc/$$/status | egrep '^Cap(Prm|Inh|Eff)'\fP
399 CapInh: 0000000000000000
400 CapPrm: 0000001fffffffff
401 CapEff: 0000001fffffffff
405 \fI/proc\fP ファイルシステムをマウントし、新しい PID 名前空間で見えるプロセス一覧を表示すると、 シェルからは PID
406 名前空間外のプロセスが見えないことが分かる。
410 bash$ \fBmount \-t proc proc /proc\fP
412 PID TTY STAT TIME COMMAND
414 22 pts/3 R+ 0:00 ps ax
420 /* userns_child_exec.c
422 GNU General Public License v2 以降の元でライセンスされる
424 新しい名前空間でシェルコマンドを実行する子プロセスを作成する。
425 ユーザー名前空間を作成する際に UID と GID のマッピングを
432 #include <sys/wait.h>
440 /* 簡単なエラー処理関数: \\(aqerrno\\(aq の値に基づいて
441 エラーメッセージを出力し、呼び出し元プロセスを終了する。 */
443 #define errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \e
447 char **argv; /* 子プロセスが実行するコマンドと引き数 */
448 int pipe_fd[2]; /* 親プロセスと子プロセスを同期するためのパイプ */
456 fprintf(stderr, "Usage: %s [options] cmd [arg...]\en\en", pname);
457 fprintf(stderr, "Create a child process that executes a shell "
458 "command in a new user namespace,\en"
459 "and possibly also other new namespace(s).\en\en");
460 fprintf(stderr, "Options can be:\en\en");
461 #define fpe(str) fprintf(stderr, " %s", str);
462 fpe("\-i New IPC namespace\en");
463 fpe("\-m New mount namespace\en");
464 fpe("\-n New network namespace\en");
465 fpe("\-p New PID namespace\en");
466 fpe("\-u New UTS namespace\en");
467 fpe("\-U New user namespace\en");
468 fpe("\-M uid_map Specify UID map for user namespace\en");
469 fpe("\-G gid_map Specify GID map for user namespace\en");
470 fpe("\-z Map user\(aqs UID and GID to 0 in user namespace\en");
471 fpe(" (equivalent to: \-M \(aq0 <uid> 1\(aq \-G \(aq0 <gid> 1\(aq)\en");
472 fpe("\-v Display verbose messages\en");
474 fpe("If \-z, \-M, or \-G is specified, \-U is required.\en");
475 fpe("It is not permitted to specify both \-z and either \-M or \-G.\en");
477 fpe("Map strings for \-M and \-G consist of records of the form:\en");
479 fpe(" ID\-inside\-ns ID\-outside\-ns len\en");
481 fpe("A map string can contain multiple records, separated"
483 fpe("the commas are replaced by newlines before writing"
484 " to map files.\en");
489 /* マッピングファイル \(aqmap_file\(aq を \(aqmapping\(aq で指定
490 された値で更新する。 \(aqmapping\(aq は UID や GID マッピングを
491 定義する文字列である。 UID や GID マッピングは以下の形式の改行
492 で区切られた 1 つ以上のレコードである。
496 ユーザーに改行を含む文字列を指定するのを求めるのは、
497 コマンドラインを使う場合にはもちろん不便なことである。
498 そのため、 この文字列でレコードを区切るのにカンマを
499 使えるようにして、ファイルにこの文字列を書き込む前に
503 update_map(char *mapping, char *map_file)
506 size_t map_len; /* \(aqmapping\(aq の長さ */
508 /* マッピング文字列内のカンマを改行で置換する */
510 map_len = strlen(mapping);
511 for (j = 0; j < map_len; j++)
512 if (mapping[j] == \(aq,\(aq)
513 mapping[j] = \(aq\en\(aq;
515 fd = open(map_file, O_RDWR);
517 fprintf(stderr, "ERROR: open %s: %s\en", map_file,
522 if (write(fd, mapping, map_len) != map_len) {
523 fprintf(stderr, "ERROR: write %s: %s\en", map_file,
531 static int /* クローンされた子プロセスの開始関数 */
534 struct child_args *args = (struct child_args *) arg;
537 /* 親プロセスが UID と GID マッピングを更新するまで待つ。
538 main() のコメントを参照。 パイプの end of file を待つ。
542 close(args\->pipe_fd[1]); /* パイプのこちら側の書き込み端のディスク
545 すると EOF が見えるようになる。 */
546 if (read(args\->pipe_fd[0], &ch, 1) != 0) {
548 "Failure in child: read from pipe returned != 0\en");
554 printf("About to exec %s\en", args\->argv[0]);
555 execvp(args\->argv[0], args\->argv);
559 #define STACK_SIZE (1024 * 1024)
561 static char child_stack[STACK_SIZE]; /* 子プロセスのスタック空間 */
564 main(int argc, char *argv[])
566 int flags, opt, map_zero;
568 struct child_args args;
569 char *uid_map, *gid_map;
570 const int MAP_BUF_SIZE = 100;
571 char map_buf[MAP_BUF_SIZE];
572 char map_path[PATH_MAX];
574 /* コマンドラインオプションを解析する。
575 最後の getopt() 引き数の最初の \(aq+\(aq 文字は
576 GNU 風のコマンドラインオプションの並び換えを防止する。
577 このプログラム自身が実行する「コマンド」にコマンドライン
578 オプションが含まれる場合があるからである。
579 getopt() にこれらをこのプログラムのオプションとして
587 while ((opt = getopt(argc, argv, "+imnpuUM:G:zv")) != \-1) {
589 case \(aqi\(aq: flags |= CLONE_NEWIPC; break;
590 case \(aqm\(aq: flags |= CLONE_NEWNS; break;
591 case \(aqn\(aq: flags |= CLONE_NEWNET; break;
592 case \(aqp\(aq: flags |= CLONE_NEWPID; break;
593 case \(aqu\(aq: flags |= CLONE_NEWUTS; break;
594 case \(aqv\(aq: verbose = 1; break;
595 case \(aqz\(aq: map_zero = 1; break;
596 case \(aqM\(aq: uid_map = optarg; break;
597 case \(aqG\(aq: gid_map = optarg; break;
598 case \(aqU\(aq: flags |= CLONE_NEWUSER; break;
599 default: usage(argv[0]);
603 /* \-U なしの \-M や \-G の指定は意味がない */
605 if (((uid_map != NULL || gid_map != NULL || map_zero) &&
606 !(flags & CLONE_NEWUSER)) ||
607 (map_zero && (uid_map != NULL || gid_map != NULL)))
610 args.argv = &argv[optind];
612 /* 親プログラムと子プロセスを同期するためにパイプを使っている。
613 これは、子プロセスが execve() を呼び出す前に、親プロセスにより
614 UID と GID マップが設定されることを保証するためである。
615 これにより、新しいユーザー名前空間において子プロセスの実効
616 ユーザー ID を 0 にマッピングしたいという通常の状況で、
617 子プロセスが execve() 実行中にそのケーパビリティを維持する
618 ことができる。 この同期を行わないと、 0 以外のユーザー ID で
619 execve() を実行した際に、子プロセスがそのケーパビリティを失う
620 ことになる (execve() 実行中のプロセスのケーパビリティの変化の
621 詳細については capabilities(7) マニュアルページを参照)。 */
623 if (pipe(args.pipe_fd) == \-1)
626 /* 新しい名前空間で子プロセスを作成する */
628 child_pid = clone(childFunc, child_stack + STACK_SIZE,
629 flags | SIGCHLD, &args);
630 if (child_pid == \-1)
636 printf("%s: PID of child created by clone() is %ld\en",
637 argv[0], (long) child_pid);
639 /* 子プロセスの UID と GID のマッピングを更新する */
641 if (uid_map != NULL || map_zero) {
642 snprintf(map_path, PATH_MAX, "/proc/%ld/uid_map",
645 snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getuid());
648 update_map(uid_map, map_path);
650 if (gid_map != NULL || map_zero) {
651 snprintf(map_path, PATH_MAX, "/proc/%ld/gid_map",
654 snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getgid());
657 update_map(gid_map, map_path);
660 /* パイプの書き込み端をクローズし、子プロセスに UID と GID の
661 マッピングが更新されたことを知らせる */
663 close(args.pipe_fd[1]);
665 if (waitpid(child_pid, NULL, 0) == \-1) /* 子プロセスを待つ */
669 printf("%s: terminating\en", argv[0]);
675 .\" From the shadow package
676 .\" From the shadow package
677 .\" From the shadow package
678 .\" From the shadow package
679 \fBnewgidmap\fP(1), \fBnewuidmap\fP(1), \fBclone\fP(2), \fBsetns\fP(2), \fBunshare\fP(2),
680 \fBproc\fP(5), \fBsubgid\fP(5), \fBsubuid\fP(5), \fBcredentials\fP(7),
681 \fBcapabilities\fP(7), \fBnamespaces\fP(7), \fBpid_namespaces\fP(7)
683 カーネルのソースファイル \fIDocumentation/namespaces/resource\-control.txt\fP
685 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.78 の一部
686 である。プロジェクトの説明とバグ報告に関する情報は
687 http://www.kernel.org/doc/man\-pages/ に書かれている。