Menggunakan libc alternatif dengan hack ld-linux.so; metode bersih?

13

Saya memiliki sistem lawas dengan glibc yang sangat lama, yang tidak dapat kami tingkatkan tanpa menimbulkan serangkaian pekerjaan pengujian / validasi.

Saya perlu menjalankan program yang lebih baru (seperti Java 1.7) pada sistem itu beberapa kali sekarang. Saya memilih solusi chroot, di mana saya mengemas semua lib yang dibutuhkan, dan menjalankan layanan dalam chroot.

Chroot sangat terbatas, dan saya lebih suka mencoba menyelesaikan masalah dengan LD_LIBRARY_PATH. Sayangnya, saya mendapatkan kesalahan tentang libc.so.6: cannot handle TLS dataketika saya mencobanya.

Ternyata saya butuh /lib/ld-linux.so.2dari chroot juga. Ini bekerja:

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

Namun, javamenggagalkan trik saya dengan memeriksa /proc/self/cmdlineuntuk menentukan dari mana memuat pustaka, yang gagal jika biner tidak bernama 'bin / java'. Juga java mengeksekusi dirinya sendiri saat startup, lebih rumit lagi.

Dalam upaya terakhir untuk membuat karya ini, saya membuka java binary dengan hex editor dan mengganti string /lib/ld-linux.so.2dengan /home/chroot/ld.so(dan membuat symlink ke ld-linux.so.2), dan berhasil!

Tapi saya pikir semua orang akan setuju bahwa itu adalah kludge besar untuk menulis ulang jalur setiap biner baru ke jalur absolut dari sistem bersarang.

Adakah yang tahu cara yang lebih bersih untuk menggunakan lintasan pustaka kustom termasuk ld-linux.so khusus?

kebodohan
sumber

Jawaban:

12

Path ke loader dikompilasi ke dalam biner seperti yang Anda temukan dengan hex editor Anda. Anda benar-benar beruntung bahwa mengedit biner langsung berfungsi karena keduanya /lib/ld-linux.so.2dan /home/chroot/ld.sopanjangnya sama. Panjang dari string-string itu juga ada dalam biner dan Anda dapat menyebabkan masalah halus jika Anda memodifikasi string secara langsung.

Jika Anda akhirnya menuju rute Anda harus melihat beberapa hal seperti patchelf untuk memperbarui penerjemah. Ini akan memungkinkan Anda mengubah juru bahasa secara cepat dan aman.

gmjosack
sumber
Bukan keberuntungan, saya tahu saya tidak perlu menggeser byte apa pun ;-) Tapi, patchelf sepertinya yang saya inginkan. Selain tidak dapat menggunakan jalur relatif, ini juga dapat menangani LD_LIBRARY_PATH yang saya gunakan sehingga saya tidak memerlukan pembungkus. Saya akan memberi Anda kredit untuk jawabannya segera setelah saya mendapat kesempatan untuk mengujinya.
dataless
1
Berhasil! Ini akan memberi saya jalan yang layak untuk mencampur program libc baru dengan program libc lama di server ini. Untuk pembaca masa depan, perintahnya adalah patchelf --set-interpreter $JAVA/lib/ld-linux.so.2 --set-rpath $JAVA/lib:$JAVA/lib/i386:$JAVA/lib/i386/jli $JAVA/bin/java, di mana $ JAVA adalah direktori JRE, dan di mana saya telah mengumpulkan semua pustaka dependen dan meletakkannya di lib/direktori JRE.
dataless
@dataless yah saya masih perlu LD_LIBRARY_PATH untuk mengatasi libjvm.so ini, karena libstdc ++ .so.6: tidak dapat membuka file objek bersama: Tidak ada file atau direktori [root @ 97245bbe7cc1 tensorflow-java] #
Amos
@Amos Sudah lama, tapi untuk kasus saya, saya tidak perlu LD_LIBRARY_PATH lagi karena default berasal dari java binary. Tapi, perhatikan bagian di mana saya mengatakan bahwa saya berkeliling dan menemukan semua lib yang digunakan oleh java dan menyalinnya ke direktori java lib. Saya biasa ldd $JAVA/bin/javamendapatkan ist. Ada juga beberapa libc dinamis yang Anda butuhkan seperti libnss.so
dataless