rpath

rpath

컴퓨팅에서 rpath는 실행 파일 또는 라이브러리에 하드 코딩된 런타임 검색 경로를 지정합니다.동적 링크 로더는 rpath를 사용하여 필요한 라이브러리를 찾습니다.

구체적으로는 공유 라이브러리의 경로를 실행 파일(또는 다른 공유 라이브러리)의 헤더로 인코딩합니다.이 RPATH 헤더 값(Executable FormatLinkable Format 헤더 표준으로 지정)은 시스템 기본 다이내믹링크 검색 경로를 덮어쓰거나 보완할 수 있습니다.

실행 파일 또는 공유 라이브러리의 rpath는 의 옵션 항목입니다..dynamicELF 실행 파일 또는 공유 라이브러리의 섹션(타입 포함)DT_RPATH, 라고 불립니다.DT_RPATH기여하다.링커에 의해 링크 시에 저장할 수 있습니다.다음과 같은 도구chrpath그리고.patchelf는 나중에 엔트리를 작성 또는 변경할 수 있습니다.

다이내믹 링커에 의한 DT_RPATH 엔트리 사용

ELF의 다른 다이내믹링커에서는, 다음의 기능을 실장합니다.DT_RPATH다양한 방법으로 속성을 지정합니다.

GNU ld.so

GNU C 라이브러리의 동적 링커는 다음 위치에서 [1]공유 라이브러리를 순서대로 검색합니다.

  1. 의 (콜론으로 구분된) 경로DT_RPATH바이너리의 동적 섹션 속성(존재하는 경우)과DT_RUNPATH특성이 존재하지 않습니다.
  2. 환경변수의 (콜론으로 구분된) 경로LD_LIBRARY_PATH(실행 가능 파일이setuid/setgid바이너리, 이 경우 무시됩니다. LD_LIBRARY_PATH옵션을 사용하여 다이내믹링커를 호출하여 덮어쓸 수 있습니다.--library-path(예:/lib/ld-linux.so.2 --library-path $HOME/mylibs myprogram).
  3. 의 (콜론으로 구분된) 경로DT_RUNPATH바이너리의 동적 섹션 속성(존재하는 경우)
  4. 에 근거한 검색ldconfig캐시 파일(대개 다음 위치에 있음/etc/ld.so.cache에 의해 이전에 증강 라이브러리 경로에서 발견된 후보 라이브러리의 컴파일 목록이 포함됩니다(설정)./etc/ld.so.conf단, 바이너리가 와 링크되어 있는 경우-z nodefaultlib링커 옵션. 기본 라이브러리 경로의 라이브러리는 건너뜁니다.
  5. 신뢰할 수 있는 기본 경로/lib,그리고 나서./usr/lib. 바이너리가 에 링크되어 있는 경우-z nodefaultliblinker 옵션입니다.이 스텝은 건너뜁니다.

이 모든 위치에서 공유 라이브러리를 찾지 못하면 "공유 개체 파일을 열 수 없습니다.해당 파일 또는 디렉터리가 없습니다." 오류입니다.

주의:

  • readelf -d <binary_name> grep 'R.*PATH'에 바이너리 파일의 RPATH 또는 RUNPATH를 나타냅니다.를 들어 gcc에서는 RPATH를 다음과 같이 지정할 수 있습니다.-Wl,-rpath,/custom/rpath/.
  • 옵션--inhibit-rpath LIST무시하도록 지시합니다.DT_RPATH그리고.DT_RUNPATHLIST에 있는 오브젝트 이름의 속성.LIST에서 메인 프로그램을 지정하려면 빈 문자열을 지정합니다.
  • 환경변수로 지정된 라이브러리LD_PRELOAD다음으로 에 기재되어 있습니다./etc/ld.so.preload는 검색이 시작되기 전에 로드됩니다.따라서 프리 로드는 요청된 라이브러리의 일반 기능 중 일부(또는 전부)를 대체하거나, 그렇지 않으면 찾을 수 없는 라이브러리를 제공하는 데 사용할 수 있습니다.
  • 정적 라이브러리는 링크 시 검색되고 ELF 파일에 링크되며 런타임에는 검색되지 않습니다.

GNU ld의 역할

GNU Linker(GNU ld)는 "new-dtags"라고 불리는 기능을 구현합니다.이 기능을 사용하여 precedence가 낮은rpath를 삽입할 수 있습니다.LD_LIBRARY_PATH환경 변수입니다.[2]

링커에서 new-dtags 기능이 네이블로 되어 있는 경우(--enable-new-dtags), GNUld, 를 설정하는 것 외에DT_RPATHattribute를 설정합니다.DT_RUNPATH같은 문자열에 속합니다.실행 시 다이내믹링커에 의해 검출된 경우DT_RUNPATHAtribute, 이 Atribute의 값은 무시됩니다.DT_RPATHAtribute, 즉 Atribute를 지정합니다.LD_LIBRARY_PATH첫 번째 체크가 이루어지고 패스가 표시됩니다.DT_RUNPATH속성은 나중에만 검색됩니다.

ld 다이내믹링커가 검색되지 않음DT_RUNPATHTransitive Dependency의 위치와는 달리DT_RPATH를 클릭합니다.

를 지정하는 대신-rpath링커에 대한 환경변수LD_RUN_PATH같은 효과를 설정할 수 있습니다.

Solaris ld.so

특히 Solaris의 다이내믹 링커/lib/ld.soSunOS 5.8 및 이와 유사한 시스템에서 LD_LIBRARY_PATH 변수에 지정된 디렉토리에서 라이브러리를 검색한 후DT_RPATH기여하다.Sun Microsystems는 동적인 라이브러리 로딩을 최초로[citation needed] 도입했습니다.Sun은 나중에 rpath 옵션을 ld에 추가하여 보안 기능을 추가하여 필수 라이브러리에서 사용했습니다.GNU ld는 Sun 스타일의 동적 라이브러리를 지원하기 위해 동일한 작업을 수행했습니다.

$ cc - shared - Wl , - soname , termcap.so . 4 , - rpath , / lib / o termcap.so . 4 $objdump -a -x termcap.so.4 필요 libc.so.6 SONAME termcap.so.4 RPATH / lib / termcap.so . 4

이 예에서 GNU 또는 Sun ld(ld.so)는 파일이 아닌 한 필요한 프로그램의 termcap 로드를 거부합니다.termcap.so/lib/및 이름 지정termcap.so.4.LD_LIBRARY_PATH는 무시됩니다.한다면/lib/termcap.so.4복구하기 위해 제거되고 셸이 소멸됩니다(대체 파일을 로드할 수 없음).termcap.so복구 디스크도 필요하지만, 새로운 디스크도 필요 없습니다.termcap.so.4RPATH /lib가 있습니다.ld.so은 클로버하지 않는 한 로드 사용을 거부합니다./lib/termcap.so.4하지만 또 다른 문제가 있습니다.리브를 복사하는 것은 안전하지 않습니다./lib"사용 중"이기 때문에 lib 테스터가 될 사람을 더욱 제한합니다.또한 vs.는 기본적인 프로그램이 필요함을 의미합니다.termcap.so위의 라이브러리가 기본 지원에 대한 ABI 액세스를 삭제했기 때문에 거부되었습니다.

$ cc - shared - Wl , - soname , libtermcap.so . 2 - o libtermcap.so . 2 $objdump - a - x termcap.so . 2 Needed libc.so . 6 SONAME termcap.so . 2

이전 Linux/Sun에서는 위의 내용을 사용했습니다.이것에 의해, 유저는 임의의 프로그램에 대해서, 다음의 조작을 지시할 수 있습니다.termcap.soLD_LIBRARY_PATH 또는 /usr/local/lib(n)에 있는 내용을 다음과 같은 검색 규칙을 사용하여 지정합니다.ld.so.conf단, GNU ld는 항상/lib또는/usr/libLD_LIBRARY_PATH 이전에 관계없이 먼저/lib/termcap.so이동처/usr/local/lib에 기재되어 있는 것ld.so.conf이동 기능을 사용할 수 있습니다.libs그리고.ld.so.conf또는 LD_LIBRARY_PATH를 사용하여 사용합니다.권장되는 방법은 "를 SONAME termcap.so사용하여 사용 가능한 기능을 사용하기 위해 프로그램에서 버전을 확인하도록 하는 것입니다(모든 libs는 해당 기능을 지원함). 그러나 이전 릴리스에서는 컴퓨팅 속도가 느리고 올바르게 코드화할 시간이 부족하기 때문에 종종 생략되었습니다.

즉, 이러한 것을 이용하기로 결정하기 전에 특정 플랫폼에서 철저히 테스트해야 합니다.현재의 릴리스 관리자는 과거의 가이드라인이나 문서를 준수할 수 없습니다.UNIX의 종류에 따라서는 링크와 로드가 전혀 다른 방법이 있습니다.rpath는 특정 배포와 함께 출하되는 ld에만 한정됩니다.

마지막으로, 전술한 바와 같이 rpath는 보안 기능입니다만, 「필수 액세스 제어」(MAC)등의 기술은, lib 의 판독과 쓰기를 제어하기 위해서 rpath 와 같이 효과적이거나 보다 효과적일 수 있습니다.

오늘날의 컴파일러를 사용하여 rpath를 제어하는 것은 길고 복잡한 make (1) 스크립트를 고려할 때 거의 불가능합니다.또한 일부 빌드 스크립트는 --disable-rpath를 옵션으로 제공하더라도 무시합니다.컴파일하는 모든 이상한 프로그램에서 빌드 스크립트를 수정하는 것은 시간이 많이 걸리고 좌절감을 줄 뿐만 아니라 실행 불가능할 수도 있습니다.

단순한 sh(1) "wrapper"는 ld.bin이라는 이름의 실제 ld를 호출할 수 있습니다.래퍼는 ld를 호출하기 전에 -rpath 옵션을 필터링할 수 있습니다.

 #!/bin/sh # - 여기서 ld 옵션 필터링 - ld.bin $opts

그러나 일부 빌드는 빌드 디렉토리에 남아 있는 중간 제품을 찾기 위해 rpath-link 또는 LD_LIBRARY_PATH 또는 $(TOP)/dir/foo.so 대신 rpath를 잘못 사용하므로 최종 제품에서 rpath를 역방향으로 요구할 수 있습니다.이것은 "what is rpath"에 관한 새로운 문제입니다.

레퍼런스

  1. ^ "Linux / Unix Command: ld.so". man7.org. Retrieved 19 February 2018.
  2. ^ "Shared Libraries: distribution and build-system issues". Official website of the Haskell Compiler. Retrieved 4 April 2019.
  3. ^ "Bug #1253638 "dynamic linker does not use DT_RUNPATH for transit... : Bugs : Eglibc package : Ubuntu".

외부 링크

  • chrpath - 를 변경하는 도구DT_RPATH실행 파일의 속성 및 변환DT_RUNPATH기여하다
  • FreeBSD devel/chrpath 포트 - 기존 ELF 이진에서 DT_RPATH를 수정하는 도구
  • patchELF - 동적 링커를 수정하기 위한 작은 유틸리티입니다.DT_RUNPATHELF 실행 파일의 속성.