將備用 libc 與 ld-linux.so hacks 一起使用;更清潔的方法?
我有一個帶有非常舊的 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)的更簡潔方法?
正如您使用十六進制編輯器發現的那樣,載入程序的路徑被編譯成二進製文件。實際上,您很幸運能夠直接編輯二進製文件,因為兩者
/lib/ld-linux.so.2
的/home/chroot/ld.so
長度相同。這些字元串的長度也在二進製文件中,如果直接修改字元串,可能會導致微妙的問題。如果你最終走這條路,你應該看看像patchelf這樣的東西來更新解釋器。這將使您能夠快速安全地永久更換口譯員。