名 前
user_namespaces − Linux ユ ー ザ ー 名 前 空 間 の 概 要
説 明
名 前 空 間 の 概 要 に つ い て は namespaces(7) を 参 照 。 ユ ー ザ ー 名 前 空 間 は 、 セ キ ュ リ テ ィ に 関 連 す る 識 別 子 や 属 性 、 特 に ユ ー ザ ー ID や グ ル ー プ ID (credentials(7) 参 照 )、 root デ ィ レ ク ト リ 、 キ ー (keyctl(2) 参 照 )、 ケ ー パ ビ リ テ ィ を 分 離 す る 。 プ ロ セ ス の ユ ー ザ ー ID と グ ル ー プ ID は ユ ー ザ ー 名 前 空 間 の 内 部 と 外 部 で 異 な る 場 合 が あ る 。 特 に 、 あ る プ ロ セ ス が ユ ー ザ ー 名 前 空 間 の 外 部 で は 通 常 の 非 特 権 ユ ー ザ ー ID を 持 つ が 、 同 時 に ユ ー ザ ー 名 前 空 間 の 内 部 で は ユ ー ザ ー ID 0 を 持 つ と い う 場 合 が あ る 。 言 い 換 え る と 、 そ の プ ロ セ ス は そ の ユ ー ザ ー 名 前 空 間 の 内 部 で の 操 作 に 対 し て す べ て の 特 権 を 持 つ が 、 名 前 空 間 の 外 部 で の 操 作 で は 特 権 を 持 た な い 。 ネ ス ト さ れ た 名 前 空 間 、 名 前 空 間 の メ ン バ ー ユ ー ザ ー 名 前 空 間 は 入 れ 子 に す る こ と が で き る 。 つ ま り 、 最 初 の ("root") 名 前 空 間 以 外 の 各 名 前 空 間 は 親 の ユ ー ザ ー 名 前 空 間 を 持 ち 、 0 個 以 上 の ユ ー ザ ー 名 前 空 間 を 持 つ と い う こ と で あ る 。 親 の ユ ー ザ ー 名 前 空 間 は 、 CLONE_NEWUSER フ ラ グ を 指 定 し て unshare(2) や clone(2) を 呼 び 出 し て ユ ー ザ ー 名 前 空 間 を 作 成 し た プ ロ セ ス の ユ ー ザ ー 名 前 空 間 で あ る 。 カ ー ネ ル に よ り (バ ー ジ ョ ン 3.11 以 降 で は ) ユ ー ザ ー 名 前 空 間 の ネ ス ト 数 に 32 と い う 上 限 が 課 さ れ る 。 unshare(2) や clone(2) の 呼 び 出 し で こ の 上 限 を 超 え て し ま う 場 合 は エ ラ ー EUSERS で 失 敗 す る 。 各 プ ロ セ ス は 必 ず 1 個 の ユ ー ザ ー 名 前 空 間 の メ ン バ ー と な る 。 CLONE_NEWUSER フ ラ グ を 指 定 せ ず に fork(2) や clone(2) で プ ロ セ ス を 作 成 し た 場 合 、 そ の プ ロ セ ス は 親 プ ロ セ ス と 同 じ ユ ー ザ ー 名 前 空 間 の メ ン バ ー と な る 。 シ ン グ ル ス レ ッ ド の プ ロ グ ラ ム は 、 変 更 先 の ユ ー ザ ー 名 前 空 間 で CAP_SYS_ADMIN を 持 っ て い れ ば 、 setns(2) を 使 っ て 別 の ユ ー ザ ー 名 前 空 間 に 参 加 す る こ と が で き る 。 変 更 時 に 、 変 更 後 の 名 前 空 間 で す べ て の ケ ー パ ビ リ テ ィ を 獲 得 す る 。
CLONE_NEWUSER
を 指 定 し て clone(2)
や unshare(2) を 呼 び
出 す と 、 新 し
い プ ロ セ ス
(clone(2) の 場 合 ) や
呼 び 出 し た プ
ロ セ ス (unshare(2) の
場 合 ) が そ の 呼
び 出 し で 作 成
さ れ た 新 し い
ユ ー ザ ー 名 前
空 間 の メ ン バ
ー と な る 。 ケ
ー パ ビ リ テ ィ
CLONE_NEWUSER フ ラ グ が
指 定 さ れ た clone(2)
で 作 成 さ れ た
子 プ ロ セ ス は
、 新 し い 名 前
空 間 で す べ て
の ケ ー パ ビ リ
テ ィ を 持 っ た
状 態 で 開 始 さ
れ る 。 同 様 に
、 unshare(2) を 使 っ
て 新 し い ユ ー
ザ ー 名 前 空 間
を 作 成 し た り
、 setns(2) を 使 っ て
既 存 の ユ ー ザ
ー 名 前 空 間 に
参 加 し た り し
た プ ロ セ ス は
、 そ の 名 前 空
間 で す べ て の
ケ ー パ ビ リ テ
ィ を 獲 得 す る
。 一 方 、 そ の
プ ロ セ ス は 、
親 の ユ ー ザ ー
名 前 空 間 (clone(2)
の 場 合 ) や 直 前
の ユ ー ザ ー 名
前 空 間 (unshare(2) や
setns(2) の 場 合 ) で
は 、 root ユ ー ザ ー
(root 名 前 空 間 の ユ
ー ザ ー ID 0 の プ ロ
セ ス ) に よ り 新
し い 名 前 空 間
の 作 成 や 参 加
が 行 わ れ た 場
合 で あ っ て も
、 ケ ー パ ビ リ
テ ィ を 全 く 持
た な い 。
execve(2) の 呼 び 出 し で は 、 プ ロ セ ス の ケ ー パ ビ リ テ ィ は 通 常 の 方 法 (capabilities(7) 参 照 ) で 再 計 算 さ れ 、 通 常 は 、 名 前 空 間 内 で ユ ー ザ ー ID 0 を 持 つ 場 合 や 実 行 フ ァ イ ル が 空 で な い 継 承 可 能 ケ ー パ ビ リ テ ィ マ ス ク を 持 っ て い る 場 合 を 除 く と 、 す べ て の ケ ー パ ビ リ テ ィ を 失 う こ と に な る 。 下 記 の 、 ユ ー ザ ー ID や グ ル ー プ ID の マ ッ ピ ン グ の 議 論 を 参 照 。
CLONE_NEWUSER フ ラ グ を 使 っ て clone(2), unshare(2), setns(2) を 呼 び 出 す と 、 子 プ ロ セ ス (clone(2) の 場 合 ) や 呼 び 出 し 元 (unshare(2) や setns(2) の 場 合 ) で は "securebits" フ ラ グ (capabilities(7) 参 照 ) が デ フ ォ ル ト 値 に 設 定 さ れ る 。 呼 び 出 し 元 は setns(2) の 呼 び 出 し 後 は 元 の ユ ー ザ ー 名 前 空 間 で は ケ ー パ ビ リ テ ィ を 持 た な い の で 、 setns(2) を 2 回 呼 び 出 し て 一 度 別 の ユ ー ザ ー 名 前 空 間 に 移 動 し て 元 の ユ ー ザ ー 名 前 空 間 に 戻 る こ と で 、 プ ロ セ ス が 元 の ユ ー ザ ー 名 前 空 間 に と ど ま り つ つ 自 身 の "securebits" フ ラ グ を 再 設 定 す る こ と は で き な い 。 ユ ー ザ ー 名 前 空 間 内 部 で ケ ー パ ビ リ テ ィ を 持 つ と い う の は 、 そ の プ ロ セ ス が そ の 名 前 空 間 の 支 配 下 に あ る リ ソ ー ス に 対 し て の み (特 権 を 必 要 と す る ) 操 作 を 実 行 で き る と い う こ と で あ る 。 プ ロ セ ス が 特 定 の ユ ー ザ ー 名 前 空 間 で ケ ー パ ビ リ テ ィ を 持 つ か ど う か を 判 定 す る ル ー ル は 以 下 の 通 り で あ る 。
1. プ ロ セ ス が そ の 名 前 空 間 の メ ン バ ー で 、 実 効 ケ ー パ ビ リ テ ィ セ ッ ト に そ の ケ ー パ ビ リ テ ィ が あ れ ば 、 そ の プ ロ セ ス は ユ ー ザ ー 名 前 空 間 内 で ケ ー パ ビ リ テ ィ を 持 つ 。 プ ロ セ ス が 実 効 ケ ー パ ビ リ テ ィ セ ッ ト で ケ ー パ ビ リ テ ィ を 得 る に は い く つ か の 方 法 が あ る 。 例 え ば 、 |
set−user−ID プ ロ グ ラ ム や 関 連 す る フ ァ イ ル ケ ー パ ビ リ テ ィ を 持 っ た 実 行 フ ァ イ ル を 実 行 す る 。 ま た 、 す で に 説 明 し た と お り 、 プ ロ セ ス は clone(2), unshare(2), setns(2) の 結 果 と し て ケ ー パ ビ リ テ ィ を 獲 得 す る こ と も で き る 。
2. プ ロ セ ス が ユ ー ザ ー 名 前 空 間 で ケ ー パ ビ リ テ ィ を 持 っ て い る 場 合 、 そ の プ ロ セ ス は す べ て の 子 供 の 名 前 空 間 |
(お よ び 削 除 さ れ た 子 孫 の 名 前 空 間 ) で ケ ー パ ビ リ テ ィ を 持 つ 。
3. ユ ー ザ ー 名 前 空 間 が 作 成 さ れ た 際 、 カ ー ネ ル は そ の 名 前 空 間 の 「 所 有 者 」 と し て 作 成 し た プ ロ セ ス の 実 効 ユ ー ザ ー |
ID を 記 録
す る 。 親 の ユ
ー ザ ー 名 前 空
間 に 属 す る プ
ロ セ ス で 、 そ
の プ ロ セ ス の
実 効 ユ ー ザ ー ID
が 名 前 空 間 の
所 有 者 と 一 致
す る 場 合 、 そ
の プ ロ セ ス は
そ の 名 前 空 間
で す べ て の ケ
ー パ ビ リ テ ィ
を 持 つ 。 一 つ
前 の ル ー ル も
合 わ せ て 考 え
る と 、 こ の プ
ロ セ ス は す べ
て の 削 除 さ れ
た 子 孫 の ユ ー
ザ ー 名 前 空 間
で す べ て の ケ
ー パ ビ リ テ ィ
を 持 つ こ と を
意 味 す る 。 ユ
ー ザ ー 名 前 空
間 と 他 の 名 前
空 間 の 関 係
Linux 3.8 以 降 で は 、
非 特 権 プ ロ セ
ス が ユ ー ザ ー
名 前 空 間 を 作
成 す る こ と が
で き る 。 ま た
、 呼 び 出 し 元
の ユ ー ザ ー 名
前 空 間 で CAP_SYS_ADMIN
ケ ー パ ビ リ テ
ィ を 持 っ て い
る だ け で 、 マ
ウ ン ト 名 前 空
間 、 PID 名 前 空 間
、 IPC 名 前 空 間 、
ネ ッ ト ワ ー ク
名 前 空 間 、 UTS 名
前 空 間 を 作 成
で き る 。 ユ ー
ザ ー 名 前 空 間
以 外 の 名 前 空
間 が 作 成 さ れ
た 場 合 、 そ の
名 前 空 間 は 呼
び 出 し た プ ロ
セ ス が 名 前 空
間 の 作 成 時 に
メ ン バ ー で あ
っ た ユ ー ザ ー
名 前 空 間 に よ
り 所 有 さ れ る
。 ユ ー ザ ー 名
前 空 間 以 外 の
名 前 空 間 に お
け る 操 作 に は
、 対 応 す る ユ
ー ザ ー 名 前 空
間 で の ケ ー パ
ビ リ テ ィ が 必
要 で あ る 。 一
つ の clone(2) や unshare(2)
の 呼 び 出 し で
CLONE_NEWUSER が 他 の
CLONE_NEW* フ ラ グ と
一 緒 に 指 定 さ
れ た 場 合 、 そ
の ユ ー ザ ー 名
前 空 間 が 最 初
に 作 成 さ れ る
こ と が 保 証 さ
れ 、 子 プ ロ セ
ス (clone(2) の 場 合 )
や 呼 び 出 し 元
(unshare(2) の 場 合 ) は
そ の 呼 び 出 し
で 作 成 さ れ る
残 り の 名 前 空
間 で 特 権 を 持
つ 。 し た が っ
て 、 特 権 を 持
た な い 呼 び 出
し 元 が フ ラ グ
を 組 み 合 わ せ
て 指 定 す る こ
と が で き る 。
新 し い IPC 名 前 空
間 、 マ ウ ン ト
名 前 空 間 、 ネ
ッ ト ワ ー ク 名
前 空 間 、 PID 名 前
空 間 、 UTS 名 前 空
間 が clone(2) や unshare(2)
で 作 成 さ れ る
際 、 カ ー ネ ル
は 新 し い 名 前
空 間 に 対 し て
作 成 し た プ ロ
セ ス の ユ ー ザ
ー 名 前 空 間 を
記 録 す る (こ の
関 連 付 け は 変
更 で き な い )。
そ の 新 し い 名
前 空 間 の プ ロ
セ ス が そ の 後
名 前 空 間 で 分
離 さ れ た グ ロ
ー バ ル リ ソ ー
ス に 対 し て 特
権 操 作 を 行 う
場 合 、 カ ー ネ
ル が 新 し い 名
前 空 間 に 対 し
て 関 連 付 け た
ユ ー ザ ー 名 前
空 間 で の プ ロ
セ ス の ケ ー パ
ビ リ テ ィ に 基
づ い て ア ク セ
ス 許 可 の チ ェ
ッ ク が 行 わ れ
る 。 マ ウ ン ト
名 前 空 間 に お
け る 制 限 マ ウ
ン ト 名 前 空 間
に 関 し て は 以
下 の 点 に 注 意
す る こ と 。
* マ ウ ン ト 名 前 空 間 は 所 有 者 の ユ ー ザ ー 名 前 空 間 を 持 つ 。 所 有 者 の ユ ー ザ ー 名 前 空 間 が 親 の マ ウ ン ト 名 前 空 間 の 所 有 者 の ユ ー ザ ー 名 前 空 間 と 異 な る マ ウ ン ト 名 前 空 間 は 、 特 権 が 少 な い マ ウ ン ト 名 前 空 間 |
(less privileged mount namespace) で あ る 。
* 特 権 が 少 な い マ ウ ン ト 名 前 空 間 を 作 成 す る 場 合 、 共 有 マ ウ ン ト は slave マ |
ウ ン ト に 縮 小 さ れ る 。 こ れ に よ り 、 特 権 の 少 な い マ ウ ン ト 名 前 空 間 で 実 行 さ れ る マ ッ ピ ン グ が 、 よ り 特 権 を 持 つ マ ウ ン ト 名 前 空 間 (more privileged mount namespace) に 伝 搬 し な い こ と が 保 証 さ れ る 。
* よ り 特 権 を 持 つ マ ウ ン ト で 一 つ の ま と ま り と し て 行 わ れ た マ ウ ン ト は 一 つ に ま と ま っ た ま ま と な り 、 特 権 が 少 な い マ ウ ン ト 名 前 空 間 で 分 割 す る こ と は で き な い 。 |
(unshare(2) の CLONE_NEWNS 操 作 で は 、 元 の マ ウ ン ト 名 前 空 間 の す べ て の マ ウ ン ト は 一 つ の ま と ま り と し て 扱 わ れ 、 マ ウ ン ト 名 前 空 間 間 で 伝 わ る 再 帰 的 な マ ウ ン ト で は 一 つ の ま と ま り と し て 伝 わ る 。 )
* よ り 特 権 を 持 つ マ ウ ン ト 名 前 空 間 か ら 特 権 の 少 な い マ ウ ン ト 名 前 空 間 に 伝 わ る 際 に 、 |
mount(2) の MS_RDONLY, MS_NOSUID, MS_NOEXEC フ ラ グ と "atime" フ ラ グ (MS_NOATIME, MS_NODIRATIME, MS_REALTIME) 設 定 は ロ ッ ク さ れ 、 特 権 の 少 な い マ ウ ン ト 名 前 空 間 で は 変 更 す る こ と は で き な い 。
* あ る 名 前 空 間 で マ ウ ン ト ポ イ ン ト と な っ て い る が 別 の 名 前 空 間 で の マ ウ ン ト ポ イ ン ト に な っ て い な い フ ァ イ ル や デ ィ レ ク ト リ は 、 マ ウ ン ト ポ イ ン ト に な っ て い な い マ ウ ン ト 名 前 空 間 で は |
(通 常 の ア ク セ ス 許 可 チ ェ ッ ク に も と づ い て ) rename, unlink, remove (rmdir(2)) を 行 う こ と が で き る 。 以 前 は 、 別 の マ ウ ン ト 名 前 空 間 で マ ウ ン ト ポ イ ン ト と な っ て い た フ ァ イ ル や デ ィ レ ク ト リ を rename, unlink, remove し よ う と す る と 、 エ ラ ー EBUSY が 返 さ れ て い た 。 こ の 動 作 は 、 (NFS な ど で ) 適 用 に あ た っ て の 技 術 的 な 問 題 が あ る と と も に 、 よ り 特 権 を 持 つ ユ ー ザ ー に 対 し て サ ー ビ ス 不 能 攻 撃 (denial−of−service attack) を 許 し て し ま っ て い た (フ ァ イ ル を バ イ ン ド マ ウ ン ト で 更 新 す る こ と が で き な く な っ て い た )。 ユ ー ザ ー ID と グ ル ー プ ID の マ ッ ピ ン グ : uid_map と gid_map ユ ー ザ ー 名 前 空 間 が 作 成 さ れ た 際 、 そ の 名 前 空 間 は 親 の ユ ー ザ ー 名 前 空 間 へ の ユ ー ザ ー ID (と グ ル ー プ ID) の マ ッ ピ ン グ を 行 わ ず に 開 始 さ れ る 。 フ ァ イ ル /proc/[pid]/uid_map と /proc/[pid]/gid_map (Linux 3.5 以 降 で 利 用 可 能 ) で プ ロ セ ス pid の ユ ー ザ ー 名 前 空 間 内 で の ユ ー ザ ー ID と グ ル ー プ ID の マ ッ ピ ン グ に ア ク セ ス で き る 。 こ れ ら の フ ァ イ ル を 読 み 出 し て ユ ー ザ ー 名 前 空 間 内 の マ ッ ピ ン グ を 参 照 し た り 、 こ れ ら の フ ァ イ ル に 書 き 込 ん で マ ッ ピ ン グ を (一 度 だ け ) 定 義 す る こ と が で き る 。 以 下 の 段 落 で uid_map の 詳 細 を 説 明 す る 。 gid_map に 関 し て も 全 く 同 じ で あ る 。 "user ID" と い う 部 分 を "group ID" に 置 き 換 え れ ば よ い 。
uid_map フ ァ イ ル で 、 プ ロ セ ス pid の ユ ー ザ ー 名 前 空 間 か ら uid_map を オ ー プ ン し た プ ロ セ ス の ユ ー ザ ー 名 前 空 間 に ユ ー ザ ー ID の マ ッ ピ ン グ が 公 開 さ れ る (公 開 す る ポ リ シ ー の 条 件 に つ い て は 下 記 を 参 照 )。 言 い 換 え る と 、 別 の ユ ー ザ ー 名 前 空 間 の プ ロ セ ス で は 、 特 定 の uid_map フ ァ イ ル を 読 み 出 し た 際 に 潜 在 的 に は 別 の 値 が 見 え る こ と が あ る と い う こ と で あ る 。 見 え る 値 は 読 み 出 し た プ ロ セ ス の ユ ー ザ ー 名 前 空 間 の ユ ー ザ ー ID マ ッ ピ ン グ に 依 存 す る 。
uid_map フ ァ イ ル の 各 行 は 2 つ の ユ ー ザ ー 名 前 空 間 間 の 連 続 す る ユ ー ザ ー ID の 範 囲 の 1 対 1 マ ッ ピ ン グ を 指 定 す る (ユ ー ザ ー 名 前 空 間 が 最 初 に 作 成 さ れ た 際 に は こ の フ ァ イ ル は 空 で あ る )。 各 行 の 指 定 の 形 式 は ホ ワ イ ト ス ペ ー ス 区 切 り の 3 つ の 数 字 で あ る 。 最 初 の 2 つ の 数 字 は 2 つ の ユ ー ザ ー 名 前 空 間 そ れ ぞ れ の 開 始 ユ ー ザ ー ID を 指 定 す る 。 3 つ 目 の 数 字 は マ ッ ピ ン グ さ れ る 範 囲 の 長 さ を 指 定 す る 。 詳 し く は 、 各 フ ィ ー ル ド は 以 下 の よ う に 解 釈 さ れ る 。
(1) プ ロ セ ス |
pid の ユ ー ザ ー 名 前 空 間 に お け る ユ ー ザ ー ID の 範 囲 の 開 始 値 。 | ||
(2) |
1 番 目 の フ ィ ー ル ド で 指 定 さ れ た ユ ー ザ ー ID が マ ッ ピ ン グ さ れ る 先 の ユ ー ザ ー ID の 範 囲 の 開 始 値 。 2 番 目 の フ ィ ー ル ド が ど の よ う に 解 釈 さ れ る か は 、 uid_map を オ ー プ ン し た プ ロ セ ス と プ ロ セ ス pid が 同 じ ユ ー ザ ー 名 前 空 間 か ど う か に 依 存 す る 。 以 下 の と お り 。
a) |
2 つ の プ ロ セ ス が 異 な る ユ ー ザ ー 名 前 空 間 に 属 す 場 合 、 2 番 目 の フ ィ ー ル ド は uid_map を オ ー プ ン し た プ ロ セ ス の ユ ー ザ ー 名 前 空 間 に お け る ユ ー ザ ー ID の 範 囲 の 開 始 値 で あ る 。 | ||
b) |
2 つ の プ ロ セ ス が 同 じ ユ ー ザ ー 名 前 空 間 に 属 す 場 合 、 2 番 目 の フ ィ ー ル ド は プ ロ セ ス pid の 親 の ユ ー ザ ー 名 前 空 間 に お け る ユ ー ザ ー ID の 範 囲 の 開 始 値 で あ る 。 こ の 場 合 、 uid_map を オ ー プ ン し た プ ロ セ ス (よ く あ る の は /proc/self/uid_map を オ ー プ ン し た 場 合 で あ る ) は 、 こ の ユ ー ザ ー 名 前 空 間 を 作 成 し た プ ロ セ ス の ユ ー ザ ー 名 前 空 間 に 対 す る ユ ー ザ ー ID マ ッ ピ ン グ を 参 照 す る こ と が で き る 。 | ||
(3) |
2 つ の ユ ー ザ ー 名 前 空 間 間 で マ ッ ピ ン グ さ れ る ユ ー ザ ー ID の 範 囲 の 長 さ 。 ユ ー ザ ー ID (グ ル ー プ ID) を 返 す シ ス テ ム コ ー ル 、 例 え ば getuid(2), getgid(2) や stat(2) が 返 す 構 造 体 の credential フ ィ ー ル ド 、 は 呼 び 出 し 元 の ユ ー ザ ー 名 前 空 間 に マ ッ ピ ン グ さ れ た ユ ー ザ ー ID (グ ル ー プ ID) を 返 す 。 プ ロ セ ス が フ ァ イ ル に ア ク セ ス す る 場 合 、 ア ク セ ス 許 可 の チ ェ ッ ク や フ ァ イ ル 作 成 時 の ID 割 り 当 て の た め に 、 そ の ユ ー ザ ー ID と グ ル ー プ ID は 初 期 ユ ー ザ ー 名 前 空 間 に マ ッ ピ ン グ さ れ る 。 プ ロ セ ス が stat(2) を 使 っ て フ ァ イ ル の ユ ー ザ ー ID や グ ル ー プ ID を 取 得 す る 際 に は 、 上 記 の 反 対 方 向 に ID の マ ッ ピ ン グ が 行 わ れ 、 プ ロ セ ス に お け る 相 対 的 な ユ ー ザ ー ID と グ ル ー プ ID の 値 が 生 成 さ れ る 。 初 期 ユ ー ザ ー 名 前 空 間 は 親 の 名 前 空 間 を 持 た な い が 、 一 貫 性 を 持 た せ る た め 、 カ ー ネ ル は 初 期 の 名 前 空 間 に 対 し て ダ ミ ー の ユ ー ザ ー ID と グ ル ー プ ID の マ ッ ピ ン グ を 提 供 す る 。 初 期 の 名 前 空 間 の シ ェ ル か ら uid_map フ ァ イ ル (gid_map も 同 じ ) を 参 照 す る に は 以 下 の よ う に す る 。
$ cat
/proc/$$/uid_map
0 0 4294967295 こ の マ ッ ピ
ン グ は 、 こ の
名 前 空 間 の ユ
ー ザ ー ID 0 か ら 始
ま る 範 囲 が (実
際 に は 存 在 し
な い ) 親 の 名 前
空 間 の 0 か ら 始
ま る 範 囲 に マ
ッ ピ ン グ さ れ
、 範 囲 の 流 さ
は 32 ビ ッ ト の unsigned
integer の 最 大 値 で
あ る 、 と 言 っ
て い る 。 (こ こ
で 4294967295 (32 ビ ッ ト の
符 号 付 き −1 の
値 ) は 意 図 的 に
マ ッ ピ ン グ さ
れ て い な い 。
(uid_t) −1 は (setreuid(2)
な ど ) い く つ か
の イ ン タ ー フ
ェ ー ス で "no user ID"
(ユ ー ザ ー ID な し )
を 示 す 手 段 と
し て 使 用 さ れ
て い る の で 、
意 図 的 に こ の
よ う に な っ て
い る 。 (uid_t) −1
を マ ッ ピ ン グ
せ ず 、 利 用 で
き な い よ う に
す る こ と で 、
こ れ ら の イ ン
タ ー フ ェ ー ス
を 使 っ た 際 に
混 乱 が 起 こ ら
な い よ う に 保
証 し て い る 。 )
ユ ー ザ ー ID と グ
ル ー プ ID の マ ッ
ピ ン グ の 定 義 :
uid_map と gid_map へ の 書 き
込 み 新 し い ユ
ー ザ ー 名 前 空
間 を 作 成 し た
後 、 新 し い ユ
ー ザ ー 名 前 空
間 に お け る ユ
ー ザ ー ID の マ ッ
ピ ン グ を 定 義
す る た め 、 そ
の 名 前 空 間 の
プ ロ セ ス の 「
一 つ 」 の uid_map フ
ァ イ ル に 「 一
度 だ け 」 書 き
込 み を 行 う こ
と が で き る 。
ユ ー ザ ー 名 前
空 間 の uid_map フ ァ
イ ル に 二 度 目
以 降 の 書 き 込
み を 行 お う と
す る と 、 エ ラ
ー EPERM で 失 敗 す
る 。 gid_map フ ァ イ
ル に つ い て は
同 じ ル ー ル が
適 用 さ れ る 。
uid_map (gid_map) に 書 き 込 む 行 は 以 下 の ル ー ル に 従 っ て い な け れ ば な ら な い 。
* |
3 の フ ィ ー ル ド は 有 効 な 数 字 で な け れ ば な ら ず 、 最 後 の フ ィ ー ル ド は 0 よ り 大 き く な け れ ば な ら な い 。 | ||
* |
行 は 改 行 文 字 で 終 了 し な け れ ば な ら な い 。
* フ ァ イ ル の 行 数 に は 上 限 が あ る 。 |
Linux 3.8 時 点 で は 、 上 限 は 5 行 で あ |
る 。 さ ら に 、 フ ァ イ ル に 書 き 込 む バ イ ト 数 は シ ス テ ム ペ ー ジ サ イ ズ よ り 小 さ く な け れ ば な ら ず 、 書 き 込 み は フ ァ イ ル の 先 頭 に 対 し て 行 わ な け れ ば な ら な い (つ ま り 、 lseek(2) や pwrite(2) を 使 っ て 0 以 外 の フ ァ イ ル オ フ セ ッ ト に 書 き 込 む こ と は で き な い )。
* 各 行 で 指 定 さ れ る ユ ー ザ ー |
ID (グ ル ー プ ID) の 範 囲 は 他 の 行 が 指 定 す る 範 |
囲 と 重 な っ て は な ら な い 。 最 初 の 実 装 (Linux 3.8) で は 、 こ の 要 件 は 、 後 続 行 の フ ィ ー ル ド 1 と フ ィ ー ル ド 2 の 両 方 の 値 が 昇 順 に な っ て い な け れ ば な ら な い と い う 追 加 の 要 件 を 設 け 、 こ れ が 満 た さ れ な か っ た 場 合 は 有 効 な マ ッ ピ ン グ は 作 成 さ れ な い 、 と い う 単 純 な 実 装 に よ り 満 た さ れ て い た 。 Linux 3.9 以 降 で は こ の 制 限 は 修 正 さ れ 、 重 複 が な い 有 効 な マ ッ ピ ン グ で あ れ ば ど ん な 組 み 合 わ せ で も 指 定 で き る よ う に な っ た 。
* 少 な く と も |
1 行 は フ ァ イ ル に 書 き 込 ま な け れ ば な ら な い 。 |
上 記 の ル ー ル を 満 た さ な い 書 き 込 み は エ ラ ー EINVAL で 失 敗 す る 。 プ ロ セ ス が /proc/[pid]/uid_map (/proc/[pid]/gid_map) フ ァ イ ル に 書 き 込 む た め に は 、 以 下 の 要 件 が す べ て 満 た さ れ る 必 要 が あ る 。
1. 書 き 込 み プ ロ セ ス は 、 プ ロ セ ス |
pid の ユ ー ザ ー 名 前 空 間 で CAP_SETUID |
(CAP_SETGID) ケ ー パ ビ リ テ ィ を 持 っ て い な け れ ば な ら な い 。
2. 書 き 込 み プ ロ セ ス は 、 プ ロ セ ス |
pid の ユ ー ザ ー 名 前 空 間 も し く は プ ロ セ ス |
pid の 親 の ユ ー ザ ー 名 前 空 間 に 属 し て い な け れ ば な ら な い 。
3. マ ッ ピ ン グ さ れ た ユ ー ザ ー |
ID (グ ル ー プ ID) は 親 の ユ ー ザ ー 名 前 空 間 に |
マ ッ ピ ン グ を 持 っ て い な け れ ば な ら な い 。
4. 以 下 の い ず れ か 一 つ が 真 で あ る 。 |
||
* |
uid_map (gid_map) に 書 き 込 ま れ る デ ー タ は 、 書 き 込 み を 行 う プ ロ セ ス の 親 の ユ ー ザ ー 名 前 空 間 で の フ ァ イ ル シ ス テ ム ユ ー ザ ー ID (グ ル ー プ ID) を そ の ユ ー ザ ー 名 前 空 間 で の ユ ー ザ ー ID (グ ル ー プ ID) に マ ッ ピ ン グ す る 1 行 で 構 成 さ れ て い る 。
* オ ー プ ン し た プ ロ セ ス が 親 の ユ ー ザ ー 名 前 空 間 で |
CAP_SETUID |
(CAP_SETGID) ケ ー パ ビ リ テ ィ を 持 っ て い る 。 し た が っ て 、 特 権 プ ロ セ ス は 親 の ユ ー ザ ー 名 前 空 間 の 任 意 の ユ ー ザ ー ID (グ ル ー プ ID) に 対 す る マ ッ ピ ン グ を 作 成 で き る 。 上 記 の ル ー ル を 満 た さ な い 書 き 込 み は エ ラ ー EPERM で 失 敗 す る 。 マ ッ ピ ン グ さ れ て い な い ユ ー ザ ー ID と グ ル ー プ ID マ ッ ピ ン グ さ れ て い な い ユ ー ザ ー ID (グ ル ー プ ID) が ユ ー ザ ー 空 間 に 公 開 さ れ る 場 合 は い ろ い ろ あ る 。 例 え ば 、 新 し い ユ ー ザ ー 名 前 空 間 の 最 初 の プ ロ セ ス が 、 そ の 名 前 空 間 に 対 す る ユ ー ザ ー ID マ ッ ピ ン グ が 定 義 さ れ る 前 に getuid() を 呼 び 出 す な ど で あ る 。 こ の よ う な ほ と ん ど の 場 合 で 、 マ ッ ピ ン グ さ れ て い な い ユ ー ザ ー ID は オ ー バ ー フ ロ ー ユ ー ザ ー ID (グ ル ー プ ID)に 変 換 さ れ る 。 デ フ ォ ル ト の オ ー バ ー フ ロ ー ユ ー ザ ー ID (グ ル ー プ ID) は 65534 で あ る 。 proc(5) の /proc/sys/kernel/overflowuid と /proc/sys/kernel/overflowgid の 説 明 を 参 照 。 マ ッ ピ ン グ さ れ て い な い ID が こ の よ う に マ ッ ピ ン グ さ れ る 場 合 と し て は 、 ユ ー ザ ー ID を 返 す シ ス テ ム コ ー ル (getuid(2), getgid(2) や そ の 同 類 )、 UNIX ド メ イ ン ソ ケ ッ ト で 渡 さ れ る ID 情 報 (credential)、 stat(2) が 返 す ID 情 報 、 waitid(2)、 System V IPC "ctl" IPC_STAT 操 作 、 /proc/PID/status や /proc/sysvipc/* 内 の フ ァ イ ル で 公 開 さ れ る ID 情 報 、 シ グ ナ ル 受 信 時 の siginfo_t の si_uid フ ィ ー ル ド で 返 さ れ る ID 情 報 (sigaction(2) 参 照 )、 プ ロ セ ス ア カ ウ ン テ ィ ン グ フ ァ イ ル に 書 き 込 ま れ る ID 情 報 (acct(5) 参 照 )、 POSIX メ ッ セ ー ジ キ ュ ー 通 知 で 返 さ れ る ID 情 報 (mq_notify(3) 参 照 ) が あ る 。 マ ッ ピ ン グ さ れ て い な い ユ ー ザ ー ID や グ ル ー プ ID が 対 応 す る オ ー バ ー フ ロ ー ID 値 に 変 換 さ れ 「 な い 」 重 要 な 場 合 が 一 つ あ る 。 2 番 目 の フ ィ ー ル ド に マ ッ ピ ン グ が な い uid_map や gid_map フ ァ イ ル を 参 照 し た 際 、 そ の フ ィ ー ル ド は 4294967295 (unsigned integer で は −1) が 表 示 さ れ る 。
set−user−ID や set−group−ID さ れ た プ ロ グ ラ ム ユ ー ザ ー 名 前 空 間 内 の プ ロ セ ス が set−user−ID (set−group−ID) さ れ た プ ロ グ ラ ム を 実 行 し た 場 合 、 そ の プ ロ セ ス の 名 前 空 間 内 の 実 効 ユ ー ザ ー ID (実 効 グ ル ー プ ID) は 、 そ の フ ァ イ ル の ユ ー ザ ー ID (グ ル ー プ ID) に マ ッ ピ ン グ さ れ る 。 し か し 、 そ の フ ァ イ ル の ユ ー ザ ー ID 「 か 」 グ ル ー プ ID が 名 前 空 間 内 の マ ッ ピ ン グ に な い 場 合 、 set−user−ID (set−group−ID) ビ ッ ト は 黙 っ て 無 視 さ れ る 。 新 し い プ ロ グ ラ ム は 実 行 さ れ る が 、 そ の プ ロ セ ス の 実 効 ユ ー ザ ー ID (実 効 グ ル ー プ ID) は 変 更 さ れ な い ま ま と な る 。 (こ れ は MS_NOSUID フ ラ グ 付 き で マ ウ ン ト さ れ た フ ァ イ ル シ ス テ ム 上 に あ る set−user−ID/set−group−ID プ ロ グ ラ ム を 実 行 し た 場 合 の 動 作 を 反 映 し た も の で あ る 。 mount(2) を 参 照 。 ) そ の 他 プ ロ セ ス の ユ ー ザ ー ID と グ ル ー プ ID が UNIX ド メ イ ン ソ ケ ッ ト を 通 し て 別 の ユ ー ザ ー 名 前 空 間 の プ ロ セ ス に 渡 さ れ た 場 合 (unix(7) の SCM_CREDENTIALS の 説 明 を 参 照 )、 ユ ー ザ ー ID と グ ル ー プ ID は 受 信 プ ロ セ ス の ユ ー ザ ー ID と グ ル ー プ ID の マ ッ ピ ン グ に 基 づ き 対 応 す る 値 に 翻 訳 さ れ る 。
準 拠
名 前 空 間 は Linux 独 自 の 機 能 で あ る 。
注 意
長 年 に わ た り 、 Linux カ ー ネ ル に は 特 権 ユ ー ザ ー に 対 し て だ け 利 用 で き る 機 能 が 多 く 追 加 さ れ て 来 た 。 こ れ は set−user−ID−root ア プ リ ケ ー シ ョ ン を 混 乱 さ せ る 潜 在 的 な 可 能 性 を 考 慮 し て で あ る 。 一 般 的 に は 、 ユ ー ザ ー 名 前 空 間 の root ユ ー ザ ー に だ け こ れ ら の 機 能 の 使 用 を 許 可 す る の が 安 全 で あ る 。 な ぜ な ら 、 ユ ー ザ ー 名 前 空 間 の 中 に い る 間 は 、 ユ ー ザ ー 名 前 空 間 の root ユ ー ザ ー が 持 っ て い る 以 上 の 特 権 を 得 る こ と は で き な い か ら で あ る 。 可 用 性 ユ ー ザ ー 名 前 空 間 を 使 用 す る に は 、 CONFIG_USER_NS オ プ シ ョ ン が 有 効 に な っ た カ ー ネ ル が 必 要 で あ る 。 ユ ー ザ ー 名 前 空 間 を カ ー ネ ル の 様 々 な サ ブ シ ス テ ム の サ ポ ー ト を 必 要 と す る 。 サ ポ ー ト さ れ て い な い サ ブ シ ス テ ム が カ ー ネ ル に 組 み 込 ま れ て い る 場 合 、 ユ ー ザ ー 名 前 空 間 の サ ポ ー ト を 有 効 に す る こ と は で き な い 。
Linux 3.8 時 点 で は 、 ほ と ん ど の 関 連 す る サ ブ シ ス テ ム は ユ ー ザ ー 名 前 空 間 に 対 応 し て い る が 、 多 く の フ ァ イ ル シ ス テ ム に ユ ー ザ ー 名 前 空 間 間 で ユ ー ザ ー ID や グ ル ー プ ID の マ ッ ピ ン グ を 行 う の に 必 要 な 基 盤 が な か っ た 。 Linux 3.9 で は 、 残 り の 未 サ ポ ー ト の フ ァ イ ル シ ス テ ム の 多 く で 必 要 な 基 盤 の サ ポ ー ト が 追 加 さ れ た (Plan 9 (9P), Andrew File System (AFS), Ceph, CIFS, CODA, NFS, OCFS2)。 Linux 3.11 で は 、 最 後 の 主 要 な 未 サ ポ ー ト の フ ァ イ ル シ ス テ ム で あ っ た XFS の サ ポ ー ト が 追 加 さ れ た 。
例
以 下 の プ ロ グ ラ ム は 、 ユ ー ザ ー 名 前 空 間 で 実 験 を 行 え る よ う に 設 計 さ れ て い る 。 他 の 種 類 の 名 前 空 間 も 扱 え る 。 こ の プ ロ グ ラ ム は コ マ ン ド ラ イ ン 引 き 数 で 指 定 さ れ た 名 前 空 間 を 作 成 し 、 作 成 し た 名 前 空 間 内 で コ マ ン ド を 実 行 す る 。 コ メ ン ト と プ ロ グ ラ ム 内 の usage() 関 数 に 、 プ ロ グ ラ ム の 詳 し い 説 明 が 書 か れ て い る 。 以 下 の シ ェ ル セ ッ シ ョ ン に 実 行 例 を 示 す 。 ま ず 最 初 に 、 実 行 環 境 を 確 認 し て お く 。
$ uname
−rs # Linux 3.8 以 降 が
必 要
Linux 3.8.0
$ id −u # 非 特 権 ユ
ー ザ ー で 実 行
す る
1000
$ id −g
1000 新 し い ユ ー ザ
ー 名 前 空 間
(−U), マ ウ ン ト
名 前 空 間 (−m), PID
名 前 空 間 (−p)
で 新 し い シ ェ
ル を 開 始 す る
。 ユ ー ザ ー ID
(−M) 1000 と グ ル ー
プ ID (−G) 1000 を ユ
ー ザ ー 名 前 空
間 内 で 0 に マ ッ
ピ ン グ し て い
る 。
$ ./userns_child_exec −p −m −U −M ’0 1000 1’ −G ’0 1000 1’ bash シ ェ ル は PID 1 を 持 つ 。 こ の シ ェ ル は 新 し い PID 名 前 空 間 の 最 初 の プ ロ セ ス だ か ら で あ る 。
bash$ echo
$$
1 ユ ー ザ ー 名 前
空 間 内 で は 、
シ ェ ル の ユ ー
ザ ー ID と グ ル ー
プ ID と も に 0 で 、
す べ て の 許 可
ケ ー パ ビ リ テ
ィ と 実 効 ケ ー
パ ビ リ テ ィ が
有 効 に な っ て
い る 。
bash$ cat /proc/$$/status | egrep ’^[UG]id’
Uid: |
0 |
0 |
0 | |||
0 | ||||||
Gid: |
0 |
0 |
0 | |||
0 |
bash$ cat /proc/$$/status | egrep ’^Cap(Prm|Inh|Eff)’
CapInh: |
0000000000000000 | |||
CapPrm: |
0000001fffffffff | |||
CapEff: |
0000001fffffffff |
/proc フ ァ イ ル シ ス テ ム を マ ウ ン ト し 、 新 し い PID 名 前 空 間 で 見 え る プ ロ セ ス 一 覧 を 表 示 す る と 、 シ ェ ル か ら は PID 名 前 空 間 外 の プ ロ セ ス が 見 え な い こ と が 分 か る 。
bash$ mount
−t proc proc /proc
bash$ ps ax
PID TTY STAT TIME COMMAND
1 pts/3 S 0:00 bash
22 pts/3 R+ 0:00 ps ax プ ロ グ
ラ ム の ソ ー
ス
/* userns_child_exec.c
GNU General
Public License v2 以 降 の 元
で ラ イ セ ン ス
さ れ る 新 し い
名 前 空 間 で シ
ェ ル コ マ ン ド
を 実 行 す る 子
プ ロ セ ス を 作
成 す る 。 ユ ー
ザ ー 名 前 空 間
を 作 成 す る 際
に
UID と GID の マ ッ ピ
ン グ を 指 定 す
る こ と が で き
る 。
*/
#define _GNU_SOURCE
#include <sched.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <signal.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <limits.h>
#include <errno.h>
/* 簡
単 な エ ラ ー 処
理 関 数 : \(aqerrno\(aq の 値
に 基 づ い て エ
ラ ー メ ッ セ ー
ジ を 出 力 し 、
呼 び 出 し 元 プ
ロ セ ス を 終 了
す る 。
*/
#define
errExit(msg) do { perror(msg); exit(EXIT_FAILURE); \ }
while (0)
struct
child_args {
char **argv; /* 子 プ ロ セ ス
が 実 行 す る コ
マ ン ド と 引 き
数 */
int pipe_fd[2]; /* 親 プ ロ セ
ス と 子 プ ロ セ
ス を 同 期 す る
た め の パ イ プ */
};
static int verbose;
static void
usage(char *pname)
{
fprintf(stderr, "Usage: %s [options] cmd
[arg...]\n\n", pname);
fprintf(stderr, "Create a child process that executes a
shell "
"command in a new user namespace,\n"
"and possibly also other new namespace(s).\n\n");
fprintf(stderr, "Options can be:\n\n");
#define fpe(str) fprintf(stderr, " %s", str);
fpe("−i New IPC namespace\n");
fpe("−m New mount namespace\n");
fpe("−n New network namespace\n");
fpe("−p New PID namespace\n");
fpe("−u New UTS namespace\n");
fpe("−U New user namespace\n");
fpe("−M uid_map Specify UID map for user
namespace\n");
fpe("−G gid_map Specify GID map for user
namespace\n");
fpe("−z Map user's UID and GID to 0 in user
namespace\n");
fpe(" (equivalent to: −M '0 <uid> 1'
−G '0 <gid> 1')\n");
fpe("−v Display verbose messages\n");
fpe("\n");
fpe("If −z, −M, or −G is specified,
−U is required.\n");
fpe("It is not permitted to specify both −z and
either −M or −G.\n");
fpe("\n");
fpe("Map strings for −M and −G consist of
records of the form:\n");
fpe("\n");
fpe(" ID−inside−ns
ID−outside−ns len\n");
fpe("\n");
fpe("A map string can contain multiple records,
separated"
" by commas;\n");
fpe("the commas are replaced by newlines before
writing"
" to map files.\n");
exit(EXIT_FAILURE); }
/* マ
ッ ピ ン グ フ ァ
イ ル 'map_file' を 'mapping' で
指 定 さ れ た 値
で 更 新 す る 。
'mapping' は UID や GID マ ッ
ピ ン グ を 定 義
す る 文 字 列 で
あ る 。
UID や GID マ ッ ピ ン
グ は 以 下 の 形
式 の 改 行 で 区
切 ら れ た
1 つ 以 上 の レ コ
ー ド で あ る 。
NS 内 ID
NS 外 ID 長 さ ユ ー ザ
ー に 改 行 を 含
む 文 字 列 を 指
定 す る の を 求
め る の は 、 コ
マ ン ド ラ イ ン
を 使 う 場 合 に
は も ち ろ ん 不
便 な こ と で あ
る 。 そ の た め
、 こ の 文 字 列
で レ コ ー ド を
区 切 る の に カ
ン マ を 使 え る
よ う に し て 、
フ ァ イ ル に こ
の 文 字 列 を 書
き 込 む 前 に カ
ン マ を 改 行 に
置 換 す る 。
*/
static void
update_map(char *mapping, char *map_file)
{
int fd, j;
size_t map_len; /* 'mapping' の 長 さ
*/
/* マ ッ ピ ン グ 文 字 列 内 の カ ン マ を 改 行 で 置 換 す る */
map_len =
strlen(mapping);
for (j = 0; j < map_len; j++)
if (mapping[j] == ',')
mapping[j] = '\n';
fd =
open(map_file, O_RDWR);
if (fd == −1) {
fprintf(stderr, "ERROR: open %s: %s\n", map_file,
strerror(errno));
exit(EXIT_FAILURE); }
if (write(fd,
mapping, map_len) != map_len) {
fprintf(stderr, "ERROR: write %s: %s\n", map_file,
strerror(errno));
exit(EXIT_FAILURE); }
close(fd); }
static int /*
ク ロ ー ン さ れ
た 子 プ ロ セ ス
の 開 始 関 数 */
childFunc(void *arg)
{
struct child_args *args = (struct child_args *) arg;
char ch;
/* 親
プ ロ セ ス が UID と
GID マ ッ ピ ン グ を
更 新 す る ま で
待 つ 。
main() の コ メ ン ト を
参 照 。 パ イ プ
の end of file を 待 つ 。
親 プ ロ セ ス が
一 旦 マ ッ ピ ン
グ を 更 新 す る
と 、 パ イ プ は
ク ロ ー ズ さ れ
る 。
*/
close(args−>pipe_fd[1]);
/* パ イ プ の こ ち
ら 側 の 書 き 込
み 端 の デ ィ ス
ク リ プ タ ー を
ク ロ ー ズ す る
。 こ れ に よ り
親 プ ロ セ ス が
デ ィ ス ク リ プ
タ ー を ク ロ ー
ズ す る と
EOF が 見 え る よ う
に な る 。 */
if (read(args−>pipe_fd[0], &ch, 1) != 0) {
fprintf(stderr,
"Failure in child: read from pipe returned !=
0\n");
exit(EXIT_FAILURE); }
/* シ ェ ル コ マ ン ド を 実 行 す る */
printf("About
to exec %s\n", args−>argv[0]);
execvp(args−>argv[0], args−>argv);
errExit("execvp"); }
#define STACK_SIZE (1024 * 1024)
static char child_stack[STACK_SIZE]; /* 子 プ ロ セ ス の ス タ ッ ク 空 間 */
int
main(int argc, char *argv[])
{
int flags, opt, map_zero;
pid_t child_pid;
struct child_args args;
char *uid_map, *gid_map;
const int MAP_BUF_SIZE = 100;
char map_buf[MAP_BUF_SIZE];
char map_path[PATH_MAX];
/* コ
マ ン ド ラ イ ン
オ プ シ ョ ン を
解 析 す る 。 最
後 の
getopt() 引 き 数 の 最
初 の '+' 文 字 は
GNU 風 の コ マ ン ド
ラ イ ン オ プ シ
ョ ン の 並 び 換
え を 防 止 す る
。 こ の プ ロ グ
ラ ム 自 身 が 実
行 す る 「 コ マ
ン ド 」 に コ マ
ン ド ラ イ ン オ
プ シ ョ ン が 含
ま れ る 場 合 が
あ る か ら で あ
る 。
getopt() に こ れ ら を
こ の プ ロ グ ラ
ム の オ プ シ ョ
ン と し て 扱 っ
て ほ し く は な
い の だ 。
*/
flags = 0;
verbose = 0;
gid_map = NULL;
uid_map = NULL;
map_zero = 0;
while ((opt = getopt(argc, argv, "+imnpuUM:G:zv"))
!= −1) {
switch (opt) {
case 'i': flags |= CLONE_NEWIPC; break;
case 'm': flags |= CLONE_NEWNS; break;
case 'n': flags |= CLONE_NEWNET; break;
case 'p': flags |= CLONE_NEWPID; break;
case 'u': flags |= CLONE_NEWUTS; break;
case 'v': verbose = 1; break;
case 'z': map_zero = 1; break;
case 'M': uid_map = optarg; break;
case 'G': gid_map = optarg; break;
case 'U': flags |= CLONE_NEWUSER; break;
default: usage(argv[0]); } }
/* −U な し の −M や −G の 指 定 は 意 味 が な い */
if (((uid_map
!= NULL || gid_map != NULL || map_zero) &&
!(flags & CLONE_NEWUSER)) ||
(map_zero && (uid_map != NULL || gid_map != NULL)))
usage(argv[0]);
args.argv = &argv[optind];
/* 親
プ ロ グ ラ ム と
子 プ ロ セ ス を
同 期 す る た め
に パ イ プ を 使
っ て い る 。 こ
れ は 、 子 プ ロ
セ ス が
execve() を 呼 び 出 す
前 に 、 親 プ ロ
セ ス に よ り
UID と GID マ ッ プ が
設 定 さ れ る こ
と を 保 証 す る
た め で あ る 。
こ れ に よ り 、
新 し い ユ ー ザ
ー 名 前 空 間 に
お い て 子 プ ロ
セ ス の 実 効 ユ
ー ザ ー
ID を 0 に マ ッ ピ ン
グ し た い と い
う 通 常 の 状 況
で 、 子 プ ロ セ
ス が
execve() 実 行 中 に そ
の ケ ー パ ビ リ
テ ィ を 維 持 す
る こ と が で き
る 。 こ の 同 期
を 行 わ な い と
、
0 以 外 の ユ ー ザ
ー ID で
execve() を 実 行 し た
際 に 、 子 プ ロ
セ ス が そ の ケ
ー パ ビ リ テ ィ
を 失 う こ と に
な る
(execve() 実 行 中 の プ
ロ セ ス の ケ ー
パ ビ リ テ ィ の
変 化 の 詳 細 に
つ い て は
capabilities(7) マ ニ ュ ア ル
ペ ー ジ を 参 照
)。 */
if
(pipe(args.pipe_fd) == −1)
errExit("pipe");
/* 新 し い 名 前 空 間 で 子 プ ロ セ ス を 作 成 す る */
child_pid =
clone(childFunc, child_stack + STACK_SIZE,
flags | SIGCHLD, &args);
if (child_pid == −1)
errExit("clone");
/* 親 プ ロ セ ス は こ こ を 実 行 す る */
if (verbose)
printf("%s: PID of child created by clone() is
%ld\n",
argv[0], (long) child_pid);
/* 子 プ ロ セ ス の UID と GID の マ ッ ピ ン グ を 更 新 す る */
if (uid_map !=
NULL || map_zero) {
snprintf(map_path, PATH_MAX, "/proc/%ld/uid_map",
(long) child_pid);
if (map_zero) {
snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long)
getuid());
uid_map = map_buf; }
update_map(uid_map, map_path); }
if (gid_map != NULL || map_zero) {
snprintf(map_path, PATH_MAX, "/proc/%ld/gid_map",
(long) child_pid);
if (map_zero) {
snprintf(map_buf, MAP_BUF_SIZE, "0 %ld 1", (long)
getgid());
gid_map = map_buf; }
update_map(gid_map, map_path); }
/* パ
イ プ の 書 き 込
み 端 を ク ロ ー
ズ し 、 子 プ ロ
セ ス に UID と GID の
マ ッ ピ ン グ が
更 新 さ れ た こ
と を 知 ら せ る
*/
close(args.pipe_fd[1]);
if
(waitpid(child_pid, NULL, 0) == −1) /* 子
プ ロ セ ス を 待
つ */
errExit("waitpid");
if (verbose)
printf("%s: terminating\n", argv[0]);
exit(EXIT_SUCCESS); }
関 連 項 目
newgidmap(1), newuidmap(1), clone(2), setns(2), unshare(2), proc(5), subgid(5), subuid(5), credentials(7), capabilities(7), namespaces(7), pid_namespaces(7) カ ー ネ ル の ソ ー ス フ ァ イ ル Documentation/namespaces/resource−control.txt
こ の 文 書 に つ い て
こ の man ペ ー ジ は Linux man−pages プ ロ ジ ェ ク ト の リ リ ー ス 3.79 の 一 部 で あ る 。 プ ロ ジ ェ ク ト の 説 明 と バ グ 報 告 に 関 す る 情 報 は http://www.kernel.org/doc/man−pages/ に 書 か れ て い る 。