Manpages

名 前

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_tsi_uid フ ィ ー ル ド で 返 さ れ る ID 情 報 (sigaction(2) 参 照 )、 プ ロ セ ス ア カ ウ ン テ ィ ン グ フ ァ イ ル に 書 き 込 ま れ る ID 情 報 (acct(5) 参 照 )、 POSIX メ ッ セ ー ジ キ ュ ー 通 知 で 返 さ れ る ID 情 報 (mq_notify(3) 参 照 ) が あ る 。 マ ッ ピ ン グ さ れ て い な い ユ ー ザ ー ID や グ ル ー プ ID が 対 応 す る オ ー バ ー フ ロ ー ID 値 に 変 換 さ れ 「 な い 」 重 要 な 場 合 が 一 つ あ る 。 2 番 目 の フ ィ ー ル ド に マ ッ ピ ン グ が な い uid_mapgid_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/ に 書 か れ て い る 。