通常、バンドルされていない製品は、独立した固有の場所にインストールされるように設計されています。この製品は、バイナリ、共有オブジェクト、および関連構成ファイルからなります。たとえば、バンドルされていない製品 ABC は、次の配置をとる場合があります。
製品が、/opt の元にインストールされるように設計されていると想定します。通常、ユーザーは、PATH に製品バイナリの位置を示す /opt/ABC/bin を追加する必要があります。各バイナリは、バイナリ内に直接記録された「実行パス」を使用して、その依存する相手を探します。アプリケーション abc の場合、この「実行パス」は次のようになります。
% cc -o abc abc.c -R/opt/ABC/lib -L/opt/ABC/lib -lA % dump -Lv abc [1] NEEDED libA.so.1 [2] RUNPATH /opt/ABC/lib |
同様に、libA.so.1 の依存関係でも、次のようになります。
% cc -o libA.so.1 -G -Kpic A.c -R/opt/ABC/lib -L/opt/ABC/lib -lB % dump -Lv libA.so.1 [1] NEEDED libB.so.1 [2] RUNPATH /opt/ABC/lib |
この依存関係の表現は、製品が推奨されているデフォルト以外のディレクトリにインストールされるまで正常に作動します。
動的トークン $ORIGIN は、オブジェクトが存在するディレクトリに展開されます。このトークンは、フィルタ、「実行パス」、または依存関係の定義に利用できます。この機構を使用すると、バンドルされていないアプリケーションを再定義して、$ORIGIN との相対位置で依存対象の位置を示すことができます。
% cc -o abc abc.c '-R$ORIGIN/../lib' -L/opt/ABC/lib -lA % dump -Lv abc [1] NEEDED libA.so.1 [2] RUNPATH $ORIGIN/../lib |
また、$ORIGIN との関係で libA.so.1 の依存関係を定義することもできます。
% cc -o libA.so.1 -G -Kpic A.c '-R$ORIGIN' -L/opt/ABC/lib -lB % dump -Lv libA.so.1 [1] NEEDED libB.so.1 [2] RUNPATH $ORIGIN |
この製品が /usr/local/ABC 内にインストールされ、ユーザーの PATH に /usr/local/ABC/bin が追加された場合、アプリケーション abc を呼び出すと次のように、パス名検索でその依存関係が探されます。
% ldd -s abc ..... find object=libA.so.1; required by abc search path=$ORIGIN/../lib (RPATH from file abc) trying path=/usr/local/ABC/lib/libA.so.1 libA.so.1 => /usr/local/ABC/lib/libA.so.1 find object=libB.so.1; required by /usr/local/ABC/lib/libA.so.1 search path=$ORIGIN (RPATH from file /usr/local/ABC/lib/libA.so.1) trying path=/usr/local/ABC/lib/libB.so.1 libB.so.1 => /usr/local/ABC/lib/libB.so.1 |
依存関係の場所に関するもう 1 つの問題は、バンドルされていない製品同士の依存関係を表現するモデルを、どのようにして確立するかです。
たとえば、バンドルされていない製品 XYZ は製品 ABC に対して依存関係を持つ場合があります。この依存関係を確立するには、ホストパッケージインストールスクリプトを使用します。このスクリプトは ABC 製品のインストール位置へのシンボリックリンクを生成します (次の図を参照)。
XYZ 製品のバイナリおよび共有オブジェクトは、シンボリックリンクを使用して、ABC 製品との依存関係を表現できます。このリンクはその時点で、安定した参照点になります。アプリケーション xyz の場合、この「実行パス」は次のようになります。
% cc -o xyz xyz.c '-R$ORIGIN/../lib:$ORIGIN/../ABC/lib' \ -L/opt/ABC/lib -lX -lA % dump -Lv xyz [1] NEEDED libX.so.1 [2] NEEDED libA.so.1 [3] RUNPATH $ORIGIN/../lib:$ORIGIN/../ABC/lib |
libX.so.1 の依存関係でも同様に、次のようになります。
% cc -o libX.so.1 -G -Kpic X.c '-R$ORIGIN:$ORIGIN/../ABC/lib' \ -L/opt/ABC/lib -lY -lC % dump -Lv libX.so.1 [1] NEEDED libY.so.1 [2] NEEDED libC.so.1 [3] RUNPATH $ORIGIN:$ORIGIN/../ABC/lib |
この製品が /usr/local/XYZ 内にインストールされている場合は、次のシンボリックリンクを確立するために、インストール後実行スクリプトが必要です。
% ln -s ../ABC /usr/local/XYZ/ABC |
ユーザーの PATH に /usr/local/XYZ/bin が追加される場合、アプリケーション xyz
の呼び出しによって、次のようにパス名検索でその依存関係が探されます。
% ldd -s xyz ..... find object=libX.so.1; required by xyz search path=$ORIGIN/../lib:$ORIGIN/../ABC/lib (RPATH from file xyz) trying path=/usr/local/XYZ/lib/libX.so.1 libX.so.1 => /usr/local/XYZ/lib/libX.so.1 find object=libA.so.1; required by xyz search path=$ORIGIN/../lib:$ORIGIN/../ABC/lib (RPATH from file xyz) trying path=/usr/local/XYZ/lib/libA.so.1 trying path=/usr/local/ABC/lib/libA.so.1 libA.so.1 => /usr/local/ABC/lib/libA.so.1 find object=libY.so.1; required by /usr/local/XYZ/lib/libX.so.1 search path=$ORIGIN:$ORIGIN/../ABC/lib \ (RPATH from file /usr/local/XYZ/lib/libX.so.1) trying path=/usr/local/XYZ/lib/libY.so.1 libY.so.1 => /usr/local/XYZ/lib/libY.so.1 find object=libC.so.1; required by /usr/local/XYZ/lib/libX.so.1 search path=$ORIGIN:$ORIGIN/../ABC/lib \ (RPATH from file /usr/local/XYZ/lib/libX.so.1) trying path=/usr/local/XYZ/lib/libC.so.1 trying path=/usr/local/ABC/lib/libC.so.1 libC.so.1 => /usr/local/ABC/lib/libC.so.1 find object=libB.so.1; required by /usr/local/ABC/lib/libA.so.1 search path=$ORIGIN (RPATH from file /usr/local/ABC/lib/libA.so.1) trying path=/usr/local/ABC/lib/libB.so.1 libB.so.1 => /usr/local/ABC/lib/libB.so.1 |
セキュアプロセスでは、$ORIGIN 文字列の拡張は、それがトラストディレクトリに拡張されるときに限り許可されます。ほかの相対パス名は、セキュリティリスクを伴います。
$ORIGIN/../lib のようなパスは一定の場所 (実行可能プログラムの場所で特定される) を指しているように見えますが、それは正しくありません。同じファイルシステム内の書き込み可能なディレクトリにより、$ORIGIN を使用するセキュアプログラムが不当に利用される可能性があります。
次の例は、$ORIGIN がセキュアプロセス内で任意に拡張された場合、セキュリティ侵入が生じる可能性があることを示しています。
% cd /worldwritable/dir/in/same/fs % mkdir bin lib % ln $ORIGIN/bin/program bin/program % cp ~/crooked-libc.so.1 lib/libc.so.1 % bin/program ..... using crooked-libc.so.1 |
ユーティリティ crle(1) を使用すれば、セキュアアプリケーションによる $ORIGIN の使用を可能するトラストディレクトリを指定できます。この方法を使用する場合には、管理者は、ターゲットディレクトリを悪意のある侵入から適切に保護する必要があります。