Linux,共享库使用主程序中的函数,而不是其他共享库

Linux, Shared library uses functions from main program instead of other shared libraries

本文关键字:共享 其他 函数 主程序 Linux      更新时间:2023-10-16

我正在构建一个共享库,该库是从应用程序(我无法控制)加载的。我的库使用其他共享库,而这些共享库又使用其他共享的库,这很复杂,但并不罕见。

问题是,主应用程序的函数存在于链中更下游的一个库中,更具体地说,是openLDAP反过来使用openSSL函数:

Main app->My library->openLDAP libraries->openSSL libraries

我的猜测是,主应用程序通过静态链接或简单的源代码复制/粘贴来实现openSSL

我的问题是:我可以控制openLDAP从我的库中使用哪些函数吗?还是必须通过与openSSL的静态链接重新编译openLDAP

由于openSSL由于安全问题而频繁更新,如果不必要的话,我不想要它的静态副本。既然openLDAP是大多数分发包的一部分,为什么要重新分发它的专有副本呢。。。

现在您所拥有的是可执行文件,它覆盖了系统默认选择的OpenSSL库。这在可执行文件的权限范围内,你无法真正阻止它

静态链接库中的OpenSSL可能也不是真正的解决方案。首先,如果可执行文件真的使用了不同的版本,该怎么办?另一方面,如果OpenSSL有一些全局变量呢?现在,您将在同一过程中拥有库的两个副本,这不是一个好主意,可能会导致错误。

对我来说,在Linux上,最好的答案是不要把这类事情视为一个问题。如果一个可执行文件加载了一个错误版本的OpenSSL,那不是库的错。您最多可以检查加载了哪个版本,如果知道它由于某种原因与库不兼容,则拒绝运行。

我的猜测是,主应用程序正在实现openSSL通过静态链接或简单的源代码复制/粘贴。

这是错误的事情。若应用程序开发人员在他的脚上开枪,那个么你们什么都不能做。

应用程序开发人员应该看到你的库依赖于OpenSSL库(使用ldd命令),然后他不应该链接OpenSSL again as staticly or copy paste its code.

如果OpenSSL中的一些函数没有造成任何混乱,并且它们可以像任何java类的任何静态方法一样使用,那么只有应用程序开发人员才应该冒险在应用程序中实现这些代码。

解决方案是在dlopen(3):中使用RTLD_DEEPBIND

RTLD_DEEPBIND(自glibc 2.3.4起)

将此库中符号的查找范围放在全球范围。这意味着一个独立的图书馆将使用拥有的符号优先于具有相同名称的全局符号包含在已加载的库中。此标志不是POSIX.1-2001中规定。

这可能不是最好的解决方案,但在这种情况下,当流程是由封闭源代码软件创建时,它是有效的。