1

次のことを手伝う必要があります。私は答えを探してみましたが、質問が残っています。

Inspector XE の結果は次のとおりです: 回線でのカーネル リソース リーク

he=BIO_gethostbyname(str);

この行は OpenSSL ソースコードの一部であり、ここで何か問題があるとは想像できません。

この関数は内部で呼び出されます:

BIO_do_connect();

私のコードは.

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

接続は成功しています。この関数をスレッドと同時に 1,000 回呼び出したときに発生する唯一のエラーです。

このプログラムは本当にカーネル リソース リークを引き起こすのでしょうか?

4

1 に答える 1

2

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 関数は実現していません。

しかし、絶望しないでください!この関数呼び出しの周りにロック コードがあるため、(おそらく) 動作させることができます。面白いことに、ロック コードが常に何もしないというわけではありません。OpenSSL はデフォルトではないため、 OpenSSL をコンパイルしなかったと仮定します。OPENSSL_NO_LOCKINGまた、マルチスレッド アプリケーションを開発したい場合に OpenSSL を使用する人がいるとは想像できません。

CRYPTO_thread_setup();

OpenSSL を使用するスレッドを生成する前。これが重要な理由CRYPTO_thread_setupは、とりわけ、実際のロックを処理するプラットフォーム依存の関数への関数ポインタを設定するためです。が呼び出されない場合CRYPTO_thread_setup、このポインタは のままNULLであり、CRYPTO_lock(呼び出しの前後で使用されるマクロの下部にある関連する関数BIO_gethostbyname) は黙って何もしません。私の知る限り、これを知ることができるドキュメントはありません。

OpenSSL コードベースの品質に関するあなたの楽観主義は的外れであると主張することができます。

于 2014-11-18T13:43:09.917 に答える