나는 이것과 똑같은 문제가 있습니다질문이전 게시물에서는 /etc/ld.so.preload
올바른 아키텍처를 가로채지 못했습니다. 약간의 배경 지식: ld.so.preload
바이너리가 실행하는 모든 파일에서 참조되는 공유 개체(64비트)를 컴파일했습니다. 문제는 ERROR: ld.so: object '/usr/local/lib/mysharedobject.so' from /etc/ld.so.preload cannot be preloaded (wrong ELF class: ELFCLASS64): ignored.
32비트 프로그램을 실행하는 동안 오류가 발생했다는 것입니다.
그 질문에 대한 답을 바탕으로 문제를 해결하기 위해 두 개의 디렉터리( lib/i386-linux-gnu
및 x86_64-linux-gnu
, 예를 들어 in /var/opt
) 를 만들고 프로그램 아키텍처에 따라 올바른 라이브러리가 미리 로드되도록 /var/opt/$LIB/mysharedobject.so
in 을 지정해야 했습니다./etc/ld.so.preload
따라서 이 경우 Debian 기반 시스템에서는 다음 /var/opt/$LIB/mysharedobject.so
과 같이 확장됩니다.
/var/opt/lib/i386-linux-gnu/mysharedobject.so
32비트 프로그램의 경우;/var/opt/x86_64-linux-gnu/mysharedobject.so
64비트 프로그램의 경우.
그러나 이것을 적용한 후 내가 실행하는 모든 바이너리(예: ls
)는 다음 "오류"를 출력합니다.
ERROR: ld.so: object '/var/opt/$LIB/mysharedobject.so' from /etc/ld.so.preload cannot be preloaded (cannot open shared object file): ignored.
보시다시피 $LIB는 아무 것도 확장되지 않습니다. 또한 이 라이브러리를 사용하여 업데이트 시스템을 설정 $LD_LIBRARY_PATH
하고 /var/opt
실행 했지만 성공하지 못했습니다. ldconfig
여기서 문제가 무엇입니까?
답변1
이것껍데기확장할 것이다$LIB
, 그러나 다음과 같은 경우에는 불가능합니다.
지정하다
/var/opt/$LIB/mysharedobject.so
존재하다/etc/ld.so.preload
이것매뉴얼 페이지언급하다/etc/ld.so.preload
전역 확장이나 환경 변수 가능성에 대한 언급은 없습니다.
프로그램 전에 로드할 공백으로 구분된 ELF 공유 객체 목록이 포함된 파일입니다. 토론 보기
LD_PRELOAD
이상. 둘 다라면LD_PRELOAD
그리고/etc/ld.so.preload
사용되면 지정된 라이브러리LD_PRELOAD
먼저 사전 로드하세요./etc/ld.so.preload
시스템 전체에 영향을 미쳐 시스템에서 실행되는 모든 프로그램에 대해 지정된 라이브러리가 미리 로드됩니다. (이것은 일반적으로 바람직하지 않으며 일반적으로 라이브러리 구성 오류 문제에 대한 임시 해결 방법과 같은 긴급 해결 방법으로만 사용됩니다.)
잠시 멈추고 데이터가 어떻게 사용되는지 생각해 보면 그럴 가능성도 거의 없습니다.
- glob 확장은 데이터(모호함)가 모든 종류의 흥미로운 파일과 일치할 수 있기 때문에 보안 문제가 될 수 있습니다.
- 환경 변수를 설정해야 합니다.어딘가에이며 사용자마다 쉽게 다를 수 있습니다.
이제... 매뉴얼 페이지에 이 내용이 언급되어 있습니다.$LIB
rpath에서 사용할 수 있지만 LD_PRELOAD
다음과 같이 말합니다.
안전 실행 모드에서는 슬래시가 포함된 사전 로드 경로 이름이 무시됩니다. 또한 공유 개체는 표준 검색 디렉터리에서만 미리 로드되며, 사용자 ID 설정 모드 비트가 활성화된 경우에만(일반적이지 않음).
이것은 당신에게 영향을 미칠 함정입니다./var/opt
아마표준 검색목차.
답변2
마침내 문제가 해결되었습니다. $LIB
환경 변수는 lib32
32비트 프로그램 및 lib/x86_64-linux-gnu
64비트 프로그램(예 : /usr/$LIB/mysharedlibrary.so
) 에 대한 디렉터리로 확장됩니다 . 이는 Debian 기반 시스템에 적용되며 다른 시스템의 경우 및 로 확장됩니다 (항상 , 보다 구체적으로 시스템 호출을 사용하여 확인할 수 있음 )./etc/ld.so.preload
strace
lib64
lib
strace
openat()
따라서 해결책은 공유 라이브러리를 사용 및 컴파일 -m32
하고 -m64
관련 아키텍처 파일을 각각의 참조 폴더에 넣는 것입니다 $LIB
.
요약하면(예):
$ mkdir {32,64}
$ gcc -Wall -m32 -fPIC -shared -o 32/mysharedlibrary.so mysharedlibrary.c -ldl
$ gcc -Wall -fPIC -shared -o 64/mysharedlibrary.so mysharedlibrary.c -ldl
$ sudo mv 32/mysharedlibrary.so /usr/lib32/mysharedlibrary.so
$ sudo mv 64/mysharedlibrary.so /usr/lib/x86_64-linux-gnu/mysharedlibrary.so
$ sudo echo '/usr/$LIB/mysharedlibrary.so' > /etc/ld.so.preload