Використання альтернативного libc з хаками ld-linux.so; чистіший метод?


13

У мене є застаріла система з дуже старим glibc, яку ми не можемо модернізувати, не піднявши на себе гору тестувальних / перевірочних робіт.

Мені потрібно було кілька разів запускати нові програми (наприклад, Java 1.7) у цій системі. Я вибрав рішення для chroot, де я пакую всі необхідні ваги і запускаю службу в chroot.

Chroot дуже обмежує, і я б скоріше спробував вирішити проблему з LD_LIBRARY_PATH. На жаль, я отримую помилку, libc.so.6: cannot handle TLS dataколи намагаюся це зробити.

Виявляється, мені потрібні ще й /lib/ld-linux.so.2з chroot. Це працює:

LD_LIBRARY_PATH=/home/chroot/lib /home/chroot/lib/ld-linux.so.2 /home/chroot/bin/program

Однак, javaфольгує мій трюк, перевіряючи, /proc/self/cmdlineщоб визначити, звідки завантажувати його бібліотеки, що не вдається, якщо двійковий файл не був названий "bin / java". Також Java виконує під час запуску, що ще більше ускладнює справи.

В останній спробі зробити цю роботу я відкрив двійковий файл Java з шестигранним редактором і замінив рядок /lib/ld-linux.so.2на /home/chroot/ld.so(і зробив це посилання на симполіс ld-linux.so.2), і воно спрацювало!

Але я думаю, що всі погодиться, що це велика хитрість переписати шлях кожного нового бінарного на абсолютний шлях вкладеної системи.

Хтось знає, чистіший спосіб використовувати користувацький шлях до бібліотеки, включаючи користувальницький ld-linux.so?

Відповіді:


12

Шлях до завантажувача компілюється у двійковий файл, як ви виявили зі своїм шестигранним редактором. Вам насправді пощастило, що редагування бінарного файлу безпосередньо працювало, тому що обидва /lib/ld-linux.so.2і /home/chroot/ld.soоднакові за довжиною. Довжина цих рядків також є у двійковій формі, і ви можете викликати тонкі проблеми, якщо змінити рядки безпосередньо.

Якщо ви в кінцевому підсумку рухаєтесь по маршруту, вам слід поглянути на якусь річ, наприклад, patchelf, щоб оновити перекладача. Це дозволить вам швидко та безпечно змінити перекладача.


Не пощастило, я знав, що мені потрібно не зміщувати жоден байт ;-) Але, patchelf виглядає як те, що я хочу. Крім неможливості використання відносного шляху, він також може подбати про LD_LIBRARY_PATH, який я використовую, щоб мені не потрібна обгортка. Я дам вам кредит за відповідь, як тільки я отримаю можливість перевірити її.
даних

1
Це працює! Це дасть мені гідний шлях вперед для змішування програм new-libc зі старими програмами libc на цьому сервері. Для майбутніх читачів команда полягала в тому patchelf --set-interpreter $JAVA/lib/ld-linux.so.2 --set-rpath $JAVA/lib:$JAVA/lib/i386:$JAVA/lib/i386/jli $JAVA/bin/java, де $ JAVA - каталог JRE, і де я зібрав усі залежні бібліотеки і помістив їх у lib/каталог JRE.
даних

@dataless добре, мені все ще потрібен LD_LIBRARY_PATH для обходу цього libjvm.so, тому що libstdc ++. so.6: не вдається відкрити спільний файл об'єкта: немає такого файлу чи каталогу [root @ 97245bbe7cc1 tensorflow-java] #
Amos

@Amos Минув час, але для мого випадку мені вже не потрібен LD_LIBRARY_PATH, тому що за замовчуванням надходить java binary. Але зауважте частину, де я сказав, що я обійшов і знайшов усі використовувані вами язики та скопіював їх у dir lib dir. Я звик ldd $JAVA/bin/javaотримувати іст. Є також деякі динамічні libc, які вам потрібні, як libnss.so
даних
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.