Linux,共享库使用主程序中的函数而不是其他共享库
Posted
技术标签:
【中文标题】Linux,共享库使用主程序中的函数而不是其他共享库【英文标题】:Linux, Shared library uses functions from main program instead of other shared libraries 【发布时间】:2014-10-09 06:32:40 【问题描述】:我正在构建一个从应用程序(我无法控制)加载的共享库。我的库使用其他共享库,而这些共享库又使用其他共享库,复杂但并不罕见。
问题在于主应用程序的函数存在于链中更靠后的一个库中,更具体地说,openLDAP
又使用 openSSL
函数:
Main app->My library->openLDAP libraries->openSSL libraries
我的猜测是,主应用程序正在通过静态链接或简单的源代码复制/粘贴来实现openSSL
。
我的问题是:我可以控制 openLDAP
使用我的库中的哪些函数,还是必须重新编译 openLDAP
并与 openSSL
建立静态链接?
由于openSSL
因安全问题而经常更新,因此如果不需要,我不想要它的静态副本。以及为什么要重新分发 openLDAP
的专有副本,因为它是大多数分发包的一部分...
【问题讨论】:
我使用 Mozilla NSS 而不是 openSSL 构建了 openLDAP。这样我就不会做任何尴尬的事情并尝试解决别人的错误。 【参考方案1】:现在您所拥有的是可执行文件,它覆盖了系统默认选择的 OpenSSL 库。这样做是在可执行文件的权利范围内,您无法真正阻止它。
在您的库中静态链接 OpenSSL 也可能不是真正的解决方案。一方面,如果可执行文件确实是使用不同的版本怎么办?另一方面,如果 OpenSSL 有一些全局变量怎么办?现在您将在同一个进程中拥有该库的两个副本,这不是一个好主意,可能会导致错误。
对我来说,我们在 Linux 上的最佳答案是不要将这类事情视为问题。如果可执行文件加载了错误版本的 OpenSSL,那不是您的库的错。最多可以检查加载了哪个版本,如果已知它由于某种原因与您的库不兼容,则拒绝运行。
【讨论】:
【参考方案2】:我的猜测是主应用程序正在实现 openSSL 通过静态链接或源代码的简单复制/粘贴。
这是错误的事情。如果应用程序开发人员在他的脚上开枪,那么您将无能为力。
应用开发者应该看到你的库依赖于 OpenSSL 库(使用 ldd 命令),那么他不应该链接OpenSSL again as staticly or copy paste its code.
如果来自 OpenSSL 的某些函数不会造成任何混乱,并且如果它们可以像任何 java 类的任何静态方法一样使用,那么只有应用程序开发人员应该冒险在应用程序中实现该代码。
【讨论】:
【参考方案3】:解决方案是在 dlopen(3) 中使用 RTLD_DEEPBIND:
RTLD_DEEPBIND(自 glibc 2.3.4 起)
将此库中符号的查找范围放在 全球范围。这意味着一个独立的库将使用它的 自己的符号优先于同名的全局符号 包含在已加载的库中。这个标志不是 在 POSIX.1-2001 中指定。
这可能不是最好的解决方案,但在这种情况下,当进程由闭源软件创建时,它可以工作。
【讨论】:
以上是关于Linux,共享库使用主程序中的函数而不是其他共享库的主要内容,如果未能解决你的问题,请参考以下文章