コマンド検索パスを指定する環境変数PATHに「::」というのが入ってたんだけど、それって実はヤバいことだった、という話。
環境変数PATHに、カレントディレクトリを意味する「.」を入れてはいけない、というのはセキュリティ対策として基本中の基本です。
たまたまカレントディレクトリに「ls」という名前の実行ファイルがあって、そこでlsコマンドを実行してしまうと、カレントディレクトリにある得体の知れないlsコマンドが実行されてしまい、危険である!っていうことなんですが。
自分もそんなことは十分承知していたのですが、たまたま.cshrcの編集ミスで、PATHの設定が少しおかしなことになっていて、それが実はとんでもないことになっていた、という恥ずかしい話。
具体的には、環境変数PATHの途中に「::」っていうのが入ってたんです。たぶんエディタで.cshrcを書き換えたときの編集ミスが原因です。
たとえばこんな感じです。こんなことが起きます。
% cd /tmp
% setenv PATH /sbin::/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/home/nhh/bin
% cat > ls
echo "Aho------!!!"
% chmod +x ls
% ls
Aho------!!!
% which ls
./ls
まじっすか!
カレントディレクトリのファイルが実行されちゃいました。
「::」を「:」に戻すと・・・
% setenv PATH /sbin:/bin:/usr/sbin:/usr/bin:/usr/games:/usr/local/sbin:/usr/local/bin:/home/nhh/bin
% rehash
% ls
dbus-B9NLymYlNW dbus-yMFq5nXnHn ls
~~~ファイル一覧あれこれ~~~
% which ls
/bin/ls
ということで正常になりました。
へー!!!はじめてUNIXに触れて20うん年、ぜんぜん知りませんでした。環境変数PATHに「::」があるとカレントディレクトリを指定したと同じことになるとは。
ちなみに、このことに気がついたきっかけは、たしかperlで書かれた何かのコマンドを実行したときに、PATHにカレントディレクトリを含めちゃいけないよ、と警告されたことでした。
☆
ん~、これってFreeBSDだけの挙動ですかね。
気になったらさっそくソースコードを調べよう!
たぶん、execlp()の処理を読めばわかるんじゃないかな?と検討がつくので、適当にgrepしてみる。なんというローテク(笑)
% grep -Rl execlp /usr/src/lib
/usr/src/lib/libc/net/rcmdsh.c
/usr/src/lib/libc/gen/Makefile.inc
/usr/src/lib/libc/gen/Symbol.map
/usr/src/lib/libc/gen/exec.3
/usr/src/lib/libc/gen/exec.c
/usr/src/lib/libedit/vi.c
/usr/src/lib/libutil/pw_util.c
たぶん、/usr/src/lib/libc/gen/exec.c がそれっぽいです。
Webでもソースコードが見られます。
http://svnweb.freebsd.org/base/release/9.1.0/lib/libc/gen/exec.c?revision=243808&view=markup
execlpを追っかけていくと、execvPe()にきて、そこでPATHを検索していました。
・・・ありました!ご丁寧なことに、::だったらカレントディレクトリだよん、という意味のコメントがついてるじゃないですか!
strcpy(cur, path);
while ((p = strsep(&cur, ":")) != NULL) {
/*
* It's a SHELL path -- double, leading and trailing colons
* mean the current directory.
*/
if (*p == '\0') {
p = ".";
lp = 1;
} else
lp = strlen(p);
ln = strlen(name);
う~ん、これが仕様なんですね。
写真は本文と関係ありません。
0 件のコメント:
コメントを投稿