UNIX/Linuxの部屋 環境変数:PATH


※空白区切りで AND 検索 (例:「ファイル 削除」)

環境変数 PATH コマンド・プログラムの置いてあるディレクトリ名を設定する

環境変数 PATH は、コマンド名のみをタイプした際、どこに置いてある実行ファイルを実行すべきかを探すための仕組みである。

ls とタイプすると /bin/ls が実行されるのはパスという仕組みのおかげである。
% setenv PATH /bin:/usr/bin:/usr/local/bin:$HOME/bin
とした場合、lessとタイプすると、
/bin/less
/usr/bin/less
/usr/local/bin/less
$HOME/bin/less
の順にプログラムが検索され、コマンドが見つかるとそれが実行される。もし /bin/less が存在すればそれが実行される。もし /bin/less がなくて、/usr/bin/less が存在すれば、/usr/bin/less が実行される。もし /usr/bin/less と /usr/local/bin/less の両方が存在すれば先に書いてある方の /usr/bin/less が実行される。

単に「less」とタイプしたとき、/usr/local/bin ではなく ~/bin/less を実行したかったら、
% setenv PATH $HOME/bin:/bin:/usr/bin:/usr/local/bin
などとパスの順番を変えるか、alias で
% alias less ~/bin/less
→ csh・tcsh の場合
% alias less="$HOME/bin/less"
→ sh・bcsh の場合
と設定すればよい。

同名のコマンドが複数存在するかどうかを調べる場合は where コマンドを使う (csh・tcsh の場合)。
% where foo
/usr/bin/foo
/usr/X11R6/bin/foo
この場合は先に表示されている /usr/bin/foo が実行されることになる。

シェル変数 path を変更すると、即座に環境変数 PATH にも反映される。逆も同じである。つまり、パスを設定するには、シェル変数 path を設定してもよいし、環境変数 PATH を設定してもよいということである。

セキュリティ上の注意点
なお、下記のようにパスに '.' (カレントディレクトリ) を含めるのは危険である。例えば
% setenv PATH ".:/bin:/usr/bin:${HOME}/bin:/usr/local/bin"
→ csh・tcsh の場合
% PATH=".:/bin:/usr/bin:${HOME}/bin:/usr/local/bin"; export PATH
→ sh・bash の場合
と PATH の先頭に '.' を記述していたとする。そのとき、
% cd /tmp
% ls
とすると、もし /tmp/ls が存在した場合、意図せず実行してしまう。もし/tmp/ls の中身が
#!/bin/sh
/bin/rm -rf $HOME
だったとしたら、あなたのホームディレクトリのファイルは全て消えてしまうことになるわけだ。もっとタチの悪いのは、
% cd /tmp
% cat ls
#!/bin/sh
cp /bin/sh /tmp/sh-$USER >/dev/null 2>&1
chmod 4755 /tmp/sh-$USER >/dev/null 2>&1
exec /bin/ls "$@"
と書いておくと、そのユーザの権限になることができる /bin/sh ができあがり。一見、ls を実行しているように見えるので、気づきにくい。

では、PATH の先頭ではなく PATH の末尾に '.' を書くのはどうか。/tmp/ls よりも /bin/ls が先に実行されてしまうので成功率は下がるだろうが、/tmp/sl を配置して ls を sl とタイプミスするのを狙う攻撃は、何日も何ヶ月も待てば成功するかもしれない。結論としては PATH に '.' を含めるべきではない、ということだ。

セキュリティ上の注意点 その2
さらにもう一点。PATH の要素に空文字があった場合、それは '.' カレントディレクトリ と同じ意味となる。例えば
% setenv PATH "${PATH}:"
% PATH="${PATH}:"; export PATH
は "${PATH}:." と同じ意味となる。「わざわざそんな書き方しないよ」と思うかもしれないが、
% setenv PATH "${PATH}:${ADD_PATH}"
% PATH="${PATH}:${ADD_PATH}"; export PATH
と書いたときに $ADD_PATH が空だったら、"${PATH}:" となってしまう。この挙動は LD_LIBRARY_PATH も同じであって、Apache httpd の CVE-2012-0883 の脆弱性がまさにこれ。"insecure ld_library_path -apache" で検索すると他にも同様に修正しているプロジェクトがたくさん見つかる。


頑張って書いたおすすめコンテンツ!