Использование альтернативного 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 для обновления интерпретатора. Это позволило бы вам быстро и безопасно сменить переводчика.


Не повезло, я знал, что мне не нужно сдвигать ни одного байта ;-) Но патчелф выглядит именно так, как я хочу. Помимо невозможности использовать относительный путь, он также может позаботиться о LD_LIBRARY_PATH, который я использую, чтобы мне не нужна оболочка. Я воздаю вам должное за ответ, как только у меня будет возможность проверить его.
без данных

1
Оно работает! Это даст мне приличный путь для смешивания программ new-libc с программами old-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 tenorflow-java] #
Amos

@Amos Это было давно, но для моего случая мне больше не нужен был LD_LIBRARY_PATH, потому что по умолчанию используется бинарный файл Java. Но обратите внимание на ту часть, в которой я сказал, что я обошел вокруг и нашел все библиотеки, используемые java, и скопировал их в java lib dir. Я имел обыкновение ldd $JAVA/bin/javaполучать ист. Есть также некоторые динамический Libc те , которые вы обязательно хотели libnss.so
без данных
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.