【问题标题】:Linux, Shared library uses functions from main program instead of other shared librariesLinux,共享库使用主程序中的函数而不是其他共享库
【发布时间】: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。这样我就不会做任何尴尬的事情并尝试解决别人的错误。

标签: c++ c linux shared-libraries


【解决方案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 中指定。

      这可能不是最好的解决方案,但在这种情况下,当进程由闭源软件创建时,它可以工作。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-19
        • 1970-01-01
        • 2011-02-28
        • 2015-09-30
        • 2020-01-01
        • 1970-01-01
        相关资源
        最近更新 更多