filename や
ス ク リ プ ト イ
ン タ ー プ リ タ
ー 名 の 構 成 要
素 に 検 索 許 可
(search permission) が 与 え ら
れ て い な い
(path_resolution(7) も 参 照
す る こ と )。
フ ァ イ
ル も し く は ス
ク リ プ ト の イ
ン タ ー プ リ タ
ー が 通 常 フ ァ
イ ル (regular file) で な い
。
フ ァ イ
ル や ス ク リ プ
ト や ELF イ ン タ ー
プ リ タ ー に 実
行 許 可 (execute permission) が
与 え ら れ て い
な い 。
フ ァ イ
ル シ ス テ ム が
noexec で マ ウ ン ト
さ れ て い る 。
EAGAIN (Linux 3.1
以 降 )
set*uid() の
い ず れ か の 呼
び 出 し で プ ロ
セ ス の 実 UID が 変
更 さ れ た と す
る と 、 呼 び 出
し 元 の RLIMIT_NPROC リ
ソ ー ス 上 限
(setrlimit(2) 参 照 ) を 超
え て し ま う 、
現 在 も ま だ 超
え て い る 。 こ
の エ ラ ー の 詳
細 な 説 明 に つ
い て は 「 注 意
」 の 節 を 参 照
。
|
EFAULT |
|
filename ま た は 配
列 argv か envp の ポ
イ ン タ ー の 一
つ が ア ク セ ス
可 能 な ア ド レ
ス 空 間 の 外 を
指 し て い る 。 |
|
EINVAL |
|
ELF 実 行 形 式 で
複 数 の PT_INTERP セ グ
メ ン ト が 存 在
す る 。 (す な わ
ち 複 数 の イ ン
タ ー プ リ タ ー
を 指 定 し た 。 ) |
|
EIO |
|
I/O エ ラ ー が 発
生 し た 。 |
|
EISDIR |
|
ELF イ ン タ ー プ
リ タ ー が デ ィ
レ ク ト リ だ っ
た 。 |
ELIBBAD
ELF イ ン タ
ー プ リ タ ー が
理 解 で き る フ
ォ ー マ ッ ト で
な か っ た 。
|
ELOOP |
|
filename や ス ク リ
プ ト や ELF の イ ン
タ ー プ リ タ ー
を 解 決 す る 際
に 遭 遇 し た シ
ン ボ リ ッ ク リ
ン ク が 多 過 ぎ
る 。 |
|
EMFILE |
|
|
そ の プ
ロ セ ス が オ ー
プ ン で き る フ
ァ イ ル 数 の 上
限 ま で 既 に オ
ー プ ン し て い
る 。
filename が
長 過 ぎ る 。
|
ENFILE オ ー プ ン
さ れ た フ ァ イ
ル の 総 数 が シ
ス テ ム 全 体 の
上 限 に 達 し て
い た 。 |
|
ENOENT フ ァ イ ル |
filename か
ス ク リ プ ト や ELF
の イ ン タ ー プ
リ タ ー が 存 在
し な い 。
ENOEXEC 実 行 フ ァ イ
ル が 理 解 で き
な い 形 式 で あ
る か 、 違 う ア
ー キ テ ク チ ャ
ー の も の か 、
そ の 他 の フ ォ
ー マ ッ ト エ ラ
ー に よ り 実 行
が で き な か っ
た 。
|
ENOMEM カ ー ネ ル
に 十 分 な メ モ
リ ー が な い 。 |
|
ENOTDIR
filename や
ス ク リ プ ト や ELF
の イ ン タ ー プ
リ タ ー の 構 成
要 素 が デ ィ レ
ク ト リ で な い
。
|
EPERM フ ァ イ ル
シ ス テ ム が |
|
nosuid で マ ウ ン
ト さ れ 、 ユ ー
ザ ー が ス ー パ
ー ユ ー |
ザ ー で
な く 、 フ ァ イ
ル に set−user−ID あ る
い は set−group−ID ビ ッ
ト が 設 定 さ れ
て い る 。
|
EPERM プ ロ
セ ス が ト レ ー
ス さ れ 、 ユ ー
ザ ー が ス ー パ
ー ユ ー ザ ー で
な く 、 フ ァ イ
ル に |
set−user−ID
あ る い は set−group−ID
ビ ッ ト が 設 定
さ れ て い る 。
ETXTBSY 実 行 フ ァ イ
ル を 書 き 込 み
用 に オ ー プ ン
し て い る プ ロ
セ ス が あ る 。
SVr4, 4.3BSD,
POSIX.1−2001. POSIX.1−2001 に は #!
動 作 に つ い て
の 記 述 は な い
が 、 他 は 互 換
性 が あ る 。
set−user−id
プ ロ セ ス と
set−group−ID プ ロ セ ス
は ptrace(2) で き な
い 。 フ ァ イ ル
シ ス テ ム を nosuid
で マ ウ ン ト し
た 場 合 に
set−user−ID/set−group−ID の
実 行 フ ァ イ ル
を ど の 様 に 扱
う か は 、 Linux カ ー
ネ ル の バ ー ジ
ョ ン に よ っ て
異 な る : あ る バ
ー ジ ョ ン で は
、 す で に 必 要
な 権 限 を 持 っ
て い る 場 合 を
除 い て 、 そ の
実 行 を 拒 否 す
る (そ し て EPERM を
返 す )。 別 の あ
る バ ー ジ ョ ン
で は
set−user−ID/set−group−ID ビ
ッ ト の み を 無
視 し exec() は 成 功
す る 。 Linux で は 、
argv と envp に NULL を
指 定 す る こ と
が で き る 。 ど
ち ら に NULL を 指 定
し た 場 合 も 、
こ れ ら の 引 き
数 に ヌ ル ポ イ
ン タ ー 1 個 だ け
を 含 む リ ス ト
へ の ポ イ ン タ
ー を 指 定 し た
の と 同 じ 効 果
を 持 つ 。 「 こ
の 間 違 っ た 機
能 を 利 用 し な
い こ と 」 。 こ
れ は 非 標 準 で
、 移 植 性 も な
い 。 他 の ほ と
ん ど の UNIX シ ス テ
ム で は 、 こ れ
を 行 う と エ ラ
ー (EFAULT) に な る
。
POSIX.1−2001
は 、 sysconf(3) が 返
す 値 は プ ロ セ
ス の 生 存 中 は
変 化 し な い べ
き だ と し て い
る 。 し か し な
が ら 、 Linux 2.6.23 以 降
で は 、 リ ソ ー
ス 上 限 RLIMIT_STACK が
変 化 し た 場 合
、 コ マ ン ド ラ
イ ン 引 き 数 と
環 境 変 数 を 保
持 す る た め の
空 間 に 対 す る
上 限 が 変 化 し
た こ と を 反 映
し て 、 _SC_ARG_MAX が
返 す 値 も 変 化
す る 。
execve()
が 失 敗 す る ほ
と ん ど の 場 合
、 制 御 は 元 の
実 行 可 能 イ メ
ー ジ に 戻 り 、
execve() の 呼 び 出 し
元 が エ ラ ー を
処 理 す る こ と
が で き る 。 し
か し な が ら 、
(リ ソ ー ス 枯 渇
が 原 因 と な っ
た 場 合 な ど 、
ま れ に ) 呼 び 出
し 元 に 制 御 が
戻 る 時 点 を 過
ぎ て か ら エ ラ
ー が 発 生 す る
場 合 が あ る 。
元 の 実 行 可 能
イ メ ー ジ は す
で に 破 棄 さ れ
て い る が 、 新
し い イ メ ー ジ
が 完 全 に は 構
築 さ れ て い な
い と い う 状 況
で あ る 。 こ の
よ う な 場 合 、
カ ー ネ ル は そ
の プ ロ セ ス を
シ グ ナ ル SIGKILL で
停 止 (kill) す る 。
イ ン タ ー プ リ
タ ー ス ク リ プ
ト イ ン タ ー プ
リ タ ー ス ク リ
プ ト の 1行 目 に
許 さ れ て い る
文 字 数 は 、 最
大 127 文 字 で あ る
。 イ ン タ ー プ
リ タ ー ス ク リ
プ ト の optional−arg
引 き 数 の 解 釈
方 法 は 実 装 に
よ り 異 な る 。 Linux
で は 、 イ ン タ
ー プ リ タ ー 名
interpreter に 続 く 文
字 列 全 体 が イ
ン タ ー プ リ タ
ー に 1個 の 引 き
数 と し て 渡 さ
れ る 。 し か し
、 動 作 が 異 な
る シ ス テ ム も
あ る 。 あ る シ
ス テ ム で は 、
optional−arg の う ち
最 初 の ホ ワ イ
ト ス ペ ー ス ま
で が 引 き 数 と
し て 渡 さ れ る
。 ま た 、 別 の
シ ス テ ム で は
イ ン タ ー プ リ
タ ー ス ク リ プ
ト は 複 数 の 引
き 数 を 持 つ こ
と が で き 、
optional−arg 内 の ホ
ワ イ ト ス ペ ー
ス が 引 き 数 の
区 切 り と な る
。
Linux は
ス ク リ プ ト の
set−user−ID と set−group−ID
ビ ッ ト を 無 視
す る 。
execve()
と EAGAIN
execve() を 呼 び 出 し
た 際 に (Linux 3.1 以 降
で ) 起 こ り 得 る
EAGAIN エ ラ ー の 詳
細 な 説 明 を 以
下 で 行 う 。 直
前 の setuid(2), setreuid(2),
setresuid(2) の 呼 び 出
し で 、 そ の プ
ロ セ ス の 実 ユ
ー ザ ー ID が 変 更
さ れ 、 そ の 変
更 に よ り そ の
プ ロ セ ス が
RLIMIT_NPROC リ ソ ー ス
上 限 を 超 過 し
て し ま っ た 場
合 (す な わ ち 、
新 し い 実 ユ ー
ザ ー ID に 属 す る
プ ロ セ ス 数 が
RLIMIT_NPROC リ ソ ー ス
上 限 を 超 過 し
た 場 合 ) に 、 EAGAIN
エ ラ ー が 発 生
す る 。 Linux 2.6.0 以 上 3.0
以 下 で は 、 こ
れ に よ り set*uid()
の 呼 び 出 し が
失 敗 し て い た
。 (Linux 2.6 よ り 前 で
は 、 こ の リ ソ
ー ス 上 限 は ユ
ー ザ ー ID を 変 更
し た プ ロ セ ス
に は 適 用 さ れ
て い な か っ た
。 )
Linux 3.1
以 降 で は 、 上
で 説 明 し た シ
ナ リ オ で は
set*uid() の 呼 び 出
し は 失 敗 し な
い 。 な ぜ な ら
、 返 さ れ た ス
テ ー タ ス の 確
認 を 行 わ ず 「
呼 び 出 し 元 が
特 権 を 持 っ て
い る 場 合 に は
」 呼 び 出 し は
必 ず 成 功 す る
と み な し て い
る バ グ が あ る
ア プ リ ケ ー シ
ョ ン で は 、 セ
キ ュ リ テ ィ ホ
ー ル に つ な が
る こ と が 非 常
に よ く あ る か
ら だ 。 そ の 代
わ り 、 set*uid() の
呼 び 出 し に よ
る 実 UID の 変 更 は
成 功 す る が 、
カ ー ネ ル は
PF_NPROC_EXCEEDED と い う 名
前 の 内 部 フ ラ
グ を セ ッ ト す
る 。 こ の フ ラ
グ は RLIMIT_NPROC リ ソ
ー ス 上 限 が 超
過 し た こ と を
示 す 。 PF_NPROC_EXCEEDED フ
ラ グ が セ ッ ト
さ れ て い て 、
そ の 後 で execve() が
呼 ば れ た 際 に
リ ソ ー ス 上 限
が ま だ 超 過 し
て い れ ば 、 そ
の execve() の 呼 び 出
し は EAGAIN エ ラ ー
で 失 敗 す る 。
こ の カ ー ネ ル
の ロ ジ ッ ク に
よ り 、 特 権 デ
ー モ ン で よ く
行 わ れ る 処 理
フ ロ ー 、 す な
わ ち fork(2) + set*uid() +
execve() に 対 し て 、
前 と 変 わ ら ず
RLIMIT_NPROC リ ソ ー ス
上 限 を 適 用 で
き る こ と が 保
証 さ れ る 。
(set*uid()
と execve() の 呼 び 出
し の 間 に 、 こ
の 実 UID に 属 す る
他 の プ ロ セ ス
が 終 了 し て ) 次
に execve() が 呼 び 出
さ れ た 際 に こ
の リ ソ ー ス 上
限 が 超 過 し て
な け れ ば 、 execve()
の 呼 び 出 し は
成 功 し 、 カ ー
ネ ル は PF_NPROC_EXCEEDED プ
ロ セ ス フ ラ グ
を ク リ ア す る
。 同 じ プ ロ セ
ス に よ っ て fork(2)
の 呼 び 出 し が
後 で 行 わ れ た
場 合 に も 、 こ
の フ ラ グ は ク
リ ア さ れ る 。
歴 史
UNIX V6 で は exec() コ
ー ル の 引 き 数
リ ス ト は 0 で 終
端 さ れ 、 main の
引 き 数 リ ス ト
は −1 で 終 端 さ
れ て い た 。 そ
の た め 、 main の
引 き 数 リ ス ト
は 、 そ の 後 の
exec() コ ー ル に は
直 接 使 用 で き
な か っ た 。 UNIX V7
以 降 で は 、 と
も に NULL で 終 端 さ
れ る 。
こ の プ
ロ グ ラ ム は 、
以 下 の 二 つ 目
の プ ロ グ ラ ム
か ら 実 行 す る
た め の も の で
あ る 。 コ マ ン
ド ラ イ ン 引 き
数 を 1行 に 1個 ず
つ 表 示 す る だ
け の プ ロ グ ラ
ム で あ る 。
/* myecho.c
*/
#include
<stdio.h>
#include <stdlib.h>
int
main(int argc, char *argv[])
{
int j;
for (j = 0; j
< argc; j++)
printf("argv[%d]: %s\n", j, argv[j]);
exit(EXIT_SUCCESS);
} 以 下 の プ ロ グ
ラ ム は 、 コ マ
ン ド ラ イ ン 引
き 数 で 指 定 し
た 名 前 の プ ロ
グ ラ ム を 実 行
す る の に 使 う
。
/* execve.c
*/
#include
<stdio.h>
#include <stdlib.h>
#include <unistd.h>
int
main(int argc, char *argv[])
{
char *newargv[] = { NULL, "hello",
"world", NULL };
char *newenviron[] = { NULL };
if (argc != 2)
{
fprintf(stderr, "Usage: %s
<file−to−exec>\n", argv[0]);
exit(EXIT_FAILURE); }
newargv[0] =
argv[1];
execve(argv[1],
newargv, newenviron);
perror("execve"); /* execve() returns only on
error */
exit(EXIT_FAILURE); } 二 つ 目 の
プ ロ グ ラ ム を
使 っ て 一 つ 目
の プ ロ グ ラ ム
を 実 行 す る に
は 以 下 の よ う
に す る 。
$ cc
myecho.c −o myecho
$ cc execve.c −o execve
$ ./execve ./myecho
argv[0]: ./myecho
argv[1]: hello
argv[2]: world さ ら に 、 こ
れ ら の プ ロ グ
ラ ム を 使 っ て
、 ス ク リ プ ト
イ ン タ ー プ リ
タ ー の 例 を 示
す 。 こ の た め
に 、 「 イ ン タ
ー プ リ タ ー 」
と し て 先 ほ ど
作 成 し た プ ロ
グ ラ ム myecho を 使
う ス ク リ プ ト
を 作 成 す る 。
$ cat >
script
#!./myecho script−arg
^D
$ chmod +x script 作 成 し て
お い た プ ロ グ
ラ ム を 使 っ て
ス ク リ プ ト を
実 行 す る 。
$ ./execve
./script
argv[0]: ./myecho
argv[1]: script−arg
argv[2]: ./script
argv[3]: hello
argv[4]: world
chmod(2),
execveat(2), fork(2), ptrace(2),
execl(3), fexecve(3), getopt(3),
credentials(7), environ(7),
path_resolution(7), ld.so(8)
こ の man ペ
ー ジ は Linux man−pages
プ ロ ジ ェ ク ト
の リ リ ー ス 3.79 の
一 部 で あ る 。
プ ロ ジ ェ ク ト
の 説 明 と バ グ
報 告 に 関 す る
情 報 は
http://www.kernel.org/doc/man−pages/ に 書
か れ て い る 。
|