Эта статья может быть слишком технической для понимания большинства читателей . ( Декабрь 2022 ) |
В информатике rpath обозначает путь поиска во время выполнения, жестко закодированный в исполняемом файле или библиотеке . Динамически связываемые загрузчики используют rpath для поиска требуемых библиотек.
В частности, он кодирует путь к разделяемым библиотекам в заголовок исполняемого файла (или другой разделяемой библиотеки). Это значение заголовка RPATH (так названо в стандартах заголовков Executable and Linkable Format ) может либо переопределять, либо дополнять системные пути поиска динамического связывания по умолчанию.
Rpath исполняемого файла или разделяемой библиотеки — это необязательная запись в .dynamic
разделе исполняемого файла ELF или разделяемых библиотек с типом DT_RPATH
, называемым DT_RPATH
атрибутом. Он может быть сохранен там во время компоновки компоновщиком. Такие инструменты, как chrpath
и patchelf
могут создать или изменить запись позже.
Различные динамические компоновщики для ELF реализуют использование атрибута DT_RPATH
по-разному.
Динамический компоновщик библиотеки GNU C ищет общие библиотеки в следующих местах в следующем порядке: [1]
DT_RPATH
атрибуте динамического раздела двоичного файла, если он присутствует, а DT_RUNPATH
атрибут не существует.LD_LIBRARY_PATH
, если только исполняемый файл не является двоичным setuid/setgid
, в этом случае он игнорируется, LD_LIBRARY_PATH
можно переопределить, вызвав динамический компоновщик с опцией --library-path
(например, /lib/ld-linux.so.2 --library-path $HOME/mylibs myprogram
).DT_RUNPATH
атрибуте динамического раздела двоичного файла, если он присутствует.ldconfig
файла кэша (часто расположенного в /etc/ld.so.cache
), который содержит скомпилированный список библиотек-кандидатов, ранее найденных в расширенном пути библиотеки (установленном /etc/ld.so.conf
). Однако, если двоичный файл был связан с -z nodefaultlib
опцией компоновщика, библиотеки в путях библиотеки по умолчанию пропускаются./lib
, а затем /usr/lib
. Если двоичный файл был связан с -z nodefaultlib
опцией компоновщика, этот шаг пропускается.Если не удастся найти общую библиотеку во всех этих местах, возникнет ошибка «невозможно открыть файл общего объекта: такого файла или каталога нет».
Примечания:
readelf -d <binary_name> | grep 'R.*PATH'
отображает RPATH или RUNPATH двоичного файла. В gcc , например, можно указать RPATH с помощью -Wl,-rpath,/custom/rpath/
.--inhibit-rpath LIST
динамического компоновщика указывает ему игнорировать DT_RPATH
и DT_RUNPATH
атрибуты имен объектов в LIST. Чтобы указать основную программу в LIST, укажите пустую строку.LD_PRELOAD
, а затем перечисленные в /etc/ld.so.preload
загружаются до начала поиска. Таким образом, предварительная загрузка может использоваться для замены некоторых (или всех) обычных функций запрошенной библиотеки, или ее можно просто использовать для предоставления библиотеки, которая в противном случае не была бы найдена.GNU Linker (GNU ld) реализует функцию, называемую «new-dtags», которую можно использовать для вставки rpath, имеющего более низкий приоритет, чем LD_LIBRARY_PATH
переменная окружения . [2]
Если в компоновщике ( ) включена функция new-dtags --enable-new-dtags
, GNU ld
, помимо установки DT_RPATH
атрибута, также устанавливает DT_RUNPATH
атрибут в ту же строку. Во время выполнения, если динамический компоновщик находит атрибут DT_RUNPATH
, он игнорирует значение атрибута DT_RPATH
, с эффектом, который LD_LIBRARY_PATH
проверяется в первую очередь, а пути в DT_RUNPATH
атрибуте ищутся только после этого.
Динамический компоновщик ld не ищет DT_RUNPATH
местоположения для транзитивных зависимостей, в отличие от DT_RPATH
. [3]
Вместо указания -rpath
компоновщику LD_RUN_PATH
можно задать переменную окружения для того же эффекта.
Динамический компоновщик Solaris , в частности /lib/ld.so
SunOS 5.8 и подобных систем, ищет библиотеки в каталогах, указанных в переменной LD_LIBRARY_PATH, прежде чем смотреть на DT_RPATH
атрибут. Sun Microsystems была первой [ нужна ссылка ] , кто ввел динамическую загрузку библиотек. Позднее Sun добавила опцию rpath в ld и использовала ее в основных библиотеках в качестве дополнительной функции безопасности. GNU ld делал то же самое для поддержки динамических библиотек в стиле Sun.
Эта статья содержит инструкции, советы или как-то контент . ( Август 2018 ) |
Релевантность конкретной информации в (или ранее в) этой статье или разделе оспаривается . Информация ( Май 2024 ) |
$ cc -shared -Wl,-soname,termcap.so.4,-rpath,/lib/termcap.so.4 -o termcap.so.4$ objdump -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.4
имеет RPATH /lib, ld.so откажется использовать для его загрузки, если он не будет затёрт /lib/termcap.so.4
). Но есть и другая проблема: небезопасно копировать некоторые библиотеки в , /lib
поскольку они «используются», что ещё больше ограничивает потенциального тестировщика библиотек. Более того,SONAME termcap.so.4против.SONAME termcap.soозначает, что программы, которым требуется базовая поддержка, termcap.so
отклонены, поскольку указанная выше библиотека удалила доступ ABI к базовой поддержке.
$ cc -shared -Wl,-soname,libtermcap.so.2 -o libtermcap.so.2$ objdump -x termcap.so.2 НУЖЕН libc.so.6 SONAME termcap.so.2
Старый Linux/Sun использовал вышеописанное, что позволяет пользователю указать любой программе использовать любой, termcap.so
указанный в LD_LIBRARY_PATH , или то, что находится в /usr/local/lib(n) с помощью правил поиска, таких как . Однако GNU ld всегда использует or независимо от LD_LIBRARY_PATH , поэтому сначала перемещается в и то, что упомянуто в , что позволяет использовать перемещение и или использование LD_LIBRARY_PATH для использования. Предпочтительная практика — использовать "ld.so.conf
/lib
/usr/lib
/lib/termcap.so
/usr/local/lib
ld.so.conf
libs
ld.so.conf
SONAME termcap.so" и программы проверяют версию (все библиотеки поддерживают это) для использования доступных функций, но в старых версиях это часто пропускалось из-за низкой скорости вычислений и нехватки времени на правильное кодирование.
При этом тщательно протестируйте этот тип вещей на данной платформе, прежде чем решить положиться на него. Администраторы релизов сегодня не гарантируют соблюдения прошлых руководств или документации. Некоторые разновидности UNIX компонуются и загружаются совершенно по-другому. rpath специфичен для ld, поставляемого с определенным дистрибутивом.
Наконец, как уже было сказано, rpath — это функция безопасности, однако «принудительный контроль доступа» (MAC) и другие методы могут быть столь же эффективны или даже более эффективны, чем rpath, для контроля чтения и записи библиотек.
Контроль над rpath с помощью современных компиляторов часто почти невозможен из-за длинных и запутанных скриптов make(1). Хуже того, некоторые скрипты сборки игнорируют —disable-rpath, хотя и представляют его как опцию. Было бы долго и утомительно, и, вероятно, невыполнимо, исправлять скрипты сборки в каждой нечетной программе для компиляции.
Простая "обертка" sh(1) может вызвать настоящий ld, названный ld.bin. Обертка может отфильтровывать в/из опции -rpath перед вызовом ld.
#!/bin/sh # - здесь фильтруются параметры ld - ld.bin $opts
Однако следует отметить, что некоторые сборки неправильно используют rpath вместо rpath-link или LD_LIBRARY_PATH или $(TOP)/dir/foo.so для поиска промежуточных продуктов, которые остаются в каталоге сборки, — таким образом, в конечном продукте возникает требование использовать rpath, что является новой проблемой, касающейся вопроса «что такое rpath».
Использование rpath, а также runpath может представлять угрозу безопасности, если применяемое значение включает каталоги, находящиеся под контролем злоумышленника. Это может включать случаи, когда определенное значение явно ссылается на доступное для записи местоположение злоумышленника, а также случаи, когда используется относительный путь, либо через наличие . или .., через $ORIGIN и т. д., либо когда оператор каталога остается незаполненным. В частности, это может позволить эксплуатировать двоичные файлы setUID, где используется небезопасный путь. Это можно использовать, чтобы обмануть двоичный файл и заставить его загрузить вредоносные библиотеки из одного или другого каталога, находящегося под контролем злоумышленника.
DT_RPATH
атрибута исполняемого файла и преобразования его в DT_RUNPATH
атрибутDT_RUNPATH
атрибутов исполняемых файлов ELF .