使用GNU Libc编译并在Linux上运行eglibc的危险?

时间:2014-05-04 16:58:45

标签: linux ubuntu libc eglibc

我有一个可执行文件,它几乎只依赖于libc。 ldd的输出是:

libpthread.so.0 => /lib64/libpthread.so.0 (0x00002b53156b9000)
libutil.so.1 => /lib64/libutil.so.1 (0x00002b53158d5000)
librt.so.1 => /lib64/librt.so.1 (0x00002b5315ad8000)
libdl.so.2 => /lib64/libdl.so.2 (0x00002b5315ce2000)
libm.so.6 => /lib64/libm.so.6 (0x00002b5315ee6000)
libc.so.6 => /lib64/libc.so.6 (0x00002b5316169000)
/lib64/ld-linux-x86-64.so.2 (0x0000003a06600000)

我已经在旧的CentOS 6上编译了这个。运行/lib64/libc.so.6说:

GNU C Library stable release version 2.5, by Roland McGrath et al.
...

在任何其他版本的linux上运行此可执行文件有多安全?具体来说,在具有eglibc的Ubuntu和Debian机器上运行是否安全?我编译的可执行文件似乎在12.04 LTS上正常运行但是我可以相信这没有微妙的错误并且还可以在这些发行版的其他版本上运行吗?

2 个答案:

答案 0 :(得分:5)

EGLIBC被设计为与GLIB兼容的API和ABI,正如您在其features page中所读到的那样,只要您使用它的默认配置(如Debian版本)就不会有任何问题) - 即您没有使用比GLIBC更少功能的某些限制版本。

特别是,您可以阅读announcement of Debian switching to EGLIBC。请记住,如果Debian没有与GLIBC完全ABI兼容,那么从Debian切换到EGLIBC是不合理的,因为它可能会破坏遗留的二进制文件或者只是来自Debian存储库的软件。

如果您使用的是有限版本的EGLIBC,除非您使用从库中删除的某些功能,否则您应该没有问题。例如,使用GLIBC编译的二进制文件应该可以正常使用没有套接字的EGLIBC版本,只要它不使用它们。

答案 1 :(得分:1)

@javidcf是正确的,因为eglibc和glibc是ABI兼容的,因为在一般意义上你不应该在eglibc上运行与glibc编译的东西。

但是,您可能会遇到与glibc与eglibc无关的问题,而是与glibc版本偏差有关。某些glibc函数标记有它们末尾的版本(例如> printf @@ GLIBC_2.2.5',当通过nm查看时,或通过在二进制文件上运行字符串并为GLIBC进行grepping)。我相信这些代表了运行生成的二进制文件的一种最小glibc版本要求。简单的程序可能很少(或没有)这些类型的函数。复杂程序可能有多个要求。这是在Ubuntu 14.04上我的firefox二进制文件上运行字符串的结果:

$ strings /usr/lib/firefox/firefox | grep GLIBC
GLIBC_2.2.5
GLIBC_2.3
GLIBC_2.4
GLIBC_2.3.2
GLIBC_2.3.4
GLIBC_2.17
GLIBCXX_3.4

这意味着我至少需要glibc库的2.17版才能解析运行该程序所需的符号。

这样做的结果是在较旧的发行版上编译的二进制文件很有可能在更新的版本上工作;但是在较新的发行版上编译的二进制文件,针对较新的glibc,可能会使用将被标记为具有更高最低要求的较新版本的函数,可能不适用于较旧的系统。例如,您的CentOS 6二进制文件可能无法在CentOS 5或Ubuntu 10.04上运行;但可能在CentOS 7和Ubuntu 12.04 / 14.04上运行良好。

如果你想要一个(更好的机会)真正的可移植二进制文件,静态链接是一个更好的选择。