OSDN Git Service

長音記号の修正を release に反映
[linuxjm/LDP_man-pages.git] / release / man7 / user_namespaces.7
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>
3 .\"
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.
8 .\"
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.
13 .\"
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
20 .\" professionally.
21 .\"
22 .\" Formatted or processed versions of this manual, if unaccompanied by
23 .\" the source, must acknowledge the copyright and authors of this work.
24 .\" %%%LICENSE_END
25 .\"
26 .\"
27 .\"*******************************************************************
28 .\"
29 .\" This file was generated with po4a. Translate the source file.
30 .\"
31 .\"*******************************************************************
32 .TH USER_NAMESPACES 7 2014\-09\-21 Linux "Linux Programmer's Manual"
33 .SH 名前
34 user_namespaces \- Linux ユーザー名前空間の概要
35 .SH 説明
36 名前空間の概要については \fBnamespaces\fP(7) を参照。
37
38 .\" FIXME: This page says very little about the interaction
39 .\" of user namespaces and keys. Add something on this topic.
40 .\"
41 .\" ============================================================
42 .\"
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) を呼び出してユーザー名前空間を作成したプロセスのユーザー名前空間である。
52
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 で失敗する。
57
58 各プロセスは必ず 1 個のユーザー名前空間のメンバーとなる。 \fBCLONE_NEWUSER\fP フラグを指定せずに \fBfork\fP(2) や
59 \fBclone\fP(2) でプロセスを作成した場合、 そのプロセスは親プロセスと同じユーザー名前空間のメンバーとなる。 シングルスレッドのプログラムは、
60 変更先のユーザー名前空間で \fBCAP_SYS_ADMIN\fP を持っていれば、 \fBsetns\fP(2)
61 を使って別のユーザー名前空間に参加することができる。 変更時に、 変更後の名前空間ですべてのケーパビリティを獲得する。
62
63 .\"
64 .\" ============================================================
65 .\"
66 \fBCLONE_NEWUSER\fP を指定して \fBclone\fP(2) や \fBunshare\fP(2) を呼び出すと、 新しいプロセス
67 (\fBclone\fP(2) の場合) や呼び出したプロセス (\fBunshare\fP(2) の場合)
68 がその呼び出しで作成された新しいユーザー名前空間のメンバーとなる。
69 .SS ケーパビリティ
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 により新しい名前空間の作成や参加が行われた場合であっても、 ケーパビリティを全く持たない。
76
77 \fBexecve\fP(2) の呼び出しでは、 プロセスのケーパビリティは通常の方法 (\fBcapabilities\fP(7) 参照) で再計算され、
78 通常は、 名前空間内でユーザー ID 0 を持つ場合や実行ファイルが空でない継承可能ケーパビリティマスクを持っている場合を除くと、
79 すべてのケーパビリティを失うことになる。 下記の、ユーザー ID やグループ ID のマッピングの議論を参照。
80
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" フラグを再設定することはできない。
87
88 ユーザー名前空間内部でケーパビリティを持つというのは、 そのプロセスがその名前空間の支配下にあるリソースに対してのみ (特権を必要とする)
89 操作を実行できるということである。 プロセスが特定のユーザー名前空間でケーパビリティを持つかどうかを判定するルールは以下の通りである。
90 .IP 1. 3
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) の結果としてケーパビリティを獲得することもできる。
96 .IP 2.
97 プロセスがユーザー名前空間でケーパビリティを持っている場合、 そのプロセスはすべての子供の名前空間 (および削除された子孫の名前空間)
98 でケーパビリティを持つ。
99 .IP 3.
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
105 .\" on this point
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.
108 .\"
109 .\" ============================================================
110 .\"
111 ユーザー名前空間が作成された際、 カーネルはその名前空間の「所有者」として作成したプロセスの実効ユーザー ID を記録する。
112 親のユーザー名前空間に属するプロセスで、 そのプロセスの実効ユーザー ID が名前空間の所有者と一致する場合、
113 そのプロセスはその名前空間ですべてのケーパビリティを持つ。 一つ前のルールも合わせて考えると、
114 このプロセスはすべての削除された子孫のユーザー名前空間ですべてのケーパビリティを持つことを意味する。
115 .SS ユーザー名前空間と他の名前空間の関係
116 Linux 3.8 以降では、 非特権プロセスがユーザー名前空間を作成することができる。 また、 呼び出し元のユーザー名前空間で
117 \fBCAP_SYS_ADMIN\fP ケーパビリティを持っているだけで、 マウント名前空間、 PID 名前空間、 IPC 名前空間、 ネットワーク名前空間、
118 UTS 名前空間を作成できる。
119
120 ユーザー名前空間以外の名前空間が作成された場合、 その名前空間は呼び出したプロセスが名前空間の作成時にメンバーであったユーザー名前空間により所有される。
121 ユーザー名前空間以外の名前空間における操作には、 対応するユーザー名前空間でのケーパビリティが必要である。
122
123 一つの \fBclone\fP(2) や \fBunshare\fP(2) の呼び出しで \fBCLONE_NEWUSER\fP が他の \fBCLONE_NEW*\fP
124 フラグと一緒に指定された場合、 そのユーザー名前空間が最初に作成されることが保証され、 子プロセス (\fBclone\fP(2) の場合) や呼び出し元
125 (\fBunshare\fP(2) の場合) はその呼び出しで作成される残りの名前空間で特権を持つ。 したがって、
126 特権を持たない呼び出し元がフラグを組み合わせて指定することができる。
127
128 .\"
129 .\" ============================================================
130 .\"
131 新しい IPC 名前空間、 マウント名前空間、 ネットワーク名前空間、 PID 名前空間、 UTS 名前空間が \fBclone\fP(2) や
132 \fBunshare\fP(2) で作成される際、 カーネルは新しい名前空間に対して作成したプロセスのユーザー名前空間を記録する
133 (この関連付けは変更できない)。 その新しい名前空間のプロセスがその後名前空間で分離されたグローバルリソースに対して特権操作を行う場合、
134 カーネルが新しい名前空間に対して関連付けたユーザー名前空間でのプロセスのケーパビリティに基づいてアクセス許可のチェックが行われる。
135 .SS マウント名前空間における制限
136
137 マウント名前空間に関しては以下の点に注意すること。
138 .IP * 3
139 マウント名前空間は所有者のユーザー名前空間を持つ。 所有者のユーザー名前空間が親のマウント名前空間の所有者のユーザー名前空間と異なるマウント名前空間は、
140 特権が少ないマウント名前空間 (less privileged mount namespace) である。
141 .IP *
142 特権が少ないマウント名前空間を作成する場合、 共有マウントは slave マウントに縮小される。 これにより、
143 特権の少ないマウント名前空間で実行されるマッピングが、 より特権を持つマウント名前空間 (more privileged mount
144 namespace) に伝搬しないことが保証される。
145 .IP *
146 .\" FIXME .
147 .\"     What does "come as a single unit from more privileged mount" mean?
148 より特権を持つマウントで一つのまとまりとして行われたマウントは一つにまとまったままとなり、 特権が少ないマウント名前空間で分割することはできない。
149 (\fBunshare\fP(2) の \fBCLONE_NEWNS\fP 操作では、 元のマウント名前空間のすべてのマウントは一つのまとまりとして扱われ、
150 マウント名前空間間で伝わる再帰的なマウントでは一つのまとまりとして伝わる。)
151 .IP *
152 .\" commit 9566d6742852c527bf5af38af5cbb878dad75705
153 .\" Author: Eric W. Biederman <ebiederm@xmission.com>
154 .\" Date:   Mon Jul 28 17:26:07 2014 -0700
155 .\"
156 .\"      mnt: Correct permission checks in do_remount
157 .\"
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) 設定はロックされ、 特権の少ないマウント名前空間では変更することはできない。
161 .IP *
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)) を行うことができる。
166 .IP
167 .\"
168 .\" ============================================================
169 .\"
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 これらのファイルを読み出してユーザー名前空間内のマッピングを参照したり、 これらのファイルに書き込んでマッピングを (一度だけ) 定義することができる。
180
181 以下の段落で \fIuid_map\fP の詳細を説明する。 \fIgid_map\fP に関しても全く同じである。 "user ID" という部分を "group
182 ID" に置き換えればよい。
183
184 \fIuid_map\fP ファイルで、 プロセス \fIpid\fP のユーザー名前空間から \fIuid_map\fP
185 をオープンしたプロセスのユーザー名前空間にユーザー ID のマッピングが公開される (公開するポリシーの条件については下記を参照)。 言い換えると、
186 別のユーザー名前空間のプロセスでは、 特定の \fIuid_map\fP ファイルを読み出した際に潜在的には別の値が見えることがあるということである。
187 見える値は読み出したプロセスのユーザー名前空間のユーザー ID マッピングに依存する。
188
189 \fIuid_map\fP ファイルの各行は 2 つのユーザー名前空間間の連続するユーザー ID の範囲の 1 対 1 マッピングを指定する
190 (ユーザー名前空間が最初に作成された際にはこのファイルは空である)。 各行の指定の形式はホワイトスペース区切りの 3 つの数字である。 最初の 2
191 つの数字は 2 つの ユーザー名前空間それぞれの開始ユーザー ID を指定する。 3 つ目の数字はマッピングされる範囲の長さを指定する。
192 詳しくは、各フィールドは以下のように解釈される。
193 .IP (1) 4
194 プロセス \fIpid\fP のユーザー名前空間におけるユーザー ID の範囲の開始値。
195 .IP (2)
196 1 番目のフィールドで指定されたユーザー ID がマッピングされる先のユーザー ID の範囲の開始値。 2 番目のフィールドがどのように解釈されるかは、
197 \fIuid_map\fP をオープンしたプロセスとプロセス \fIpid\fP が同じユーザー名前空間かどうかに依存する。 以下のとおり。
198 .RS
199 .IP a) 3
200 2 つのプロセスが異なるユーザー名前空間に属す場合、 2 番目のフィールドは \fIuid_map\fP
201 をオープンしたプロセスのユーザー名前空間におけるユーザー ID の範囲の開始値である。
202 .IP b)
203 2 つのプロセスが同じユーザー名前空間に属す場合、 2 番目のフィールドはプロセス \fIpid\fP の親のユーザー名前空間におけるユーザー ID
204 の範囲の開始値である。 この場合、 \fIuid_map\fP をオープンしたプロセス (よくあるのは \fI/proc/self/uid_map\fP
205 をオープンした場合である) は、 このユーザー名前空間を作成したプロセスのユーザー名前空間に対するユーザー ID マッピングを参照することができる。
206 .RE
207 .IP (3)
208 2 つのユーザー名前空間間でマッピングされるユーザー ID の範囲の長さ。
209 .PP
210 ユーザー ID (グループ ID) を返すシステムコール、例えば \fBgetuid\fP(2), \fBgetgid\fP(2) や \fBstat\fP(2)
211 が返す構造体の credential フィールド、は呼び出し元のユーザー名前空間にマッピングされたユーザー ID (グループ ID) を返す。
212
213 プロセスがファイルにアクセスする場合、 アクセス許可のチェックやファイル作成時の ID 割り当てのために、 そのユーザー ID とグループ ID
214 は初期ユーザー名前空間にマッピングされる。 プロセスが \fBstat\fP(2) を使ってファイルのユーザー ID やグループ ID を取得する際には、
215 上記の反対方向に ID のマッピングが行われ、 プロセスにおける相対的なユーザー ID とグループ ID の値が生成される。
216
217 初期ユーザー名前空間は親の名前空間を持たないが、 一貫性を持たせるため、 カーネルは初期の名前空間に対してダミーのユーザー ID とグループ ID
218 のマッピングを提供する。 初期の名前空間のシェルから \fIuid_map\fP ファイル (\fIgid_map\fP も同じ) を参照するには以下のようにする。
219
220 .in +4n
221 .nf
222 $ \fBcat /proc/$$/uid_map\fP
223          0          0 4294967295
224 .fi
225 .in
226
227 .\"
228 .\" ============================================================
229 .\"
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 への書き込み"
237 .PP
238 新しいユーザー名前空間を作成した後、 新しいユーザー名前空間におけるユーザー ID のマッピングを定義するため、 その名前空間のプロセスの「一つ」の
239 \fIuid_map\fP ファイルに「一度だけ」書き込みを行うことができる。 ユーザー名前空間の \fIuid_map\fP
240 ファイルに二度目以降の書き込みを行おうとすると、 エラー \fBEPERM\fP で失敗する。 \fIgid_map\fP
241 ファイルについては同じルールが適用される。
242
243 \fIuid_map\fP (\fIgid_map\fP) に書き込む行は以下のルールに従っていなければならない。
244 .IP * 3
245 3 のフィールドは有効な数字でなければならず、最後のフィールドは 0 より大きくなければならない。
246 .IP *
247 行は改行文字で終了しなければならない。
248 .IP *
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 以外のファイルオフセットに書き込むことはできない)。
255 .IP *
256 .\" commit 0bd14b4fd72afd5df41e9fd59f356740f22fceba
257 各行で指定されるユーザー ID (グループ ID) の範囲は他の行が指定する範囲と重なってはならない。 最初の実装 (Linux 3.8) では、
258 この要件は、 後続行のフィールド 1 とフィールド 2 の両方の値が昇順になっていなければならないという追加の要件を設け、
259 これが満たされなかった場合は有効なマッピングは作成されない、 という単純な実装により満たされていた。 Linux 3.9 以降ではこの制限は修正され、
260 重複がない有効なマッピングであればどんな組み合わせでも指定できるようになった。
261 .IP *
262 少なくとも 1 行はファイルに書き込まなければならない。
263 .PP
264 上記のルールを満たさない書き込みはエラー \fBEINVAL\fP で失敗する。
265
266 プロセスが \fI/proc/[pid]/uid_map\fP (\fI/proc/[pid]/gid_map\fP) ファイルに書き込むためには、
267 以下の要件がすべて満たされる必要がある。
268 .IP 1. 3
269 書き込みプロセスは、 プロセス \fIpid\fP のユーザー名前空間で \fBCAP_SETUID\fP (\fBCAP_SETGID\fP)
270 ケーパビリティを持っていなければならない。
271 .IP 2.
272 書き込みプロセスは、 プロセス \fIpid\fP のユーザー名前空間もしくはプロセス \fIpid\fP の親のユーザー名前空間に属していなければならない。
273 .IP 3.
274 マッピングされたユーザー ID (グループ ID) は親のユーザー名前空間にマッピングを持っていなければならない。
275 .IP 4.
276 以下のいずれか一つが真である。
277 .RS
278 .IP * 3
279 \fIuid_map\fP (\fIgid_map\fP) に書き込まれるデータは、 書き込みを行うプロセスの親のユーザー名前空間でのファイルシステムユーザー ID
280 (グループ ID) をそのユーザー名前空間でのユーザー ID (グループ ID) にマッピングする 1 行で構成されている。
281 .IP * 3
282 オープンしたプロセスが親のユーザー名前空間で \fBCAP_SETUID\fP (\fBCAP_SETGID\fP) ケーパビリティを持っている。 したがって、
283 特権プロセスは親のユーザー名前空間の任意のユーザー ID (グループ ID) に対するマッピングを作成できる。
284 .RE
285 .PP
286 .\"
287 .\" ============================================================
288 .\"
289 上記のルールを満たさない書き込みはエラー \fBEPERM\fP で失敗する。
290 .SS "マッピングされていないユーザー ID とグループ ID"
291 .PP
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 の説明を参照。
298
299 .\" also SO_PEERCRED
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) 参照) がある。
306
307 .\" from_kuid(), from_kgid()
308 .\" Also F_GETOWNER_UIDS is an exception
309 .\"
310 .\" ============================================================
311 .\"
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 されたプログラム"
316 .PP
317 .\"
318 .\" ============================================================
319 .\"
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) を参照。)
326 .SS その他
327 .PP
328 .\"
329 プロセスのユーザー ID とグループ ID が UNIX ドメインソケットを通して別のユーザー名前空間のプロセスに渡された場合 (\fBunix\fP(7)
330 の \fBSCM_CREDENTIALS\fP の説明を参照)、 ユーザー ID とグループ ID は受信プロセスのユーザー ID とグループ ID
331 のマッピングに基づき対応する値に翻訳される。
332 .SH 準拠
333 .\"
334 名前空間は Linux 独自の機能である。
335 .SH 注意
336 .\"
337 .\" ============================================================
338 .\"
339 長年にわたり、Linux カーネルには特権ユーザーに対してだけ利用できる機能が多く追加されて来た。 これは set\-user\-ID\-root
340 アプリケーションを混乱させる潜在的な可能性を考慮してである。 一般的には、 ユーザー名前空間の root
341 ユーザーにだけこれらの機能の使用を許可するのが安全である。 なぜなら、ユーザー名前空間の中にいる間は、 ユーザー名前空間の root
342 ユーザーが持っている以上の特権を得ることはできないからである。
343 .SS 可用性
344 ユーザー名前空間を使用するには、 \fBCONFIG_USER_NS\fP オプションが有効になったカーネルが必要である。
345 ユーザー名前空間をカーネルの様々なサブシステムのサポートを必要とする。 サポートされていないサブシステムがカーネルに組み込まれている場合、
346 ユーザー名前空間のサポートを有効にすることはできない。
347
348 .\" commit d6970d4b726cea6d7a9bc4120814f95c09571fc3
349 .\"
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 では、最後の主要な未サポートのファイルシステムであった
354 XFS のサポートが追加された。
355 .SH 例
356 以下のプログラムは、ユーザー名前空間で実験を行えるように設計されている。 他の種類の名前空間も扱える。
357 このプログラムはコマンドライン引き数で指定された名前空間を作成し、作成した名前空間内でコマンドを実行する。 コメントとプログラム内の
358 \fIusage()\fP 関数に、プログラムの詳しい説明が書かれている。 以下のシェルセッションに実行例を示す。
359
360 まず最初に、実行環境を確認しておく。
361
362 .in +4n
363 .nf
364 $ \fBuname \-rs\fP     # Linux 3.8 以降が必要
365 Linux 3.8.0
366 $ \fBid \-u\fP         # 非特権ユーザーで実行する
367 1000
368 $ \fBid \-g\fP
369 1000
370 .fi
371 .in
372
373 新しいユーザー名前空間 (\fI\-U\fP), マウント名前空間 (\fI\-m\fP), PID 名前空間 (\fI\-p\fP) で新しいシェルを開始する。ユーザー ID
374 (\fI\-M\fP) 1000 とグループ ID (\fI\-G\fP) 1000 をユーザー名前空間内で 0 にマッピングしている。
375
376 .in +4n
377 .nf
378 $ \fB./userns_child_exec \-p \-m \-U \-M '0 1000 1' \-G '0 1000 1' bash\fP
379 .fi
380 .in
381
382 シェルは PID 1 を持つ。このシェルは新しい PID 名前空間の最初のプロセスだからである。
383
384 .in +4n
385 .nf
386 bash$ \fBecho $$\fP
387 1
388 .fi
389 .in
390
391 ユーザー名前空間内では、シェルのユーザー ID とグループ ID ともに 0 で、すべての許可ケーパビリティと実効ケーパビリティが有効になっている。
392
393 .in +4n
394 .nf
395 bash$ \fBcat /proc/$$/status | egrep '^[UG]id'\fP
396 Uid:    0       0       0       0
397 Gid:    0       0       0       0
398 bash$ \fBcat /proc/$$/status | egrep '^Cap(Prm|Inh|Eff)'\fP
399 CapInh: 0000000000000000
400 CapPrm: 0000001fffffffff
401 CapEff: 0000001fffffffff
402 .fi
403 .in
404
405 \fI/proc\fP ファイルシステムをマウントし、新しい PID 名前空間で見えるプロセス一覧を表示すると、 シェルからは PID
406 名前空間外のプロセスが見えないことが分かる。
407
408 .in +4n
409 .nf
410 bash$ \fBmount \-t proc proc /proc\fP
411 bash$ \fBps ax\fP
412   PID TTY      STAT   TIME COMMAND
413     1 pts/3    S      0:00 bash
414    22 pts/3    R+     0:00 ps ax
415 .fi
416 .in
417 .SS プログラムのソース
418 \&
419 .nf
420 /* userns_child_exec.c
421
422    GNU General Public License v2 以降の元でライセンスされる
423
424    新しい名前空間でシェルコマンドを実行する子プロセスを作成する。
425    ユーザー名前空間を作成する際に UID と GID のマッピングを
426    指定することができる。
427 */
428 #define _GNU_SOURCE
429 #include <sched.h>
430 #include <unistd.h>
431 #include <stdlib.h>
432 #include <sys/wait.h>
433 #include <signal.h>
434 #include <fcntl.h>
435 #include <stdio.h>
436 #include <string.h>
437 #include <limits.h>
438 #include <errno.h>
439
440 /* 簡単なエラー処理関数: \\(aqerrno\\(aq の値に基づいて
441    エラーメッセージを出力し、呼び出し元プロセスを終了する。 */
442
443 #define errExit(msg)    do { perror(msg); exit(EXIT_FAILURE); \e
444                         } while (0)
445
446 struct child_args {
447     char **argv;        /* 子プロセスが実行するコマンドと引き数 */
448     int    pipe_fd[2];  /* 親プロセスと子プロセスを同期するためのパイプ */
449 };
450
451 static int verbose;
452
453 static void
454 usage(char *pname)
455 {
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");
473     fpe("\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");
476     fpe("\en");
477     fpe("Map strings for \-M and \-G consist of records of the form:\en");
478     fpe("\en");
479     fpe("    ID\-inside\-ns   ID\-outside\-ns   len\en");
480     fpe("\en");
481     fpe("A map string can contain multiple records, separated"
482         " by commas;\en");
483     fpe("the commas are replaced by newlines before writing"
484         " to map files.\en");
485
486     exit(EXIT_FAILURE);
487 }
488
489 /* マッピングファイル \(aqmap_file\(aq を \(aqmapping\(aq で指定
490    された値で更新する。 \(aqmapping\(aq は UID や GID マッピングを
491    定義する文字列である。 UID や GID マッピングは以下の形式の改行
492    で区切られた 1 つ以上のレコードである。
493
494        NS 内 ID        NS 外 ID        長さ
495
496    ユーザーに改行を含む文字列を指定するのを求めるのは、
497    コマンドラインを使う場合にはもちろん不便なことである。
498    そのため、 この文字列でレコードを区切るのにカンマを
499    使えるようにして、ファイルにこの文字列を書き込む前に
500    カンマを改行に置換する。 */
501
502 static void
503 update_map(char *mapping, char *map_file)
504 {
505     int fd, j;
506     size_t map_len;     /* \(aqmapping\(aq の長さ */
507
508     /* マッピング文字列内のカンマを改行で置換する */
509
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;
514
515     fd = open(map_file, O_RDWR);
516     if (fd == \-1) {
517         fprintf(stderr, "ERROR: open %s: %s\en", map_file,
518                 strerror(errno));
519         exit(EXIT_FAILURE);
520     }
521
522     if (write(fd, mapping, map_len) != map_len) {
523         fprintf(stderr, "ERROR: write %s: %s\en", map_file,
524                 strerror(errno));
525         exit(EXIT_FAILURE);
526     }
527
528     close(fd);
529 }
530
531 static int              /* クローンされた子プロセスの開始関数 */
532 childFunc(void *arg)
533 {
534     struct child_args *args = (struct child_args *) arg;
535     char ch;
536
537     /* 親プロセスが UID と GID マッピングを更新するまで待つ。
538        main() のコメントを参照。 パイプの end of file を待つ。
539        親プロセスが一旦マッピングを更新すると、
540        パイプはクローズされる。 */
541
542     close(args\->pipe_fd[1]);    /* パイプのこちら側の書き込み端のディスク
543                                        リプターをクローズする。これにより
544                                        親プロセスがディスクリプターをクローズ
545                                        すると EOF が見えるようになる。 */
546     if (read(args\->pipe_fd[0], &ch, 1) != 0) {
547         fprintf(stderr,
548                 "Failure in child: read from pipe returned != 0\en");
549         exit(EXIT_FAILURE);
550     }
551
552     /* シェルコマンドを実行する */
553
554     printf("About to exec %s\en", args\->argv[0]);
555     execvp(args\->argv[0], args\->argv);
556     errExit("execvp");
557 }
558
559 #define STACK_SIZE (1024 * 1024)
560
561 static char child_stack[STACK_SIZE];    /* 子プロセスのスタック空間 */
562
563 int
564 main(int argc, char *argv[])
565 {
566     int flags, opt, map_zero;
567     pid_t child_pid;
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];
573
574     /* コマンドラインオプションを解析する。
575        最後の getopt() 引き数の最初の \(aq+\(aq 文字は
576        GNU 風のコマンドラインオプションの並び換えを防止する。
577        このプログラム自身が実行する「コマンド」にコマンドライン
578        オプションが含まれる場合があるからである。
579        getopt() にこれらをこのプログラムのオプションとして
580        扱ってほしくはないのだ。 */
581
582     flags = 0;
583     verbose = 0;
584     gid_map = NULL;
585     uid_map = NULL;
586     map_zero = 0;
587     while ((opt = getopt(argc, argv, "+imnpuUM:G:zv")) != \-1) {
588         switch (opt) {
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]);
600         }
601     }
602
603     /* \-U なしの \-M や \-G の指定は意味がない */
604
605     if (((uid_map != NULL || gid_map != NULL || map_zero) &&
606                 !(flags & CLONE_NEWUSER)) ||
607             (map_zero && (uid_map != NULL || gid_map != NULL)))
608         usage(argv[0]);
609
610     args.argv = &argv[optind];
611
612     /* 親プログラムと子プロセスを同期するためにパイプを使っている。
613        これは、子プロセスが execve() を呼び出す前に、親プロセスにより
614        UID と GID マップが設定されることを保証するためである。
615        これにより、新しいユーザー名前空間において子プロセスの実効
616        ユーザー ID を 0 にマッピングしたいという通常の状況で、
617        子プロセスが execve() 実行中にそのケーパビリティを維持する
618        ことができる。 この同期を行わないと、 0 以外のユーザー ID で
619        execve() を実行した際に、子プロセスがそのケーパビリティを失う
620        ことになる (execve() 実行中のプロセスのケーパビリティの変化の
621        詳細については capabilities(7) マニュアルページを参照)。 */
622
623     if (pipe(args.pipe_fd) == \-1)
624         errExit("pipe");
625
626     /* 新しい名前空間で子プロセスを作成する */
627
628     child_pid = clone(childFunc, child_stack + STACK_SIZE,
629                       flags | SIGCHLD, &args);
630     if (child_pid == \-1)
631         errExit("clone");
632
633     /* 親プロセスはここを実行する */
634
635     if (verbose)
636         printf("%s: PID of child created by clone() is %ld\en",
637                 argv[0], (long) child_pid);
638
639     /* 子プロセスの UID と GID のマッピングを更新する */
640
641     if (uid_map != NULL || map_zero) {
642         snprintf(map_path, PATH_MAX, "/proc/%ld/uid_map",
643                 (long) child_pid);
644         if (map_zero) {
645             snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getuid());
646             uid_map = map_buf;
647         }
648         update_map(uid_map, map_path);
649     }
650     if (gid_map != NULL || map_zero) {
651         snprintf(map_path, PATH_MAX, "/proc/%ld/gid_map",
652                 (long) child_pid);
653         if (map_zero) {
654             snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long) getgid());
655             gid_map = map_buf;
656         }
657         update_map(gid_map, map_path);
658     }
659
660     /* パイプの書き込み端をクローズし、子プロセスに UID と GID の
661        マッピングが更新されたことを知らせる */
662
663     close(args.pipe_fd[1]);
664
665     if (waitpid(child_pid, NULL, 0) == \-1)      /* 子プロセスを待つ */
666         errExit("waitpid");
667
668     if (verbose)
669         printf("%s: terminating\en", argv[0]);
670
671     exit(EXIT_SUCCESS);
672 }
673 .fi
674 .SH 関連項目
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)
682 .sp
683 カーネルのソースファイル \fIDocumentation/namespaces/resource\-control.txt\fP
684 .SH この文書について
685 この man ページは Linux \fIman\-pages\fP プロジェクトのリリース 3.78 の一部
686 である。プロジェクトの説明とバグ報告に関する情報は
687 http://www.kernel.org/doc/man\-pages/ に書かれている。