对ld-linux.so黑客使用替代libc;更清洁的方法?


13

我有一个带有非常老的glibc的遗留系统,如果不进行大量测试/验证工作,就无法升级。

我现在需要多次在该系统上运行较新的程序(例如Java 1.7)。我选择了chroot解决方案,其中打包了所有需要的库,并在chroot中运行服务。

chroot的限制非常大,我宁愿尝试使用LD_LIBRARY_PATH解决问题。不幸的是,我libc.so.6: cannot handle TLS data在尝试时遇到错误。

事实证明,我也需要/lib/ld-linux.so.2chroot的。这有效:

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)的更简洁方法?

Answers:


12

如您在十六进制编辑器中发现的那样,加载程序的路径被编译为二进制文件。您实际上很幸运,因为/lib/ld-linux.so.2/home/chroot/ld.so的长度相同,所以直接编辑二进制文件有效。这些字符串的长度也在二进制文件中,如果直接修改字符串,可能会引起一些细微问题。

如果您最终选择了该路线,则应查看patchelf之类的东西来更新解释器。这样一来,您就可以快速,安全地永久更改解释器。


运气不好,我知道我不需要移动任何字节;-)但是,patchelf看起来就像我想要的那样。除了无法使用相对路径之外,它还可以照顾我正在使用的LD_LIBRARY_PATH,因此不需要包装器。只要有机会测试一下,我就会为您提供答案。
无数据,2014年

1
有用!这将为我提供一个不错的方法,可以将此服务器上的新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 的目录中。
2014年

@dataless好,我仍然需要LD_LIBRARY_PATH来解决此libjvm.so,因为libstdc ++。so.6:无法打开共享对象文件:没有这样的文件或目录[root @ 97245bbe7cc1 tensorflow-java]#
Amos,

@Amos已经有一段时间了,但就我而言,我不再需要LD_LIBRARY_PATH,因为默认值来自Java二进制文件。但是,请注意我说过的部分,找到了Java使用的所有库并将它们复制到Java库目录中。我曾经ldd $JAVA/bin/java得到过ist。您还需要一些动态的libc文件,例如libnss.so
无数据
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.