Это не дубликат, поскольку он связан с особенностью, которую я заметил при использовании /etc/ld.so.conf
.
Чтобы получить пути, по которым динамический компоновщик ищет библиотеки, я запускаю команду ldconfig -v | grep -v "^"$'\t' | sed "s/:$//g"
. Когда /etc/ld.so.conf
в ней нет путей. Вывод предыдущей команды:
/lib
/usr/lib
Я понял, что он /lib
сначала ищет, а затем /usr/lib
. Когда я добавляю новый путь, например /usr/local/lib
, в , /etc/ld.so.conf
а затем переделываю /etc/ld.so.cache
, вывод ldconfig -v | grep -v "^"$'\t' | sed "s/:$//g"
становится
/usr/local/lib
/lib
/usr/lib
Я нахожу это странным, потому что если я прав, что порядок, в котором выполняется поиск в перечисленных каталогах, сверху вниз, то дополнительные каталоги просматриваются до /lib
и /usr/lib
. То, что дополнительные каталоги просматриваются до доверенных каталогов, само по себе не является странным, но когда /lib
просматривается до /usr/lib
, это странно, потому что /bin
и /sbin
просматриваются после /usr/bin
и /usr/sbin
в PATH
.
Даже если бы поиск по путям, перечисленным по , ldconfig -v | grep -Ev "^"$'\t' | sed "s/:$//g"
производился снизу вверх, порядок все равно был бы искажен, поскольку поиск по дополнительным каталогам производился бы после доверенных, а /lib
поиск по /usr/lib
.
Итак, в каком порядке ld.so
выполняется поиск путей для библиотек? Почему выполняется /lib
поиск до /usr/lib
? Если нет, то почему после /lib
?
решение1
Порядок документирован в руководстве динамического компоновщика, которое находитсяld.so
. Это:
- каталоги из
LD_LIBRARY_PATH
; - каталоги из
/etc/ld.so.conf
; /lib
;/usr/lib
.
(Я немного упрощаю, подробности смотрите в руководстве.)
Порядок имеет смысл, если учесть, что это единственный способ переопределить библиотеку в расположении по умолчанию с помощью пользовательской библиотеки. LD_LIBRARY_PATH
— это настройка пользователя, она должна быть перед другими. /etc/ld.so.conf
— это локальная настройка, она должна быть перед настройками операционной системы по умолчанию. Поэтому как пользователь, если я хочу запустить программу с другой версией библиотеки, я могу запустить программу с , LD_LIBRARY_PATH
содержащей расположение этой другой версии библиотеки. И как администратор, я могу поместить другую версию библиотеки в /usr/local/lib
и перечислить /usr/local/lib
в /etc/ld.so.conf
.
Доверие сюда не входит. Любой каталог, указанный в этом пути поиска, должен быть доверенным, потому что любая библиотека может быть загружена оттуда. Теоретически вы можете перечислить имена библиотек, используемых всеми программами, «требующими большего доверия» в вашей системе, и убедиться, что все эти библиотеки присутствуют в «наиболее доверенных» каталогах, и тогда «менее доверенные» каталоги не будут использоваться, если они идут после более доверенных каталогов в пути поиска, за исключением программ, «требующих меньшего доверия». Но это было бы крайне хрупко. Это также было бы довольно бессмысленно: если злоумышленник может внедрить значение LD_LIBRARY_PATH
или элемент /etc/ld.so.conf
, у него наверняка есть более прямой путь к выполнению произвольного кода, например, внедрить значение PATH
, из LD_PRELOAD
и т. д. Доверие к пути загрузки библиотеки имеет значение, когда выполнение пересекает границу доверия, т. е. при запуске программы с дополнительными привилегиями (например, программа setuid/setgid или через sudo
). В этом случае происходит то, что LD_LIBRARY_PATH
стирается.
Что касается /lib
vs /usr/lib
, это не имеет большого значения: они предоставляются одной и той же сущностью (операционной системой), и не должно быть библиотеки, которая присутствует в обеих. Имеет смысл перечислить их /lib
первыми, поскольку это обеспечивает (очень небольшое) преимущество в производительности: наиболее часто используемые библиотеки, особенно библиотеки, используемые небольшими базовыми программами (для которых время загрузки составляет более высокую долю от общего времени выполнения, чем для больших, долго выполняющихся программ), находятся в /lib
.