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가 일치할 수 있다고 가정).