LINUX.ORG.RU

Добавить префикс для поиска интерпретатора

 ,


0

2

Привет. В исполняемых файлах зашита инофмация с абсолютными путями к загрузчику/интерпретатору (/lib64/ld-linux-x86-64.so, #!/bin/bash). Можно ли задать какой-то префикс, который будет прилепляться к абсолютному путю во время поиска? Например в консоле (псевдокоманда): # setprefix /sandbox; ./bash_script, и скрипт затребует /sandbox/bin/bash. Сомневаюсь, но вдруг есть какие-то варианты. Править исполняемые файлы - не вариант.

Посмотрел сейчас, вроде binfmt_misc должен вставать в списке впереди binfmt_script (по крайней мере когда script монолитно, а misc модулем).

Стало быть, если через binfmt_misc добавить свой обработчик для #!, он вызовется. Напишите бинарник, который отдаст скрипт кому надо в зависимости от окружения, и зарегистрируйте в misc.

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

А, пропустил, что для эльфов вам тоже надо. К ним мой рецепт подходит, только обработчик сложнее (а потом эльф захочет библиотеку, вы достанете LD_LIBRARY_PATH, а потом кто-то захочет конкретный rpath... и тут мы, кажется, упёрлись, нормальных решений не будет).

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

Вообще изначальная задача - составить log установленных файлов от make install. Ставить в DESTDIR и проанализировать установленное - вариант, но хлопотно в случае большого объёма (около сотни пакетов) + частенько к make install необходимо сделать cp/mv/ln. Подумал - сделаю загончик для установки, /bin и смежные подмонтирую в /old/bin, подправлю PATH и LD_LIBRARY_PATH, chroot'нусь в загончик и установлю софтину (выигрыш в том, что один и тот же набор команд при установке для анализа и реальной). И всё вроде ничего, но что делать с абсолютными путями в файлах - не знаю (ведь может же какой-нибудь скрипт из make дёрнуться, с загрузчиком решаемо - создать в корне /lib/ld-linux-x86-64.so, а после установки удалить). О вашем варианте впервые слышу, посмотрю, спасибо. Но чую, что магии там много )).

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

checkinstall использует installwatch для составления лога. Я в начале installwatch'ом начал поьзоваться, но оказалось, что его логи пропускают некоторые действия. Я с этими логами уже мозг сломал. Что ещё, искать установленное через timestamp? вроде не надёжно, каждый пакет - отдельный user? хлопотно

Кстати, я наверное понял как решить свою задачу - заселю /bin всякими ссылками на интерпретаторы, а установку (для анализа) выполню от другого пользователя с последующим поиском файлов принадлежащих ему.

pavlick ()
Последнее исправление: pavlick (всего исправлений: 1)
Ответ на: комментарий от pavlick

Я бы для вашей задачи в песочницу совал overlayfs (можно что-то аналогичное, но overlayfs есть в современных ядрах из коробки), нижним слоем — read-only bind mount настоящей rootfs, в верхний слой пусть пишут make-install'ы (как вариант: для каждого make install'а его заново создавать чистым, а для зависимостей подкладывать на «пред-верхний слой» комбинацию результатов от make-install'а зависимостей). Можно ещё fakeroot пристегнуть, чтобы избежать make-install'ов от реального рута.

Или таки докер, но я не подскажу, как у него быстро узнать «что изменил по сравнению с базовым image конкретный make install», хотя способ скорее всего есть.

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

Вообще изначальная задача - составить log

Если вам главнее не просто поместить в свой корень, что решается с помощью chroot, а именно log, то может написать preload библиотеку с перехватом open+rename ?

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

Так installwatch вроде это и делает

Ага, уже оказывается есть готовое...

и раз туда не всё попадает, очевидно, кто-то проходит мимо preloada

Интересно, как и главное — зачем оно так «проходит»?

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

Интересно, но скорее всего низачем, а просто так получилось.

Например, какой-то из этих пакетов статически собирает инструмент, которым ставит [некоторые] свои файлы (представьте my_cool_install в проекте на golang). Или теряет LD_PRELOAD из окружения (с помощью su, скажем). Или installwatch.so не ловит какой-нибудь хитрый способ создания файла (что-нибудь вроде O_TMPFILE, за которым следует link «/proc/self/fd/%d» в нужное место, или, к примеру, openat(), который сложнее обрабатывать и на него могли плюнуть, поскольку так никто не делает).

Можно было бы анализировать strace -f make install, но это тоже нетривиально (не знаю, что бы я предпочёл велосипедить сам — LD_PRELOAD и молиться, что не пропустил какой-нибудь __open64_2, который тоже надо перехватить, или strace и мучиться, что означает open с относительным путём и куда ведёт dirfd для openat).

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

Или теряет LD_PRELOAD из окружения

Да, это кажется наиболее вероятным как самое простое.

openat()

Это installwatch перехватывает, определение реального пути и происходит через readlink(«/proc/self/fd/%d»==dirfd).

и молиться, что не пропустил какой-нибудь __open64_2,

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

vodz ★★★★ ()
Последнее исправление: vodz (всего исправлений: 3)
Ответ на: комментарий от pavlick

Буду ею пользоваться, это идеально подходит.

Но ведь она не привязана к группе процессов, то есть все изменения в FS помимо действия install так же попадут туда.

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

Не попадают, как пример, только что делал:

/sandbox_root
  old
    bin,lib,sbin,usr,...
  up
  work
  install_sandbox

в old делаю mount --bind настоящего кореня. Далее
# mount -t overlay -olowerdir=old,upperdir=up,workdir=work overlay install_sandbox
# В up mount --bind устанавливаемой софтины.
# chroot /sandbox_root/install_sandbox/
# cd софтина && make install && cp ... && ln ...

только что поставил так gcc-8.2.0, в /sandbox_root/up получил полное дерево установленных файлов.
# find /sandbox_root/up/
usr/libexec
usr/libexec/gcc
usr/libexec/gcc/x86_64-pc-linux-gnu
usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0
usr/libexec/gcc/x86_64-pc-linux-gnu/8.2.0/cc1
...

Интересно то, что модификация корня напрямую (mkdir /q___ (не из chroot), например) или через /sandbox_root/old не отображается в /sandbox_root/up (видна только модификация через up или install_sandbox). Т.е old играет роль шаблона при создании образа install_sandbox во время mount. Ну возможно там есть какие-то опции для получения иного поведения, но дефолтно так.

pavlick ()
Последнее исправление: pavlick (всего исправлений: 3)
Ответ на: комментарий от pavlick

Я ничего не понял. Зачем вам overlay, если вы сделали chroot и что-то этим пытаетесь возразить.

Я вообще хотел сказать, что из-за того, что overlay накладывается на текущую FS, то единственным разумным применением получается использовать её как сохранение «factory default», либо как-то чрезвычайно жёстко запретить какую-либо другую активность в момент install-ов и использовать полученный оверлей как снапшот всего дерева системы начиная от точки монтирования оверллея на некую дату, но последовательно, миксовать без глюков эти снапшоты не получится.

vodz ★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Я что-то тоже не очень вас понимаю. Когда мы накладываем old на up, то после этого up пустая (если была таковой до mount), а install_sandbox содержит сумму up и old. Сделав touch file, например, в install_sandbox, up будет содержать один лишь file, а сделав make install в install_sandbox, будет содержать всё хозяйство, которое make записал. И повторю - модификация не через up или install_sandbox не отразится на up, т.е. никакой другой процесс не сможет вмешаться и нагадить в up, только мои установочные команды. В up я получаю чистое дерего файлов без микса с old.

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

т.е. никакой другой процесс не сможет вмешаться и нагадить в up, только мои установочные команды.

С чего вы взяли? Если вы наложили на корень, то вы и оверлеите корень, если на како-то левый каталог, про который никто никогда не догадывался, то оверлей и не при чём.

vodz ★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от pavlick

не отображается в /sandbox_root/up.

Это сделано специально, чтобы был каталог со старым содержимым, то есть все процессы работают как раз с новым содержимым, а у вас есть возможность сравнить что поменялось чтобы поменять старый cнапшот. Это очень нужно рутерам, у которых оверлай в памяти и надо спец команду для сохранения нового конфига, а по внезапному/преднамеренному пропаданию питания происходит возврат на последний сохраненный конфиг.

vodz ★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Т.е. вы утверждаете, что запись в lowerdir (не в upperdir или meregedir) отобразится в upperdir. Что для этого должно произойти, как заставить изменениям сделанным через cd lowerdir; touch ...; попасть в upperdir? Я часа два назад делал тестовые модификации, которых до сих пор не видно в upperdir. Подчёркиваю, cd lowerdir; touch ...;

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

Нет. Никакого лага по времени там в работе оверлей-fs нет. :) Принцип оверлея состоит в том, чтобы у вас был «изначальный» снапшот системы и другое место хранения (в рутерах ОЗУ как правило больше флеша) для новых версий тех же самых файлов, по тем же путям. Чтобы сохранить эти изменения из памяти во флеш, желательно не записывать всё подряд, это может не влезть, а спец программой найти разницу со старыми файлами по заранее изестным файлам/каталогам, опустив всё остальное как временный мусор, недостойный сохранения. Какие процессы, с какой параллельностью в работе производять эти изменения предсказать невозможно и это не делается. Просто на админа возлагают отвественность, что в момент, когда он нажал «сохранить конфиг» он должен осознавать, что активность по изменению необходимых файлов желательно прекратить.

vodz ★★★★ ()
Последнее исправление: vodz (всего исправлений: 1)
Ответ на: комментарий от vodz

Отлично, так тогда почему работать то не будет? Я ведь о чём говорил - есть low директория, up, merge. Если cd merge; touch ...;, то изменения в up попадают, если cd low; touch ...;, то нет. Очевидно, что cd merge; сhroot; make install;, выполнил лишь один процесс (ну кто ещаё знает о моём sandbox_root/sandbox_install), другие используют корень напрямую (cd /...).

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

Отлично, так тогда почему работать то не будет?

Потому что результат отличается от того, что я понял в вашем изначальном вопросе надо и сразу об этом и сказал — менять будет всё, а не только ваш install. Если вас это устраивает, то с install вы только всех запутали.

vodz ★★★★ ()

Похоже я рано обрадовался, overlayfs в принципе не подходит для тех целей, которые мне нужны:

Changes to the underlying filesystems while part of a mounted overlay filesystem are not allowed. If the underlying filesystem is changed, the behavior of the overlay is undefined, though it will not result in a crash or deadlock.

т.е. неизменность корня я гарантировать ведь не могу (ну не бить же мне сейчас диск и монтировать разделы read only). + сделав mv file file_ в merge dir, в up dir получил какое-то символьной устройство file (каковым file никогда не являлся). В общем надо оставить overlayfs для всяких cd дисков, наверное. Неужели я хочу столь странного - знать какие файлы принадлежат пакету? И над этой задачей бьюсь уже не первый день )). Еще раз всех благодарю за ответы, буду дальше велосипедить.

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

Вообще изначальная задача - составить log установленных файлов от make install. Ставить в DESTDIR и проанализировать установленное - вариант, но хлопотно в случае большого объёма (около сотни пакетов) + частенько к make install необходимо сделать cp/mv/ln.

я могу ошибаться, но, вроде как, для этого fakeroot

teod0r ★★★★★ ()