ld-linux.soを使用してプログラムを実行し、patchelfを使用してインタプリタを変更すると他の結果が表示されるのはなぜですか?

ld-linux.soを使用してプログラムを実行し、patchelfを使用してインタプリタを変更すると他の結果が表示されるのはなぜですか?


ld + --library-pathを使ってプログラムを実行することとpatchelfを使ってローダを変更することの違いは何ですか?

これを説明するために、以下は現状のまま実行されないバイナリです。それはおそらく、最新バージョンのライブラリがないからです。

$ ~/DOWNLOADS/APPS/magick
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10)
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libc.so.6: version `GLIBC_2.25' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/libMagickCore-7.Q16HDRI.so.10)
/tmp/.mount_magickXiWzgy/usr/bin/magick: /lib/x86_64-linux-gnu/libm.so.6: version `GLIBC_2.29' not found (required by /tmp/.mount_magickXiWzgy/usr/lib/liblcms2.so.2)
...
$

私は3つの異なるローダーとライブラリパス(core18、core20、およびcore22)を使って実行しました。 ELFファイルのABIバージョンが無効であるたびに。

$ /snap/core18/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core18/current/usr/lib/x86_64-linux-gnu/  ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$ /snap/core20/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core20/current/usr/lib/x86_64-linux-gnu/  ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$ /snap/core22/current/lib64/ld-linux-x86-64.so.2 --library-path /snap/core22/current/usr/lib/x86_64-linux-gnu/  ~/DOWNLOADS/APPS/magick
/home/ychaouche/DOWNLOADS/APPS/magick: error while loading shared libraries: /home/ychaouche/DOWNLOADS/APPS/magick: ELF file ABI version invalid
$

その後、patchelfを使用してバイナリから直接ローダーとrpathを変更して実行しようとすると、次
の分割エラーが発生します。

$ patchelf --set-interpreter /snap/core18/current/lib64/ld-linux-x86-64.so.2 --set-rpath /snap/core18/current/usr/lib/x86_64-linux-gnu/  magick
$ ./magick
Segmentation fault
$ ldd magick
        not a dynamic executable
$

readelfは読み取ることができますが、lddはそれを動的実行可能ファイルとして認識しません。

@user10489が要求したldd出力。

$ file DOWNLOADS/APPS/magick
DOWNLOADS/APPS/magick: ELF 64-bit LSB  executable, x86-64, version 1, dynamically linked (uses shared libs), for GNU/Linux 2.6.32, BuildID[sha1]=9fdbc145689e0fb79cb7291203431012ae8e1911, stripped
$

私の質問は、コマンドラインでローダを指定したときにELFファイルABIのバージョンが無効で、バイナリ内でローダ(およびrpath)を変更すると分割エラーが発生するのはなぜですか?

ベストアンサー1

ライブラリのバージョン管理の全体的な目的は、ライブラリのABIが変更されたときの問題を回避し、アプリケーションが期待するABIと一致するライブラリを見つけることを可能にすることです。

ライブラリのバージョンを強制することで、実行可能ファイルに期待されたものとは異なるABIを使用して関数を呼び出すように強制しました。その結果、エラーで失敗し、最悪の場合、予測不能な方法で競合が発生します。

特定のライブラリでプログラムを使用するには、そのライブラリのコンパイルされたバージョンを探すか、ソースから再コンパイルする必要があります(APIが一致する可能性があると仮定)。

おすすめ記事