Утечка ресурсов ядра BIO_do_connect

Мне нужно помочь со следующим; Я пытался найти ответ, и я остался с вопросом.

Инспектор XE дал следующий результат: Утечка ресурсов ядра на линии

he=BIO_gethostbyname(str);

Эта строка является частью исходного кода OpenSSL, и я не могу представить, что здесь что-то не так.

Эта функция вызывается внутри:

BIO_do_connect();

Мой код

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

Соединение установлено успешно, единственные ошибки, которые возникают, когда я вызываю эту функцию 1000 раз одновременно с потоками.

Может ли эта программа вызвать утечку ресурсов ядра?

1

Решение

BIO_gethostbyname не является (не может быть) потокобезопасным, поскольку возвращает указатель на статический буфер. В самом деле, есть упоминание об этом в биографии openssl.

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 с OPENSSL_NO_LOCKING потому что это не по умолчанию, и я не могу представить, чтобы кто-то вставил его, если бы он хотел разрабатывать многопоточные приложения, поэтому я предполагаю, что вы забыли позвонить

CRYPTO_thread_setup();

до порождения потоков, использующих OpenSSL. Это важно по той причине, что CRYPTO_thread_setup помимо прочего, устанавливает указатель на функцию, зависящую от платформы, которая обрабатывает фактическую блокировку. Если CRYPTO_thread_setup не вызывается, этот указатель остается NULL, а также CRYPTO_lock (соответствующая функция в нижней части макроса используется вокруг BIO_gethostbyname позвони) молча ничего не сделаю. Насколько я знаю, нет никакой документации, из которой вы могли бы знать это.

Можно утверждать, что ваш оптимизм по поводу качества кодовой базы OpenSSL неуместен.

2

Другие решения


По вопросам рекламы [email protected]