私は非常に古いglibcを備えたレガシーシステムを使用しています。これは、大量のテスト/検証作業を行わずにアップグレードすることはできません。
そのシステムで新しいプログラム(Java 1.7)など)を数回実行する必要がありました。必要なすべてのライブラリをパッケージ化し、サービスを実行するchrootソリューションを選択しましたchroot。
ただし、chrootは非常に制限があり、LD_LIBRARY_PATHの問題を解決しようとしています。残念ながら、試してみるとlibc.so.6: cannot handle TLS data
に関するエラーが表示されます。
Chrootからの/lib/ld-linux.so.2
も必要だとわかりました。これは機能します:
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バイナリを16進エディターで開き、文字列/lib/ld-linux.so.2
を/home/chroot/ld.so
に置き換えました(そして、 ld-linux.so.2
)に、それはうまくいきました!
しかし、すべての新しいバイナリのパスをネストされたシステムの絶対パスに書き直すのは大げさだと誰もが同意するだろうと思います。
カスタムライブラリパス含むカスタムld-linux.soを使用するよりクリーンな方法を知っている人はいますか?
ローダーへのパスは、16進数エディターで検出したバイナリにコンパイルされます。両方の/lib/ld-linux.so.2
および/home/chroot/ld.so
は同じ長さです。これらの文字列の長さもバイナリにあり、文字列を直接変更すると微妙な問題が発生する可能性があります。
最終的にルートに行く場合は、インタープリターを更新するために patchelf のようなものを確認する必要があります。これにより、インタープリターを迅速かつ安全に永久に変更できます。