【问题标题】:Kernel Resource Leak BIO_do_connect内核资源泄漏 BIO_do_connect
【发布时间】:2014-11-18 11:52:29
【问题描述】:

我需要帮助解决以下问题;我试图寻找答案,但我一直在问。

Inspector XE 给出如下结果:Kernel Resource Leak on the line

he=BIO_gethostbyname(str);

这一行是 OpenSSL 源代码的一部分,我无法想象这里有什么问题。

内部调用了这个函数:

BIO_do_connect();

我的代码是。

bio = BIO_new_connect(...);
if (BIO_do_connect(bio) != 1) { ... }
...
if (BIO_free(bio) != 0) { ... }

连接成功,唯一的错误发生在我与线程同时调用此函数 1000 次时。

这个程序真的会导致内核资源泄漏吗?

【问题讨论】:

    标签: c++ c memory-leaks openssl inspector


    【解决方案1】:

    BIO_gethostbyname 不是(不能是)线程安全的,因为它返回一个指向静态缓冲区的指针。确实,在 openssl 的 bio.h 中提到了这一点,阅读

    struct hostent *BIO_gethostbyname(const char *name);
    /* We might want a thread-safe interface too:
     * struct hostent *BIO_gethostbyname_r(const char *name,
     *     struct hostent *result, void *buffer, size_t buflen);
     * or something similar (caller allocates a struct hostent,
     * pointed to by "result", and additional buffer space for the various
     * substructures; if the buffer does not suffice, NULL is returned
     * and an appropriate error code is set).
     */
    

    ...但是,到目前为止,还没有实现 BIO_gethostbyname_r 函数,无论如何,如果它有并且 BIO_do_connect 没有使用它,它对您没有帮助。

    但不要绝望!此函数调用周围有锁定代码,因此可以(可能)使其工作。不过有趣的是——锁定代码并不总是有任何作用。我假设您没有使用OPENSSL_NO_LOCKING 编译 OpenSSL,因为它不是默认设置,如果他们想开发多线程应用程序,我无法想象有人会使用它,所以我猜您忘记调用

    CRYPTO_thread_setup();
    

    在生成使用 OpenSSL 的线程之前。这很重要的原因是CRYPTO_thread_setup 确实设置了一个函数指针,指向一个处理实际锁定的平台相关函数。如果CRYPTO_thread_setup 没有被调用,这个指针仍然是NULL,并且CRYPTO_lock(在BIO_gethostbyname 调用周围使用的宏底部的相关函数)将默默地什么都不做。据我所知,没有任何文档可以让您知道这一点。

    您可能认为您对 OpenSSL 代码库质量的乐观是错误的。

    【讨论】:

    • 我需要 15 声望才能增加 +1。我不得不说 BIO_* 函数似乎没有很好的文档记录。
    • 最后我自己编写了 OpenSSL BIO 函数。现在也有一个巨大的性能提升,没有错误。谢谢。
    猜你喜欢
    • 1970-01-01
    • 2014-02-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-07-07
    • 2012-09-29
    • 1970-01-01
    相关资源
    最近更新 更多