LINUX.ORG.RU

Подмена зависимых динамических библиотек в процессе работы программы

 ,


0

1

Здравствуйте! У меня появился такой вопрос. Я полазил по форуму и прочел, что если некий бинарник использует разделяемые библиотеки, то они mmap-ятся в оперативную память. В таком случае, если во время работы бинарника заменить либу на более новую (или вообще удалить), то есть вероятность, что система переммапит его в память и выполнение бинарника испоритится. Эксперименты показывают, что вероятность такая довольно велика. Бинарник падает. Но тогда мне непонятно, как пакетный менеджер может обновлять пакеты, от которых зависит? Например pacman:

$ ldd /bin/pacman
        linux-vdso.so.1 (0x00007fff6df57000)
        libalpm.so.9 => /usr/lib/libalpm.so.9 (0x00007fd0e6059000)
        libarchive.so.13 => /usr/lib/libarchive.so.13 (0x00007fd0e5db6000)
        libc.so.6 => /usr/lib/libc.so.6 (0x00007fd0e5a13000)
        libgpgme.so.11 => /usr/lib/libgpgme.so.11 (0x00007fd0e57da000)
        libcurl.so.4 => /usr/lib/libcurl.so.4 (0x00007fd0e5567000)
        libcrypto.so.1.0.0 => /usr/lib/libcrypto.so.1.0.0 (0x00007fd0e50eb000)
        libacl.so.1 => /usr/lib/libacl.so.1 (0x00007fd0e4ee2000)
        libattr.so.1 => /usr/lib/libattr.so.1 (0x00007fd0e4cdd000)
        libexpat.so.1 => /usr/lib/libexpat.so.1 (0x00007fd0e4ab3000)
        liblzo2.so.2 => /usr/lib/liblzo2.so.2 (0x00007fd0e4891000)
        liblzma.so.5 => /usr/lib/liblzma.so.5 (0x00007fd0e466b000)
        libbz2.so.1.0 => /usr/lib/libbz2.so.1.0 (0x00007fd0e445b000)
        libz.so.1 => /usr/lib/libz.so.1 (0x00007fd0e4245000)
        /lib64/ld-linux-x86-64.so.2 (0x00007fd0e628a000)
        libassuan.so.0 => /usr/lib/libassuan.so.0 (0x00007fd0e4033000)
        libgpg-error.so.0 => /usr/lib/libgpg-error.so.0 (0x00007fd0e3e21000)
        libidn.so.11 => /usr/lib/libidn.so.11 (0x00007fd0e3bed000)
        libssh2.so.1 => /usr/lib/libssh2.so.1 (0x00007fd0e39c4000)
        libssl.so.1.0.0 => /usr/lib/libssl.so.1.0.0 (0x00007fd0e3749000)
        libgssapi_krb5.so.2 => /usr/lib/libgssapi_krb5.so.2 (0x00007fd0e34fc000)
        libkrb5.so.3 => /usr/lib/libkrb5.so.3 (0x00007fd0e3217000)
        libk5crypto.so.3 => /usr/lib/libk5crypto.so.3 (0x00007fd0e2fe4000)
        libcom_err.so.2 => /usr/lib/libcom_err.so.2 (0x00007fd0e2de0000)
        libpthread.so.0 => /usr/lib/libpthread.so.0 (0x00007fd0e2bc3000)
        libdl.so.2 => /usr/lib/libdl.so.2 (0x00007fd0e29bf000)
        libkrb5support.so.0 => /usr/lib/libkrb5support.so.0 (0x00007fd0e27b2000)
        libkeyutils.so.1 => /usr/lib/libkeyutils.so.1 (0x00007fd0e25ae000)
        libresolv.so.2 => /usr/lib/libresolv.so.2 (0x00007fd0e2397000)
Очень много от чего зависит. Но почему тогда при переустановке пакетов, от которых от зависит, он не падает? У меня довольно давно стоит Арч и я регулярно его обновляю, но всегда все проходило стабильно.

В таком случае, если во время работы бинарника заменить либу на более новую (или вообще удалить), то есть вероятность, что система переммапит его в память и выполнение бинарника испоритится.

Можешь как-то подкрепить ссылочкой это утверждение? Насколько мне известно, пока все программы не закроют shared library, новая подгружаться не будет. Для этого ld cache и придумали.

UVV ★★★★★ ()
Ответ на: комментарий от UVV

Два чая сему товарищу. Процесс будет работать со старой, иначе был бы разброд и шатания. вариант, только, если сама аппликуха следит за своими либами и перегружает.

anonymous ()
Ответ на: комментарий от anonymous

если сама аппликуха следит за своими либами и перегружает.

даже мысли о том, зачем и как это делать вызывают пошлые ассоциации..

UVV ★★★★★ ()
Ответ на: комментарий от anonymous

К сожалению, там и выходит разброд и шатания( Ссылку выше предоставил на тему, где прочел про это.

esvstn ()
Ответ на: комментарий от esvstn

Там какой-то бугурт по ссылке. Возможно речь о lazy binding http://linux.die.net/man/3/dlopen . Т.е. по факту библиотека мапится тогда, когда начнут пользоваться её функциями. Но это никак не вяжется с «подменой в памяти».

UVV ★★★★★ ()
Ответ на: комментарий от UVV

Нет, речь идет не о явной загрузке. Речь там о том, что при ммапинге кэш только отображается в память. И при замене файла может переотобразиться.

esvstn ()

Ну вообще, насколько я помню, удалённые файлы остаются в памяти, пока их кто-то использует, и подмена файла без перезапуска приложения никакого результата не даст. (если только в процессе работы не подгружает другие либы, названия/abi которых захардкожены в старой либе, и которых уже нет)

wakuwaku ★★★★ ()
Последнее исправление: wakuwaku (всего исправлений: 2)

Но почему тогда при переустановке пакетов, от которых от зависит, он не падает?

Потому что установщики не меняют файлы, а создают новые. Возможно, с теми же именами, но новые.

tailgunner ★★★★★ ()

Пакетные менеджеры перезаписывают файлы не так как ты думаешь. Они не записывают новое содержимое в сущнствующий файл, а создают новый файл с временным именем, записывают содержимое в него, а затем переименовывают его постоянное имя. Запись каталога после этого ссылается на файл с новым содержимым, а на файл со старым содержимым ссылки в каталоге не остается. Но ссылки на старый файл из открывших его процессов остаются, поэтому файл продолжает жить без имени. Файл улаляется, когда на него не остается ссылок.

iliyap ★★★★★ ()
Ответ на: комментарий от esvstn

Командой rm. Удалится ли при сам файл зависит от того, является ли удаленная запись каталога последней ссылкой на файл, или нет.

iliyap ★★★★★ ()
Ответ на: комментарий от anonymous

Большое спасибо. Я уже посмотрел трассировку pacman и rm. Они оба делают unlink. А cp - нет. И dd не делает. В целом, понял механизм.

esvstn ()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.